render / rpms / libvirt

Forked from rpms/libvirt 4 months ago
Clone
7a3408
From 6b1d9c4ab470b81eb903bebc8255911142a01df9 Mon Sep 17 00:00:00 2001
7a3408
Message-Id: <6b1d9c4ab470b81eb903bebc8255911142a01df9@dist-git>
7a3408
From: Andrea Bolognani <abologna@redhat.com>
7a3408
Date: Tue, 11 Aug 2015 17:16:05 +0200
7a3408
Subject: [PATCH] cpu: Support multiple PVRs in the ppc64 driver
7a3408
7a3408
This will allow us to perform PVR matching more broadly, eg. consider
7a3408
both POWER8 and POWER8E CPUs to be the same even though they have
7a3408
different PVR values.
7a3408
7a3408
(cherry picked from commit 59fcc9619522d4ac837dafc3c04f6309761f3c5b)
7a3408
7a3408
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1250977
7a3408
7a3408
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
7a3408
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7a3408
---
7a3408
 src/cpu/cpu_ppc64.c      | 71 ++++++++++++++++++++++++++++++++++++++++--------
7a3408
 src/cpu/cpu_ppc64_data.h |  8 +++++-
7a3408
 2 files changed, 66 insertions(+), 13 deletions(-)
7a3408
7a3408
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
7a3408
index 6c78ab8..ba33e05 100644
7a3408
--- a/src/cpu/cpu_ppc64.c
7a3408
+++ b/src/cpu/cpu_ppc64.c
7a3408
@@ -60,6 +60,10 @@ struct ppc64_map {
7a3408
 static void
7a3408
 ppc64DataFree(virCPUppc64Data *data)
7a3408
 {
7a3408
+    if (!data)
7a3408
+        return;
7a3408
+
7a3408
+    VIR_FREE(data->pvr);
7a3408
     VIR_FREE(data);
7a3408
 }
7a3408
 
7a3408
@@ -67,13 +71,24 @@ static virCPUppc64Data *
7a3408
 ppc64DataCopy(const virCPUppc64Data *data)
7a3408
 {
7a3408
     virCPUppc64Data *copy;
7a3408
+    size_t i;
7a3408
 
7a3408
     if (VIR_ALLOC(copy) < 0)
7a3408
-        return NULL;
7a3408
+        goto error;
7a3408
 
7a3408
-    copy->pvr = data->pvr;
7a3408
+    if (VIR_ALLOC_N(copy->pvr, data->len) < 0)
7a3408
+        goto error;
7a3408
+
7a3408
+    copy->len = data->len;
7a3408
+
7a3408
+    for (i = 0; i < data->len; i++)
7a3408
+        copy->pvr[i].value = data->pvr[i].value;
7a3408
 
7a3408
     return copy;
7a3408
+
7a3408
+ error:
7a3408
+    ppc64DataFree(copy);
7a3408
+    return NULL;
7a3408
 }
7a3408
 
7a3408
 static void
7a3408
@@ -159,12 +174,14 @@ ppc64ModelFindPVR(const struct ppc64_map *map,
7a3408
                   uint32_t pvr)
7a3408
 {
7a3408
     struct ppc64_model *model;
7a3408
+    size_t i;
7a3408
 
7a3408
     model = map->models;
7a3408
     while (model) {
7a3408
-        if (model->data->pvr == pvr)
7a3408
-            return model;
7a3408
-
7a3408
+        for (i = 0; i < model->data->len; i++) {
7a3408
+            if (model->data->pvr[i].value == pvr)
7a3408
+                return model;
7a3408
+        }
7a3408
         model = model->next;
7a3408
     }
7a3408
 
7a3408
@@ -257,8 +274,16 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt,
7a3408
                struct ppc64_map *map)
7a3408
 {
7a3408
     struct ppc64_model *model;
7a3408
+    xmlNodePtr *nodes = NULL;
7a3408
+    xmlNodePtr bookmark;
7a3408
     char *vendor = NULL;
7a3408
     unsigned long pvr;
7a3408
+    size_t i;
7a3408
+    int n;
7a3408
+
7a3408
+    /* Save the node the context was pointing to, as we're going
7a3408
+     * to change it later. It's going to be restored on exit */
7a3408
+    bookmark = ctxt->node;
7a3408
 
7a3408
     if (VIR_ALLOC(model) < 0)
7a3408
         return -1;
7a3408
@@ -298,14 +323,29 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt,
7a3408
         }
7a3408
     }
