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