[libvirt] [RFC PATCH v2 08/12] qemu: introduce qemuBuildCPUDeviceStr

Zhu Guihua zhugh.fnst at cn.fujitsu.com
Wed Feb 4 09:18:26 UTC 2015


qemuBuildCPUDeviceStr being introduced is responsible for creating command
line argument for '-device' for given cpu device, and checking host cpu compat.

Signed-off-by: Zhu Guihua <zhugh.fnst at cn.fujitsu.com>
---
 src/qemu/qemu_command.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_command.h |  7 ++++
 2 files changed, 95 insertions(+)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6201e29..513b726 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6003,6 +6003,88 @@ static char *qemuBuildTPMDevStr(const virDomainDef *def,
 }
 
 
+int
+qemuBuildCPUDeviceStr(char **deviceStr,
+                      virQEMUDriverPtr driver,
+                      const virDomainDef *def,
+                      virDomainCPUDefPtr dev,
+                      virQEMUCapsPtr qemuCaps)
+{
+    char *model = NULL;
+    virCPUDefPtr host = NULL;
+    char *compare_msg = NULL;
+    virCPUCompareResult cmp;
+    virCapsPtr caps = NULL;
+    bool compareAgainstHost = ((def->virtType == VIR_DOMAIN_VIRT_KVM ||
+                                def->cpu->mode != VIR_CPU_MODE_CUSTOM) &&
+                                def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH);
+
+    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_X86_64_CPU)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("%s not supported in this QEMU binary"), dev->virCPU->model);
+        goto error;
+    }
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto error;
+
+    host = caps->host.cpu;
+
+    /* For KVM, CPU features are not emulated, so should consider host compat */
+    if (compareAgainstHost) {
+        cmp = cpuGuestData(host, dev->virCPU, NULL, &compare_msg);
+        switch (cmp) {
+        case VIR_CPU_COMPARE_INCOMPATIBLE:
+            if (compare_msg) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("guest and host CPU are not compatible: %s"),
+                               compare_msg);
+            } else {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("guest CPU is not compatible with host CPU"));
+            }
+        case VIR_CPU_COMPARE_ERROR:
+            goto error;
+
+        default:
+            break;
+        }
+    }
+
+    if (virAsprintf(&model, "%s-x86_64-cpu", dev->virCPU->model) < 0)
+        goto error;
+
+    if (virAsprintf(deviceStr, "%s,id=%s,apic-id=%d",
+                    model, dev->info.alias, dev->apic_id) < 0)
+        goto error;
+
+    return 0;
+
+ error:
+    VIR_FREE(model);
+    VIR_FREE(compare_msg);
+    virObjectUnref(caps);
+    return -1;
+}
+
+static int
+qemuBuildCPUDeviceCommandLine(virCommandPtr cmd,
+                              virQEMUDriverPtr driver,
+                              const virDomainDef *def,
+                              virDomainCPUDefPtr dev,
+                              virQEMUCapsPtr qemuCaps)
+{
+    char *devstr = NULL;
+
+    if (qemuBuildCPUDeviceStr(&devstr, driver, def, dev, qemuCaps) < 0)
+        return -1;
+
+    virCommandAddArgList(cmd, "-device", devstr, NULL);
+    VIR_FREE(devstr);
+    return 0;
+}
+
+
 static char *qemuBuildSmbiosBiosStr(virSysinfoDefPtr def)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -9922,6 +10004,12 @@ qemuBuildCommandLine(virConnectPtr conn,
             goto error;
     }
 
+    /* add cpu devices */
+    for (i = 0; i < def->ncpus; i++) {
+        if (qemuBuildCPUDeviceCommandLine(cmd, driver, def, def->cpus[i], qemuCaps) < 0)
+            goto error;
+    }
+
     if (def->nvram) {
         if (ARCH_IS_PPC64(def->os.arch) &&
             STRPREFIX(def->os.machine, "pseries")) {
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index c63fd30..18e0dfb 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -94,6 +94,13 @@ qemuBuildChrDeviceStr(char **deviceStr,
                       virDomainChrDefPtr chr,
                       virQEMUCapsPtr qemuCaps);
 
+int
+qemuBuildCPUDeviceStr(char **deviceStr,
+                      virQEMUDriverPtr driver,
+                      const virDomainDef *def,
+                      virDomainCPUDefPtr cpu,
+                      virQEMUCapsPtr qemuCaps);
+
 /* With vlan == -1, use netdev syntax, else old hostnet */
 char *qemuBuildHostNetStr(virDomainNetDefPtr net,
                           virQEMUDriverPtr driver,
-- 
1.9.3




More information about the libvir-list mailing list