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. --- src/cpu/cpu_map.xml | 14 +++++++------- src/cpu/cpu_ppc64.c | 24 ++++++++++++++---------- src/cpu/cpu_ppc64_data.h | 1 + 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml index b3c4477..0895ada 100644 --- a/src/cpu/cpu_map.xml +++ b/src/cpu/cpu_map.xml @@ -1360,30 +1360,30 @@ <!-- IBM-based CPU models --> <model name='POWER6'> <vendor name='IBM'/> - <pvr value='0x003e0000'/> + <pvr value='0x003e0000' mask='0xffff0000'/> </model> <model name='POWER7'> <vendor name='IBM'/> - <pvr value='0x003f0000'/> - <pvr value='0x004a0000'/> + <pvr value='0x003f0000' mask='0xffff0000'/> + <pvr value='0x004a0000' mask='0xffff0000'/> </model> <model name='POWER8'> <vendor name='IBM'/> - <pvr value='0x004b0000'/> - <pvr value='0x004d0000'/> + <pvr value='0x004b0000' mask='0xffff0000'/> + <pvr value='0x004d0000' mask='0xffff0000'/> </model> <!-- Freescale-based CPU models --> <model name='POWERPC_e5500'> <vendor name='Freescale'/> - <pvr value='0x80240000'/> + <pvr value='0x80240000' mask='0xffff0000'/> </model> <model name='POWERPC_e6500'> <vendor name='Freescale'/> - <pvr value='0x80400000'/> + <pvr value='0x80400000' mask='0xffff0000'/> </model> </arch> </cpus> diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c index db25f27..bf8f4da 100644 --- a/src/cpu/cpu_ppc64.c +++ b/src/cpu/cpu_ppc64.c @@ -81,8 +81,10 @@ ppc64DataCopy(const 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; @@ -179,20 +181,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; } @@ -346,6 +340,15 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, goto ignore; } model->data->pvr[i].value = pvr; + + if (!virXPathBoolean("boolean(./@mask)", ctxt) || + virXPathULongHex("string(./@mask)", ctxt, &pvr) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing or invalid PVR mask in CPU model %s"), + model->name); + goto ignore; + } + model->data->pvr[i].mask = pvr; } if (!map->models) { @@ -609,6 +612,7 @@ ppc64DriverNodeData(virArch arch) asm("mfpvr %0" : "=r" (data->pvr[0].value)); #endif + data->pvr[0].mask = 0xfffffffful; nodeData->arch = arch; diff --git a/src/cpu/cpu_ppc64_data.h b/src/cpu/cpu_ppc64_data.h index 0d3cb0b..c0a130e 100644 --- a/src/cpu/cpu_ppc64_data.h +++ b/src/cpu/cpu_ppc64_data.h @@ -29,6 +29,7 @@ typedef struct _virCPUppc64PVR virCPUppc64PVR; struct _virCPUppc64PVR { uint32_t value; + uint32_t mask; }; typedef struct _virCPUppc64Data virCPUppc64Data; -- 2.4.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list