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. --- src/cpu/cpu_ppc64.c | 73 ++++++++++++++++++++++++++++++++++++++++-------- src/cpu/cpu_ppc64_data.h | 8 +++++- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c index d186d4c..9351729 100644 --- a/src/cpu/cpu_ppc64.c +++ b/src/cpu/cpu_ppc64.c @@ -63,6 +63,7 @@ ppc64DataFree(virCPUppc64Data *data) if (!data) return; + VIR_FREE(data->pvr); VIR_FREE(data); } @@ -70,16 +71,27 @@ static virCPUppc64Data * ppc64DataCopy(virCPUppc64Data *data) { virCPUppc64Data *copy; + size_t i; if (!data) return NULL; if (VIR_ALLOC(copy) < 0) - return NULL; + goto error; + + if (VIR_ALLOC_N(copy->pvr, data->len) < 0) + goto error; + + copy->len = data->len; - copy->pvr = data->pvr; + for (i = 0; i < data->len; i++) + copy->pvr[i].value = data->pvr[i].value; return copy; + + error: + ppc64DataFree(copy); + return NULL; } static void @@ -168,11 +180,13 @@ ppc64ModelFindPVR(const struct ppc64_map *map, uint32_t pvr) { struct ppc64_model *model; + size_t i; model = map->models; while (model) { - if (model->data->pvr == pvr) - return model; + for (i = 0; i < model->data->len; i++) + if (model->data->pvr[i].value == pvr) + return model; model = model->next; } @@ -274,8 +288,12 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, struct ppc64_map *map) { struct ppc64_model *model; + xmlNodePtr *nodes = NULL; char *vendor = NULL; + char *prop = NULL; unsigned long pvr; + size_t i; + int n; if (VIR_ALLOC(model) < 0) return -1; @@ -315,14 +333,38 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, } } - if (!virXPathBoolean("boolean(./pvr)", ctxt) || - virXPathULongHex("string(./pvr/@value)", ctxt, &pvr) < 0) { + if ((n = virXPathNodeSet("./pvr", ctxt, &nodes)) <= 0) { virReportError(VIR_ERR_INTERNAL_ERROR, - _("Missing or invalid PVR value in CPU model %s"), + _("Missing PVR information for CPU model %s"), model->name); 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++) { + + if (!(prop = virXMLPropString(nodes[i], "value"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing PVR value in CPU model %s"), + model->name); + goto ignore; + } + + if (virStrToLong_ul(prop, NULL, 16, &pvr) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid PVR value in CPU model %s"), + model->name); + goto ignore; + } + + model->data->pvr[i].value = pvr; + + VIR_FREE(prop); + } if (!map->models) { map->models = model; @@ -332,7 +374,9 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, } cleanup: + VIR_FREE(prop); VIR_FREE(vendor); + VIR_FREE(nodes); return 0; ignore: @@ -523,10 +567,10 @@ ppc64DriverDecode(virCPUDefPtr cpu, if (!data || !(map = ppc64LoadMap())) 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, _("Cannot find CPU model with PVR 0x%08x"), - data->data.ppc64->pvr); + data->data.ppc64->pvr[0].value); goto cleanup; } @@ -571,16 +615,23 @@ ppc64DriverNodeData(virArch arch) 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; #if defined(__powerpc__) || defined(__powerpc64__) asm("mfpvr %0" - : "=r" (cpuData->data.ppc64->pvr)); + : "=r" (cpuData->data.ppc64->pvr[0].value)); #endif return cpuData; error: + if (cpuData) + ppc64DataFree(cpuData->data.ppc64); VIR_FREE(cpuData); return NULL; } diff --git a/src/cpu/cpu_ppc64_data.h b/src/cpu/cpu_ppc64_data.h index c18fc63..0d3cb0b 100644 --- a/src/cpu/cpu_ppc64_data.h +++ b/src/cpu/cpu_ppc64_data.h @@ -26,9 +26,15 @@ # include <stdint.h> +typedef struct _virCPUppc64PVR virCPUppc64PVR; +struct _virCPUppc64PVR { + uint32_t value; +}; + typedef struct _virCPUppc64Data virCPUppc64Data; struct _virCPUppc64Data { - uint32_t pvr; + size_t len; + virCPUppc64PVR *pvr; }; #endif /* __VIR_CPU_PPC64_DATA_H__ */ -- 2.4.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list