[libvirt] [PATCH 16/18] cpu: Parse and use PVR masks in the ppc64 driver

Jiri Denemark jdenemar at redhat.com
Thu Aug 6 14:42:54 UTC 2015


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




More information about the libvir-list mailing list