[libvirt] [PATCH 7/7] qemu: Use host CPU from QEMU for computations

Jiri Denemark jdenemar at redhat.com
Tue Jul 23 16:11:36 UTC 2013


Use the host CPU data probed by the current emulator when updating a
guest CPU according to a host CPU or when checking whether they are
compatible.
---
 src/qemu/qemu_command.c | 32 ++++++++++++++++++++++++++------
 src/qemu/qemu_domain.c  | 21 +++++++++++++++------
 2 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d0aed7c..f2124d8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5683,13 +5683,19 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver,
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     size_t i;
     virCapsPtr caps = NULL;
+    bool filteredHost = false;
 
     *hasHwVirt = false;
 
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
         goto cleanup;
 
-    host = caps->host.cpu;
+    if (def->virtType == VIR_DOMAIN_VIRT_KVM)
+        host = virQEMUCapsGetHostCPU(qemuCaps);
+    if (host)
+        filteredHost = true;
+    else
+        host = caps->host.cpu;
 
     if (def->os.arch == VIR_ARCH_I686)
         default_model = "qemu32";
@@ -5722,12 +5728,26 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver,
         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);
+                if (filteredHost) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("requested guest CPU cannot be provided "
+                                     "by QEMU binary on this host: %s"),
+                                   compare_msg);
+                } else {
+                    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"));
+                if (filteredHost) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                   _("requested guest CPU cannot be provided "
+                                     "by QEMU binary on this host"));
+                } else {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                   _("guest CPU is not compatible "
+                                     "with host CPU"));
+                }
             }
             /* fall through */
         case VIR_CPU_COMPARE_ERROR:
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index da3b768..83197e0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1347,6 +1347,8 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
     virDomainControllerDefPtr *controllers = NULL;
     int ncontrollers = 0;
     virCapsPtr caps = NULL;
+    virQEMUCapsPtr qemuCaps = NULL;
+    virCPUDefPtr hostCPU = NULL;
 
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
         goto cleanup;
@@ -1355,15 +1357,21 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
     if ((flags & VIR_DOMAIN_XML_UPDATE_CPU) &&
         def_cpu &&
         (def_cpu->mode != VIR_CPU_MODE_CUSTOM || def_cpu->model)) {
-        if (!caps->host.cpu ||
-            !caps->host.cpu->model) {
-            virReportError(VIR_ERR_OPERATION_FAILED,
-                           "%s", _("cannot get host CPU capabilities"));
-            goto cleanup;
+        if ((qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
+                                               def->emulator)))
+            hostCPU = virQEMUCapsGetHostCPU(qemuCaps);
+
+        if (!hostCPU) {
+            if (!caps->host.cpu || !caps->host.cpu->model) {
+                virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                               _("cannot get host CPU capabilities"));
+                goto cleanup;
+            }
+            hostCPU = caps->host.cpu;
         }
 
         if (!(cpu = virCPUDefCopy(def_cpu)) ||
-            cpuUpdate(cpu, caps->host.cpu) < 0)
+            cpuUpdate(cpu, hostCPU) < 0)
             goto cleanup;
         def->cpu = cpu;
     }
@@ -1445,6 +1453,7 @@ cleanup:
         def->ncontrollers = ncontrollers;
     }
     virObjectUnref(caps);
+    virObjectUnref(qemuCaps);
     return ret;
 }
 
-- 
1.8.3.2




More information about the libvir-list mailing list