1f76b348eSCornelia Huck /* SPDX-License-Identifier: BSD-3-Clause */ 2f76b348eSCornelia Huck /* 3f76b348eSCornelia Huck * Virtio Mem Device 4f76b348eSCornelia Huck * 5f76b348eSCornelia Huck * Copyright Red Hat, Inc. 2020 6f76b348eSCornelia Huck * 7f76b348eSCornelia Huck * Authors: 8f76b348eSCornelia Huck * David Hildenbrand <david@redhat.com> 9f76b348eSCornelia Huck * 10f76b348eSCornelia Huck * This header is BSD licensed so anyone can use the definitions 11f76b348eSCornelia Huck * to implement compatible drivers/servers: 12f76b348eSCornelia Huck * 13f76b348eSCornelia Huck * Redistribution and use in source and binary forms, with or without 14f76b348eSCornelia Huck * modification, are permitted provided that the following conditions 15f76b348eSCornelia Huck * are met: 16f76b348eSCornelia Huck * 1. Redistributions of source code must retain the above copyright 17f76b348eSCornelia Huck * notice, this list of conditions and the following disclaimer. 18f76b348eSCornelia Huck * 2. Redistributions in binary form must reproduce the above copyright 19f76b348eSCornelia Huck * notice, this list of conditions and the following disclaimer in the 20f76b348eSCornelia Huck * documentation and/or other materials provided with the distribution. 21f76b348eSCornelia Huck * 3. Neither the name of IBM nor the names of its contributors 22f76b348eSCornelia Huck * may be used to endorse or promote products derived from this software 23f76b348eSCornelia Huck * without specific prior written permission. 24f76b348eSCornelia Huck * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25f76b348eSCornelia Huck * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26f76b348eSCornelia Huck * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27f76b348eSCornelia Huck * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM OR 28f76b348eSCornelia Huck * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29f76b348eSCornelia Huck * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30f76b348eSCornelia Huck * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 31f76b348eSCornelia Huck * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32f76b348eSCornelia Huck * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33f76b348eSCornelia Huck * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 34f76b348eSCornelia Huck * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35f76b348eSCornelia Huck * SUCH DAMAGE. 36f76b348eSCornelia Huck */ 37f76b348eSCornelia Huck 38f76b348eSCornelia Huck #ifndef _LINUX_VIRTIO_MEM_H 39f76b348eSCornelia Huck #define _LINUX_VIRTIO_MEM_H 40f76b348eSCornelia Huck 41f76b348eSCornelia Huck #include "standard-headers/linux/types.h" 42f76b348eSCornelia Huck #include "standard-headers/linux/virtio_types.h" 43f76b348eSCornelia Huck #include "standard-headers/linux/virtio_ids.h" 44f76b348eSCornelia Huck #include "standard-headers/linux/virtio_config.h" 45f76b348eSCornelia Huck 46f76b348eSCornelia Huck /* 47f76b348eSCornelia Huck * Each virtio-mem device manages a dedicated region in physical address 48f76b348eSCornelia Huck * space. Each device can belong to a single NUMA node, multiple devices 49f76b348eSCornelia Huck * for a single NUMA node are possible. A virtio-mem device is like a 50f76b348eSCornelia Huck * "resizable DIMM" consisting of small memory blocks that can be plugged 51f76b348eSCornelia Huck * or unplugged. The device driver is responsible for (un)plugging memory 52f76b348eSCornelia Huck * blocks on demand. 53f76b348eSCornelia Huck * 54f76b348eSCornelia Huck * Virtio-mem devices can only operate on their assigned memory region in 55f76b348eSCornelia Huck * order to (un)plug memory. A device cannot (un)plug memory belonging to 56f76b348eSCornelia Huck * other devices. 57f76b348eSCornelia Huck * 58f76b348eSCornelia Huck * The "region_size" corresponds to the maximum amount of memory that can 59f76b348eSCornelia Huck * be provided by a device. The "size" corresponds to the amount of memory 60f76b348eSCornelia Huck * that is currently plugged. "requested_size" corresponds to a request 61f76b348eSCornelia Huck * from the device to the device driver to (un)plug blocks. The 62f76b348eSCornelia Huck * device driver should try to (un)plug blocks in order to reach the 63f76b348eSCornelia Huck * "requested_size". It is impossible to plug more memory than requested. 64f76b348eSCornelia Huck * 65f76b348eSCornelia Huck * The "usable_region_size" represents the memory region that can actually 66f76b348eSCornelia Huck * be used to (un)plug memory. It is always at least as big as the 67f76b348eSCornelia Huck * "requested_size" and will grow dynamically. It will only shrink when 68f76b348eSCornelia Huck * explicitly triggered (VIRTIO_MEM_REQ_UNPLUG). 69f76b348eSCornelia Huck * 70f76b348eSCornelia Huck * There are no guarantees what will happen if unplugged memory is 713ff9b192SDavid Hildenbrand * read/written. In general, unplugged memory should not be touched, because 723ff9b192SDavid Hildenbrand * the resulting action is undefined. There is one exception: without 733ff9b192SDavid Hildenbrand * VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, unplugged memory inside the usable 743ff9b192SDavid Hildenbrand * region can be read, to simplify creation of memory dumps. 75f76b348eSCornelia Huck * 76f76b348eSCornelia Huck * It can happen that the device cannot process a request, because it is 77f76b348eSCornelia Huck * busy. The device driver has to retry later. 78f76b348eSCornelia Huck * 79f76b348eSCornelia Huck * Usually, during system resets all memory will get unplugged, so the 80f76b348eSCornelia Huck * device driver can start with a clean state. However, in specific 81f76b348eSCornelia Huck * scenarios (if the device is busy) it can happen that the device still 82f76b348eSCornelia Huck * has memory plugged. The device driver can request to unplug all memory 83f76b348eSCornelia Huck * (VIRTIO_MEM_REQ_UNPLUG) - which might take a while to succeed if the 84f76b348eSCornelia Huck * device is busy. 85f76b348eSCornelia Huck */ 86f76b348eSCornelia Huck 87f76b348eSCornelia Huck /* --- virtio-mem: feature bits --- */ 88f76b348eSCornelia Huck 89f76b348eSCornelia Huck /* node_id is an ACPI PXM and is valid */ 90f76b348eSCornelia Huck #define VIRTIO_MEM_F_ACPI_PXM 0 913ff9b192SDavid Hildenbrand /* unplugged memory must not be accessed */ 923ff9b192SDavid Hildenbrand #define VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE 1 93*c5614ee3SThomas Weißschuh /* plugged memory will remain plugged when suspending+resuming */ 94*c5614ee3SThomas Weißschuh #define VIRTIO_MEM_F_PERSISTENT_SUSPEND 2 95f76b348eSCornelia Huck 96f76b348eSCornelia Huck 97f76b348eSCornelia Huck /* --- virtio-mem: guest -> host requests --- */ 98f76b348eSCornelia Huck 99f76b348eSCornelia Huck /* request to plug memory blocks */ 100f76b348eSCornelia Huck #define VIRTIO_MEM_REQ_PLUG 0 101f76b348eSCornelia Huck /* request to unplug memory blocks */ 102f76b348eSCornelia Huck #define VIRTIO_MEM_REQ_UNPLUG 1 103f76b348eSCornelia Huck /* request to unplug all blocks and shrink the usable size */ 104f76b348eSCornelia Huck #define VIRTIO_MEM_REQ_UNPLUG_ALL 2 105f76b348eSCornelia Huck /* request information about the plugged state of memory blocks */ 106f76b348eSCornelia Huck #define VIRTIO_MEM_REQ_STATE 3 107f76b348eSCornelia Huck 108f76b348eSCornelia Huck struct virtio_mem_req_plug { 109f76b348eSCornelia Huck __virtio64 addr; 110f76b348eSCornelia Huck __virtio16 nb_blocks; 111f76b348eSCornelia Huck __virtio16 padding[3]; 112f76b348eSCornelia Huck }; 113f76b348eSCornelia Huck 114f76b348eSCornelia Huck struct virtio_mem_req_unplug { 115f76b348eSCornelia Huck __virtio64 addr; 116f76b348eSCornelia Huck __virtio16 nb_blocks; 117f76b348eSCornelia Huck __virtio16 padding[3]; 118f76b348eSCornelia Huck }; 119f76b348eSCornelia Huck 120f76b348eSCornelia Huck struct virtio_mem_req_state { 121f76b348eSCornelia Huck __virtio64 addr; 122f76b348eSCornelia Huck __virtio16 nb_blocks; 123f76b348eSCornelia Huck __virtio16 padding[3]; 124f76b348eSCornelia Huck }; 125f76b348eSCornelia Huck 126f76b348eSCornelia Huck struct virtio_mem_req { 127f76b348eSCornelia Huck __virtio16 type; 128f76b348eSCornelia Huck __virtio16 padding[3]; 129f76b348eSCornelia Huck 130f76b348eSCornelia Huck union { 131f76b348eSCornelia Huck struct virtio_mem_req_plug plug; 132f76b348eSCornelia Huck struct virtio_mem_req_unplug unplug; 133f76b348eSCornelia Huck struct virtio_mem_req_state state; 134f76b348eSCornelia Huck } u; 135f76b348eSCornelia Huck }; 136f76b348eSCornelia Huck 137f76b348eSCornelia Huck 138f76b348eSCornelia Huck /* --- virtio-mem: host -> guest response --- */ 139f76b348eSCornelia Huck 140f76b348eSCornelia Huck /* 141f76b348eSCornelia Huck * Request processed successfully, applicable for 142f76b348eSCornelia Huck * - VIRTIO_MEM_REQ_PLUG 143f76b348eSCornelia Huck * - VIRTIO_MEM_REQ_UNPLUG 144f76b348eSCornelia Huck * - VIRTIO_MEM_REQ_UNPLUG_ALL 145f76b348eSCornelia Huck * - VIRTIO_MEM_REQ_STATE 146f76b348eSCornelia Huck */ 147f76b348eSCornelia Huck #define VIRTIO_MEM_RESP_ACK 0 148f76b348eSCornelia Huck /* 149f76b348eSCornelia Huck * Request denied - e.g. trying to plug more than requested, applicable for 150f76b348eSCornelia Huck * - VIRTIO_MEM_REQ_PLUG 151f76b348eSCornelia Huck */ 152f76b348eSCornelia Huck #define VIRTIO_MEM_RESP_NACK 1 153f76b348eSCornelia Huck /* 154f76b348eSCornelia Huck * Request cannot be processed right now, try again later, applicable for 155f76b348eSCornelia Huck * - VIRTIO_MEM_REQ_PLUG 156f76b348eSCornelia Huck * - VIRTIO_MEM_REQ_UNPLUG 157f76b348eSCornelia Huck * - VIRTIO_MEM_REQ_UNPLUG_ALL 158f76b348eSCornelia Huck */ 159f76b348eSCornelia Huck #define VIRTIO_MEM_RESP_BUSY 2 160f76b348eSCornelia Huck /* 161f76b348eSCornelia Huck * Error in request (e.g. addresses/alignment), applicable for 162f76b348eSCornelia Huck * - VIRTIO_MEM_REQ_PLUG 163f76b348eSCornelia Huck * - VIRTIO_MEM_REQ_UNPLUG 164f76b348eSCornelia Huck * - VIRTIO_MEM_REQ_STATE 165f76b348eSCornelia Huck */ 166f76b348eSCornelia Huck #define VIRTIO_MEM_RESP_ERROR 3 167f76b348eSCornelia Huck 168f76b348eSCornelia Huck 169f76b348eSCornelia Huck /* State of memory blocks is "plugged" */ 170f76b348eSCornelia Huck #define VIRTIO_MEM_STATE_PLUGGED 0 171f76b348eSCornelia Huck /* State of memory blocks is "unplugged" */ 172f76b348eSCornelia Huck #define VIRTIO_MEM_STATE_UNPLUGGED 1 173f76b348eSCornelia Huck /* State of memory blocks is "mixed" */ 174f76b348eSCornelia Huck #define VIRTIO_MEM_STATE_MIXED 2 175f76b348eSCornelia Huck 176f76b348eSCornelia Huck struct virtio_mem_resp_state { 177f76b348eSCornelia Huck __virtio16 state; 178f76b348eSCornelia Huck }; 179f76b348eSCornelia Huck 180f76b348eSCornelia Huck struct virtio_mem_resp { 181f76b348eSCornelia Huck __virtio16 type; 182f76b348eSCornelia Huck __virtio16 padding[3]; 183f76b348eSCornelia Huck 184f76b348eSCornelia Huck union { 185f76b348eSCornelia Huck struct virtio_mem_resp_state state; 186f76b348eSCornelia Huck } u; 187f76b348eSCornelia Huck }; 188f76b348eSCornelia Huck 189f76b348eSCornelia Huck /* --- virtio-mem: configuration --- */ 190f76b348eSCornelia Huck 191f76b348eSCornelia Huck struct virtio_mem_config { 192f76b348eSCornelia Huck /* Block size and alignment. Cannot change. */ 193f76b348eSCornelia Huck uint64_t block_size; 194f76b348eSCornelia Huck /* Valid with VIRTIO_MEM_F_ACPI_PXM. Cannot change. */ 195f76b348eSCornelia Huck uint16_t node_id; 196f76b348eSCornelia Huck uint8_t padding[6]; 197f76b348eSCornelia Huck /* Start address of the memory region. Cannot change. */ 198f76b348eSCornelia Huck uint64_t addr; 199f76b348eSCornelia Huck /* Region size (maximum). Cannot change. */ 200f76b348eSCornelia Huck uint64_t region_size; 201f76b348eSCornelia Huck /* 202f76b348eSCornelia Huck * Currently usable region size. Can grow up to region_size. Can 203f76b348eSCornelia Huck * shrink due to VIRTIO_MEM_REQ_UNPLUG_ALL (in which case no config 204f76b348eSCornelia Huck * update will be sent). 205f76b348eSCornelia Huck */ 206f76b348eSCornelia Huck uint64_t usable_region_size; 207f76b348eSCornelia Huck /* 208f76b348eSCornelia Huck * Currently used size. Changes due to plug/unplug requests, but no 209f76b348eSCornelia Huck * config updates will be sent. 210f76b348eSCornelia Huck */ 211f76b348eSCornelia Huck uint64_t plugged_size; 212f76b348eSCornelia Huck /* Requested size. New plug requests cannot exceed it. Can change. */ 213f76b348eSCornelia Huck uint64_t requested_size; 214f76b348eSCornelia Huck }; 215f76b348eSCornelia Huck 216f76b348eSCornelia Huck #endif /* _LINUX_VIRTIO_MEM_H */ 217