[PATCH v3 17/28] qemu: Get host CPU model from QEMU on x86_64

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

 



Until now host-model CPU mode tried to enable all CPU features supported
by the host CPU even if QEMU/KVM did not support them. This caused a
number of issues and made host-model quite unreliable. Asking QEMU for
the CPU it can provide and the current host makes host-model much more
robust.

This commit fixes the following bugs:

    https://bugzilla.redhat.com/show_bug.cgi?id=1018251
    https://bugzilla.redhat.com/show_bug.cgi?id=1371617
    https://bugzilla.redhat.com/show_bug.cgi?id=1372581
    https://bugzilla.redhat.com/show_bug.cgi?id=1404627
    https://bugzilla.redhat.com/show_bug.cgi?id=870071

In addition to that, the following bug should be mostly limited to cases
when an unsupported feature is explicitly requested:

    https://bugzilla.redhat.com/show_bug.cgi?id=1335534

Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx>
---

Notes:
    Version 3:
    - added #include "cpu/cpu_x86.h" removed in an earlier patch
    - adapted to changes to qemuMonitorCPUModelProperty
    
    Version 2:
    - no change

 src/qemu/qemu_capabilities.c                       | 77 ++++++++++++++++++++++
 .../domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml | 33 +++++++++-
 tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml   | 11 +++-
 3 files changed, 119 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 5c0353159..adfe84bff 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -33,6 +33,7 @@
 #include "virprocess.h"
 #include "nodeinfo.h"
 #include "cpu/cpu.h"
+#include "cpu/cpu_x86.h"
 #include "domain_conf.h"
 #include "vircommand.h"
 #include "virbitmap.h"
@@ -3129,6 +3130,80 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps,
  *         -1 on error.
  */
 static int
+virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
+                           virDomainVirtType type,
+                           virCPUDefPtr cpu)
+{
+    qemuMonitorCPUModelInfoPtr model;
+    virCPUDataPtr data = NULL;
+    unsigned long long sigFamily = 0;
+    unsigned long long sigModel = 0;
+    size_t nmodels = 0;
+    char **models = NULL;
+    int ret = -1;
+    size_t i;
+
+    if (type == VIR_DOMAIN_VIRT_KVM)
+        model = qemuCaps->kvmCPUModelInfo;
+    else
+        model = qemuCaps->tcgCPUModelInfo;
+
+    if (!model)
+        return 1;
+
+    if (!(data = virCPUDataNew(VIR_ARCH_X86_64)))
+        goto cleanup;
+
+    for (i = 0; i < model->nprops; i++) {
+        qemuMonitorCPUPropertyPtr prop = model->props + i;
+
+        switch (prop->type) {
+        case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN:
+            if (prop->value.boolean &&
+                virCPUx86DataAddFeature(data, prop->name) < 0)
+                goto cleanup;
+            break;
+
+        case QEMU_MONITOR_CPU_PROPERTY_STRING:
+            if (STREQ(prop->name, "vendor") &&
+                virCPUx86DataSetVendor(data, prop->value.string) < 0)
+                goto cleanup;
+            break;
+
+        case QEMU_MONITOR_CPU_PROPERTY_NUMBER:
+            if (STREQ(prop->name, "family"))
+                sigFamily = prop->value.number;
+            else if (STREQ(prop->name, "model"))
+                sigModel = prop->value.number;
+            break;
+
+        case QEMU_MONITOR_CPU_PROPERTY_LAST:
+            break;
+        }
+    }
+
+    if (virCPUx86DataSetSignature(data, sigFamily, sigModel) < 0)
+        goto cleanup;
+
+    if (virQEMUCapsGetCPUDefinitions(qemuCaps, type, &models, &nmodels) < 0 ||
+        cpuDecode(cpu, data, (const char **) models, nmodels, NULL) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    virCPUDataFree(data);
+    virStringListFreeCount(models, nmodels);
+    return ret;
+}
+
+
+/**
+ * Returns  0 when host CPU model provided by QEMU was filled in qemuCaps,
+ *          1 when the caller should fall back to using virCapsPtr->host.cpu,
+ *         -1 on error.
+ */
+static int
 virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
                         virDomainVirtType type,
                         virCPUDefPtr cpu)
@@ -3137,6 +3212,8 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
 
     if (ARCH_IS_S390(qemuCaps->arch))
         ret = virQEMUCapsInitCPUModelS390(qemuCaps, type, cpu);
+    else if (ARCH_IS_X86(qemuCaps->arch))
+        ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpu);
 
     if (ret == 0)
         cpu->fallback = VIR_CPU_FALLBACK_FORBID;
diff --git a/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml b/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml
index 9b9dfec09..1827b1d6f 100644
--- a/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml
+++ b/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml
@@ -21,7 +21,38 @@
   <cpu>
     <mode name='host-passthrough' supported='no'/>
     <mode name='host-model' supported='yes'>
-      <model fallback='allow'>Broadwell</model>
+      <model fallback='forbid'>Opteron_G4</model>
+      <vendor>AMD</vendor>
+      <feature policy='require' name='acpi'/>
+      <feature policy='require' name='ss'/>
+      <feature policy='require' name='monitor'/>
+      <feature policy='require' name='movbe'/>
+      <feature policy='require' name='hypervisor'/>
+      <feature policy='require' name='arat'/>
+      <feature policy='require' name='fsgsbase'/>
+      <feature policy='require' name='bmi1'/>
+      <feature policy='require' name='smep'/>
+      <feature policy='require' name='bmi2'/>
+      <feature policy='require' name='erms'/>
+      <feature policy='require' name='mpx'/>
+      <feature policy='require' name='adx'/>
+      <feature policy='require' name='smap'/>
+      <feature policy='require' name='clflushopt'/>
+      <feature policy='require' name='pku'/>
+      <feature policy='require' name='ospke'/>
+      <feature policy='require' name='xsaveopt'/>
+      <feature policy='require' name='xgetbv1'/>
+      <feature policy='require' name='mmxext'/>
+      <feature policy='require' name='3dnowext'/>
+      <feature policy='require' name='3dnow'/>
+      <feature policy='require' name='cr8legacy'/>
+      <feature policy='disable' name='pclmuldq'/>
+      <feature policy='disable' name='avx'/>
+      <feature policy='disable' name='lahf_lm'/>
+      <feature policy='disable' name='misalignsse'/>
+      <feature policy='disable' name='3dnowprefetch'/>
+      <feature policy='disable' name='xop'/>
+      <feature policy='disable' name='fma4'/>
     </mode>
     <mode name='custom' supported='yes'>
       <model usable='yes'>qemu64</model>
diff --git a/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml b/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml
index 49722f91f..a7a2ecdea 100644
--- a/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml
+++ b/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml
@@ -21,7 +21,16 @@
   <cpu>
     <mode name='host-passthrough' supported='yes'/>
     <mode name='host-model' supported='yes'>
-      <model fallback='allow'>Broadwell</model>
+      <model fallback='forbid'>Skylake-Client</model>
+      <vendor>Intel</vendor>
+      <feature policy='require' name='ss'/>
+      <feature policy='require' name='vmx'/>
+      <feature policy='require' name='hypervisor'/>
+      <feature policy='require' name='clflushopt'/>
+      <feature policy='require' name='xsaves'/>
+      <feature policy='require' name='pdpe1gb'/>
+      <feature policy='disable' name='pclmuldq'/>
+      <feature policy='disable' name='lahf_lm'/>
     </mode>
     <mode name='custom' supported='yes'>
       <model usable='yes'>qemu64</model>
-- 
2.11.1

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]
  Powered by Linux