|
|
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 |
|