
On Tue, Aug 04, 2015 at 11:38:07 +0200, Andrea Bolognani wrote:
Instead of relying on a hard-coded mask value, read it from the CPU map XML and use it when looking up models by PVR.
Rewrite ppc64DriverNodeData() to use this feature. --- src/cpu/cpu_ppc64.c | 74 ++++++++++++++++++++++++++++-------------------- src/cpu/cpu_ppc64_data.h | 1 + 2 files changed, 44 insertions(+), 31 deletions(-)
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c index 9351729..add5ede 100644 --- a/src/cpu/cpu_ppc64.c +++ b/src/cpu/cpu_ppc64.c @@ -84,8 +84,10 @@ ppc64DataCopy(virCPUppc64Data *data)
copy->len = data->len;
- for (i = 0; i < data->len; i++) + for (i = 0; i < data->len; i++) { copy->pvr[i].value = data->pvr[i].value; + copy->pvr[i].mask = data->pvr[i].mask; + }
return copy;
@@ -185,20 +187,12 @@ ppc64ModelFindPVR(const struct ppc64_map *map, model = map->models; while (model) { for (i = 0; i < model->data->len; i++) - if (model->data->pvr[i].value == pvr) + if ((pvr & model->data->pvr[i].mask) == model->data->pvr[i].value) return model;
model = model->next; }
- /* PowerPC Processor Version Register is interpreted as follows : - * Higher order 16 bits : Power ISA generation. - * Lower order 16 bits : CPU chip version number. - * If the exact CPU isn't found, return the nearest matching CPU generation - */ - if (pvr & 0x0000FFFFul) - return ppc64ModelFindPVR(map, (pvr & 0xFFFF0000ul)); - return NULL; }
@@ -364,6 +358,24 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, model->data->pvr[i].value = pvr;
VIR_FREE(prop); + + if (!(prop = virXMLPropString(nodes[i], "mask"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing PVR mask in CPU model %s"), + model->name); + goto ignore; + } + + if (virStrToLong_ul(prop, NULL, 16, &pvr) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid PVR mask in CPU model %s"), + model->name); + goto ignore; + } + + model->data->pvr[i].mask = pvr;
Wouldn't virXPathULongHex be good enough?
+ + VIR_FREE(prop); }
if (!map->models) { @@ -607,33 +619,33 @@ ppc64DriverFree(virCPUDataPtr data) static virCPUDataPtr ppc64DriverNodeData(virArch arch) { - virCPUDataPtr cpuData; - - if (VIR_ALLOC(cpuData) < 0) - goto error; - - if (VIR_ALLOC(cpuData->data.ppc64) < 0) - goto error; - - if (VIR_ALLOC_N(cpuData->data.ppc64->pvr, 1) < 0) - goto error; - - cpuData->data.ppc64->len = 1; - - cpuData->arch = arch; + virCPUDataPtr nodeData = NULL; + struct ppc64_map *map = NULL; + struct ppc64_model *model = NULL; + uint32_t pvr = 0;
#if defined(__powerpc__) || defined(__powerpc64__) asm("mfpvr %0" - : "=r" (cpuData->data.ppc64->pvr[0].value)); + : "=r" (pvr)); #endif
- return cpuData; + if (!(map = ppc64LoadMap())) + goto cleanup;
- error: - if (cpuData) - ppc64DataFree(cpuData->data.ppc64); - VIR_FREE(cpuData); - return NULL; + if (!(model = ppc64ModelFindPVR(map, pvr))) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Cannot find CPU model with PVR 0x%08x"), + pvr); + goto cleanup; + } + + if (!(nodeData = ppc64MakeCPUData(arch, model->data))) + goto cleanup; + + cleanup: + ppc64MapFree(map); + + return nodeData; }
The ppc64DriverNodeData API is supposed to return raw data from the host, which is then passed to ppc64DriverDecode to be translated into a CPU model name. In other words, you copied most of the internals of ppc64DriverDecode here while you in fact only need to add a single line cpuData->data.ppc64->pvr[0].mask = 0xffffffff; Jirka