Memory slots are required only for DIMM-like devices, while other devices defined via <memory> such as virtio-mem may use the PCI bus and thus do not require/consume a memory slot. Fix the validation code to calculate the required count of memory devices only for DIMMs and NVDIMMs. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/qemu/qemu_domain.c | 31 ++++++++++++++----- ...mory-hotplug-virtio-mem.x86_64-latest.args | 2 +- .../memory-hotplug-virtio-mem.xml | 2 +- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 8f77e8fc58..c65c571398 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -9279,6 +9279,7 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, unsigned int nmems = def->nmems; unsigned long long hotplugSpace; unsigned long long hotplugMemory = 0; + size_t slotsNeeded = 0; size_t i; hotplugSpace = def->mem.max_memory - virDomainDefGetMemoryInitial(def); @@ -9289,6 +9290,20 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, if (qemuDomainDefValidateMemoryHotplugDevice(mem, def) < 0) return -1; + + switch (mem->model) { + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + slotsNeeded++; + break; + + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + case VIR_DOMAIN_MEMORY_MODEL_NONE: + break; + } } if (!virDomainDefHasMemoryHotplug(def)) { @@ -9315,19 +9330,14 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, } } - if (nmems > def->mem.memory_slots) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("memory device count '%1$u' exceeds slots count '%2$u'"), - nmems, def->mem.memory_slots); - return -1; - } - for (i = 0; i < def->nmems; i++) { hotplugMemory += def->mems[i]->size; switch (def->mems[i]->model) { case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + slotsNeeded++; + G_GNUC_FALLTHROUGH; case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: /* already existing devices don't need to be checked on hotplug */ @@ -9344,6 +9354,13 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, } } + if (slotsNeeded > def->mem.memory_slots) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("count of memory devices requiring memory slots '%1$zu' exceeds slots count '%2$u'"), + slotsNeeded, def->mem.memory_slots); + return -1; + } + if (hotplugMemory > hotplugSpace) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("memory device total size exceeds hotplug space")); diff --git a/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.x86_64-latest.args b/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.x86_64-latest.args index 592578fb59..7309fea2ff 100644 --- a/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.x86_64-latest.args +++ b/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.x86_64-latest.args @@ -13,7 +13,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -machine pc,usb=off,dump-guest-core=off,acpi=off \ -accel kvm \ -cpu qemu64 \ --m size=2095104k,slots=16,maxmem=1099511627776k \ +-m size=2095104k,slots=1,maxmem=1099511627776k \ -overcommit mem-lock=off \ -smp 2,sockets=2,dies=1,cores=1,threads=1 \ -object '{"qom-type":"memory-backend-ram","id":"ram-node0","size":2145386496}' \ diff --git a/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml b/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml index f5cc4a35ed..6220ab4c82 100644 --- a/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml +++ b/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml @@ -1,7 +1,7 @@ <domain type='kvm'> <name>QEMUGuest1</name> <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> - <maxMemory slots='16' unit='KiB'>1099511627776</maxMemory> + <maxMemory slots='1' unit='KiB'>1099511627776</maxMemory> <memory unit='KiB'>8388608</memory> <currentMemory unit='KiB'>8388608</currentMemory> <vcpu placement='static' cpuset='0-1'>2</vcpu> -- 2.40.1