Blame SOURCES/libvirt-cpu_x86-Replace-32b-signatures-in-virCPUx86Model-with-a-struct.patch

b971b8
From 22fecd96659495908f37e1c33c1ed52be5fb2d44 Mon Sep 17 00:00:00 2001
b971b8
Message-Id: <22fecd96659495908f37e1c33c1ed52be5fb2d44@dist-git>
b971b8
From: Jiri Denemark <jdenemar@redhat.com>
b971b8
Date: Tue, 26 May 2020 10:59:32 +0200
b971b8
Subject: [PATCH] cpu_x86: Replace 32b signatures in virCPUx86Model with a
b971b8
 struct
b971b8
MIME-Version: 1.0
b971b8
Content-Type: text/plain; charset=UTF-8
b971b8
Content-Transfer-Encoding: 8bit
b971b8
b971b8
The CPU models in our cpu_map define their signatures using separate
b971b8
family and model numbers. Let's store the signatures in the same way in
b971b8
our runtime representation of the cpu_map.
b971b8
b971b8
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
b971b8
Reviewed-by: Ján Tomko <jtomko@redhat.com>
b971b8
(cherry picked from commit 22bded201ffc91661e44065203dcb987e51084ca)
b971b8
b971b8
https://bugzilla.redhat.com/show_bug.cgi?id=1840010
b971b8
b971b8
Conflicts:
b971b8
	src/cpu/cpu_x86.c
b971b8
            - v6.0.0-264-g0a125c7144 which removes the third argument
b971b8
              from virBufferTrim was not backported
b971b8
b971b8
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
b971b8
Message-Id: <21c1eee9c7bb3811f43aa044bb97fa373a159e26.1590483392.git.jdenemar@redhat.com>
b971b8
Reviewed-by: Ján Tomko <jtomko@redhat.com>
b971b8
---
b971b8
 src/cpu/cpu_x86.c | 149 +++++++++++++++++++++++++++++-----------------
b971b8
 1 file changed, 95 insertions(+), 54 deletions(-)
b971b8
b971b8
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
b971b8
index dad3bceff0..b87e3753da 100644
b971b8
--- a/src/cpu/cpu_x86.c
b971b8
+++ b/src/cpu/cpu_x86.c
b971b8
@@ -121,6 +121,19 @@ static virCPUx86Feature x86_kvm_features[] =
b971b8
     KVM_FEATURE(VIR_CPU_x86_HV_STIMER_DIRECT),
b971b8
 };
b971b8
 
b971b8
+typedef struct _virCPUx86Signature virCPUx86Signature;
b971b8
+struct _virCPUx86Signature {
b971b8
+    unsigned int family;
b971b8
+    unsigned int model;
b971b8
+};
b971b8
+
b971b8
+typedef struct _virCPUx86Signatures virCPUx86Signatures;
b971b8
+typedef virCPUx86Signatures *virCPUx86SignaturesPtr;
b971b8
+struct _virCPUx86Signatures {
b971b8
+    size_t count;
b971b8
+    virCPUx86Signature *items;
b971b8
+};
b971b8
+
b971b8
 typedef struct _virCPUx86Model virCPUx86Model;
b971b8
 typedef virCPUx86Model *virCPUx86ModelPtr;
