master
h 146 lines 3.99 KB
Raw
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/core/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 /* Catch system resets -> qemu_devices_reset() only. */
122 VirtioMemSystemReset *system_reset;
123 };
124
125 struct VirtioMemSystemReset {
126 Object parent;
127
128 ResettableState reset_state;
129 VirtIOMEM *vmem;
130 };
131
132 struct VirtIOMEMClass {
133 /* private */
134 VirtioDeviceClass parent_class;
135
136 /* public */
137 void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi);
138 MemoryRegion *(*get_memory_region)(VirtIOMEM *vmem, Error **errp);
139 void (*decide_memslots)(VirtIOMEM *vmem, unsigned int limit);
140 unsigned int (*get_memslots)(VirtIOMEM *vmem);
141 void (*add_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
142 void (*remove_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
143 void (*unplug_request_check)(VirtIOMEM *vmem, Error **errp);
144 };
145
146 #endif