7a3408
 
7a3408
-    if (!virXPathBoolean("boolean(./pvr)", ctxt) ||
7a3408
-        virXPathULongHex("string(./pvr/@value)", ctxt, &pvr) < 0) {
7a3408
+    if ((n = virXPathNodeSet("./pvr", ctxt, &nodes)) <= 0) {
7a3408
         virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
-                       _("Missing or invalid PVR value in CPU model %s"),
7a3408
+                       _("Missing PVR information for CPU model %s"),
7a3408
                        model->name);
7a3408
         goto ignore;
7a3408
     }
7a3408
-    model->data->pvr = pvr;
7a3408
+
7a3408
+    if (VIR_ALLOC_N(model->data->pvr, n) < 0)
7a3408
+        goto ignore;
7a3408
+
7a3408
+    model->data->len = n;
7a3408
+
7a3408
+    for (i = 0; i < n; i++) {
7a3408
+        ctxt->node = nodes[i];
7a3408
+
7a3408
+        if (virXPathULongHex("string(./@value)", ctxt, &pvr) < 0) {
7a3408
+            virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                           _("Missing or invalid PVR value in CPU model %s"),
7a3408
+                           model->name);
7a3408
+            goto ignore;
7a3408
+        }
7a3408
+        model->data->pvr[i].value = pvr;
7a3408
+    }
7a3408
 
7a3408
     if (!map->models) {
7a3408
         map->models = model;
7a3408
@@ -315,7 +355,9 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt,
7a3408
     }
7a3408
 
7a3408
  cleanup:
7a3408
+    ctxt->node = bookmark;
7a3408
     VIR_FREE(vendor);
7a3408
+    VIR_FREE(nodes);
7a3408
     return 0;
7a3408
 
7a3408
  ignore:
7a3408
@@ -506,10 +548,10 @@ ppc64DriverDecode(virCPUDefPtr cpu,
7a3408
     if (!data || !(map = ppc64LoadMap()))
7a3408
         return -1;
7a3408
 
7a3408
-    if (!(model = ppc64ModelFindPVR(map, data->data.ppc64->pvr))) {
7a3408
+    if (!(model = ppc64ModelFindPVR(map, data->data.ppc64->pvr[0].value))) {
7a3408
         virReportError(VIR_ERR_OPERATION_FAILED,
7a3408
                        _("Cannot find CPU model with PVR 0x%08x"),
7a3408
-                       data->data.ppc64->pvr);
7a3408
+                       data->data.ppc64->pvr[0].value);
7a3408
         goto cleanup;
7a3408
     }
7a3408
 
7a3408
@@ -557,9 +599,14 @@ ppc64DriverNodeData(virArch arch)
7a3408
 
7a3408
     data = nodeData->data.ppc64;
7a3408
 
7a3408
+    if (VIR_ALLOC_N(data->pvr, 1) < 0)
7a3408
+        goto error;
7a3408
+
7a3408
+    data->len = 1;
7a3408
+
7a3408
 #if defined(__powerpc__) || defined(__powerpc64__)
7a3408
     asm("mfpvr %0"
7a3408
-        : "=r" (data->pvr));
7a3408
+        : "=r" (data->pvr[0].value));
7a3408
 #endif
7a3408
 
7a3408
     nodeData->arch = arch;
7a3408
diff --git a/src/cpu/cpu_ppc64_data.h b/src/cpu/cpu_ppc64_data.h
7a3408
index c18fc63..0d3cb0b 100644
7a3408
--- a/src/cpu/cpu_ppc64_data.h
7a3408
+++ b/src/cpu/cpu_ppc64_data.h
7a3408
@@ -26,9 +26,15 @@
7a3408
 
7a3408
 # include <stdint.h>
7a3408
 
7a3408
+typedef struct _virCPUppc64PVR virCPUppc64PVR;
7a3408
+struct _virCPUppc64PVR {
7a3408
+    uint32_t value;
7a3408
+};
7a3408
+
7a3408
 typedef struct _virCPUppc64Data virCPUppc64Data;
7a3408
 struct _virCPUppc64Data {
7a3408
-    uint32_t pvr;
7a3408
+    size_t len;
7a3408
+    virCPUppc64PVR *pvr;
7a3408
 };
7a3408
 
7a3408
 #endif /* __VIR_CPU_PPC64_DATA_H__ */
7a3408
-- 
7a3408
2.5.0
7a3408