1 /* 2 * Virtio MEM device 3 * 4 * Copyright (C) 2020 Red Hat, Inc. 5 * 6 * Authors: 7 * David Hildenbrand <david@redhat.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2. 10 * See the COPYING file in the top-level directory. 11 */ 12 13 #ifndef HW_VIRTIO_MEM_H 14 #define HW_VIRTIO_MEM_H 15 16 #include "standard-headers/linux/virtio_mem.h" 17 #include "hw/resettable.h" 18 #include "hw/virtio/virtio.h" 19 #include "qapi/qapi-types-misc.h" 20 #include "system/hostmem.h" 21 #include "qom/object.h" 22 23 #define TYPE_VIRTIO_MEM "virtio-mem" 24 25 OBJECT_DECLARE_TYPE(VirtIOMEM, VirtIOMEMClass, 26 VIRTIO_MEM) 27 28 #define TYPE_VIRTIO_MEM_SYSTEM_RESET "virtio-mem-system-reset" 29 30 OBJECT_DECLARE_SIMPLE_TYPE(VirtioMemSystemReset, VIRTIO_MEM_SYSTEM_RESET) 31 32 #define VIRTIO_MEM_MEMDEV_PROP "memdev" 33 #define VIRTIO_MEM_NODE_PROP "node" 34 #define VIRTIO_MEM_SIZE_PROP "size" 35 #define VIRTIO_MEM_REQUESTED_SIZE_PROP "requested-size" 36 #define VIRTIO_MEM_BLOCK_SIZE_PROP "block-size" 37 #define VIRTIO_MEM_ADDR_PROP "memaddr" 38 #define VIRTIO_MEM_UNPLUGGED_INACCESSIBLE_PROP "unplugged-inaccessible" 39 #define VIRTIO_MEM_EARLY_MIGRATION_PROP "x-early-migration" 40 #define VIRTIO_MEM_PREALLOC_PROP "prealloc" 41 #define VIRTIO_MEM_DYNAMIC_MEMSLOTS_PROP "dynamic-memslots" 42 43 struct VirtIOMEM { 44 VirtIODevice parent_obj; 45 46 /* guest -> host request queue */ 47 VirtQueue *vq; 48 49 /* bitmap used to track unplugged memory */ 50 int32_t bitmap_size; 51 unsigned long *bitmap; 52 53 /* 54 * With "dynamic-memslots=on": Device memory region in which we dynamically 55 * map the memslots. 56 */ 57 MemoryRegion *mr; 58 59 /* 60 * With "dynamic-memslots=on": The individual memslots (aliases into the 61 * memory backend). 62 */ 63 MemoryRegion *memslots; 64 65 /* With "dynamic-memslots=on": The total number of memslots. */ 66 uint16_t nb_memslots; 67 68 /* 69 * With "dynamic-memslots=on": Size of one memslot (the size of the 70 * last one can differ). 71 */ 72 uint64_t memslot_size; 73 74 /* Assigned memory backend with the RAM memory region. */ 75 HostMemoryBackend *memdev; 76 77 /* NUMA node */ 78 uint32_t node; 79 80 /* assigned address of the region in guest physical memory */ 81 uint64_t addr; 82 83 /* usable region size (<= region_size) */ 84 uint64_t usable_region_size; 85 86 /* actual size (how much the guest plugged) */ 87 uint64_t size; 88 89 /* requested size */ 90 uint64_t requested_size; 91 92 /* block size and alignment */ 93 uint64_t block_size; 94 95 /* 96 * Whether we indicate VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE to the guest. 97 * For !x86 targets this will always be "on" and consequently indicate 98 * VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE. 99 */ 100 OnOffAuto unplugged_inaccessible; 101 102 /* whether to prealloc memory when plugging new blocks */ 103 bool prealloc; 104 105 /* 106 * Whether we migrate properties that are immutable while migration is 107 * active early, before state of other devices and especially, before 108 * migrating any RAM content. 109 */ 110 bool early_migration; 111 112 /* 113 * Whether we dynamically map (multiple, if possible) memslots instead of 114 * statically mapping the whole RAM memory region. 115 */ 116 bool dynamic_memslots; 117 118 /* notifiers to notify when "size" changes */ 119 NotifierList size_change_notifiers; 120 121 /* listeners to notify on plug/unplug activity. */ 122 QLIST_HEAD(, RamDiscardListener) rdl_list; 123 124 /* Catch system resets -> qemu_devices_reset() only. */ 125 VirtioMemSystemReset *system_reset; 126 }; 127 128 struct VirtioMemSystemReset { 129 Object parent; 130 131 ResettableState reset_state; 132 VirtIOMEM *vmem; 133 }; 134 135 struct VirtIOMEMClass { 136 /* private */ 137 VirtIODevice parent; 138 139 /* public */ 140 void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi); 141 MemoryRegion *(*get_memory_region)(VirtIOMEM *vmem, Error **errp); 142 void (*decide_memslots)(VirtIOMEM *vmem, unsigned int limit); 143 unsigned int (*get_memslots)(VirtIOMEM *vmem); 144 void (*add_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier); 145 void (*remove_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier); 146 void (*unplug_request_check)(VirtIOMEM *vmem, Error **errp); 147 }; 148 149 #endif 150