[libvirt] [PATCH 1/3] CPU: Implement guestData for PPC CPU driver

Li Zhang zhlcindy at gmail.com
Mon Sep 2 02:45:22 UTC 2013


Any comments about my CPU patches?


On 2013年08月29日 16:46, Li Zhang wrote:
> From: Li Zhang <zhlcindy at linux.vnet.ibm.com>
>
> On Power platform, Power7+ can support Power7 guest.
> It needs to define XML configuration to specify guest's CPU model.
>
> For exmaple:
>    <cpu match='exact'>
>      <model>POWER7+_v2.1</model>
>      <vendor>IBM</vendor>
>    </cpu>
>
> Signed-off-by: Li Zhang <zhlcindy at linux.vnet.ibm.com>
> ---
>   src/cpu/cpu_powerpc.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++-
>   1 file changed, 164 insertions(+), 2 deletions(-)
>
> diff --git a/src/cpu/cpu_powerpc.c b/src/cpu/cpu_powerpc.c
> index 647a8a1..84fa3f7 100644
> --- a/src/cpu/cpu_powerpc.c
> +++ b/src/cpu/cpu_powerpc.c
> @@ -99,6 +99,23 @@ ppcModelFindPVR(const struct ppc_map *map,
>       return NULL;
>   }
>   
> +static struct ppc_model *
> +ppcModelCopy(const struct ppc_model *model)
> +{
> +    struct ppc_model *copy;
> +
> +    if (VIR_ALLOC(copy) < 0 ||
> +        VIR_STRDUP(copy->name, model->name) < 0) {
> +        ppcModelFree(copy);
> +        return NULL;
> +    }
> +
> +    copy->data.pvr = model->data.pvr;
> +    copy->vendor = model->vendor;
> +
> +    return copy;
> +}
> +
>   static struct ppc_vendor *
>   ppcVendorFind(const struct ppc_map *map,
>                 const char *name)
> @@ -126,6 +143,29 @@ ppcVendorFree(struct ppc_vendor *vendor)
>       VIR_FREE(vendor);
>   }
>   
> +static struct ppc_model *
> +ppcModelFromCPU(const virCPUDefPtr cpu,
> +                const struct ppc_map *map)
> +{
> +    struct ppc_model *model = NULL;
> +
> +    if ((model = ppcModelFind(map, cpu->model)) == NULL) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR,
> +                       _("Unknown CPU model %s"), cpu->model);
> +        goto error;
> +    }
> +
> +    if ((model = ppcModelCopy(model)) == NULL)
> +        goto error;
> +
> +    return model;
> +
> +error:
> +    ppcModelFree(model);
> +    return NULL;
> +}
> +
> +
>   static int
>   ppcVendorLoad(xmlXPathContextPtr ctxt,
>                 struct ppc_map *map)
> @@ -288,6 +328,112 @@ error:
>       return NULL;
>   }
>   
> +static virCPUDataPtr
> +ppcMakeCPUData(virArch arch, struct cpuPPCData *data)
> +{
> +    virCPUDataPtr cpuData;
> +
> +    if (VIR_ALLOC(cpuData) < 0)
> +        return NULL;
> +
> +    cpuData->arch = arch;
> +    cpuData->data.ppc = *data;
> +    data = NULL;
> +
> +    return cpuData;
> +}
> +
> +static virCPUCompareResult
> +ppcCompute(virCPUDefPtr host,
> +             const virCPUDefPtr cpu,
> +             virCPUDataPtr *guestData,
> +             char **message)
> +
> +{
> +    struct ppc_map *map = NULL;
> +    struct ppc_model *host_model = NULL;
> +    struct ppc_model *guest_model = NULL;
> +
> +    int ret = 0;
> +    virArch arch;
> +    size_t i;
> +
> +    if (cpu->arch != VIR_ARCH_NONE) {
> +        bool found = false;
> +
> +        for (i = 0; i < ARRAY_CARDINALITY(archs); i++) {
> +            if (archs[i] == cpu->arch) {
> +                found = true;
> +                break;
> +            }
> +        }
> +
> +        if (!found) {
> +            VIR_DEBUG("CPU arch %s does not match host arch",
> +                      virArchToString(cpu->arch));
> +            if (message &&
> +                virAsprintf(message,
> +                            _("CPU arch %s does not match host arch"),
> +                            virArchToString(cpu->arch)) < 0)
> +                goto error;
> +            return VIR_CPU_COMPARE_INCOMPATIBLE;
> +        }
> +        arch = cpu->arch;
> +    } else {
> +        arch = host->arch;
> +    }
> +
> +   if (cpu->vendor &&
> +        (!host->vendor || STRNEQ(cpu->vendor, host->vendor))) {
> +        VIR_DEBUG("host CPU vendor does not match required CPU vendor %s",
> +                  cpu->vendor);
> +        if (message &&
> +            virAsprintf(message,
> +                        _("host CPU vendor does not match required "
> +                          "CPU vendor %s"),
> +                        cpu->vendor) < 0)
> +            goto error;
> +        return VIR_CPU_COMPARE_INCOMPATIBLE;
> +    }
> +
> +    if (!(map = ppcLoadMap()) ||
> +        !(host_model = ppcModelFromCPU(host, map)) ||
> +        !(guest_model = ppcModelFromCPU(cpu, map)))
> +        goto error;
> +
> +    if (guestData != NULL) {
> +        if (cpu->type == VIR_CPU_TYPE_GUEST &&
> +            cpu->match == VIR_CPU_MATCH_STRICT &&
> +            STRNEQ(guest_model->name, host_model->name)) {
> +            VIR_DEBUG("host CPU model does not match required CPU model %s",
> +                     guest_model->name);
> +            if (message &&
> +                virAsprintf(message,
> +                            _("host CPU model does not match required "
> +                            "CPU model %s"),
> +                            guest_model->name) < 0)
> +                goto error;
> +            return VIR_CPU_COMPARE_INCOMPATIBLE;
> +        }
> +
> +        if (!(*guestData = ppcMakeCPUData(arch, &guest_model->data)))
> +            goto error;
> +    }
> +
> +    ret = VIR_CPU_COMPARE_IDENTICAL;
> +
> +out:
> +   ppcMapFree(map);
> +   ppcModelFree(host_model);
> +   ppcModelFree(guest_model);
> +   return ret;
> +
> +error:
> +   ret = VIR_CPU_COMPARE_ERROR;
> +   goto out;
> +
> +}
> +
>   static virCPUCompareResult
>   ppcCompare(virCPUDefPtr host,
>              virCPUDefPtr cpu)
> @@ -369,6 +515,15 @@ ppcNodeData(void)
>   }
>   #endif
>   
> +static virCPUCompareResult
> +ppcGuestData(virCPUDefPtr host,
> +             virCPUDefPtr guest,
> +             virCPUDataPtr *data,
> +             char **message)
> +{
> +    return ppcCompute(host, guest, data, message);
> +}
> +
>   static int
>   ppcUpdate(virCPUDefPtr guest ATTRIBUTE_UNUSED,
>             const virCPUDefPtr host ATTRIBUTE_UNUSED)
> @@ -466,6 +621,13 @@ error:
>       goto cleanup;
>   }
>   
> +static int
> +ppcHasFeature(const virCPUDataPtr data ATTRIBUTE_UNUSED,
> +                         const char *name ATTRIBUTE_UNUSED)
> +{
> +    return 0;
> +}
> +
>   struct cpuArchDriver cpuDriverPowerPC = {
>       .name = "ppc64",
>       .arch = archs,
> @@ -479,8 +641,8 @@ struct cpuArchDriver cpuDriverPowerPC = {
>   #else
>       .nodeData   = NULL,
>   #endif
> -    .guestData  = NULL,
> +    .guestData  = ppcGuestData,
>       .baseline   = ppcBaseline,
>       .update     = ppcUpdate,
> -    .hasFeature = NULL,
> +    .hasFeature = ppcHasFeature,
>   };




More information about the libvir-list mailing list