[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