1910b2576SDavid Hildenbrand /* 2910b2576SDavid Hildenbrand * Virtio MEM device 3910b2576SDavid Hildenbrand * 4910b2576SDavid Hildenbrand * Copyright (C) 2020 Red Hat, Inc. 5910b2576SDavid Hildenbrand * 6910b2576SDavid Hildenbrand * Authors: 7910b2576SDavid Hildenbrand * David Hildenbrand <david@redhat.com> 8910b2576SDavid Hildenbrand * 9910b2576SDavid Hildenbrand * This work is licensed under the terms of the GNU GPL, version 2. 10910b2576SDavid Hildenbrand * See the COPYING file in the top-level directory. 11910b2576SDavid Hildenbrand */ 12910b2576SDavid Hildenbrand 13910b2576SDavid Hildenbrand #ifndef HW_VIRTIO_MEM_H 14910b2576SDavid Hildenbrand #define HW_VIRTIO_MEM_H 15910b2576SDavid Hildenbrand 16910b2576SDavid Hildenbrand #include "standard-headers/linux/virtio_mem.h" 17910b2576SDavid Hildenbrand #include "hw/virtio/virtio.h" 18910b2576SDavid Hildenbrand #include "qapi/qapi-types-misc.h" 19910b2576SDavid Hildenbrand #include "sysemu/hostmem.h" 20db1015e9SEduardo Habkost #include "qom/object.h" 21910b2576SDavid Hildenbrand 22910b2576SDavid Hildenbrand #define TYPE_VIRTIO_MEM "virtio-mem" 23910b2576SDavid Hildenbrand 24c821774aSEduardo Habkost OBJECT_DECLARE_TYPE(VirtIOMEM, VirtIOMEMClass, 2530b5707cSEduardo Habkost VIRTIO_MEM) 26910b2576SDavid Hildenbrand 27910b2576SDavid Hildenbrand #define VIRTIO_MEM_MEMDEV_PROP "memdev" 28910b2576SDavid Hildenbrand #define VIRTIO_MEM_NODE_PROP "node" 29910b2576SDavid Hildenbrand #define VIRTIO_MEM_SIZE_PROP "size" 30910b2576SDavid Hildenbrand #define VIRTIO_MEM_REQUESTED_SIZE_PROP "requested-size" 31910b2576SDavid Hildenbrand #define VIRTIO_MEM_BLOCK_SIZE_PROP "block-size" 32910b2576SDavid Hildenbrand #define VIRTIO_MEM_ADDR_PROP "memaddr" 3323ad8decSDavid Hildenbrand #define VIRTIO_MEM_UNPLUGGED_INACCESSIBLE_PROP "unplugged-inaccessible" 343b95a71bSDavid Hildenbrand #define VIRTIO_MEM_EARLY_MIGRATION_PROP "x-early-migration" 3509b3b7e0SDavid Hildenbrand #define VIRTIO_MEM_PREALLOC_PROP "prealloc" 36*177f9b1eSDavid Hildenbrand #define VIRTIO_MEM_DYNAMIC_MEMSLOTS_PROP "dynamic-memslots" 37910b2576SDavid Hildenbrand 38db1015e9SEduardo Habkost struct VirtIOMEM { 39910b2576SDavid Hildenbrand VirtIODevice parent_obj; 40910b2576SDavid Hildenbrand 41910b2576SDavid Hildenbrand /* guest -> host request queue */ 42910b2576SDavid Hildenbrand VirtQueue *vq; 43910b2576SDavid Hildenbrand 44910b2576SDavid Hildenbrand /* bitmap used to track unplugged memory */ 45910b2576SDavid Hildenbrand int32_t bitmap_size; 46910b2576SDavid Hildenbrand unsigned long *bitmap; 47910b2576SDavid Hildenbrand 48*177f9b1eSDavid Hildenbrand /* 49*177f9b1eSDavid Hildenbrand * With "dynamic-memslots=on": Device memory region in which we dynamically 50*177f9b1eSDavid Hildenbrand * map the memslots. 51*177f9b1eSDavid Hildenbrand */ 52*177f9b1eSDavid Hildenbrand MemoryRegion *mr; 53*177f9b1eSDavid Hildenbrand 54*177f9b1eSDavid Hildenbrand /* 55*177f9b1eSDavid Hildenbrand * With "dynamic-memslots=on": The individual memslots (aliases into the 56*177f9b1eSDavid Hildenbrand * memory backend). 57*177f9b1eSDavid Hildenbrand */ 58*177f9b1eSDavid Hildenbrand MemoryRegion *memslots; 59*177f9b1eSDavid Hildenbrand 60*177f9b1eSDavid Hildenbrand /* With "dynamic-memslots=on": The total number of memslots. */ 61*177f9b1eSDavid Hildenbrand uint16_t nb_memslots; 62*177f9b1eSDavid Hildenbrand 63*177f9b1eSDavid Hildenbrand /* 64*177f9b1eSDavid Hildenbrand * With "dynamic-memslots=on": Size of one memslot (the size of the 65*177f9b1eSDavid Hildenbrand * last one can differ). 66*177f9b1eSDavid Hildenbrand */ 67*177f9b1eSDavid Hildenbrand uint64_t memslot_size; 68*177f9b1eSDavid Hildenbrand 69*177f9b1eSDavid Hildenbrand /* Assigned memory backend with the RAM memory region. */ 70910b2576SDavid Hildenbrand HostMemoryBackend *memdev; 71910b2576SDavid Hildenbrand 72910b2576SDavid Hildenbrand /* NUMA node */ 73910b2576SDavid Hildenbrand uint32_t node; 74910b2576SDavid Hildenbrand 75910b2576SDavid Hildenbrand /* assigned address of the region in guest physical memory */ 76910b2576SDavid Hildenbrand uint64_t addr; 77910b2576SDavid Hildenbrand 78910b2576SDavid Hildenbrand /* usable region size (<= region_size) */ 79910b2576SDavid Hildenbrand uint64_t usable_region_size; 80910b2576SDavid Hildenbrand 81910b2576SDavid Hildenbrand /* actual size (how much the guest plugged) */ 82910b2576SDavid Hildenbrand uint64_t size; 83910b2576SDavid Hildenbrand 84910b2576SDavid Hildenbrand /* requested size */ 85910b2576SDavid Hildenbrand uint64_t requested_size; 86910b2576SDavid Hildenbrand 87910b2576SDavid Hildenbrand /* block size and alignment */ 88910b2576SDavid Hildenbrand uint64_t block_size; 89c95b4437SDavid Hildenbrand 9023ad8decSDavid Hildenbrand /* 9123ad8decSDavid Hildenbrand * Whether we indicate VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE to the guest. 9223ad8decSDavid Hildenbrand * For !x86 targets this will always be "on" and consequently indicate 9323ad8decSDavid Hildenbrand * VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE. 9423ad8decSDavid Hildenbrand */ 9523ad8decSDavid Hildenbrand OnOffAuto unplugged_inaccessible; 9623ad8decSDavid Hildenbrand 9709b3b7e0SDavid Hildenbrand /* whether to prealloc memory when plugging new blocks */ 9809b3b7e0SDavid Hildenbrand bool prealloc; 9909b3b7e0SDavid Hildenbrand 1003b95a71bSDavid Hildenbrand /* 1013b95a71bSDavid Hildenbrand * Whether we migrate properties that are immutable while migration is 1023b95a71bSDavid Hildenbrand * active early, before state of other devices and especially, before 1033b95a71bSDavid Hildenbrand * migrating any RAM content. 1043b95a71bSDavid Hildenbrand */ 1053b95a71bSDavid Hildenbrand bool early_migration; 1063b95a71bSDavid Hildenbrand 107*177f9b1eSDavid Hildenbrand /* 108*177f9b1eSDavid Hildenbrand * Whether we dynamically map (multiple, if possible) memslots instead of 109*177f9b1eSDavid Hildenbrand * statically mapping the whole RAM memory region. 110*177f9b1eSDavid Hildenbrand */ 111*177f9b1eSDavid Hildenbrand bool dynamic_memslots; 112*177f9b1eSDavid Hildenbrand 113c95b4437SDavid Hildenbrand /* notifiers to notify when "size" changes */ 114c95b4437SDavid Hildenbrand NotifierList size_change_notifiers; 1150bc7806cSDavid Hildenbrand 1162044969fSDavid Hildenbrand /* listeners to notify on plug/unplug activity. */ 1172044969fSDavid Hildenbrand QLIST_HEAD(, RamDiscardListener) rdl_list; 118db1015e9SEduardo Habkost }; 119910b2576SDavid Hildenbrand 120db1015e9SEduardo Habkost struct VirtIOMEMClass { 121910b2576SDavid Hildenbrand /* private */ 122910b2576SDavid Hildenbrand VirtIODevice parent; 123910b2576SDavid Hildenbrand 124910b2576SDavid Hildenbrand /* public */ 125910b2576SDavid Hildenbrand void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi); 126910b2576SDavid Hildenbrand MemoryRegion *(*get_memory_region)(VirtIOMEM *vmem, Error **errp); 127*177f9b1eSDavid Hildenbrand void (*decide_memslots)(VirtIOMEM *vmem, unsigned int limit); 128*177f9b1eSDavid Hildenbrand unsigned int (*get_memslots)(VirtIOMEM *vmem); 129c95b4437SDavid Hildenbrand void (*add_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier); 130c95b4437SDavid Hildenbrand void (*remove_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier); 13192a8ee1bSDavid Hildenbrand void (*unplug_request_check)(VirtIOMEM *vmem, Error **errp); 132db1015e9SEduardo Habkost }; 133910b2576SDavid Hildenbrand 134910b2576SDavid Hildenbrand #endif 135