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