[libvirt] [PATCH v3 15/20] cpu: Parse and use PVR masks in the ppc64 driver

Andrea Bolognani abologna at redhat.com
Mon Aug 10 08:55:57 UTC 2015


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




More information about the libvir-list mailing list