b971b8
 struct _virCPUx86Model {
b971b8
@@ -128,8 +141,7 @@ struct _virCPUx86Model {
b971b8
     bool decodeHost;
b971b8
     bool decodeGuest;
b971b8
     virCPUx86VendorPtr vendor;
b971b8
-    size_t nsignatures;
b971b8
-    uint32_t *signatures;
b971b8
+    virCPUx86SignaturesPtr signatures;
b971b8
     virCPUx86Data data;
b971b8
 };
b971b8
 
b971b8
@@ -717,6 +729,13 @@ x86MakeSignature(unsigned int family,
b971b8
 }
b971b8
 
b971b8
 
b971b8
+static uint32_t
b971b8
+virCPUx86SignatureToCPUID(virCPUx86Signature *sig)
b971b8
+{
b971b8
+    return x86MakeSignature(sig->family, sig->model, 0);
b971b8
+}
b971b8
+
b971b8
+
b971b8
 static void
b971b8
 virCPUx86SignatureFromCPUID(uint32_t sig,
b971b8
                             unsigned int *family,
b971b8
@@ -1099,41 +1118,65 @@ x86FeatureParse(xmlXPathContextPtr ctxt,
b971b8
 }
b971b8
 
b971b8
 
b971b8
+static virCPUx86SignaturesPtr
b971b8
+virCPUx86SignaturesNew(size_t count)
b971b8
+{
b971b8
+    virCPUx86SignaturesPtr sigs;
b971b8
+
b971b8
+    sigs = g_new0(virCPUx86Signatures, 1);
b971b8
+    sigs->items = g_new0(virCPUx86Signature, count);
b971b8
+    sigs->count = count;
b971b8
+
b971b8
+    return sigs;
b971b8
+}
b971b8
+
b971b8
+
b971b8
 static void
b971b8
-virCPUx86SignaturesFree(uint32_t *signatures)
b971b8
+virCPUx86SignaturesFree(virCPUx86SignaturesPtr sigs)
b971b8
 {
b971b8
-    g_free(signatures);
b971b8
+    if (!sigs)
b971b8
+        return;
b971b8
+
b971b8
+    g_free(sigs->items);
b971b8
+    g_free(sigs);
b971b8
 }
b971b8
 
b971b8
 
b971b8
-static int
b971b8
-virCPUx86SignaturesCopy(virCPUx86ModelPtr dst,
b971b8
-                        virCPUx86ModelPtr src)
b971b8
+static virCPUx86SignaturesPtr
b971b8
+virCPUx86SignaturesCopy(virCPUx86SignaturesPtr src)
b971b8
 {
b971b8
+    virCPUx86SignaturesPtr dst;
b971b8
     size_t i;
b971b8
 
b971b8
-    if (src->nsignatures == 0)
b971b8
-        return 0;
b971b8
+    if (!src || src->count == 0)
b971b8
+        return NULL;
b971b8
 
b971b8
-    if (VIR_ALLOC_N(dst->signatures, src->nsignatures) < 0)
b971b8
-        return -1;
b971b8
+    dst = virCPUx86SignaturesNew(src->count);
b971b8
 
b971b8
-    dst->nsignatures = src->nsignatures;
b971b8
-    for (i = 0; i < src->nsignatures; i++)
b971b8
-        dst->signatures[i] = src->signatures[i];
b971b8
+    for (i = 0; i < src->count; i++)
b971b8
+        dst->items[i] = src->items[i];
b971b8
 
b971b8
-    return 0;
b971b8
+    return dst;
b971b8
 }
b971b8
 
b971b8
 
b971b8
 static bool
b971b8
-virCPUx86SignaturesMatch(virCPUx86ModelPtr model,
b971b8
+virCPUx86SignaturesMatch(virCPUx86SignaturesPtr sigs,
b971b8
                          uint32_t signature)
b971b8
 {
b971b8
     size_t i;
b971b8
+    unsigned int family;
b971b8
+    unsigned int model;
b971b8
+    unsigned int stepping;
b971b8
 
b971b8
-    for (i = 0; i < model->nsignatures; i++) {
b971b8
-        if (model->signatures[i] == signature)
b971b8
+    if (!sigs)
b971b8
+        return false;
b971b8
+
b971b8
+    virCPUx86SignatureFromCPUID(signature, &family, &model, &stepping);
b971b8
+
b971b8
+    for (i = 0; i < sigs->count; i++) {
b971b8
+        if (sigs->items[i].family == family &&
b971b8
+            sigs->items[i].model == model)
b971b8
             return true;
b971b8
     }
b971b8
 
b971b8
@@ -1142,17 +1185,21 @@ virCPUx86SignaturesMatch(virCPUx86ModelPtr model,
b971b8
 
b971b8
 
b971b8
 static char *
b971b8
-virCPUx86SignaturesFormat(virCPUx86ModelPtr model)
b971b8
+virCPUx86SignaturesFormat(virCPUx86SignaturesPtr sigs)
b971b8
 {
b971b8
     virBuffer buf = VIR_BUFFER_INITIALIZER;
b971b8
     size_t i;
b971b8
 
b971b8
-    for (i = 0; i < model->nsignatures; i++) {
b971b8
-        virBufferAsprintf(&buf, "%06lx,",
b971b8
-                          (unsigned long)model->signatures[i]);
b971b8
+    if (!sigs)
b971b8
+        return virBufferContentAndReset(&buf;;
b971b8
+
b971b8
+    for (i = 0; i < sigs->count; i++) {
b971b8
+        virBufferAsprintf(&buf, "(%u,%u,0), ",
b971b8
+                          sigs->items[i].family,
b971b8
+                          sigs->items[i].model);
b971b8
     }
b971b8
 
b971b8
-    virBufferTrim(&buf, ",", -1);
b971b8
+    virBufferTrim(&buf, ", ", -1);
b971b8
 
b971b8
     return virBufferContentAndReset(&buf;;
b971b8
 }
b971b8
@@ -1179,16 +1226,11 @@ x86ModelCopy(virCPUx86ModelPtr model)
b971b8
 
b971b8
     copy = g_new0(virCPUx86Model, 1);
b971b8
     copy->name = g_strdup(model->name);
b971b8
-
b971b8
-    if (virCPUx86SignaturesCopy(copy, model) < 0) {
b971b8
-        x86ModelFree(copy);
b971b8
-        return NULL;
b971b8
-    }
b971b8
+    copy->signatures = virCPUx86SignaturesCopy(model->signatures);
b971b8
     x86DataCopy(&copy->data, &model->data);
b971b8
-
b971b8
     copy->vendor = model->vendor;
b971b8
 
b971b8
-    return copy;
b971b8
+    return g_steal_pointer(©);
b971b8
 }
b971b8
 
b971b8
 
b971b8
@@ -1408,9 +1450,7 @@ x86ModelParseAncestor(virCPUx86ModelPtr model,
b971b8
     }
b971b8
 
b971b8
     model->vendor = ancestor->vendor;
b971b8
-    if (virCPUx86SignaturesCopy(model, ancestor) < 0)
b971b8
-        return -1;
b971b8
-
b971b8
+    model->signatures = virCPUx86SignaturesCopy(ancestor->signatures);
b971b8
     x86DataCopy(&model->data, &ancestor->data);
b971b8
 
b971b8
     return 0;
b971b8
@@ -1432,34 +1472,29 @@ x86ModelParseSignatures(virCPUx86ModelPtr model,
b971b8
     /* Remove inherited signatures. */
b971b8
     virCPUx86SignaturesFree(model->signatures);
b971b8
 
b971b8
-    model->nsignatures = n;
b971b8
-    if (VIR_ALLOC_N(model->signatures, n) < 0)
b971b8
-       return -1;
b971b8
+    model->signatures = virCPUx86SignaturesNew(n);
b971b8
 
b971b8
     for (i = 0; i < n; i++) {
b971b8
-        unsigned int sigFamily = 0;
b971b8
-        unsigned int sigModel = 0;
b971b8
+        virCPUx86Signature *sig = &model->signatures->items[i];
b971b8
         int rc;
b971b8
 
b971b8
         ctxt->node = nodes[i];
b971b8
 
b971b8
-        rc = virXPathUInt("string(@family)", ctxt, &sigFamily);
b971b8
-        if (rc < 0 || sigFamily == 0) {
b971b8
+        rc = virXPathUInt("string(@family)", ctxt, &sig->family);
b971b8
+        if (rc < 0 || sig->family == 0) {
b971b8
             virReportError(VIR_ERR_INTERNAL_ERROR,
b971b8
                            _("Invalid CPU signature family in model %s"),
b971b8
                            model->name);
b971b8
             return -1;
b971b8
         }
b971b8
 
b971b8
-        rc = virXPathUInt("string(@model)", ctxt, &sigModel);
b971b8
+        rc = virXPathUInt("string(@model)", ctxt, &sig->model);
b971b8
         if (rc < 0) {
b971b8
             virReportError(VIR_ERR_INTERNAL_ERROR,
b971b8
                            _("Invalid CPU signature model in model %s"),
b971b8
                            model->name);
b971b8
             return -1;
b971b8
         }
b971b8
-
b971b8
-        model->signatures[i] = x86MakeSignature(sigFamily, sigModel, 0);
b971b8
     }
b971b8
 
b971b8
     ctxt->node = root;
b971b8
@@ -1865,9 +1900,12 @@ x86Compute(virCPUDefPtr host,
b971b8
                                  &host_model->vendor->data) < 0)
b971b8
             return VIR_CPU_COMPARE_ERROR;
b971b8
 
b971b8
-        if (host_model->signatures &&
b971b8
-            x86DataAddSignature(&guest_model->data, *host_model->signatures) < 0)
b971b8
-            return VIR_CPU_COMPARE_ERROR;
b971b8
+        if (host_model->signatures && host_model->signatures->count > 0) {
b971b8
+            virCPUx86Signature *sig = &host_model->signatures->items[0];
b971b8
+            if (x86DataAddSignature(&guest_model->data,
b971b8
+                                    virCPUx86SignatureToCPUID(sig)) < 0)
b971b8
+                return VIR_CPU_COMPARE_ERROR;
b971b8
+        }
b971b8
 
b971b8
         if (cpu->type == VIR_CPU_TYPE_GUEST
b971b8
             && cpu->match == VIR_CPU_MATCH_EXACT)
b971b8
@@ -1977,8 +2015,8 @@ x86DecodeUseCandidate(virCPUx86ModelPtr current,
b971b8
      * consider candidates with matching family/model.
b971b8
      */
b971b8
     if (signature &&
b971b8
-        virCPUx86SignaturesMatch(current, signature) &&
b971b8
-        !virCPUx86SignaturesMatch(candidate, signature)) {
b971b8
+        virCPUx86SignaturesMatch(current->signatures, signature) &&
b971b8
+        !virCPUx86SignaturesMatch(candidate->signatures, signature)) {
b971b8
         VIR_DEBUG("%s differs in signature from matching %s",
b971b8
                   cpuCandidate->model, cpuCurrent->model);
b971b8
         return 0;
b971b8
@@ -1994,8 +2032,8 @@ x86DecodeUseCandidate(virCPUx86ModelPtr current,
b971b8
      * result in longer list of features.
b971b8
      */
b971b8
     if (signature &&
b971b8
-        virCPUx86SignaturesMatch(candidate, signature) &&
b971b8
-        !virCPUx86SignaturesMatch(current, signature)) {
b971b8
+        virCPUx86SignaturesMatch(candidate->signatures, signature) &&
b971b8
+        !virCPUx86SignaturesMatch(current->signatures, signature)) {
b971b8
         VIR_DEBUG("%s provides matching signature", cpuCandidate->model);
b971b8
         return 1;
b971b8
     }
b971b8
@@ -2150,7 +2188,7 @@ x86Decode(virCPUDefPtr cpu,
b971b8
     if (vendor)
b971b8
         cpu->vendor = g_strdup(vendor->name);
b971b8
 
b971b8
-    sigs = virCPUx86SignaturesFormat(model);
b971b8
+    sigs = virCPUx86SignaturesFormat(model->signatures);
b971b8
 
b971b8
     VIR_DEBUG("Using CPU model %s (signatures %s) for CPU with signature %06lx",
b971b8
               model->name, NULLSTR(sigs), (unsigned long)signature);
b971b8
@@ -3046,9 +3084,12 @@ virCPUx86Translate(virCPUDefPtr cpu,
b971b8
         virCPUx86DataAddItem(&model->data, &model->vendor->data) < 0)
b971b8
         return -1;
b971b8
 
b971b8
-    if (model->signatures &&
b971b8
-        x86DataAddSignature(&model->data, model->signatures[0]) < 0)
b971b8
-        return -1;
b971b8
+    if (model->signatures && model->signatures->count > 0) {
b971b8
+        virCPUx86Signature *sig = &model->signatures->items[0];
b971b8
+        if (x86DataAddSignature(&model->data,
b971b8
+                                virCPUx86SignatureToCPUID(sig)) < 0)
b971b8
+            return -1;
b971b8
+    }
b971b8
 
b971b8
     if (!(translated = virCPUDefCopyWithoutModel(cpu)))
b971b8
         return -1;
b971b8
-- 
b971b8
2.26.2
b971b8