]> xenbits.xensource.com Git - libvirt.git/commitdiff
domain_validate: Move memdevice address conflict check into a separate function
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 2 Nov 2023 15:05:46 +0000 (16:05 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 24 Nov 2023 11:37:38 +0000 (12:37 +0100)
At the end of virDomainMemoryDefValidate() there's a code that
checks whether two virtio-mem/virtio-pmem devices don't overlap.
Separate this code into its own function
(virDomainMemoryDefCheckConflict()).

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
src/conf/domain_validate.c

index bc3d00f89c76b17603173cdc6e665a2f2359f35c..b4ffef919ad908270d4fa09b7b90e64760f27a06 100644 (file)
@@ -2217,15 +2217,96 @@ virDomainHostdevDefValidate(const virDomainHostdevDef *hostdev)
 }
 
 
+static int
+virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
+                                const virDomainDef *def)
+{
+    unsigned long long thisStart = 0;
+    unsigned long long thisEnd = 0;
+    size_t i;
+
+    switch (mem->model) {
+    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
+        thisStart = mem->target.virtio_pmem.address;
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
+        thisStart = mem->target.virtio_mem.address;
+        break;
+    case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+    case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+    case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
+    case VIR_DOMAIN_MEMORY_MODEL_NONE:
+    case VIR_DOMAIN_MEMORY_MODEL_LAST:
+        break;
+    }
+
+    if (thisStart == 0) {
+        return 0;
+    }
+
+    /* thisStart and thisEnd are in bytes, mem->size in kibibytes */
+    thisEnd = thisStart + mem->size * 1024;
+
+    for (i = 0; i < def->nmems; i++) {
+        const virDomainMemoryDef *other = def->mems[i];
+        unsigned long long otherStart = 0;
+
+        if (other == mem)
+            continue;
+
+        /* In case we're updating an existing memory device (e.g. virtio-mem),
+         * then pointers will be different. But addresses and aliases are the
+         * same. However, STREQ_NULLABLE() returns true if both strings are
+         * NULL which is not what we want. */
+        if (virDomainDeviceInfoAddressIsEqual(&other->info,
+                                              &mem->info)) {
+            continue;
+        }
+
+        if (mem->info.alias &&
+            STREQ_NULLABLE(other->info.alias,
+                           mem->info.alias)) {
+            continue;
+        }
+
+        switch (other->model) {
+        case VIR_DOMAIN_MEMORY_MODEL_NONE:
+        case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+        case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+        case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
+        case VIR_DOMAIN_MEMORY_MODEL_LAST:
+            continue;
+            break;
+
+        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
+            otherStart = other->target.virtio_pmem.address;
+            break;
+        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
+            otherStart = other->target.virtio_mem.address;
+            break;
+        }
+
+        if (otherStart == 0)
+            continue;
+
+        if (thisStart <= otherStart && thisEnd > otherStart) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("memory device address [0x%1$llx:0x%2$llx] overlaps with other memory device (0x%3$llx)"),
+                           thisStart, thisEnd, otherStart);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+
 static int
 virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
                            const virDomainDef *def)
 {
     const long pagesize = virGetSystemPageSize();
     unsigned long long thpSize;
-    unsigned long long thisStart = 0;
-    unsigned long long thisEnd = 0;
-    size_t i;
 
     /* Guest NUMA nodes are continuous and indexed from zero. */
     if (mem->targetNode != -1) {
@@ -2307,7 +2388,6 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
                            pagesize);
             return -1;
         }
-        thisStart = mem->target.virtio_pmem.address;
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
@@ -2351,7 +2431,6 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
                            _("memory device address must be aligned to blocksize"));
             return -1;
         }
-        thisStart = mem->target.virtio_mem.address;
         break;
 
     case VIR_DOMAIN_MEMORY_MODEL_DIMM:
@@ -2373,62 +2452,8 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem,
         return -1;
     }
 
-    if (thisStart == 0) {
-        return 0;
-    }
-
-    /* thisStart and thisEnd are in bytes, mem->size in kibibytes */
-    thisEnd = thisStart + mem->size * 1024;
-
-    for (i = 0; i < def->nmems; i++) {
-        const virDomainMemoryDef *other = def->mems[i];
-        unsigned long long otherStart = 0;
-
-        if (other == mem)
-            continue;
-
-        /* In case we're updating an existing memory device (e.g. virtio-mem),
-         * then pointers will be different. But addresses and aliases are the
-         * same. However, STREQ_NULLABLE() returns true if both strings are
-         * NULL which is not what we want. */
-        if (virDomainDeviceInfoAddressIsEqual(&other->info,
-                                              &mem->info)) {
-            continue;
-        }
-
-        if (mem->info.alias &&
-            STREQ_NULLABLE(other->info.alias,
-                           mem->info.alias)) {
-            continue;
-        }
-
-        switch (other->model) {
-        case VIR_DOMAIN_MEMORY_MODEL_NONE:
-        case VIR_DOMAIN_MEMORY_MODEL_DIMM:
-        case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
-        case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC:
-        case VIR_DOMAIN_MEMORY_MODEL_LAST:
-            continue;
-            break;
-
-        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
-            otherStart = other->target.virtio_pmem.address;
-            break;
-        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
-            otherStart = other->target.virtio_mem.address;
-            break;
-        }
-
-        if (otherStart == 0)
-            continue;
-
-        if (thisStart <= otherStart && thisEnd > otherStart) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("memory device address [0x%1$llx:0x%2$llx] overlaps with other memory device (0x%3$llx)"),
-                           thisStart, thisEnd, otherStart);
-            return -1;
-        }
-    }
+    if (virDomainMemoryDefCheckConflict(mem, def) < 0)
+        return -1;
 
     return 0;
 }