[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCHv2] qemu: add a check for slot and base when build dimm address



When hot-plug a memory device, we don't check if there
is a memory device have the same address with the memory device
we want hot-pluged. Qemu forbid use/hot-plug 2 memory device
with same slot or the same base(qemu side this elemnt named addr).

Introduce a address check when build memory device qemu command line.

Signed-off-by: Luyao Huang <lhuang redhat com>
---
v2:
 move the check to qemuBuildMemoryDeviceStr() to check the dimm address
 when start/hot-plug a memory device.

 src/qemu/qemu_command.c | 77 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 57 insertions(+), 20 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d8ce511..0380a3b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4955,6 +4955,61 @@ qemuBuildMemoryDimmBackendStr(virDomainMemoryDefPtr mem,
 }
 
 
+static int
+qemuBuildMemoryDeviceAddr(virBuffer *buf,
+                          virDomainDefPtr def,
+                          virDomainMemoryDefPtr mem)
+{
+    ssize_t i;
+
+    if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+        return 0;
+
+    if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("only 'dimm' addresses are supported for the "
+                         "pc-dimm device"));
+        return -1;
+    }
+
+    if (mem->info.addr.dimm.slot >= def->mem.memory_slots) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("memory device slot '%u' exceeds slots count '%u'"),
+                       mem->info.addr.dimm.slot, def->mem.memory_slots);
+        return -1;
+    }
+
+    for (i = 0; i < def->nmems; i++) {
+         virDomainMemoryDefPtr tmp = def->mems[i];
+
+         if (tmp == mem ||
+             tmp->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM)
+             continue;
+
+         if (mem->info.addr.dimm.slot == tmp->info.addr.dimm.slot) {
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("memory device slot '%u' already been"
+                              " used by other memory device"),
+                            mem->info.addr.dimm.slot);
+             return -1;
+         }
+
+         if (mem->info.addr.dimm.base != 0 && tmp->info.addr.dimm.base != 0 &&
+             mem->info.addr.dimm.base == tmp->info.addr.dimm.base) {
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("memory device base '0x%llx' already been"
+                              " used by other memory device"),
+                            mem->info.addr.dimm.base);
+             return -1;
+         }
+    }
+
+    virBufferAsprintf(buf, ",slot=%d", mem->info.addr.dimm.slot);
+    virBufferAsprintf(buf, ",addr=%llu", mem->info.addr.dimm.base);
+
+    return 0;
+}
+
 char *
 qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
                          virDomainDefPtr def,
@@ -4976,29 +5031,11 @@ qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
             return NULL;
         }
 
-        if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM &&
-            mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("only 'dimm' addresses are supported for the "
-                             "pc-dimm device"));
-            return NULL;
-        }
-
-        if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM &&
-            mem->info.addr.dimm.slot >= def->mem.memory_slots) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("memory device slot '%u' exceeds slots count '%u'"),
-                           mem->info.addr.dimm.slot, def->mem.memory_slots);
-            return NULL;
-        }
-
         virBufferAsprintf(&buf, "pc-dimm,node=%d,memdev=mem%s,id=%s",
                           mem->targetNode, mem->info.alias, mem->info.alias);
 
-        if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) {
-            virBufferAsprintf(&buf, ",slot=%d", mem->info.addr.dimm.slot);
-            virBufferAsprintf(&buf, ",addr=%llu", mem->info.addr.dimm.base);
-        }
+        if (qemuBuildMemoryDeviceAddr(&buf, def, mem) < 0)
+            return NULL;
 
         break;
 
-- 
1.8.3.1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]