2 * Memory Device Interface
4 * Copyright ProfitBricks GmbH 2012
5 * Copyright (C) 2014 Red Hat Inc
6 * Copyright (c) 2018 Red Hat Inc
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
12 #include "qemu/osdep.h"
13 #include "hw/mem/memory-device.h"
15 #include "qapi/error.h"
16 #include "hw/boards.h"
17 #include "qemu/range.h"
18 #include "hw/virtio/vhost.h"
19 #include "sysemu/kvm.h"
21 static gint
memory_device_addr_sort(gconstpointer a
, gconstpointer b
)
23 const MemoryDeviceState
*md_a
= MEMORY_DEVICE(a
);
24 const MemoryDeviceState
*md_b
= MEMORY_DEVICE(b
);
25 const MemoryDeviceClass
*mdc_a
= MEMORY_DEVICE_GET_CLASS(a
);
26 const MemoryDeviceClass
*mdc_b
= MEMORY_DEVICE_GET_CLASS(b
);
27 const uint64_t addr_a
= mdc_a
->get_addr(md_a
);
28 const uint64_t addr_b
= mdc_b
->get_addr(md_b
);
30 if (addr_a
> addr_b
) {
32 } else if (addr_a
< addr_b
) {
38 static int memory_device_build_list(Object
*obj
, void *opaque
)
40 GSList
**list
= opaque
;
42 if (object_dynamic_cast(obj
, TYPE_MEMORY_DEVICE
)) {
43 DeviceState
*dev
= DEVICE(obj
);
44 if (dev
->realized
) { /* only realized memory devices matter */
45 *list
= g_slist_insert_sorted(*list
, dev
, memory_device_addr_sort
);
49 object_child_foreach(obj
, memory_device_build_list
, opaque
);
53 static int memory_device_used_region_size(Object
*obj
, void *opaque
)
55 uint64_t *size
= opaque
;
57 if (object_dynamic_cast(obj
, TYPE_MEMORY_DEVICE
)) {
58 const DeviceState
*dev
= DEVICE(obj
);
59 const MemoryDeviceState
*md
= MEMORY_DEVICE(obj
);
60 const MemoryDeviceClass
*mdc
= MEMORY_DEVICE_GET_CLASS(obj
);
63 *size
+= mdc
->get_region_size(md
);
67 object_child_foreach(obj
, memory_device_used_region_size
, opaque
);
71 static void memory_device_check_addable(MachineState
*ms
, uint64_t size
,
74 uint64_t used_region_size
= 0;
76 /* we will need a new memory slot for kvm and vhost */
77 if (kvm_enabled() && !kvm_has_free_slot(ms
)) {
78 error_setg(errp
, "hypervisor has no free memory slots left");
81 if (!vhost_has_free_slot()) {
82 error_setg(errp
, "a used vhost backend has no free memory slots left");
86 /* will we exceed the total amount of memory specified */
87 memory_device_used_region_size(OBJECT(ms
), &used_region_size
);
88 if (used_region_size
+ size
> ms
->maxram_size
- ms
->ram_size
) {
89 error_setg(errp
, "not enough space, currently 0x%" PRIx64
90 " in use of total hot pluggable 0x" RAM_ADDR_FMT
,
91 used_region_size
, ms
->maxram_size
- ms
->ram_size
);
97 uint64_t memory_device_get_free_addr(MachineState
*ms
, const uint64_t *hint
,
98 uint64_t align
, uint64_t size
,
101 uint64_t address_space_start
, address_space_end
;
102 GSList
*list
= NULL
, *item
;
103 uint64_t new_addr
= 0;
105 if (!ms
->device_memory
) {
106 error_setg(errp
, "memory devices (e.g. for memory hotplug) are not "
107 "supported by the machine");
111 if (!memory_region_size(&ms
->device_memory
->mr
)) {
112 error_setg(errp
, "memory devices (e.g. for memory hotplug) are not "
113 "enabled, please specify the maxmem option");
116 address_space_start
= ms
->device_memory
->base
;
117 address_space_end
= address_space_start
+
118 memory_region_size(&ms
->device_memory
->mr
);
119 g_assert(address_space_end
>= address_space_start
);
121 /* address_space_start indicates the maximum alignment we expect */
122 if (QEMU_ALIGN_UP(address_space_start
, align
) != address_space_start
) {
123 error_setg(errp
, "the alignment (0%" PRIx64
") is not supported",
128 memory_device_check_addable(ms
, size
, errp
);
133 if (hint
&& QEMU_ALIGN_UP(*hint
, align
) != *hint
) {
134 error_setg(errp
, "address must be aligned to 0x%" PRIx64
" bytes",
139 if (QEMU_ALIGN_UP(size
, align
) != size
) {
140 error_setg(errp
, "backend memory size must be multiple of 0x%"
147 if (new_addr
< address_space_start
) {
148 error_setg(errp
, "can't add memory [0x%" PRIx64
":0x%" PRIx64
149 "] at 0x%" PRIx64
, new_addr
, size
, address_space_start
);
151 } else if ((new_addr
+ size
) > address_space_end
) {
152 error_setg(errp
, "can't add memory [0x%" PRIx64
":0x%" PRIx64
153 "] beyond 0x%" PRIx64
, new_addr
, size
,
158 new_addr
= address_space_start
;
161 /* find address range that will fit new memory device */
162 object_child_foreach(OBJECT(ms
), memory_device_build_list
, &list
);
163 for (item
= list
; item
; item
= g_slist_next(item
)) {
164 const MemoryDeviceState
*md
= item
->data
;
165 const MemoryDeviceClass
*mdc
= MEMORY_DEVICE_GET_CLASS(OBJECT(md
));
166 uint64_t md_size
, md_addr
;
168 md_addr
= mdc
->get_addr(md
);
169 md_size
= mdc
->get_region_size(md
);
174 if (ranges_overlap(md_addr
, md_size
, new_addr
, size
)) {
176 const DeviceState
*d
= DEVICE(md
);
177 error_setg(errp
, "address range conflicts with '%s'", d
->id
);
180 new_addr
= QEMU_ALIGN_UP(md_addr
+ md_size
, align
);
184 if (new_addr
+ size
> address_space_end
) {
185 error_setg(errp
, "could not find position in guest address space for "
186 "memory device - memory fragmented due to alignments");
194 MemoryDeviceInfoList
*qmp_memory_device_list(void)
196 GSList
*devices
= NULL
, *item
;
197 MemoryDeviceInfoList
*list
= NULL
, *prev
= NULL
;
199 object_child_foreach(qdev_get_machine(), memory_device_build_list
,
202 for (item
= devices
; item
; item
= g_slist_next(item
)) {
203 const MemoryDeviceState
*md
= MEMORY_DEVICE(item
->data
);
204 const MemoryDeviceClass
*mdc
= MEMORY_DEVICE_GET_CLASS(item
->data
);
205 MemoryDeviceInfoList
*elem
= g_new0(MemoryDeviceInfoList
, 1);
206 MemoryDeviceInfo
*info
= g_new0(MemoryDeviceInfo
, 1);
208 mdc
->fill_device_info(md
, info
);
220 g_slist_free(devices
);
225 static int memory_device_plugged_size(Object
*obj
, void *opaque
)
227 uint64_t *size
= opaque
;
229 if (object_dynamic_cast(obj
, TYPE_MEMORY_DEVICE
)) {
230 const DeviceState
*dev
= DEVICE(obj
);
231 const MemoryDeviceState
*md
= MEMORY_DEVICE(obj
);
232 const MemoryDeviceClass
*mdc
= MEMORY_DEVICE_GET_CLASS(obj
);
235 *size
+= mdc
->get_plugged_size(md
);
239 object_child_foreach(obj
, memory_device_plugged_size
, opaque
);
243 uint64_t get_plugged_memory_size(void)
247 memory_device_plugged_size(qdev_get_machine(), &size
);
252 void memory_device_plug_region(MachineState
*ms
, MemoryRegion
*mr
,
255 /* we expect a previous call to memory_device_get_free_addr() */
256 g_assert(ms
->device_memory
);
258 memory_region_add_subregion(&ms
->device_memory
->mr
,
259 addr
- ms
->device_memory
->base
, mr
);
262 void memory_device_unplug_region(MachineState
*ms
, MemoryRegion
*mr
)
264 /* we expect a previous call to memory_device_get_free_addr() */
265 g_assert(ms
->device_memory
);
267 memory_region_del_subregion(&ms
->device_memory
->mr
, mr
);
270 static const TypeInfo memory_device_info
= {
271 .name
= TYPE_MEMORY_DEVICE
,
272 .parent
= TYPE_INTERFACE
,
273 .class_size
= sizeof(MemoryDeviceClass
),
276 static void memory_device_register_types(void)
278 type_register_static(&memory_device_info
);
281 type_init(memory_device_register_types
)