Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: BSD-3-Clause */
0002 /*
0003  * Virtio Mem Device
0004  *
0005  * Copyright Red Hat, Inc. 2020
0006  *
0007  * Authors:
0008  *     David Hildenbrand <david@redhat.com>
0009  *
0010  * This header is BSD licensed so anyone can use the definitions
0011  * to implement compatible drivers/servers:
0012  *
0013  * Redistribution and use in source and binary forms, with or without
0014  * modification, are permitted provided that the following conditions
0015  * are met:
0016  * 1. Redistributions of source code must retain the above copyright
0017  *    notice, this list of conditions and the following disclaimer.
0018  * 2. Redistributions in binary form must reproduce the above copyright
0019  *    notice, this list of conditions and the following disclaimer in the
0020  *    documentation and/or other materials provided with the distribution.
0021  * 3. Neither the name of IBM nor the names of its contributors
0022  *    may be used to endorse or promote products derived from this software
0023  *    without specific prior written permission.
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0025  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0026  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
0027  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR
0028  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0029  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0030  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0031  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0032  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0033  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0034  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0035  * SUCH DAMAGE.
0036  */
0037 
0038 #ifndef _LINUX_VIRTIO_MEM_H
0039 #define _LINUX_VIRTIO_MEM_H
0040 
0041 #include <linux/types.h>
0042 #include <linux/virtio_types.h>
0043 #include <linux/virtio_ids.h>
0044 #include <linux/virtio_config.h>
0045 
0046 /*
0047  * Each virtio-mem device manages a dedicated region in physical address
0048  * space. Each device can belong to a single NUMA node, multiple devices
0049  * for a single NUMA node are possible. A virtio-mem device is like a
0050  * "resizable DIMM" consisting of small memory blocks that can be plugged
0051  * or unplugged. The device driver is responsible for (un)plugging memory
0052  * blocks on demand.
0053  *
0054  * Virtio-mem devices can only operate on their assigned memory region in
0055  * order to (un)plug memory. A device cannot (un)plug memory belonging to
0056  * other devices.
0057  *
0058  * The "region_size" corresponds to the maximum amount of memory that can
0059  * be provided by a device. The "size" corresponds to the amount of memory
0060  * that is currently plugged. "requested_size" corresponds to a request
0061  * from the device to the device driver to (un)plug blocks. The
0062  * device driver should try to (un)plug blocks in order to reach the
0063  * "requested_size". It is impossible to plug more memory than requested.
0064  *
0065  * The "usable_region_size" represents the memory region that can actually
0066  * be used to (un)plug memory. It is always at least as big as the
0067  * "requested_size" and will grow dynamically. It will only shrink when
0068  * explicitly triggered (VIRTIO_MEM_REQ_UNPLUG).
0069  *
0070  * There are no guarantees what will happen if unplugged memory is
0071  * read/written. In general, unplugged memory should not be touched, because
0072  * the resulting action is undefined. There is one exception: without
0073  * VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE, unplugged memory inside the usable
0074  * region can be read, to simplify creation of memory dumps.
0075  *
0076  * It can happen that the device cannot process a request, because it is
0077  * busy. The device driver has to retry later.
0078  *
0079  * Usually, during system resets all memory will get unplugged, so the
0080  * device driver can start with a clean state. However, in specific
0081  * scenarios (if the device is busy) it can happen that the device still
0082  * has memory plugged. The device driver can request to unplug all memory
0083  * (VIRTIO_MEM_REQ_UNPLUG) - which might take a while to succeed if the
0084  * device is busy.
0085  */
0086 
0087 /* --- virtio-mem: feature bits --- */
0088 
0089 /* node_id is an ACPI PXM and is valid */
0090 #define VIRTIO_MEM_F_ACPI_PXM       0
0091 /* unplugged memory must not be accessed */
0092 #define VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE 1
0093 
0094 
0095 /* --- virtio-mem: guest -> host requests --- */
0096 
0097 /* request to plug memory blocks */
0098 #define VIRTIO_MEM_REQ_PLUG         0
0099 /* request to unplug memory blocks */
0100 #define VIRTIO_MEM_REQ_UNPLUG           1
0101 /* request to unplug all blocks and shrink the usable size */
0102 #define VIRTIO_MEM_REQ_UNPLUG_ALL       2
0103 /* request information about the plugged state of memory blocks */
0104 #define VIRTIO_MEM_REQ_STATE            3
0105 
0106 struct virtio_mem_req_plug {
0107     __virtio64 addr;
0108     __virtio16 nb_blocks;
0109     __virtio16 padding[3];
0110 };
0111 
0112 struct virtio_mem_req_unplug {
0113     __virtio64 addr;
0114     __virtio16 nb_blocks;
0115     __virtio16 padding[3];
0116 };
0117 
0118 struct virtio_mem_req_state {
0119     __virtio64 addr;
0120     __virtio16 nb_blocks;
0121     __virtio16 padding[3];
0122 };
0123 
0124 struct virtio_mem_req {
0125     __virtio16 type;
0126     __virtio16 padding[3];
0127 
0128     union {
0129         struct virtio_mem_req_plug plug;
0130         struct virtio_mem_req_unplug unplug;
0131         struct virtio_mem_req_state state;
0132     } u;
0133 };
0134 
0135 
0136 /* --- virtio-mem: host -> guest response --- */
0137 
0138 /*
0139  * Request processed successfully, applicable for
0140  * - VIRTIO_MEM_REQ_PLUG
0141  * - VIRTIO_MEM_REQ_UNPLUG
0142  * - VIRTIO_MEM_REQ_UNPLUG_ALL
0143  * - VIRTIO_MEM_REQ_STATE
0144  */
0145 #define VIRTIO_MEM_RESP_ACK         0
0146 /*
0147  * Request denied - e.g. trying to plug more than requested, applicable for
0148  * - VIRTIO_MEM_REQ_PLUG
0149  */
0150 #define VIRTIO_MEM_RESP_NACK            1
0151 /*
0152  * Request cannot be processed right now, try again later, applicable for
0153  * - VIRTIO_MEM_REQ_PLUG
0154  * - VIRTIO_MEM_REQ_UNPLUG
0155  * - VIRTIO_MEM_REQ_UNPLUG_ALL
0156  */
0157 #define VIRTIO_MEM_RESP_BUSY            2
0158 /*
0159  * Error in request (e.g. addresses/alignment), applicable for
0160  * - VIRTIO_MEM_REQ_PLUG
0161  * - VIRTIO_MEM_REQ_UNPLUG
0162  * - VIRTIO_MEM_REQ_STATE
0163  */
0164 #define VIRTIO_MEM_RESP_ERROR           3
0165 
0166 
0167 /* State of memory blocks is "plugged" */
0168 #define VIRTIO_MEM_STATE_PLUGGED        0
0169 /* State of memory blocks is "unplugged" */
0170 #define VIRTIO_MEM_STATE_UNPLUGGED      1
0171 /* State of memory blocks is "mixed" */
0172 #define VIRTIO_MEM_STATE_MIXED          2
0173 
0174 struct virtio_mem_resp_state {
0175     __virtio16 state;
0176 };
0177 
0178 struct virtio_mem_resp {
0179     __virtio16 type;
0180     __virtio16 padding[3];
0181 
0182     union {
0183         struct virtio_mem_resp_state state;
0184     } u;
0185 };
0186 
0187 /* --- virtio-mem: configuration --- */
0188 
0189 struct virtio_mem_config {
0190     /* Block size and alignment. Cannot change. */
0191     __le64 block_size;
0192     /* Valid with VIRTIO_MEM_F_ACPI_PXM. Cannot change. */
0193     __le16 node_id;
0194     __u8 padding[6];
0195     /* Start address of the memory region. Cannot change. */
0196     __le64 addr;
0197     /* Region size (maximum). Cannot change. */
0198     __le64 region_size;
0199     /*
0200      * Currently usable region size. Can grow up to region_size. Can
0201      * shrink due to VIRTIO_MEM_REQ_UNPLUG_ALL (in which case no config
0202      * update will be sent).
0203      */
0204     __le64 usable_region_size;
0205     /*
0206      * Currently used size. Changes due to plug/unplug requests, but no
0207      * config updates will be sent.
0208      */
0209     __le64 plugged_size;
0210     /* Requested size. New plug requests cannot exceed it. Can change. */
0211     __le64 requested_size;
0212 };
0213 
0214 #endif /* _LINUX_VIRTIO_MEM_H */