15f1f79bbSDavid Hildenbrand /* SPDX-License-Identifier: BSD-3-Clause */ 25f1f79bbSDavid Hildenbrand /* 35f1f79bbSDavid Hildenbrand * Virtio Mem Device 45f1f79bbSDavid Hildenbrand * 55f1f79bbSDavid Hildenbrand * Copyright Red Hat, Inc. 2020 65f1f79bbSDavid Hildenbrand * 75f1f79bbSDavid Hildenbrand * Authors: 85f1f79bbSDavid Hildenbrand * David Hildenbrand <david@redhat.com> 95f1f79bbSDavid Hildenbrand * 105f1f79bbSDavid Hildenbrand * This header is BSD licensed so anyone can use the definitions 115f1f79bbSDavid Hildenbrand * to implement compatible drivers/servers: 125f1f79bbSDavid Hildenbrand * 135f1f79bbSDavid Hildenbrand * Redistribution and use in source and binary forms, with or without 145f1f79bbSDavid Hildenbrand * modification, are permitted provided that the following conditions 155f1f79bbSDavid Hildenbrand * are met: 165f1f79bbSDavid Hildenbrand * 1. Redistributions of source code must retain the above copyright 175f1f79bbSDavid Hildenbrand * notice, this list of conditions and the following disclaimer. 185f1f79bbSDavid Hildenbrand * 2. Redistributions in binary form must reproduce the above copyright 195f1f79bbSDavid Hildenbrand * notice, this list of conditions and the following disclaimer in the 205f1f79bbSDavid Hildenbrand * documentation and/or other materials provided with the distribution. 215f1f79bbSDavid Hildenbrand * 3. Neither the name of IBM nor the names of its contributors 225f1f79bbSDavid Hildenbrand * may be used to endorse or promote products derived from this software 235f1f79bbSDavid Hildenbrand * without specific prior written permission. 245f1f79bbSDavid Hildenbrand * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 255f1f79bbSDavid Hildenbrand * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 265f1f79bbSDavid Hildenbrand * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 275f1f79bbSDavid Hildenbrand * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM OR 285f1f79bbSDavid Hildenbrand * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 295f1f79bbSDavid Hildenbrand * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 305f1f79bbSDavid Hildenbrand * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 315f1f79bbSDavid Hildenbrand * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 325f1f79bbSDavid Hildenbrand * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 335f1f79bbSDavid Hildenbrand * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 345f1f79bbSDavid Hildenbrand * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 355f1f79bbSDavid Hildenbrand * SUCH DAMAGE. 365f1f79bbSDavid Hildenbrand */ 375f1f79bbSDavid Hildenbrand 385f1f79bbSDavid Hildenbrand #ifndef _LINUX_VIRTIO_MEM_H 395f1f79bbSDavid Hildenbrand #define _LINUX_VIRTIO_MEM_H 405f1f79bbSDavid Hildenbrand 415f1f79bbSDavid Hildenbrand #include <linux/types.h> 425f1f79bbSDavid Hildenbrand #include <linux/virtio_types.h> 435f1f79bbSDavid Hildenbrand #include <linux/virtio_ids.h> 445f1f79bbSDavid Hildenbrand #include <linux/virtio_config.h> 455f1f79bbSDavid Hildenbrand 465f1f79bbSDavid Hildenbrand /* 475f1f79bbSDavid Hildenbrand * Each virtio-mem device manages a dedicated region in physical address 485f1f79bbSDavid Hildenbrand * space. Each device can belong to a single NUMA node, multiple devices 495f1f79bbSDavid Hildenbrand * for a single NUMA node are possible. A virtio-mem device is like a 505f1f79bbSDavid Hildenbrand * "resizable DIMM" consisting of small memory blocks that can be plugged 515f1f79bbSDavid Hildenbrand * or unplugged. The device driver is responsible for (un)plugging memory 525f1f79bbSDavid Hildenbrand * blocks on demand. 535f1f79bbSDavid Hildenbrand * 545f1f79bbSDavid Hildenbrand * Virtio-mem devices can only operate on their assigned memory region in 555f1f79bbSDavid Hildenbrand * order to (un)plug memory. A device cannot (un)plug memory belonging to 565f1f79bbSDavid Hildenbrand * other devices. 575f1f79bbSDavid Hildenbrand * 585f1f79bbSDavid Hildenbrand * The "region_size" corresponds to the maximum amount of memory that can 595f1f79bbSDavid Hildenbrand * be provided by a device. The "size" corresponds to the amount of memory 605f1f79bbSDavid Hildenbrand * that is currently plugged. "requested_size" corresponds to a request 615f1f79bbSDavid Hildenbrand * from the device to the device driver to (un)plug blocks. The 625f1f79bbSDavid Hildenbrand * device driver should try to (un)plug blocks in order to reach the 635f1f79bbSDavid Hildenbrand * "requested_size". It is impossible to plug more memory than requested. 645f1f79bbSDavid Hildenbrand * 655f1f79bbSDavid Hildenbrand * The "usable_region_size" represents the memory region that can actually 665f1f79bbSDavid Hildenbrand * be used to (un)plug memory. It is always at least as big as the 675f1f79bbSDavid Hildenbrand * "requested_size" and will grow dynamically. It will only shrink when 685f1f79bbSDavid Hildenbrand * explicitly triggered (VIRTIO_MEM_REQ_UNPLUG). 695f1f79bbSDavid Hildenbrand * 705f1f79bbSDavid Hildenbrand * There are no guarantees what will happen if unplugged memory is 71*61082ad6SDavid Hildenbrand * read/written. In general, unplugged memory should not be touched, because 72*61082ad6SDavid Hildenbrand * the resulting action is undefined. There is one exception: without 73*61082ad6SDavid Hildenbrand * VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, unplugged memory inside the usable 74*61082ad6SDavid Hildenbrand * region can be read, to simplify creation of memory dumps. 755f1f79bbSDavid Hildenbrand * 765f1f79bbSDavid Hildenbrand * It can happen that the device cannot process a request, because it is 775f1f79bbSDavid Hildenbrand * busy. The device driver has to retry later. 785f1f79bbSDavid Hildenbrand * 795f1f79bbSDavid Hildenbrand * Usually, during system resets all memory will get unplugged, so the 805f1f79bbSDavid Hildenbrand * device driver can start with a clean state. However, in specific 815f1f79bbSDavid Hildenbrand * scenarios (if the device is busy) it can happen that the device still 825f1f79bbSDavid Hildenbrand * has memory plugged. The device driver can request to unplug all memory 835f1f79bbSDavid Hildenbrand * (VIRTIO_MEM_REQ_UNPLUG) - which might take a while to succeed if the 845f1f79bbSDavid Hildenbrand * device is busy. 855f1f79bbSDavid Hildenbrand */ 865f1f79bbSDavid Hildenbrand 87f2af6d39SDavid Hildenbrand /* --- virtio-mem: feature bits --- */ 88f2af6d39SDavid Hildenbrand 89f2af6d39SDavid Hildenbrand /* node_id is an ACPI PXM and is valid */ 90f2af6d39SDavid Hildenbrand #define VIRTIO_MEM_F_ACPI_PXM 0 91*61082ad6SDavid Hildenbrand /* unplugged memory must not be accessed */ 92*61082ad6SDavid Hildenbrand #define VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE 1 93f2af6d39SDavid Hildenbrand 94f2af6d39SDavid Hildenbrand 955f1f79bbSDavid Hildenbrand /* --- virtio-mem: guest -> host requests --- */ 965f1f79bbSDavid Hildenbrand 975f1f79bbSDavid Hildenbrand /* request to plug memory blocks */ 985f1f79bbSDavid Hildenbrand #define VIRTIO_MEM_REQ_PLUG 0 995f1f79bbSDavid Hildenbrand /* request to unplug memory blocks */ 1005f1f79bbSDavid Hildenbrand #define VIRTIO_MEM_REQ_UNPLUG 1 1015f1f79bbSDavid Hildenbrand /* request to unplug all blocks and shrink the usable size */ 1025f1f79bbSDavid Hildenbrand #define VIRTIO_MEM_REQ_UNPLUG_ALL 2 1035f1f79bbSDavid Hildenbrand /* request information about the plugged state of memory blocks */ 1045f1f79bbSDavid Hildenbrand #define VIRTIO_MEM_REQ_STATE 3 1055f1f79bbSDavid Hildenbrand 1065f1f79bbSDavid Hildenbrand struct virtio_mem_req_plug { 1075f1f79bbSDavid Hildenbrand __virtio64 addr; 1085f1f79bbSDavid Hildenbrand __virtio16 nb_blocks; 109fce8afd7SDavid Hildenbrand __virtio16 padding[3]; 1105f1f79bbSDavid Hildenbrand }; 1115f1f79bbSDavid Hildenbrand 1125f1f79bbSDavid Hildenbrand struct virtio_mem_req_unplug { 1135f1f79bbSDavid Hildenbrand __virtio64 addr; 1145f1f79bbSDavid Hildenbrand __virtio16 nb_blocks; 115fce8afd7SDavid Hildenbrand __virtio16 padding[3]; 1165f1f79bbSDavid Hildenbrand }; 1175f1f79bbSDavid Hildenbrand 1185f1f79bbSDavid Hildenbrand struct virtio_mem_req_state { 1195f1f79bbSDavid Hildenbrand __virtio64 addr; 1205f1f79bbSDavid Hildenbrand __virtio16 nb_blocks; 121fce8afd7SDavid Hildenbrand __virtio16 padding[3]; 1225f1f79bbSDavid Hildenbrand }; 1235f1f79bbSDavid Hildenbrand 1245f1f79bbSDavid Hildenbrand struct virtio_mem_req { 1255f1f79bbSDavid Hildenbrand __virtio16 type; 1265f1f79bbSDavid Hildenbrand __virtio16 padding[3]; 1275f1f79bbSDavid Hildenbrand 1285f1f79bbSDavid Hildenbrand union { 1295f1f79bbSDavid Hildenbrand struct virtio_mem_req_plug plug; 1305f1f79bbSDavid Hildenbrand struct virtio_mem_req_unplug unplug; 1315f1f79bbSDavid Hildenbrand struct virtio_mem_req_state state; 1325f1f79bbSDavid Hildenbrand } u; 1335f1f79bbSDavid Hildenbrand }; 1345f1f79bbSDavid Hildenbrand 1355f1f79bbSDavid Hildenbrand 1365f1f79bbSDavid Hildenbrand /* --- virtio-mem: host -> guest response --- */ 1375f1f79bbSDavid Hildenbrand 1385f1f79bbSDavid Hildenbrand /* 1395f1f79bbSDavid Hildenbrand * Request processed successfully, applicable for 1405f1f79bbSDavid Hildenbrand * - VIRTIO_MEM_REQ_PLUG 1415f1f79bbSDavid Hildenbrand * - VIRTIO_MEM_REQ_UNPLUG 1425f1f79bbSDavid Hildenbrand * - VIRTIO_MEM_REQ_UNPLUG_ALL 1435f1f79bbSDavid Hildenbrand * - VIRTIO_MEM_REQ_STATE 1445f1f79bbSDavid Hildenbrand */ 1455f1f79bbSDavid Hildenbrand #define VIRTIO_MEM_RESP_ACK 0 1465f1f79bbSDavid Hildenbrand /* 1475f1f79bbSDavid Hildenbrand * Request denied - e.g. trying to plug more than requested, applicable for 1485f1f79bbSDavid Hildenbrand * - VIRTIO_MEM_REQ_PLUG 1495f1f79bbSDavid Hildenbrand */ 1505f1f79bbSDavid Hildenbrand #define VIRTIO_MEM_RESP_NACK 1 1515f1f79bbSDavid Hildenbrand /* 1525f1f79bbSDavid Hildenbrand * Request cannot be processed right now, try again later, applicable for 1535f1f79bbSDavid Hildenbrand * - VIRTIO_MEM_REQ_PLUG 1545f1f79bbSDavid Hildenbrand * - VIRTIO_MEM_REQ_UNPLUG 1555f1f79bbSDavid Hildenbrand * - VIRTIO_MEM_REQ_UNPLUG_ALL 1565f1f79bbSDavid Hildenbrand */ 1575f1f79bbSDavid Hildenbrand #define VIRTIO_MEM_RESP_BUSY 2 1585f1f79bbSDavid Hildenbrand /* 1595f1f79bbSDavid Hildenbrand * Error in request (e.g. addresses/alignment), applicable for 1605f1f79bbSDavid Hildenbrand * - VIRTIO_MEM_REQ_PLUG 1615f1f79bbSDavid Hildenbrand * - VIRTIO_MEM_REQ_UNPLUG 1625f1f79bbSDavid Hildenbrand * - VIRTIO_MEM_REQ_STATE 1635f1f79bbSDavid Hildenbrand */ 1645f1f79bbSDavid Hildenbrand #define VIRTIO_MEM_RESP_ERROR 3 1655f1f79bbSDavid Hildenbrand 1665f1f79bbSDavid Hildenbrand 1675f1f79bbSDavid Hildenbrand /* State of memory blocks is "plugged" */ 1685f1f79bbSDavid Hildenbrand #define VIRTIO_MEM_STATE_PLUGGED 0 1695f1f79bbSDavid Hildenbrand /* State of memory blocks is "unplugged" */ 1705f1f79bbSDavid Hildenbrand #define VIRTIO_MEM_STATE_UNPLUGGED 1 1715f1f79bbSDavid Hildenbrand /* State of memory blocks is "mixed" */ 1725f1f79bbSDavid Hildenbrand #define VIRTIO_MEM_STATE_MIXED 2 1735f1f79bbSDavid Hildenbrand 1745f1f79bbSDavid Hildenbrand struct virtio_mem_resp_state { 1755f1f79bbSDavid Hildenbrand __virtio16 state; 1765f1f79bbSDavid Hildenbrand }; 1775f1f79bbSDavid Hildenbrand 1785f1f79bbSDavid Hildenbrand struct virtio_mem_resp { 1795f1f79bbSDavid Hildenbrand __virtio16 type; 1805f1f79bbSDavid Hildenbrand __virtio16 padding[3]; 1815f1f79bbSDavid Hildenbrand 1825f1f79bbSDavid Hildenbrand union { 1835f1f79bbSDavid Hildenbrand struct virtio_mem_resp_state state; 1845f1f79bbSDavid Hildenbrand } u; 1855f1f79bbSDavid Hildenbrand }; 1865f1f79bbSDavid Hildenbrand 1875f1f79bbSDavid Hildenbrand /* --- virtio-mem: configuration --- */ 1885f1f79bbSDavid Hildenbrand 1895f1f79bbSDavid Hildenbrand struct virtio_mem_config { 1905f1f79bbSDavid Hildenbrand /* Block size and alignment. Cannot change. */ 19179268954SMichael S. Tsirkin __le64 block_size; 192f2af6d39SDavid Hildenbrand /* Valid with VIRTIO_MEM_F_ACPI_PXM. Cannot change. */ 19379268954SMichael S. Tsirkin __le16 node_id; 194544fc7dbSMichael S. Tsirkin __u8 padding[6]; 1955f1f79bbSDavid Hildenbrand /* Start address of the memory region. Cannot change. */ 19679268954SMichael S. Tsirkin __le64 addr; 1975f1f79bbSDavid Hildenbrand /* Region size (maximum). Cannot change. */ 19879268954SMichael S. Tsirkin __le64 region_size; 1995f1f79bbSDavid Hildenbrand /* 2005f1f79bbSDavid Hildenbrand * Currently usable region size. Can grow up to region_size. Can 2015f1f79bbSDavid Hildenbrand * shrink due to VIRTIO_MEM_REQ_UNPLUG_ALL (in which case no config 2025f1f79bbSDavid Hildenbrand * update will be sent). 2035f1f79bbSDavid Hildenbrand */ 20479268954SMichael S. Tsirkin __le64 usable_region_size; 2055f1f79bbSDavid Hildenbrand /* 2065f1f79bbSDavid Hildenbrand * Currently used size. Changes due to plug/unplug requests, but no 2075f1f79bbSDavid Hildenbrand * config updates will be sent. 2085f1f79bbSDavid Hildenbrand */ 20979268954SMichael S. Tsirkin __le64 plugged_size; 2105f1f79bbSDavid Hildenbrand /* Requested size. New plug requests cannot exceed it. Can change. */ 21179268954SMichael S. Tsirkin __le64 requested_size; 2125f1f79bbSDavid Hildenbrand }; 2135f1f79bbSDavid Hildenbrand 2145f1f79bbSDavid Hildenbrand #endif /* _LINUX_VIRTIO_MEM_H */ 215