
On Mon, Aug 10, 2015 at 10:55:55 +0200, Andrea Bolognani wrote:
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 | 72 ++++++++++++++++++++++++++++++++++++++++-------- src/cpu/cpu_ppc64_data.h | 8 +++++- 2 files changed, 67 insertions(+), 13 deletions(-)
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c index 6c78ab8..db25f27 100644 --- a/src/cpu/cpu_ppc64.c +++ b/src/cpu/cpu_ppc64.c @@ -60,6 +60,10 @@ struct ppc64_map { static void ppc64DataFree(virCPUppc64Data *data) { + if (!data) + return; + + VIR_FREE(data->pvr); VIR_FREE(data); }
@@ -67,13 +71,24 @@ static virCPUppc64Data * ppc64DataCopy(const virCPUppc64Data *data) { virCPUppc64Data *copy; + size_t i;
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 @@ -159,12 +174,14 @@ 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; }
@@ -257,8 +274,16 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, struct ppc64_map *map) { struct ppc64_model *model; + xmlNodePtr *nodes = NULL; + xmlNodePtr bookmark; char *vendor = NULL; 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) return -1; @@ -298,14 +323,30 @@ 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++) { + ctxt->node = nodes[i]; + + if (!virXPathBoolean("boolean(./@value)", ctxt) || + virXPathULongHex("string(./@value)", ctxt, &pvr) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing or invalid PVR value in CPU model %s"), + model->name); + goto ignore;
Wrong indentation, s/^ // in the 4 lines above. ACK once it's fixed. Jirka