]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Parse CPU stepping from query-cpu-model-expansion
authorJiri Denemark <jdenemar@redhat.com>
Tue, 10 Oct 2017 11:34:28 +0000 (13:34 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Tue, 17 Oct 2017 20:37:04 +0000 (22:37 +0200)
Even though only family and model are used for matching CPUID data with
CPU models from cpu_map.xml, stepping is used by x86DataFilterTSX which
is supposed to disable TSX on CPU models with broken TSX support. Thus
we need to start parsing stepping from QEMU to make sure we don't
disable TSX on CPUs which provide working TSX implementation. See the
following patch for a real world example of such CPU.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
src/cpu/cpu_x86.c
src/cpu/cpu_x86.h
src/qemu/qemu_capabilities.c

index b177885f5ec5629a0a88bae9c1aa71dcc7fb1136..a6cbd457662b5b542b58026446db07e94912cb55 100644 (file)
@@ -531,7 +531,8 @@ virCPUx86VendorToCPUID(const char *vendor,
 
 static uint32_t
 x86MakeSignature(unsigned int family,
-                 unsigned int model)
+                 unsigned int model,
+                 unsigned int stepping)
 {
     uint32_t sig = 0;
 
@@ -551,6 +552,7 @@ x86MakeSignature(unsigned int family,
      *
      * family = eax[27:20] + eax[11:8]
      * model = eax[19:16] << 4 + eax[7:4]
+     * stepping = eax[3:0]
      */
 
     /* extFam */
@@ -570,9 +572,8 @@ x86MakeSignature(unsigned int family,
     /* Mod */
     sig |= (model & 0xf) << 4;
 
-    /* Step is irrelevant, it is used to distinguish different revisions
-     * of the same CPU model
-     */
+    /* Step */
+    sig |= stepping & 0xf;
 
     return sig;
 }
@@ -1248,7 +1249,7 @@ x86ModelParse(xmlXPathContextPtr ctxt,
             goto cleanup;
         }
 
-        model->signature = x86MakeSignature(sigFamily, sigModel);
+        model->signature = x86MakeSignature(sigFamily, sigModel, 0);
     }
 
     if (virXPathBoolean("boolean(./vendor)", ctxt)) {
@@ -2971,9 +2972,10 @@ virCPUx86DataAddCPUID(virCPUDataPtr cpuData,
 int
 virCPUx86DataSetSignature(virCPUDataPtr cpuData,
                           unsigned int family,
-                          unsigned int model)
+                          unsigned int model,
+                          unsigned int stepping)
 {
-    uint32_t signature = x86MakeSignature(family, model);
+    uint32_t signature = x86MakeSignature(family, model, stepping);
 
     return x86DataAddSignature(&cpuData->data.x86, signature);
 }
index 91ec43fea982c1cc4fc6db76e9b9b473344052b3..5d14d83e1b91cd6c69b67e8b16f550a80b77bc12 100644 (file)
@@ -34,7 +34,8 @@ int virCPUx86DataAddCPUID(virCPUDataPtr cpuData,
 
 int virCPUx86DataSetSignature(virCPUDataPtr cpuData,
                               unsigned int family,
-                              unsigned int model);
+                              unsigned int model,
+                              unsigned int stepping);
 
 int virCPUx86DataSetVendor(virCPUDataPtr cpuData,
                            const char *vendor);
index 4de411e397bf0db9a46cbcffb64ad6f067353df1..6cea1ccfa50b5e74a384e0d5a6f8acb292e2c762 100644 (file)
@@ -3353,6 +3353,7 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
     virCPUDataPtr data = NULL;
     unsigned long long sigFamily = 0;
     unsigned long long sigModel = 0;
+    unsigned long long sigStepping = 0;
     int ret = -1;
     size_t i;
 
@@ -3387,6 +3388,8 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
                 sigFamily = prop->value.number;
             else if (STREQ(prop->name, "model"))
                 sigModel = prop->value.number;
+            else if (STREQ(prop->name, "stepping"))
+                sigStepping = prop->value.number;
             break;
 
         case QEMU_MONITOR_CPU_PROPERTY_LAST:
@@ -3394,7 +3397,7 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps,
         }
     }
 
-    if (virCPUx86DataSetSignature(data, sigFamily, sigModel) < 0)
+    if (virCPUx86DataSetSignature(data, sigFamily, sigModel, sigStepping) < 0)
         goto cleanup;
 
     if (cpuDecode(cpu, data, virQEMUCapsGetCPUDefinitions(qemuCaps, type)) < 0)