Blob Blame History Raw
From c7a8133cbe9d0612db2889038079d260c3a8334f Mon Sep 17 00:00:00 2001
Message-Id: <c7a8133cbe9d0612db2889038079d260c3a8334f@dist-git>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 21 Jun 2019 09:25:00 +0200
Subject: [PATCH] cpu_x86: Store CPU signature in an array
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

In preparation for storing several CPU signatures in a single CPU model,
we need to turn virCPUx86Model's signature into an array of signatures.

The parser still hardcodes the number of signatures to 1, but the
following patch will drop this limit.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit b07b8b7750c6a505d4b00bd272e79ea0305cb610)

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

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Message-Id: <1d24aad1c6b9aa8142a2e882511f52a41fbaff67.1561068591.git.jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
---
 src/cpu/cpu_x86.c | 50 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index e25bc691ae..f8b8d8a96b 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -145,7 +145,8 @@ typedef virCPUx86Model *virCPUx86ModelPtr;
 struct _virCPUx86Model {
     char *name;
     virCPUx86VendorPtr vendor;
-    uint32_t signature;
+    size_t nsignatures;
+    uint32_t *signatures;
     virCPUx86Data data;
 };
 
@@ -972,6 +973,7 @@ x86ModelFree(virCPUx86ModelPtr model)
         return;
 
     VIR_FREE(model->name);
+    VIR_FREE(model->signatures);
     virCPUx86DataClear(&model->data);
     VIR_FREE(model);
 }
@@ -981,7 +983,14 @@ static int
 x86ModelCopySignatures(virCPUx86ModelPtr dst,
                        virCPUx86ModelPtr src)
 {
-    dst->signature = src->signature;
+    size_t i;
+
+    if (VIR_ALLOC_N(dst->signatures, src->nsignatures) < 0)
+        return -1;
+
+    dst->nsignatures = src->nsignatures;
+    for (i = 0; i < src->nsignatures; i++)
+        dst->signatures[i] = src->signatures[i];
 
     return 0;
 }
@@ -1198,12 +1207,18 @@ static int
 x86ModelParseSignature(virCPUx86ModelPtr model,
                        xmlXPathContextPtr ctxt)
 {
+    /* Remove inherited signatures. */
+    VIR_FREE(model->signatures);
 
     if (virXPathBoolean("boolean(./signature)", ctxt)) {
         unsigned int sigFamily = 0;
         unsigned int sigModel = 0;
         int rc;
 
+        model->nsignatures = 1;
+        if (VIR_ALLOC_N(model->signatures, 1) < 0)
+            return -1;
+
         rc = virXPathUInt("string(./signature/@family)", ctxt, &sigFamily);
         if (rc < 0 || sigFamily == 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -1220,7 +1235,7 @@ x86ModelParseSignature(virCPUx86ModelPtr model,
             return -1;
         }
 
-        model->signature = x86MakeSignature(sigFamily, sigModel, 0);
+        model->signatures[0] = x86MakeSignature(sigFamily, sigModel, 0);
     }
 
     return 0;
@@ -1621,7 +1636,8 @@ x86Compute(virCPUDefPtr host,
                                      &host_model->vendor->cpuid) < 0)
             goto error;
 
-        if (x86DataAddSignature(&guest_model->data, host_model->signature) < 0)
+        if (host_model->signatures &&
+            x86DataAddSignature(&guest_model->data, *host_model->signatures) < 0)
             goto error;
 
         if (cpu->type == VIR_CPU_TYPE_GUEST
@@ -1727,6 +1743,21 @@ virCPUx86Compare(virCPUDefPtr host,
 }
 
 
+static bool
+x86ModelHasSignature(virCPUx86ModelPtr model,
+                     uint32_t signature)
+{
+    size_t i;
+
+    for (i = 0; i < model->nsignatures; i++) {
+        if (model->signatures[i] == signature)
+            return true;
+    }
+
+    return false;
+}
+
+
 /*
  * Checks whether a candidate model is a better fit for the CPU data than the
  * current model.
@@ -1768,8 +1799,8 @@ x86DecodeUseCandidate(virCPUx86ModelPtr current,
      * consider candidates with matching family/model.
      */
     if (signature &&
-        current->signature == signature &&
-        candidate->signature != signature) {
+        x86ModelHasSignature(current, signature) &&
+        !x86ModelHasSignature(candidate, signature)) {
         VIR_DEBUG("%s differs in signature from matching %s",
                   cpuCandidate->model, cpuCurrent->model);
         return 0;
@@ -1785,8 +1816,8 @@ x86DecodeUseCandidate(virCPUx86ModelPtr current,
      * result in longer list of features.
      */
     if (signature &&
-        candidate->signature == signature &&
-        current->signature != signature) {
+        x86ModelHasSignature(candidate, signature) &&
+        !x86ModelHasSignature(current, signature)) {
         VIR_DEBUG("%s provides matching signature", cpuCandidate->model);
         return 1;
     }
@@ -2854,7 +2885,8 @@ virCPUx86Translate(virCPUDefPtr cpu,
         virCPUx86DataAddCPUIDInt(&model->data, &model->vendor->cpuid) < 0)
         goto cleanup;
 
-    if (x86DataAddSignature(&model->data, model->signature) < 0)
+    if (model->signatures &&
+        x86DataAddSignature(&model->data, model->signatures[0]) < 0)
         goto cleanup;
 
     if (!(translated = virCPUDefCopyWithoutModel(cpu)))
-- 
2.22.0