12cc0e2e8SDavid Hildenbrand /*
22cc0e2e8SDavid Hildenbrand * Memory Device Interface
32cc0e2e8SDavid Hildenbrand *
42cc0e2e8SDavid Hildenbrand * Copyright ProfitBricks GmbH 2012
52cc0e2e8SDavid Hildenbrand * Copyright (C) 2014 Red Hat Inc
62cc0e2e8SDavid Hildenbrand * Copyright (c) 2018 Red Hat Inc
72cc0e2e8SDavid Hildenbrand *
82cc0e2e8SDavid Hildenbrand * This work is licensed under the terms of the GNU GPL, version 2 or later.
92cc0e2e8SDavid Hildenbrand * See the COPYING file in the top-level directory.
102cc0e2e8SDavid Hildenbrand */
112cc0e2e8SDavid Hildenbrand
122cc0e2e8SDavid Hildenbrand #include "qemu/osdep.h"
13cc37d98bSRichard Henderson #include "qemu/error-report.h"
142cc0e2e8SDavid Hildenbrand #include "hw/mem/memory-device.h"
152cc0e2e8SDavid Hildenbrand #include "qapi/error.h"
162cc0e2e8SDavid Hildenbrand #include "hw/boards.h"
172cc0e2e8SDavid Hildenbrand #include "qemu/range.h"
181b6d6af2SDavid Hildenbrand #include "hw/virtio/vhost.h"
191b6d6af2SDavid Hildenbrand #include "sysemu/kvm.h"
20cc0afd8aSDavid Hildenbrand #include "exec/address-spaces.h"
21005feccfSDavid Hildenbrand #include "trace.h"
222cc0e2e8SDavid Hildenbrand
memory_device_is_empty(const MemoryDeviceState * md)236c1b28e9SDavid Hildenbrand static bool memory_device_is_empty(const MemoryDeviceState *md)
246c1b28e9SDavid Hildenbrand {
256c1b28e9SDavid Hildenbrand const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
266c1b28e9SDavid Hildenbrand Error *local_err = NULL;
276c1b28e9SDavid Hildenbrand MemoryRegion *mr;
286c1b28e9SDavid Hildenbrand
296c1b28e9SDavid Hildenbrand /* dropping const here is fine as we don't touch the memory region */
306c1b28e9SDavid Hildenbrand mr = mdc->get_memory_region((MemoryDeviceState *)md, &local_err);
316c1b28e9SDavid Hildenbrand if (local_err) {
32d1c2fbc9SMichael Tokarev /* Not empty, we'll report errors later when containing the MR again. */
336c1b28e9SDavid Hildenbrand error_free(local_err);
346c1b28e9SDavid Hildenbrand return false;
356c1b28e9SDavid Hildenbrand }
366c1b28e9SDavid Hildenbrand return !mr;
376c1b28e9SDavid Hildenbrand }
386c1b28e9SDavid Hildenbrand
memory_device_addr_sort(gconstpointer a,gconstpointer b)392cc0e2e8SDavid Hildenbrand static gint memory_device_addr_sort(gconstpointer a, gconstpointer b)
402cc0e2e8SDavid Hildenbrand {
412cc0e2e8SDavid Hildenbrand const MemoryDeviceState *md_a = MEMORY_DEVICE(a);
422cc0e2e8SDavid Hildenbrand const MemoryDeviceState *md_b = MEMORY_DEVICE(b);
432cc0e2e8SDavid Hildenbrand const MemoryDeviceClass *mdc_a = MEMORY_DEVICE_GET_CLASS(a);
442cc0e2e8SDavid Hildenbrand const MemoryDeviceClass *mdc_b = MEMORY_DEVICE_GET_CLASS(b);
452cc0e2e8SDavid Hildenbrand const uint64_t addr_a = mdc_a->get_addr(md_a);
462cc0e2e8SDavid Hildenbrand const uint64_t addr_b = mdc_b->get_addr(md_b);
472cc0e2e8SDavid Hildenbrand
482cc0e2e8SDavid Hildenbrand if (addr_a > addr_b) {
492cc0e2e8SDavid Hildenbrand return 1;
502cc0e2e8SDavid Hildenbrand } else if (addr_a < addr_b) {
512cc0e2e8SDavid Hildenbrand return -1;
522cc0e2e8SDavid Hildenbrand }
532cc0e2e8SDavid Hildenbrand return 0;
542cc0e2e8SDavid Hildenbrand }
552cc0e2e8SDavid Hildenbrand
memory_device_build_list(Object * obj,void * opaque)562cc0e2e8SDavid Hildenbrand static int memory_device_build_list(Object *obj, void *opaque)
572cc0e2e8SDavid Hildenbrand {
582cc0e2e8SDavid Hildenbrand GSList **list = opaque;
592cc0e2e8SDavid Hildenbrand
602cc0e2e8SDavid Hildenbrand if (object_dynamic_cast(obj, TYPE_MEMORY_DEVICE)) {
612cc0e2e8SDavid Hildenbrand DeviceState *dev = DEVICE(obj);
622cc0e2e8SDavid Hildenbrand if (dev->realized) { /* only realized memory devices matter */
632cc0e2e8SDavid Hildenbrand *list = g_slist_insert_sorted(*list, dev, memory_device_addr_sort);
642cc0e2e8SDavid Hildenbrand }
652cc0e2e8SDavid Hildenbrand }
662cc0e2e8SDavid Hildenbrand
672cc0e2e8SDavid Hildenbrand object_child_foreach(obj, memory_device_build_list, opaque);
682cc0e2e8SDavid Hildenbrand return 0;
692cc0e2e8SDavid Hildenbrand }
702cc0e2e8SDavid Hildenbrand
memory_device_get_memslots(MemoryDeviceState * md)717975feecSDavid Hildenbrand static unsigned int memory_device_get_memslots(MemoryDeviceState *md)
727975feecSDavid Hildenbrand {
737975feecSDavid Hildenbrand const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
747975feecSDavid Hildenbrand
757975feecSDavid Hildenbrand if (mdc->get_memslots) {
767975feecSDavid Hildenbrand return mdc->get_memslots(md);
777975feecSDavid Hildenbrand }
787975feecSDavid Hildenbrand return 1;
797975feecSDavid Hildenbrand }
807975feecSDavid Hildenbrand
81766aa0a6SDavid Hildenbrand /*
82766aa0a6SDavid Hildenbrand * Memslots that are reserved by memory devices (required but still reported
83766aa0a6SDavid Hildenbrand * as free from KVM / vhost).
84766aa0a6SDavid Hildenbrand */
get_reserved_memslots(MachineState * ms)85766aa0a6SDavid Hildenbrand static unsigned int get_reserved_memslots(MachineState *ms)
86766aa0a6SDavid Hildenbrand {
87766aa0a6SDavid Hildenbrand if (ms->device_memory->used_memslots >
88766aa0a6SDavid Hildenbrand ms->device_memory->required_memslots) {
89766aa0a6SDavid Hildenbrand /* This is unexpected, and we warned already in the memory notifier. */
90766aa0a6SDavid Hildenbrand return 0;
91766aa0a6SDavid Hildenbrand }
92766aa0a6SDavid Hildenbrand return ms->device_memory->required_memslots -
93766aa0a6SDavid Hildenbrand ms->device_memory->used_memslots;
94766aa0a6SDavid Hildenbrand }
95766aa0a6SDavid Hildenbrand
memory_devices_get_reserved_memslots(void)96766aa0a6SDavid Hildenbrand unsigned int memory_devices_get_reserved_memslots(void)
97766aa0a6SDavid Hildenbrand {
98766aa0a6SDavid Hildenbrand if (!current_machine->device_memory) {
99766aa0a6SDavid Hildenbrand return 0;
100766aa0a6SDavid Hildenbrand }
101766aa0a6SDavid Hildenbrand return get_reserved_memslots(current_machine);
102766aa0a6SDavid Hildenbrand }
103766aa0a6SDavid Hildenbrand
memory_devices_memslot_auto_decision_active(void)104a2335113SDavid Hildenbrand bool memory_devices_memslot_auto_decision_active(void)
105a2335113SDavid Hildenbrand {
106a2335113SDavid Hildenbrand if (!current_machine->device_memory) {
107a2335113SDavid Hildenbrand return false;
108a2335113SDavid Hildenbrand }
109a2335113SDavid Hildenbrand
110a2335113SDavid Hildenbrand return current_machine->device_memory->memslot_auto_decision_active;
111a2335113SDavid Hildenbrand }
112a2335113SDavid Hildenbrand
memory_device_memslot_decision_limit(MachineState * ms,MemoryRegion * mr)113a2335113SDavid Hildenbrand static unsigned int memory_device_memslot_decision_limit(MachineState *ms,
114a2335113SDavid Hildenbrand MemoryRegion *mr)
115a2335113SDavid Hildenbrand {
116a2335113SDavid Hildenbrand const unsigned int reserved = get_reserved_memslots(ms);
117a2335113SDavid Hildenbrand const uint64_t size = memory_region_size(mr);
118a2335113SDavid Hildenbrand unsigned int max = vhost_get_max_memslots();
119a2335113SDavid Hildenbrand unsigned int free = vhost_get_free_memslots();
120a2335113SDavid Hildenbrand uint64_t available_space;
121a2335113SDavid Hildenbrand unsigned int memslots;
122a2335113SDavid Hildenbrand
123a2335113SDavid Hildenbrand if (kvm_enabled()) {
124a2335113SDavid Hildenbrand max = MIN(max, kvm_get_max_memslots());
125a2335113SDavid Hildenbrand free = MIN(free, kvm_get_free_memslots());
126a2335113SDavid Hildenbrand }
127a2335113SDavid Hildenbrand
128a2335113SDavid Hildenbrand /*
129a2335113SDavid Hildenbrand * If we only have less overall memslots than what we consider reasonable,
130a2335113SDavid Hildenbrand * just keep it to a minimum.
131a2335113SDavid Hildenbrand */
132a2335113SDavid Hildenbrand if (max < MEMORY_DEVICES_SAFE_MAX_MEMSLOTS) {
133a2335113SDavid Hildenbrand return 1;
134a2335113SDavid Hildenbrand }
135a2335113SDavid Hildenbrand
136a2335113SDavid Hildenbrand /*
137a2335113SDavid Hildenbrand * Consider our soft-limit across all memory devices. We don't really
138a2335113SDavid Hildenbrand * expect to exceed this limit in reasonable configurations.
139a2335113SDavid Hildenbrand */
140a2335113SDavid Hildenbrand if (MEMORY_DEVICES_SOFT_MEMSLOT_LIMIT <=
141a2335113SDavid Hildenbrand ms->device_memory->required_memslots) {
142a2335113SDavid Hildenbrand return 1;
143a2335113SDavid Hildenbrand }
144a2335113SDavid Hildenbrand memslots = MEMORY_DEVICES_SOFT_MEMSLOT_LIMIT -
145a2335113SDavid Hildenbrand ms->device_memory->required_memslots;
146a2335113SDavid Hildenbrand
147a2335113SDavid Hildenbrand /*
148a2335113SDavid Hildenbrand * Consider the actually still free memslots. This is only relevant if
149a2335113SDavid Hildenbrand * other memslot consumers would consume *significantly* more memslots than
150a2335113SDavid Hildenbrand * what we prepared for (> 253). Unlikely, but let's just handle it
151a2335113SDavid Hildenbrand * cleanly.
152a2335113SDavid Hildenbrand */
153a2335113SDavid Hildenbrand memslots = MIN(memslots, free - reserved);
154a2335113SDavid Hildenbrand if (memslots < 1 || unlikely(free < reserved)) {
155a2335113SDavid Hildenbrand return 1;
156a2335113SDavid Hildenbrand }
157a2335113SDavid Hildenbrand
158a2335113SDavid Hildenbrand /* We cannot have any other memory devices? So give all to this device. */
159a2335113SDavid Hildenbrand if (size == ms->maxram_size - ms->ram_size) {
160a2335113SDavid Hildenbrand return memslots;
161a2335113SDavid Hildenbrand }
162a2335113SDavid Hildenbrand
163a2335113SDavid Hildenbrand /*
164a2335113SDavid Hildenbrand * Simple heuristic: equally distribute the memslots over the space
165a2335113SDavid Hildenbrand * still available for memory devices.
166a2335113SDavid Hildenbrand */
167a2335113SDavid Hildenbrand available_space = ms->maxram_size - ms->ram_size -
168a2335113SDavid Hildenbrand ms->device_memory->used_region_size;
169a2335113SDavid Hildenbrand memslots = (double)memslots * size / available_space;
170a2335113SDavid Hildenbrand return memslots < 1 ? 1 : memslots;
171a2335113SDavid Hildenbrand }
172a2335113SDavid Hildenbrand
memory_device_check_addable(MachineState * ms,MemoryDeviceState * md,MemoryRegion * mr,Error ** errp)1737975feecSDavid Hildenbrand static void memory_device_check_addable(MachineState *ms, MemoryDeviceState *md,
1747975feecSDavid Hildenbrand MemoryRegion *mr, Error **errp)
1751b6d6af2SDavid Hildenbrand {
176a2335113SDavid Hildenbrand const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
177ac23dd2fSDavid Hildenbrand const uint64_t used_region_size = ms->device_memory->used_region_size;
178d7f4891cSDavid Hildenbrand const uint64_t size = memory_region_size(mr);
179766aa0a6SDavid Hildenbrand const unsigned int reserved_memslots = get_reserved_memslots(ms);
180a2335113SDavid Hildenbrand unsigned int required_memslots, memslot_limit;
181a2335113SDavid Hildenbrand
182a2335113SDavid Hildenbrand /*
183a2335113SDavid Hildenbrand * Instruct the device to decide how many memslots to use, if applicable,
184a2335113SDavid Hildenbrand * before we query the number of required memslots the first time.
185a2335113SDavid Hildenbrand */
186a2335113SDavid Hildenbrand if (mdc->decide_memslots) {
187a2335113SDavid Hildenbrand memslot_limit = memory_device_memslot_decision_limit(ms, mr);
188a2335113SDavid Hildenbrand mdc->decide_memslots(md, memslot_limit);
189a2335113SDavid Hildenbrand }
190a2335113SDavid Hildenbrand required_memslots = memory_device_get_memslots(md);
1911b6d6af2SDavid Hildenbrand
1927975feecSDavid Hildenbrand /* we will need memory slots for kvm and vhost */
193766aa0a6SDavid Hildenbrand if (kvm_enabled() &&
194766aa0a6SDavid Hildenbrand kvm_get_free_memslots() < required_memslots + reserved_memslots) {
1957975feecSDavid Hildenbrand error_setg(errp, "hypervisor has not enough free memory slots left");
1961b6d6af2SDavid Hildenbrand return;
1971b6d6af2SDavid Hildenbrand }
198766aa0a6SDavid Hildenbrand if (vhost_get_free_memslots() < required_memslots + reserved_memslots) {
1997975feecSDavid Hildenbrand error_setg(errp, "a used vhost backend has not enough free memory slots left");
2001b6d6af2SDavid Hildenbrand return;
2011b6d6af2SDavid Hildenbrand }
2021b6d6af2SDavid Hildenbrand
2031b6d6af2SDavid Hildenbrand /* will we exceed the total amount of memory specified */
2045e6aa267SDavid Hildenbrand if (used_region_size + size < used_region_size ||
2055e6aa267SDavid Hildenbrand used_region_size + size > ms->maxram_size - ms->ram_size) {
2061b6d6af2SDavid Hildenbrand error_setg(errp, "not enough space, currently 0x%" PRIx64
20726b1d1fdSDavid Hildenbrand " in use of total space for memory devices 0x" RAM_ADDR_FMT,
2081b6d6af2SDavid Hildenbrand used_region_size, ms->maxram_size - ms->ram_size);
2091b6d6af2SDavid Hildenbrand return;
2101b6d6af2SDavid Hildenbrand }
2111b6d6af2SDavid Hildenbrand
2121b6d6af2SDavid Hildenbrand }
2131b6d6af2SDavid Hildenbrand
memory_device_get_free_addr(MachineState * ms,const uint64_t * hint,uint64_t align,uint64_t size,Error ** errp)2146ef2c0f2SDavid Hildenbrand static uint64_t memory_device_get_free_addr(MachineState *ms,
2156ef2c0f2SDavid Hildenbrand const uint64_t *hint,
216bb0831bdSDavid Hildenbrand uint64_t align, uint64_t size,
217bb0831bdSDavid Hildenbrand Error **errp)
218bb0831bdSDavid Hildenbrand {
219bb0831bdSDavid Hildenbrand GSList *list = NULL, *item;
220e3213eb5SDavid Hildenbrand Range as, new = range_empty;
221bb0831bdSDavid Hildenbrand
222e3213eb5SDavid Hildenbrand range_init_nofail(&as, ms->device_memory->base,
223e3213eb5SDavid Hildenbrand memory_region_size(&ms->device_memory->mr));
224bb0831bdSDavid Hildenbrand
225e3213eb5SDavid Hildenbrand /* start of address space indicates the maximum alignment we expect */
226e3213eb5SDavid Hildenbrand if (!QEMU_IS_ALIGNED(range_lob(&as), align)) {
227780a4d24SDavid Hildenbrand warn_report("the alignment (0x%" PRIx64 ") exceeds the expected"
228780a4d24SDavid Hildenbrand " maximum alignment, memory will get fragmented and not"
229780a4d24SDavid Hildenbrand " all 'maxmem' might be usable for memory devices.",
2304d8938a0SDavid Hildenbrand align);
2314d8938a0SDavid Hildenbrand }
2324d8938a0SDavid Hildenbrand
2333e18dbbbSDavid Hildenbrand if (hint && !QEMU_IS_ALIGNED(*hint, align)) {
234bb0831bdSDavid Hildenbrand error_setg(errp, "address must be aligned to 0x%" PRIx64 " bytes",
235bb0831bdSDavid Hildenbrand align);
236bb0831bdSDavid Hildenbrand return 0;
237bb0831bdSDavid Hildenbrand }
238bb0831bdSDavid Hildenbrand
239bb0831bdSDavid Hildenbrand if (hint) {
240e3213eb5SDavid Hildenbrand if (range_init(&new, *hint, size) || !range_contains_range(&as, &new)) {
24126b1d1fdSDavid Hildenbrand error_setg(errp, "can't add memory device [0x%" PRIx64 ":0x%" PRIx64
242e3213eb5SDavid Hildenbrand "], usable range for memory devices [0x%" PRIx64 ":0x%"
243e3213eb5SDavid Hildenbrand PRIx64 "]", *hint, size, range_lob(&as),
244e3213eb5SDavid Hildenbrand range_size(&as));
245bb0831bdSDavid Hildenbrand return 0;
246bb0831bdSDavid Hildenbrand }
247bb0831bdSDavid Hildenbrand } else {
248780a4d24SDavid Hildenbrand if (range_init(&new, QEMU_ALIGN_UP(range_lob(&as), align), size)) {
249e3213eb5SDavid Hildenbrand error_setg(errp, "can't add memory device, device too big");
250e3213eb5SDavid Hildenbrand return 0;
251e3213eb5SDavid Hildenbrand }
252bb0831bdSDavid Hildenbrand }
253bb0831bdSDavid Hildenbrand
254bb0831bdSDavid Hildenbrand /* find address range that will fit new memory device */
255bb0831bdSDavid Hildenbrand object_child_foreach(OBJECT(ms), memory_device_build_list, &list);
256bb0831bdSDavid Hildenbrand for (item = list; item; item = g_slist_next(item)) {
257bb0831bdSDavid Hildenbrand const MemoryDeviceState *md = item->data;
258bb0831bdSDavid Hildenbrand const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(OBJECT(md));
259e3213eb5SDavid Hildenbrand uint64_t next_addr;
260e3213eb5SDavid Hildenbrand Range tmp;
261bb0831bdSDavid Hildenbrand
2626c1b28e9SDavid Hildenbrand if (memory_device_is_empty(md)) {
2636c1b28e9SDavid Hildenbrand continue;
2646c1b28e9SDavid Hildenbrand }
2656c1b28e9SDavid Hildenbrand
266e3213eb5SDavid Hildenbrand range_init_nofail(&tmp, mdc->get_addr(md),
267e3213eb5SDavid Hildenbrand memory_device_get_region_size(md, &error_abort));
268bb0831bdSDavid Hildenbrand
269e3213eb5SDavid Hildenbrand if (range_overlaps_range(&tmp, &new)) {
270bb0831bdSDavid Hildenbrand if (hint) {
271bb0831bdSDavid Hildenbrand const DeviceState *d = DEVICE(md);
272f99d84b1SDavid Hildenbrand error_setg(errp, "address range conflicts with memory device"
273f99d84b1SDavid Hildenbrand " id='%s'", d->id ? d->id : "(unnamed)");
274bb0831bdSDavid Hildenbrand goto out;
275bb0831bdSDavid Hildenbrand }
276e3213eb5SDavid Hildenbrand
277e3213eb5SDavid Hildenbrand next_addr = QEMU_ALIGN_UP(range_upb(&tmp) + 1, align);
278e3213eb5SDavid Hildenbrand if (!next_addr || range_init(&new, next_addr, range_size(&new))) {
279e3213eb5SDavid Hildenbrand range_make_empty(&new);
280e3213eb5SDavid Hildenbrand break;
281e3213eb5SDavid Hildenbrand }
28264afc7c3SWei Yang } else if (range_lob(&tmp) > range_upb(&new)) {
28364afc7c3SWei Yang break;
284bb0831bdSDavid Hildenbrand }
285bb0831bdSDavid Hildenbrand }
286bb0831bdSDavid Hildenbrand
287e3213eb5SDavid Hildenbrand if (!range_contains_range(&as, &new)) {
288bb0831bdSDavid Hildenbrand error_setg(errp, "could not find position in guest address space for "
289bb0831bdSDavid Hildenbrand "memory device - memory fragmented due to alignments");
290bb0831bdSDavid Hildenbrand }
291bb0831bdSDavid Hildenbrand out:
292bb0831bdSDavid Hildenbrand g_slist_free(list);
293e3213eb5SDavid Hildenbrand return range_lob(&new);
294bb0831bdSDavid Hildenbrand }
295bb0831bdSDavid Hildenbrand
qmp_memory_device_list(void)2962cc0e2e8SDavid Hildenbrand MemoryDeviceInfoList *qmp_memory_device_list(void)
2972cc0e2e8SDavid Hildenbrand {
2982cc0e2e8SDavid Hildenbrand GSList *devices = NULL, *item;
29995b3a8c8SEric Blake MemoryDeviceInfoList *list = NULL, **tail = &list;
3002cc0e2e8SDavid Hildenbrand
3012cc0e2e8SDavid Hildenbrand object_child_foreach(qdev_get_machine(), memory_device_build_list,
3022cc0e2e8SDavid Hildenbrand &devices);
3032cc0e2e8SDavid Hildenbrand
3042cc0e2e8SDavid Hildenbrand for (item = devices; item; item = g_slist_next(item)) {
3052cc0e2e8SDavid Hildenbrand const MemoryDeviceState *md = MEMORY_DEVICE(item->data);
3062cc0e2e8SDavid Hildenbrand const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(item->data);
3072cc0e2e8SDavid Hildenbrand MemoryDeviceInfo *info = g_new0(MemoryDeviceInfo, 1);
3082cc0e2e8SDavid Hildenbrand
3096c1b28e9SDavid Hildenbrand /* Let's query infotmation even for empty memory devices. */
3102cc0e2e8SDavid Hildenbrand mdc->fill_device_info(md, info);
3112cc0e2e8SDavid Hildenbrand
31295b3a8c8SEric Blake QAPI_LIST_APPEND(tail, info);
3132cc0e2e8SDavid Hildenbrand }
3142cc0e2e8SDavid Hildenbrand
3152cc0e2e8SDavid Hildenbrand g_slist_free(devices);
3162cc0e2e8SDavid Hildenbrand
3172cc0e2e8SDavid Hildenbrand return list;
3182cc0e2e8SDavid Hildenbrand }
3192cc0e2e8SDavid Hildenbrand
memory_device_plugged_size(Object * obj,void * opaque)3202cc0e2e8SDavid Hildenbrand static int memory_device_plugged_size(Object *obj, void *opaque)
3212cc0e2e8SDavid Hildenbrand {
3222cc0e2e8SDavid Hildenbrand uint64_t *size = opaque;
3232cc0e2e8SDavid Hildenbrand
3242cc0e2e8SDavid Hildenbrand if (object_dynamic_cast(obj, TYPE_MEMORY_DEVICE)) {
3252cc0e2e8SDavid Hildenbrand const DeviceState *dev = DEVICE(obj);
3262cc0e2e8SDavid Hildenbrand const MemoryDeviceState *md = MEMORY_DEVICE(obj);
3272cc0e2e8SDavid Hildenbrand const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(obj);
3282cc0e2e8SDavid Hildenbrand
3296c1b28e9SDavid Hildenbrand if (dev->realized && !memory_device_is_empty(md)) {
330e40c5b6bSDavid Hildenbrand *size += mdc->get_plugged_size(md, &error_abort);
3312cc0e2e8SDavid Hildenbrand }
3322cc0e2e8SDavid Hildenbrand }
3332cc0e2e8SDavid Hildenbrand
3342cc0e2e8SDavid Hildenbrand object_child_foreach(obj, memory_device_plugged_size, opaque);
3352cc0e2e8SDavid Hildenbrand return 0;
3362cc0e2e8SDavid Hildenbrand }
3372cc0e2e8SDavid Hildenbrand
get_plugged_memory_size(void)3382cc0e2e8SDavid Hildenbrand uint64_t get_plugged_memory_size(void)
3392cc0e2e8SDavid Hildenbrand {
3402cc0e2e8SDavid Hildenbrand uint64_t size = 0;
3412cc0e2e8SDavid Hildenbrand
3422cc0e2e8SDavid Hildenbrand memory_device_plugged_size(qdev_get_machine(), &size);
3432cc0e2e8SDavid Hildenbrand
3442cc0e2e8SDavid Hildenbrand return size;
3452cc0e2e8SDavid Hildenbrand }
3462cc0e2e8SDavid Hildenbrand
memory_device_pre_plug(MemoryDeviceState * md,MachineState * ms,Error ** errp)3476ef2c0f2SDavid Hildenbrand void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms,
348*0e0bf77dSPhilippe Mathieu-Daudé Error **errp)
3496ef2c0f2SDavid Hildenbrand {
3506ef2c0f2SDavid Hildenbrand const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
3516ef2c0f2SDavid Hildenbrand Error *local_err = NULL;
352c726aa69SDavid Hildenbrand uint64_t addr, align = 0;
3536ef2c0f2SDavid Hildenbrand MemoryRegion *mr;
3546ef2c0f2SDavid Hildenbrand
3556c1b28e9SDavid Hildenbrand /* We support empty memory devices even without device memory. */
3566c1b28e9SDavid Hildenbrand if (memory_device_is_empty(md)) {
3576c1b28e9SDavid Hildenbrand return;
3586c1b28e9SDavid Hildenbrand }
3596c1b28e9SDavid Hildenbrand
360d7f4891cSDavid Hildenbrand if (!ms->device_memory) {
361d7f4891cSDavid Hildenbrand error_setg(errp, "the configuration is not prepared for memory devices"
362d7f4891cSDavid Hildenbrand " (e.g., for memory hotplug), consider specifying the"
363d7f4891cSDavid Hildenbrand " maxmem option");
364d7f4891cSDavid Hildenbrand return;
365d7f4891cSDavid Hildenbrand }
366d7f4891cSDavid Hildenbrand
3676ef2c0f2SDavid Hildenbrand mr = mdc->get_memory_region(md, &local_err);
3686ef2c0f2SDavid Hildenbrand if (local_err) {
3696ef2c0f2SDavid Hildenbrand goto out;
3706ef2c0f2SDavid Hildenbrand }
3716ef2c0f2SDavid Hildenbrand
3727975feecSDavid Hildenbrand memory_device_check_addable(ms, md, mr, &local_err);
373d7f4891cSDavid Hildenbrand if (local_err) {
374d7f4891cSDavid Hildenbrand goto out;
375d7f4891cSDavid Hildenbrand }
376d7f4891cSDavid Hildenbrand
377540a1abbSDavid Hildenbrand /*
378540a1abbSDavid Hildenbrand * We always want the memory region size to be multiples of the memory
379540a1abbSDavid Hildenbrand * region alignment: for example, DIMMs with 1G+1byte size don't make
380540a1abbSDavid Hildenbrand * any sense. Note that we don't check that the size is multiples
381540a1abbSDavid Hildenbrand * of any additional alignment requirements the memory device might
382540a1abbSDavid Hildenbrand * have when it comes to the address in physical address space.
383540a1abbSDavid Hildenbrand */
384540a1abbSDavid Hildenbrand if (!QEMU_IS_ALIGNED(memory_region_size(mr),
385540a1abbSDavid Hildenbrand memory_region_get_alignment(mr))) {
386540a1abbSDavid Hildenbrand error_setg(errp, "backend memory size must be multiple of 0x%"
387540a1abbSDavid Hildenbrand PRIx64, memory_region_get_alignment(mr));
388540a1abbSDavid Hildenbrand return;
389540a1abbSDavid Hildenbrand }
390540a1abbSDavid Hildenbrand
391c726aa69SDavid Hildenbrand if (mdc->get_min_alignment) {
392c726aa69SDavid Hildenbrand align = mdc->get_min_alignment(md);
393c726aa69SDavid Hildenbrand }
394c726aa69SDavid Hildenbrand align = MAX(align, memory_region_get_alignment(mr));
3956ef2c0f2SDavid Hildenbrand addr = mdc->get_addr(md);
3966ef2c0f2SDavid Hildenbrand addr = memory_device_get_free_addr(ms, !addr ? NULL : &addr, align,
3976ef2c0f2SDavid Hildenbrand memory_region_size(mr), &local_err);
3986ef2c0f2SDavid Hildenbrand if (local_err) {
3996ef2c0f2SDavid Hildenbrand goto out;
4006ef2c0f2SDavid Hildenbrand }
4016ef2c0f2SDavid Hildenbrand mdc->set_addr(md, addr, &local_err);
402005feccfSDavid Hildenbrand if (!local_err) {
403005feccfSDavid Hildenbrand trace_memory_device_pre_plug(DEVICE(md)->id ? DEVICE(md)->id : "",
404005feccfSDavid Hildenbrand addr);
405005feccfSDavid Hildenbrand }
4066ef2c0f2SDavid Hildenbrand out:
4076ef2c0f2SDavid Hildenbrand error_propagate(errp, local_err);
4086ef2c0f2SDavid Hildenbrand }
4096ef2c0f2SDavid Hildenbrand
memory_device_plug(MemoryDeviceState * md,MachineState * ms)41055d67a04SDavid Hildenbrand void memory_device_plug(MemoryDeviceState *md, MachineState *ms)
41118d11dc9SDavid Hildenbrand {
41255d67a04SDavid Hildenbrand const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
4136c1b28e9SDavid Hildenbrand unsigned int memslots;
4146c1b28e9SDavid Hildenbrand uint64_t addr;
41555d67a04SDavid Hildenbrand MemoryRegion *mr;
41655d67a04SDavid Hildenbrand
4176c1b28e9SDavid Hildenbrand if (memory_device_is_empty(md)) {
4186c1b28e9SDavid Hildenbrand return;
4196c1b28e9SDavid Hildenbrand }
4206c1b28e9SDavid Hildenbrand
4216c1b28e9SDavid Hildenbrand memslots = memory_device_get_memslots(md);
4226c1b28e9SDavid Hildenbrand addr = mdc->get_addr(md);
4236c1b28e9SDavid Hildenbrand
42455d67a04SDavid Hildenbrand /*
42555d67a04SDavid Hildenbrand * We expect that a previous call to memory_device_pre_plug() succeeded, so
42655d67a04SDavid Hildenbrand * it can't fail at this point.
42755d67a04SDavid Hildenbrand */
42855d67a04SDavid Hildenbrand mr = mdc->get_memory_region(md, &error_abort);
42918d11dc9SDavid Hildenbrand g_assert(ms->device_memory);
43018d11dc9SDavid Hildenbrand
431ac23dd2fSDavid Hildenbrand ms->device_memory->used_region_size += memory_region_size(mr);
432a2335113SDavid Hildenbrand ms->device_memory->required_memslots += memslots;
433a2335113SDavid Hildenbrand if (mdc->decide_memslots && memslots > 1) {
434a2335113SDavid Hildenbrand ms->device_memory->memslot_auto_decision_active++;
435a2335113SDavid Hildenbrand }
436a2335113SDavid Hildenbrand
43718d11dc9SDavid Hildenbrand memory_region_add_subregion(&ms->device_memory->mr,
43818d11dc9SDavid Hildenbrand addr - ms->device_memory->base, mr);
439005feccfSDavid Hildenbrand trace_memory_device_plug(DEVICE(md)->id ? DEVICE(md)->id : "", addr);
44018d11dc9SDavid Hildenbrand }
44118d11dc9SDavid Hildenbrand
memory_device_unplug(MemoryDeviceState * md,MachineState * ms)4428288590dSDavid Hildenbrand void memory_device_unplug(MemoryDeviceState *md, MachineState *ms)
44318d11dc9SDavid Hildenbrand {
4448288590dSDavid Hildenbrand const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
445a2335113SDavid Hildenbrand const unsigned int memslots = memory_device_get_memslots(md);
4468288590dSDavid Hildenbrand MemoryRegion *mr;
4478288590dSDavid Hildenbrand
4486c1b28e9SDavid Hildenbrand if (memory_device_is_empty(md)) {
4496c1b28e9SDavid Hildenbrand return;
4506c1b28e9SDavid Hildenbrand }
4516c1b28e9SDavid Hildenbrand
4528288590dSDavid Hildenbrand /*
4538288590dSDavid Hildenbrand * We expect that a previous call to memory_device_pre_plug() succeeded, so
4548288590dSDavid Hildenbrand * it can't fail at this point.
4558288590dSDavid Hildenbrand */
4568288590dSDavid Hildenbrand mr = mdc->get_memory_region(md, &error_abort);
45718d11dc9SDavid Hildenbrand g_assert(ms->device_memory);
45818d11dc9SDavid Hildenbrand
45918d11dc9SDavid Hildenbrand memory_region_del_subregion(&ms->device_memory->mr, mr);
460a2335113SDavid Hildenbrand
461a2335113SDavid Hildenbrand if (mdc->decide_memslots && memslots > 1) {
462a2335113SDavid Hildenbrand ms->device_memory->memslot_auto_decision_active--;
463a2335113SDavid Hildenbrand }
464ac23dd2fSDavid Hildenbrand ms->device_memory->used_region_size -= memory_region_size(mr);
465a2335113SDavid Hildenbrand ms->device_memory->required_memslots -= memslots;
466005feccfSDavid Hildenbrand trace_memory_device_unplug(DEVICE(md)->id ? DEVICE(md)->id : "",
467005feccfSDavid Hildenbrand mdc->get_addr(md));
46818d11dc9SDavid Hildenbrand }
46918d11dc9SDavid Hildenbrand
memory_device_get_region_size(const MemoryDeviceState * md,Error ** errp)470946d6154SDavid Hildenbrand uint64_t memory_device_get_region_size(const MemoryDeviceState *md,
471946d6154SDavid Hildenbrand Error **errp)
472946d6154SDavid Hildenbrand {
473af390027SDavid Hildenbrand const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
474af390027SDavid Hildenbrand MemoryRegion *mr;
475946d6154SDavid Hildenbrand
476af390027SDavid Hildenbrand /* dropping const here is fine as we don't touch the memory region */
477af390027SDavid Hildenbrand mr = mdc->get_memory_region((MemoryDeviceState *)md, errp);
478af390027SDavid Hildenbrand if (!mr) {
479af390027SDavid Hildenbrand return 0;
480af390027SDavid Hildenbrand }
481af390027SDavid Hildenbrand
482af390027SDavid Hildenbrand return memory_region_size(mr);
483946d6154SDavid Hildenbrand }
484946d6154SDavid Hildenbrand
memory_devices_region_mod(MemoryListener * listener,MemoryRegionSection * mrs,bool add)485f9716f4bSDavid Hildenbrand static void memory_devices_region_mod(MemoryListener *listener,
486f9716f4bSDavid Hildenbrand MemoryRegionSection *mrs, bool add)
487f9716f4bSDavid Hildenbrand {
488f9716f4bSDavid Hildenbrand DeviceMemoryState *dms = container_of(listener, DeviceMemoryState,
489f9716f4bSDavid Hildenbrand listener);
490f9716f4bSDavid Hildenbrand
491f9716f4bSDavid Hildenbrand if (!memory_region_is_ram(mrs->mr)) {
492f9716f4bSDavid Hildenbrand warn_report("Unexpected memory region mapped into device memory region.");
493f9716f4bSDavid Hildenbrand return;
494f9716f4bSDavid Hildenbrand }
495f9716f4bSDavid Hildenbrand
496f9716f4bSDavid Hildenbrand /*
497f9716f4bSDavid Hildenbrand * The expectation is that each distinct RAM memory region section in
498f9716f4bSDavid Hildenbrand * our region for memory devices consumes exactly one memslot in KVM
499f9716f4bSDavid Hildenbrand * and in vhost. For vhost, this is true, except:
500f9716f4bSDavid Hildenbrand * * ROM memory regions don't consume a memslot. These get used very
501f9716f4bSDavid Hildenbrand * rarely for memory devices (R/O NVDIMMs).
502f9716f4bSDavid Hildenbrand * * Memslots without a fd (memory-backend-ram) don't necessarily
503f9716f4bSDavid Hildenbrand * consume a memslot. Such setups are quite rare and possibly bogus:
504f9716f4bSDavid Hildenbrand * the memory would be inaccessible by such vhost devices.
505f9716f4bSDavid Hildenbrand *
506f9716f4bSDavid Hildenbrand * So for vhost, in corner cases we might over-estimate the number of
507f9716f4bSDavid Hildenbrand * memslots that are currently used or that might still be reserved
508f9716f4bSDavid Hildenbrand * (required - used).
509f9716f4bSDavid Hildenbrand */
510f9716f4bSDavid Hildenbrand dms->used_memslots += add ? 1 : -1;
511f9716f4bSDavid Hildenbrand
512f9716f4bSDavid Hildenbrand if (dms->used_memslots > dms->required_memslots) {
513f9716f4bSDavid Hildenbrand warn_report("Memory devices use more memory slots than indicated as required.");
514f9716f4bSDavid Hildenbrand }
515f9716f4bSDavid Hildenbrand }
516f9716f4bSDavid Hildenbrand
memory_devices_region_add(MemoryListener * listener,MemoryRegionSection * mrs)517f9716f4bSDavid Hildenbrand static void memory_devices_region_add(MemoryListener *listener,
518f9716f4bSDavid Hildenbrand MemoryRegionSection *mrs)
519f9716f4bSDavid Hildenbrand {
520f9716f4bSDavid Hildenbrand return memory_devices_region_mod(listener, mrs, true);
521f9716f4bSDavid Hildenbrand }
522f9716f4bSDavid Hildenbrand
memory_devices_region_del(MemoryListener * listener,MemoryRegionSection * mrs)523f9716f4bSDavid Hildenbrand static void memory_devices_region_del(MemoryListener *listener,
524f9716f4bSDavid Hildenbrand MemoryRegionSection *mrs)
525f9716f4bSDavid Hildenbrand {
526f9716f4bSDavid Hildenbrand return memory_devices_region_mod(listener, mrs, false);
527f9716f4bSDavid Hildenbrand }
528f9716f4bSDavid Hildenbrand
machine_memory_devices_init(MachineState * ms,hwaddr base,uint64_t size)529cc0afd8aSDavid Hildenbrand void machine_memory_devices_init(MachineState *ms, hwaddr base, uint64_t size)
530cc0afd8aSDavid Hildenbrand {
531cc0afd8aSDavid Hildenbrand g_assert(size);
532cc0afd8aSDavid Hildenbrand g_assert(!ms->device_memory);
533cc0afd8aSDavid Hildenbrand ms->device_memory = g_new0(DeviceMemoryState, 1);
534cc0afd8aSDavid Hildenbrand ms->device_memory->base = base;
535cc0afd8aSDavid Hildenbrand
536cc0afd8aSDavid Hildenbrand memory_region_init(&ms->device_memory->mr, OBJECT(ms), "device-memory",
537cc0afd8aSDavid Hildenbrand size);
538f9716f4bSDavid Hildenbrand address_space_init(&ms->device_memory->as, &ms->device_memory->mr,
539f9716f4bSDavid Hildenbrand "device-memory");
540cc0afd8aSDavid Hildenbrand memory_region_add_subregion(get_system_memory(), ms->device_memory->base,
541cc0afd8aSDavid Hildenbrand &ms->device_memory->mr);
542f9716f4bSDavid Hildenbrand
543f9716f4bSDavid Hildenbrand /* Track the number of memslots used by memory devices. */
544f9716f4bSDavid Hildenbrand ms->device_memory->listener.region_add = memory_devices_region_add;
545f9716f4bSDavid Hildenbrand ms->device_memory->listener.region_del = memory_devices_region_del;
546f9716f4bSDavid Hildenbrand memory_listener_register(&ms->device_memory->listener,
547f9716f4bSDavid Hildenbrand &ms->device_memory->as);
548cc0afd8aSDavid Hildenbrand }
549cc0afd8aSDavid Hildenbrand
5502cc0e2e8SDavid Hildenbrand static const TypeInfo memory_device_info = {
5512cc0e2e8SDavid Hildenbrand .name = TYPE_MEMORY_DEVICE,
5522cc0e2e8SDavid Hildenbrand .parent = TYPE_INTERFACE,
5532cc0e2e8SDavid Hildenbrand .class_size = sizeof(MemoryDeviceClass),
5542cc0e2e8SDavid Hildenbrand };
5552cc0e2e8SDavid Hildenbrand
memory_device_register_types(void)5562cc0e2e8SDavid Hildenbrand static void memory_device_register_types(void)
5572cc0e2e8SDavid Hildenbrand {
5582cc0e2e8SDavid Hildenbrand type_register_static(&memory_device_info);
5592cc0e2e8SDavid Hildenbrand }
5602cc0e2e8SDavid Hildenbrand
5612cc0e2e8SDavid Hildenbrand type_init(memory_device_register_types)
562