[libvirt] [PATCH v2 4/8] qemu_driver: hook up query-cpu-model-baseline

Daniel Henrique Barboza danielhb413 at gmail.com
Mon Apr 29 18:31:22 UTC 2019



On 4/26/19 5:22 PM, walling at linux.ibm.com wrote:
> From: Collin Walling <walling at linux.ibm.com>
>
> This command is hooked into the virsh hypervisor-cpu-baseline command.
> As such, the CPU models provided in the XML sent to the command will be
> baselined with the CPU contained in the QEMU capabilities file for the
> appropriate QEMU binary (for s390x, this CPU definition can be observed
> via virsh domcapabilities).
>
> Signed-off-by: Collin Walling <walling at linux.ibm.com>

Reviewed-by: Daniel Henrique Barboza <danielhb413 at gmail.com>

> ---
>   src/qemu/qemu_capabilities.c | 102 +++++++++++++++++++++++++++++++++++++++++++
>   src/qemu/qemu_capabilities.h |   7 +++
>   src/qemu/qemu_driver.c       |  28 ++++++++++++
>   3 files changed, 137 insertions(+)
>
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 0835f65..e3f3d0b 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -5402,3 +5402,105 @@ virQEMUCapsStripMachineAliases(virQEMUCapsPtr qemuCaps)
>       for (i = 0; i < qemuCaps->nmachineTypes; i++)
>           VIR_FREE(qemuCaps->machineTypes[i].alias);
>   }
> +
> +
> +static void
> +virQEMUCapsFixFeatPolicy(virCPUDefPtr cpu)
> +{
> +    size_t i;
> +
> +    /* Features reported by QMP are either on or off. If the feature is
> +     * off, let's set the policy to disabled. Otherwise set it to required.
> +     */
> +    for (i = 0; i < cpu->nfeatures; i++) {
> +        if (cpu->features[i].policy == 0)
> +            cpu->features[i].policy = VIR_CPU_FEATURE_DISABLE;
> +        else
> +            cpu->features[i].policy = VIR_CPU_FEATURE_REQUIRE;
> +    }
> +}
> +
> +
> +static int
> +virQEMUCapsStealCPUModelFromInfo(qemuMonitorCPUModelInfoPtr info,
> +                                 virCPUDefPtr cpu)
> +{
> +    size_t i;
> +
> +    virCPUDefFreeModel(cpu);
> +
> +    VIR_STEAL_PTR(cpu->model, info->name);
> +
> +    for (i = 0; i < info->nprops; i++) {
> +        char *name = info->props[i].name;
> +        int policy = 0;
> +
> +        /* If monitor prop type is boolean and is true, force the feat on */
> +        if (info->props[i].type == QEMU_MONITOR_CPU_PROPERTY_BOOLEAN)
> +            policy = info->props[i].value.boolean;
> +
> +        if (virCPUDefAddFeature(cpu, name, policy) < 0)
> +            goto error;
> +    }
> +
> +    qemuMonitorCPUModelInfoFree(info);
> +    return 0;
> +
> + error:
> +    virCPUDefFree(cpu);
> +    return -1;
> +}
> +
> +
> +virCPUDefPtr
> +virQEMUCapsCPUModelBaseline(virQEMUCapsPtr qemuCaps,
> +                            const char *libDir,
> +                            uid_t runUid,
> +                            gid_t runGid,
> +                            int ncpus,
> +                            virCPUDefPtr *cpus)
> +{
> +    qemuMonitorCPUModelInfoPtr result = NULL;
> +    qemuProcessQMPPtr proc = NULL;
> +    virCPUDefPtr cpu = NULL;
> +    virCPUDefPtr baseline = NULL;
> +    size_t i;
> +
> +    if (VIR_ALLOC(cpu) < 0)
> +        goto cleanup;
> +
> +    if (virCPUDefCopyModel(cpu, cpus[0], false))
> +        goto cleanup;
> +
> +    if (!(proc = qemuProcessQMPNew(qemuCaps->binary, libDir,
> +                                   runUid, runGid, false)))
> +        goto cleanup;
> +
> +    if (qemuProcessQMPStart(proc) < 0)
> +        goto cleanup;
> +
> +    for (i = 1; i < ncpus; i++) {
> +        if (qemuMonitorGetCPUModelBaseline(proc->mon, cpu->model,
> +                                           cpu->nfeatures, cpu->features,
> +                                           cpus[i]->model, cpus[i]->nfeatures,
> +                                           cpus[i]->features, &result) < 0)
> +            goto cleanup;
> +
> +        if (virQEMUCapsStealCPUModelFromInfo(result, cpu) < 0)
> +            goto cleanup;
> +
> +        result = NULL;
> +    }
> +
> +    virQEMUCapsFixFeatPolicy(cpu);
> +    VIR_STEAL_PTR(baseline, cpu);
> +
> + cleanup:
> +    if (!baseline)
> +        virQEMUCapsLogProbeFailure(qemuCaps->binary);
> +
> +    qemuMonitorCPUModelInfoFree(result);
> +    qemuProcessQMPFree(proc);
> +    virCPUDefFree(cpu);
> +    return baseline;
> +}
> diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
> index 102f259..08fd555 100644
> --- a/src/qemu/qemu_capabilities.h
> +++ b/src/qemu/qemu_capabilities.h
> @@ -648,4 +648,11 @@ virQEMUCapsGetSEVCapabilities(virQEMUCapsPtr qemuCaps);
>   virArch virQEMUCapsArchFromString(const char *arch);
>   const char *virQEMUCapsArchToString(virArch arch);
>   
> +virCPUDefPtr virQEMUCapsCPUModelBaseline(virQEMUCapsPtr qemuCaps,
> +                                        const char *libDir,
> +                                        uid_t runUid,
> +                                        gid_t runGid,
> +                                        int ncpus,
> +                                        virCPUDefPtr *cpus);
> +
>   #endif /* LIBVIRT_QEMU_CAPABILITIES_H */
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index f48d925..e1e1fea 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -13576,6 +13576,7 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
>                                    unsigned int flags)
>   {
>       virQEMUDriverPtr driver = conn->privateData;
> +    virQEMUDriverConfigPtr config = driver->config;
>       virCPUDefPtr *cpus = NULL;
>       virQEMUCapsPtr qemuCaps = NULL;
>       virArch arch;
> @@ -13630,6 +13631,33 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
>           if (!(cpu = virCPUBaseline(arch, cpus, ncpus, cpuModels,
>                                      (const char **)features, migratable)))
>               goto cleanup;
> +    } else if (ARCH_IS_S390(arch) &&
> +               virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_BASELINE)) {
> +        /* Add the hypervisor CPU to the list */
> +        virCPUDefPtr hvCPU;
> +        size_t alloc = ncpus + 1;
> +
> +        if (VIR_RESIZE_N(cpus, alloc, ncpus, 1) < 0)
> +            goto cleanup;
> +
> +        if (VIR_ALLOC(cpus[ncpus]) < 0)
> +            goto cleanup;
> +
> +        hvCPU = virQEMUCapsGetHostModel(qemuCaps, virttype,
> +                                        VIR_QEMU_CAPS_HOST_CPU_REPORTED);
> +
> +        if (virCPUDefCopyModel(cpus[ncpus], hvCPU, false) < 0)
> +            goto cleanup;
> +
> +        ncpus++;
> +
> +        if (!(cpu = virQEMUCapsCPUModelBaseline(qemuCaps, config->libDir,
> +                                                config->user, config->group,
> +                                                ncpus, cpus)))
> +            goto cleanup;
> +
> +        if (!(flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES))
> +            virCPUDefFreeFeatures(cpu);
>       } else {
>           virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
>                          _("computing baseline hypervisor CPU is not supported "




More information about the libvir-list mailing list