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/virtio/virtio.h" 18 #include "qapi/qapi-types-misc.h" 19 #include "sysemu/hostmem.h" 20 #include "qom/object.h" 21 22 #define TYPE_VIRTIO_MEM "virtio-mem" 23 24 OBJECT_DECLARE_TYPE(VirtIOMEM, VirtIOMEMClass, 25 VIRTIO_MEM) 26 27 #define VIRTIO_MEM_MEMDEV_PROP "memdev" 28 #define VIRTIO_MEM_NODE_PROP "node" 29 #define VIRTIO_MEM_SIZE_PROP "size" 30 #define VIRTIO_MEM_REQUESTED_SIZE_PROP "requested-size" 31 #define VIRTIO_MEM_BLOCK_SIZE_PROP "block-size" 32 #define VIRTIO_MEM_ADDR_PROP "memaddr" 33 #define VIRTIO_MEM_UNPLUGGED_INACCESSIBLE_PROP "unplugged-inaccessible" 34 #define VIRTIO_MEM_EARLY_MIGRATION_PROP "x-early-migration" 35 #define VIRTIO_MEM_PREALLOC_PROP "prealloc" 36 #define VIRTIO_MEM_DYNAMIC_MEMSLOTS_PROP "dynamic-memslots" 37 38 struct VirtIOMEM { 39 VirtIODevice parent_obj; 40 41 /* guest -> host request queue */ 42 VirtQueue *vq; 43 44 /* bitmap used to track unplugged memory */ 45 int32_t bitmap_size; 46 unsigned long *bitmap; 47 48 /* 49 * With "dynamic-memslots=on": Device memory region in which we dynamically 50 * map the memslots. 51 */ 52 MemoryRegion *mr; 53 54 /* 55 * With "dynamic-memslots=on": The individual memslots (aliases into the 56 * memory backend). 57 */ 58 MemoryRegion *memslots; 59 60 /* With "dynamic-memslots=on": The total number of memslots. */ 61 uint16_t nb_memslots; 62 63 /* 64 * With "dynamic-memslots=on": Size of one memslot (the size of the 65 * last one can differ). 66 */ 67 uint64_t memslot_size; 68 69 /* Assigned memory backend with the RAM memory region. */ 70 HostMemoryBackend *memdev; 71 72 /* NUMA node */ 73 uint32_t node; 74 75 /* assigned address of the region in guest physical memory */ 76 uint64_t addr; 77 78 /* usable region size (<= region_size) */ 79 uint64_t usable_region_size; 80 81 /* actual size (how much the guest plugged) */ 82 uint64_t size; 83 84 /* requested size */ 85 uint64_t requested_size; 86 87 /* block size and alignment */ 88 uint64_t block_size; 89 90 /* 91 * Whether we indicate VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE to the guest. 92 * For !x86 targets this will always be "on" and consequently indicate 93 * VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE. 94 */ 95 OnOffAuto unplugged_inaccessible; 96 97 /* whether to prealloc memory when plugging new blocks */ 98 bool prealloc; 99 100 /* 101 * Whether we migrate properties that are immutable while migration is 102 * active early, before state of other devices and especially, before 103 * migrating any RAM content. 104 */ 105 bool early_migration; 106 107 /* 108 * Whether we dynamically map (multiple, if possible) memslots instead of 109 * statically mapping the whole RAM memory region. 110 */ 111 bool dynamic_memslots; 112 113 /* notifiers to notify when "size" changes */ 114 NotifierList size_change_notifiers; 115 116 /* listeners to notify on plug/unplug activity. */ 117 QLIST_HEAD(, RamDiscardListener) rdl_list; 118 }; 119 120 struct VirtIOMEMClass { 121 /* private */ 122 VirtIODevice parent; 123 124 /* public */ 125 void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi); 126 MemoryRegion *(*get_memory_region)(VirtIOMEM *vmem, Error **errp); 127 void (*decide_memslots)(VirtIOMEM *vmem, unsigned int limit); 128 unsigned int (*get_memslots)(VirtIOMEM *vmem); 129 void (*add_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier); 130 void (*remove_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier); 131 void (*unplug_request_check)(VirtIOMEM *vmem, Error **errp); 132 }; 133 134 #endif 135