bcddb9
From ac2924813141609b07860a0df5c6bd56eddf0b3e Mon Sep 17 00:00:00 2001
bcddb9
Message-Id: <ac2924813141609b07860a0df5c6bd56eddf0b3e@dist-git>
bcddb9
From: Jiri Denemark <jdenemar@redhat.com>
bcddb9
Date: Fri, 22 Feb 2019 17:20:59 +0100
bcddb9
Subject: [PATCH] cpu_x86: Allow multiple signatures for a CPU model
bcddb9
MIME-Version: 1.0
bcddb9
Content-Type: text/plain; charset=UTF-8
bcddb9
Content-Transfer-Encoding: 8bit
bcddb9
bcddb9
CPU signatures in the cpu_map serve as a hint for CPUID to CPU model
bcddb9
matching algorithm. If the CPU signatures matches any CPU model in the
bcddb9
cpu_map, this model will be the preferred one.
bcddb9
bcddb9
This works out well and solved several mismatches, but in real world
bcddb9
CPUs which should match a single CPU model may be produced with several
bcddb9
different signatures. For example, low voltage Broadwell CPUs for
bcddb9
laptops and Broadwell CPUs for servers differ in CPU model numbers while
bcddb9
we should detect them all as Broadwell CPU model.
bcddb9
bcddb9
This patch adds support for storing several signatures for a single CPU
bcddb9
model to make this hint useful for more CPUs. Later commits will provide
bcddb9
additional signatures for existing CPU models, which will correct some
bcddb9
results in our CPU test suite.
bcddb9
bcddb9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
bcddb9
Reviewed-by: Ján Tomko <jtomko@redhat.com>
bcddb9
(cherry picked from commit dfeb3e598438a891a05487c34e6723d1d3ed9256)
bcddb9
bcddb9
https://bugzilla.redhat.com/show_bug.cgi?id=1558558
bcddb9
https://bugzilla.redhat.com/show_bug.cgi?id=1687515
bcddb9
bcddb9
Conflicts:
bcddb9
	src/cpu/cpu_x86.c
bcddb9
            - most refactoring was not backported
bcddb9
            - VIR_AUTOFREE is not in RHEL-7.6
bcddb9
bcddb9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
bcddb9
Reviewed-by: Ján Tomko <jtomko@redhat.com>
bcddb9
---
bcddb9
 src/cpu/cpu_x86.c | 44 ++++++++++++++++++++++++++++++--------------
bcddb9
 1 file changed, 30 insertions(+), 14 deletions(-)
bcddb9
bcddb9
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
bcddb9
index 543533148f..f6844aaa0d 100644
bcddb9
--- a/src/cpu/cpu_x86.c
bcddb9
+++ b/src/cpu/cpu_x86.c
bcddb9
@@ -1204,41 +1204,57 @@ x86ModelCompare(virCPUx86ModelPtr model1,
bcddb9
 
bcddb9
 
bcddb9
 static int
bcddb9
-x86ModelParseSignature(virCPUx86ModelPtr model,
bcddb9
-                       xmlXPathContextPtr ctxt)
bcddb9
+x86ModelParseSignatures(virCPUx86ModelPtr model,
bcddb9
+                        xmlXPathContextPtr ctxt)
bcddb9
 {
bcddb9
+    xmlNodePtr *nodes = NULL;
bcddb9
+    xmlNodePtr root = ctxt->node;
bcddb9
+    size_t i;
bcddb9
+    int n;
bcddb9
+    int ret = -1;
bcddb9
+
bcddb9
+    if ((n = virXPathNodeSet("./signature", ctxt, &nodes)) <= 0)
bcddb9
+        return n;
bcddb9
+
bcddb9
     /* Remove inherited signatures. */
bcddb9
     VIR_FREE(model->signatures);
bcddb9
 
bcddb9
-    if (virXPathBoolean("boolean(./signature)", ctxt)) {
bcddb9
+    model->nsignatures = n;
bcddb9
+    if (VIR_ALLOC_N(model->signatures, n) < 0)
bcddb9
+       goto cleanup;
bcddb9
+
bcddb9
+    for (i = 0; i < n; i++) {
bcddb9
         unsigned int sigFamily = 0;
bcddb9
         unsigned int sigModel = 0;
bcddb9
         int rc;
bcddb9
 
bcddb9
-        model->nsignatures = 1;
bcddb9
-        if (VIR_ALLOC_N(model->signatures, 1) < 0)
bcddb9
-            return -1;
bcddb9
+        ctxt->node = nodes[i];
bcddb9
 
bcddb9
-        rc = virXPathUInt("string(./signature/@family)", ctxt, &sigFamily);
bcddb9
+        rc = virXPathUInt("string(@family)", ctxt, &sigFamily);
bcddb9
         if (rc < 0 || sigFamily == 0) {
bcddb9
             virReportError(VIR_ERR_INTERNAL_ERROR,
bcddb9
                            _("Invalid CPU signature family in model %s"),
bcddb9
                            model->name);
bcddb9
-            return -1;
bcddb9
+            goto cleanup;
bcddb9
         }
bcddb9
 
bcddb9
-        rc = virXPathUInt("string(./signature/@model)", ctxt, &sigModel);
bcddb9
+        rc = virXPathUInt("string(@model)", ctxt, &sigModel);
bcddb9
         if (rc < 0 || sigModel == 0) {
bcddb9
             virReportError(VIR_ERR_INTERNAL_ERROR,
bcddb9
                            _("Invalid CPU signature model in model %s"),
bcddb9
                            model->name);
bcddb9
-            return -1;
bcddb9
+            goto cleanup;
bcddb9
         }
bcddb9
 
bcddb9
-        model->signatures[0] = x86MakeSignature(sigFamily, sigModel, 0);
bcddb9
+        model->signatures[i] = x86MakeSignature(sigFamily, sigModel, 0);
bcddb9
     }
bcddb9
 
bcddb9
-    return 0;
bcddb9
+    ctxt->node = root;
bcddb9
+    ret = 0;
bcddb9
+
bcddb9
+ cleanup:
bcddb9
+    VIR_FREE(nodes);
bcddb9
+    return ret;
bcddb9
 }
bcddb9
 
bcddb9
 
bcddb9
@@ -1290,8 +1306,8 @@ x86ModelParse(xmlXPathContextPtr ctxt,
bcddb9
             goto error;
bcddb9
     }
bcddb9
 
bcddb9
-    if (x86ModelParseSignature(model, ctxt) < 0)
bcddb9
-        goto error;
bcddb9
+    if (x86ModelParseSignatures(model, ctxt) < 0)
bcddb9
+        goto cleanup;
bcddb9
 
bcddb9
     if (virXPathBoolean("boolean(./vendor)", ctxt)) {
bcddb9
         vendor = virXPathString("string(./vendor/@name)", ctxt);
bcddb9
-- 
bcddb9
2.21.0
bcddb9