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(a)redhat.com>
---
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