diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index b35a95f08c..6ce3b1ef74 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -1748,6 +1748,94 @@ qemuDomainUSBAddressAddHubs(virDomainDefPtr def) } +static virBitmapPtr +qemuDomainGetMemorySlotMap(const virDomainDef *def) +{ + virBitmapPtr ret; + virDomainMemoryDefPtr mem; + size_t i; + + if (!(ret = virBitmapNew(def->mem.memory_slots))) + return NULL; + + for (i = 0; i < def->nmems; i++) { + mem = def->mems[i]; + + if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) + ignore_value(virBitmapSetBit(ret, mem->info.addr.dimm.slot)); + } + + return ret; +} + + +static int +qemuAssignMemoryDeviceSlot(virDomainMemoryDefPtr mem, + virBitmapPtr slotmap) +{ + ssize_t nextslot = -1; + + if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) + return 0; + + if ((nextslot = virBitmapNextClearBit(slotmap, -1)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to find a emtpy memory slot")); + return -1; + } + + ignore_value(virBitmapSetBit(slotmap, nextslot)); + mem->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM; + mem->info.addr.dimm.slot = nextslot; + + return 0; +} + + +int +qemuDomainAssignMemoryDeviceSlot(virDomainDefPtr def, + virDomainMemoryDefPtr mem) +{ + virBitmapPtr slotmap = NULL; + int ret; + + if (!(slotmap = qemuDomainGetMemorySlotMap(def))) + return -1; + + ret = qemuAssignMemoryDeviceSlot(mem, slotmap); + + virBitmapFree(slotmap); + return ret; +} + + +static int +qemuDomainAssignMemorySlots(virDomainDefPtr def) +{ + virBitmapPtr slotmap = NULL; + int ret = -1; + size_t i; + + if (!virDomainDefHasMemoryHotplug(def)) + return 0; + + if (!(slotmap = qemuDomainGetMemorySlotMap(def))) + return -1; + + for (i = 0; i < def->nmems; i++) { + if (qemuAssignMemoryDeviceSlot(def->mems[i], slotmap) < 0) + goto cleanup; + } + + ret = 0; + + cleanup: + virBitmapFree(slotmap); + return ret; + +} + + static int qemuDomainAssignUSBAddresses(virDomainDefPtr def, virDomainObjPtr obj, @@ -1827,6 +1915,9 @@ qemuDomainAssignAddresses(virDomainDefPtr def, if (qemuDomainAssignUSBAddresses(def, obj, newDomain) < 0) return -1; + if (qemuDomainAssignMemorySlots(def) < 0) + return -1; + return 0; } diff --git a/src/qemu/qemu_domain_address.h b/src/qemu/qemu_domain_address.h index 11d6e92a41..ecb92b5400 100644 --- a/src/qemu/qemu_domain_address.h +++ b/src/qemu/qemu_domain_address.h @@ -45,6 +45,10 @@ virDomainCCWAddressSetPtr qemuDomainCCWAddrSetCreateFromDomain(virDomainDefPtr def) ATTRIBUTE_NONNULL(1); +int qemuDomainAssignMemoryDeviceSlot(virDomainDefPtr def, + virDomainMemoryDefPtr mem); + + # define __QEMU_DOMAIN_ADDRESS_H__ #endif /* __QEMU_DOMAIN_ADDRESS_H__ */ diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index fa96a76163..7a023d2974 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2132,6 +2132,9 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, if (qemuDomainDefValidateMemoryHotplug(vm->def, priv->qemuCaps, mem) < 0) goto cleanup; + if (qemuDomainAssignMemoryDeviceSlot(vm->def, mem) < 0) + goto cleanup; + if (qemuAssignDeviceMemoryAlias(vm->def, mem) < 0) goto cleanup; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args index 2eb006e643..7b90784020 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-numa.args @@ -16,7 +16,7 @@ QEMU_AUDIO_DRV=spice \ -object memory-backend-file,id=memdimm0,prealloc=yes,\ mem-path=/dev/hugepages1G/libvirt/qemu,size=1073741824,host-nodes=1-3,\ policy=bind \ --device pc-dimm,node=0,memdev=memdimm0,id=dimm0 \ +-device pc-dimm,node=0,memdev=memdimm0,id=dimm0,slot=0 \ -uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \ -nodefaults \ -monitor unix:/tmp/lib/domain--1-fedora/monitor.sock,server,nowait \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-dimm.args b/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-dimm.args index fa64fcf41c..1587aba534 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-dimm.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-dimm.args @@ -12,11 +12,11 @@ QEMU_AUDIO_DRV=none \ -smp 2,sockets=2,cores=1,threads=1 \ -numa node,nodeid=0,cpus=0-1,mem=214 \ -object memory-backend-ram,id=memdimm0,size=536870912 \ --device pc-dimm,node=0,memdev=memdimm0,id=dimm0 \ +-device pc-dimm,node=0,memdev=memdimm0,id=dimm0,slot=0 \ -object memory-backend-file,id=memdimm1,prealloc=yes,\ mem-path=/dev/hugepages2M/libvirt/qemu,size=536870912,host-nodes=1-3,\ policy=bind \ --device pc-dimm,node=0,memdev=memdimm1,id=dimm1 \ +-device pc-dimm,node=0,memdev=memdimm1,id=dimm1,slot=1 \ -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ -nographic \ -nodefaults \ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-ppc64-nonuma.args b/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-ppc64-nonuma.args index 8a85fb1c38..475b7214ec 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-ppc64-nonuma.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-memory-hotplug-ppc64-nonuma.args @@ -11,9 +11,9 @@ QEMU_AUDIO_DRV=none \ -m size=1310720k,slots=16,maxmem=4194304k \ -smp 1,sockets=1,cores=1,threads=1 \ -object memory-backend-ram,id=memdimm0,size=536870912 \ --device pc-dimm,memdev=memdimm0,id=dimm0 \ +-device pc-dimm,memdev=memdimm0,id=dimm0,slot=0 \ -object memory-backend-ram,id=memdimm1,size=536870912 \ --device pc-dimm,memdev=memdimm1,id=dimm1 \ +-device pc-dimm,memdev=memdimm1,id=dimm1,slot=1 \ -uuid 49545eb3-75e1-2d0a-acdd-f0294406c99e \ -nographic \ -nodefaults \ diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-memory-hotplug-dimm.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memory-hotplug-dimm.xml index c5b5d7595b..be97e4ebd4 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-memory-hotplug-dimm.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memory-hotplug-dimm.xml @@ -47,6 +47,7 @@ 523264 0 +
@@ -57,6 +58,7 @@ 524287 0 +