提交 59fcc961 编写于 作者: A Andrea Bolognani

cpu: Support multiple PVRs in the ppc64 driver

This will allow us to perform PVR matching more broadly, eg. consider
both POWER8 and POWER8E CPUs to be the same even though they have
different PVR values.
上级 adb865df
...@@ -60,6 +60,10 @@ struct ppc64_map { ...@@ -60,6 +60,10 @@ struct ppc64_map {
static void static void
ppc64DataFree(virCPUppc64Data *data) ppc64DataFree(virCPUppc64Data *data)
{ {
if (!data)
return;
VIR_FREE(data->pvr);
VIR_FREE(data); VIR_FREE(data);
} }
...@@ -67,13 +71,24 @@ static virCPUppc64Data * ...@@ -67,13 +71,24 @@ static virCPUppc64Data *
ppc64DataCopy(const virCPUppc64Data *data) ppc64DataCopy(const virCPUppc64Data *data)
{ {
virCPUppc64Data *copy; virCPUppc64Data *copy;
size_t i;
if (VIR_ALLOC(copy) < 0) if (VIR_ALLOC(copy) < 0)
return NULL; goto error;
if (VIR_ALLOC_N(copy->pvr, data->len) < 0)
goto error;
copy->pvr = data->pvr; copy->len = data->len;
for (i = 0; i < data->len; i++)
copy->pvr[i].value = data->pvr[i].value;
return copy; return copy;
error:
ppc64DataFree(copy);
return NULL;
} }
static void static void
...@@ -159,12 +174,14 @@ ppc64ModelFindPVR(const struct ppc64_map *map, ...@@ -159,12 +174,14 @@ ppc64ModelFindPVR(const struct ppc64_map *map,
uint32_t pvr) uint32_t pvr)
{ {
struct ppc64_model *model; struct ppc64_model *model;
size_t i;
model = map->models; model = map->models;
while (model) { while (model) {
if (model->data->pvr == pvr) for (i = 0; i < model->data->len; i++) {
return model; if (model->data->pvr[i].value == pvr)
return model;
}
model = model->next; model = model->next;
} }
...@@ -257,8 +274,16 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, ...@@ -257,8 +274,16 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt,
struct ppc64_map *map) struct ppc64_map *map)
{ {
struct ppc64_model *model; struct ppc64_model *model;
xmlNodePtr *nodes = NULL;
xmlNodePtr bookmark;
char *vendor = NULL; char *vendor = NULL;
unsigned long pvr; unsigned long pvr;
size_t i;
int n;
/* Save the node the context was pointing to, as we're going
* to change it later. It's going to be restored on exit */
bookmark = ctxt->node;
if (VIR_ALLOC(model) < 0) if (VIR_ALLOC(model) < 0)
return -1; return -1;
...@@ -298,14 +323,29 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, ...@@ -298,14 +323,29 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt,
} }
} }
if (!virXPathBoolean("boolean(./pvr)", ctxt) || if ((n = virXPathNodeSet("./pvr", ctxt, &nodes)) <= 0) {
virXPathULongHex("string(./pvr/@value)", ctxt, &pvr) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing or invalid PVR value in CPU model %s"), _("Missing PVR information for CPU model %s"),
model->name); model->name);
goto ignore; goto ignore;
} }
model->data->pvr = pvr;
if (VIR_ALLOC_N(model->data->pvr, n) < 0)
goto ignore;
model->data->len = n;
for (i = 0; i < n; i++) {
ctxt->node = nodes[i];
if (virXPathULongHex("string(./@value)", ctxt, &pvr) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing or invalid PVR value in CPU model %s"),
model->name);
goto ignore;
}
model->data->pvr[i].value = pvr;
}
if (!map->models) { if (!map->models) {
map->models = model; map->models = model;
...@@ -315,7 +355,9 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, ...@@ -315,7 +355,9 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt,
} }
cleanup: cleanup:
ctxt->node = bookmark;
VIR_FREE(vendor); VIR_FREE(vendor);
VIR_FREE(nodes);
return 0; return 0;
ignore: ignore:
...@@ -506,10 +548,10 @@ ppc64DriverDecode(virCPUDefPtr cpu, ...@@ -506,10 +548,10 @@ ppc64DriverDecode(virCPUDefPtr cpu,
if (!data || !(map = ppc64LoadMap())) if (!data || !(map = ppc64LoadMap()))
return -1; return -1;
if (!(model = ppc64ModelFindPVR(map, data->data.ppc64->pvr))) { if (!(model = ppc64ModelFindPVR(map, data->data.ppc64->pvr[0].value))) {
virReportError(VIR_ERR_OPERATION_FAILED, virReportError(VIR_ERR_OPERATION_FAILED,
_("Cannot find CPU model with PVR 0x%08x"), _("Cannot find CPU model with PVR 0x%08x"),
data->data.ppc64->pvr); data->data.ppc64->pvr[0].value);
goto cleanup; goto cleanup;
} }
...@@ -557,9 +599,14 @@ ppc64DriverNodeData(virArch arch) ...@@ -557,9 +599,14 @@ ppc64DriverNodeData(virArch arch)
data = nodeData->data.ppc64; data = nodeData->data.ppc64;
if (VIR_ALLOC_N(data->pvr, 1) < 0)
goto error;
data->len = 1;
#if defined(__powerpc__) || defined(__powerpc64__) #if defined(__powerpc__) || defined(__powerpc64__)
asm("mfpvr %0" asm("mfpvr %0"
: "=r" (data->pvr)); : "=r" (data->pvr[0].value));
#endif #endif
nodeData->arch = arch; nodeData->arch = arch;
......
...@@ -26,9 +26,15 @@ ...@@ -26,9 +26,15 @@
# include <stdint.h> # include <stdint.h>
typedef struct _virCPUppc64PVR virCPUppc64PVR;
struct _virCPUppc64PVR {
uint32_t value;
};
typedef struct _virCPUppc64Data virCPUppc64Data; typedef struct _virCPUppc64Data virCPUppc64Data;
struct _virCPUppc64Data { struct _virCPUppc64Data {
uint32_t pvr; size_t len;
virCPUppc64PVR *pvr;
}; };
#endif /* __VIR_CPU_PPC64_DATA_H__ */ #endif /* __VIR_CPU_PPC64_DATA_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册