xref: /openbmc/qemu/hw/mem/memory-device.c (revision 80748eb4fbc70f0a3ae423f2c01cb5a4584d803f)
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