qemu_domain: Properly validate count of memory slots

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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2023-06-21 15:31:24 +02:00
parent a52c68443d
commit e3ce39195c
3 changed files with 26 additions and 9 deletions

View File

@ -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"));

View File

@ -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}' \

View File

@ -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>