]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu_domain: Properly validate count of memory slots
authorPeter Krempa <pkrempa@redhat.com>
Wed, 21 Jun 2023 13:31:24 +0000 (15:31 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 26 Jun 2023 10:58:24 +0000 (12:58 +0200)
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>
src/qemu/qemu_domain.c
tests/qemuxml2argvdata/memory-hotplug-virtio-mem.x86_64-latest.args
tests/qemuxml2argvdata/memory-hotplug-virtio-mem.xml

index 8f77e8fc582dc466d8e016eb6b0887f426eb8d29..c65c571398b3b4091d293c71122aed5f3f323886 100644 (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"));
index 592578fb597e2f0488514d0b34cb54fce367f239..7309fea2ff0626b6c025b7633e9fde418f62fdc6 100644 (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}' \
index f5cc4a35ed6e120e93f1ebc5baf7f5c807f66623..6220ab4c82e52f91893f428a16ae94f86e0fc469 100644 (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>