From 09d23faac16b8fdaae71c2a0efe896855d07d32e Mon Sep 17 00:00:00 2001 From: Collin Walling Date: Thu, 19 Sep 2019 16:25:00 -0400 Subject: [PATCH] qemu_driver: hook up query-cpu-model-baseline This command is hooked into the virsh hypervisor-cpu-baseline command. The CPU models provided in the XML sent to the command will be baselined via the query-cpu-model-baseline QMP command. The resulting CPU model will be reported. Signed-off-by: Collin Walling Reviewed-by: Daniel Henrique Barboza Message-Id: <1568924706-2311-10-git-send-email-walling@linux.ibm.com> Reviewed-by: Jiri Denemark --- src/qemu/qemu_driver.c | 91 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 95fe844c34..5daa4b3f82 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13739,6 +13739,90 @@ qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED, } +/** + * qemuConnectStealCPUModelFromInfo: + * + * Consumes @src and replaces the content of @dst with CPU model name and + * features from @src. When this function returns (both with success or + * failure), @src is freed. + */ +static int +qemuConnectStealCPUModelFromInfo(virCPUDefPtr dst, + qemuMonitorCPUModelInfoPtr *src) +{ + qemuMonitorCPUModelInfoPtr info; + size_t i; + int ret = -1; + + virCPUDefFreeModel(dst); + + VIR_STEAL_PTR(info, *src); + VIR_STEAL_PTR(dst->model, info->name); + + for (i = 0; i < info->nprops; i++) { + char *name = info->props[i].name; + + if (info->props[i].type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN || + !info->props[i].value.boolean) + continue; + + if (virCPUDefAddFeature(dst, name, VIR_CPU_FEATURE_REQUIRE) < 0) + goto cleanup; + } + + ret = 0; + + cleanup: + qemuMonitorCPUModelInfoFree(info); + return ret; +} + + +static virCPUDefPtr +qemuConnectCPUModelBaseline(virQEMUCapsPtr qemuCaps, + const char *libDir, + uid_t runUid, + gid_t runGid, + virCPUDefPtr *cpus, + int ncpus) +{ + qemuProcessQMPPtr proc; + virCPUDefPtr ret = NULL; + virCPUDefPtr baseline = NULL; + qemuMonitorCPUModelInfoPtr result = NULL; + size_t i; + + if (!(proc = qemuProcessQMPNew(virQEMUCapsGetBinary(qemuCaps), + libDir, runUid, runGid, false))) + goto cleanup; + + if (qemuProcessQMPStart(proc) < 0) + goto cleanup; + + if (VIR_ALLOC(baseline) < 0) + goto cleanup; + + if (virCPUDefCopyModel(baseline, cpus[0], false)) + goto cleanup; + + for (i = 1; i < ncpus; i++) { + if (qemuMonitorGetCPUModelBaseline(proc->mon, baseline, + cpus[i], &result) < 0) + goto cleanup; + + if (qemuConnectStealCPUModelFromInfo(baseline, &result) < 0) + goto cleanup; + } + + VIR_STEAL_PTR(ret, baseline); + + cleanup: + qemuProcessQMPFree(proc); + virCPUDefFree(baseline); + return ret; +} + + static char * qemuConnectBaselineHypervisorCPU(virConnectPtr conn, const char *emulator, @@ -13750,6 +13834,7 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn, unsigned int flags) { virQEMUDriverPtr driver = conn->privateData; + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); virCPUDefPtr *cpus = NULL; virQEMUCapsPtr qemuCaps = NULL; virArch arch; @@ -13804,6 +13889,12 @@ 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)) { + if (!(cpu = qemuConnectCPUModelBaseline(qemuCaps, cfg->libDir, + cfg->user, cfg->group, + cpus, ncpus))) + goto cleanup; } else { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("computing baseline hypervisor CPU is not supported " -- 2.47.2