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 <walling(a)linux.ibm.com>
Reviewed-by: Daniel Henrique Barboza <danielh413(a)gmail.com>
---
src/qemu/qemu_driver.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1e041a8..2a5a3ca 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13810,6 +13810,83 @@ qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
}
+static int
+qemuConnectStealCPUModelFromInfo(virCPUDefPtr dst,
+ qemuMonitorCPUModelInfoPtr *src)
+{
+ qemuMonitorCPUModelInfoPtr info = *src;
+ size_t i;
+ int ret = 0;
+
+ virCPUDefFreeModel(dst);
+
+ 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 &&
+ virCPUDefAddFeature(dst, name, VIR_CPU_FEATURE_REQUIRE) < 0) {
+ virCPUDefFree(dst);
+ ret = -1;
+ break;
+ }
+ }
+
+ qemuMonitorCPUModelInfoFree(info);
+ *src = NULL;
+ return ret;
+}
+
+
+static virCPUDefPtr
+qemuConnectCPUModelBaseline(virQEMUCapsPtr qemuCaps,
+ const char *libDir,
+ uid_t runUid,
+ gid_t runGid,
+ int ncpus,
+ virCPUDefPtr *cpus)
+{
+ qemuProcessQMPPtr proc;
+ 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 error;
+
+ if (virCPUDefCopyModel(baseline, cpus[0], false))
+ goto error;
+
+ for (i = 1; i < ncpus; i++) {
+
+ if (qemuMonitorGetCPUModelBaseline(proc->mon, baseline,
+ cpus[i], &result) < 0)
+ goto error;
+
+ /* result is freed regardless of this function's success */
+ if (qemuConnectStealCPUModelFromInfo(baseline, &result) < 0)
+ goto error;
+ }
+
+ cleanup:
+ qemuProcessQMPFree(proc);
+ return baseline;
+
+ error:
+ virCPUDefFree(baseline);
+ goto cleanup;
+}
+
+
static char *
qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
const char *emulator,
@@ -13821,6 +13898,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;
@@ -13875,6 +13953,16 @@ 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,
+ ncpus,
+ cpus)))
+ goto cleanup;
+
} else {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("computing baseline hypervisor CPU is not supported "
--
2.7.4