Use the host CPU data probed by the current emulator when updating a guest CPU according to a host CPU or when checking whether they are compatible. --- src/qemu/qemu_command.c | 32 ++++++++++++++++++++++++++------ src/qemu/qemu_domain.c | 21 +++++++++++++++------ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d0aed7c..f2124d8 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5683,13 +5683,19 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver, virBuffer buf = VIR_BUFFER_INITIALIZER; size_t i; virCapsPtr caps = NULL; + bool filteredHost = false; *hasHwVirt = false; if (!(caps = virQEMUDriverGetCapabilities(driver, false))) goto cleanup; - host = caps->host.cpu; + if (def->virtType == VIR_DOMAIN_VIRT_KVM) + host = virQEMUCapsGetHostCPU(qemuCaps); + if (host) + filteredHost = true; + else + host = caps->host.cpu; if (def->os.arch == VIR_ARCH_I686) default_model = "qemu32"; @@ -5722,12 +5728,26 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver, switch (cmp) { case VIR_CPU_COMPARE_INCOMPATIBLE: if (compare_msg) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("guest and host CPU are not compatible: %s"), - compare_msg); + if (filteredHost) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("requested guest CPU cannot be provided " + "by QEMU binary on this host: %s"), + compare_msg); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("guest and host CPU are not " + "compatible: %s"), compare_msg); + } } else { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("guest CPU is not compatible with host CPU")); + if (filteredHost) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("requested guest CPU cannot be provided " + "by QEMU binary on this host")); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("guest CPU is not compatible " + "with host CPU")); + } } /* fall through */ case VIR_CPU_COMPARE_ERROR: diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index da3b768..83197e0 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1347,6 +1347,8 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver, virDomainControllerDefPtr *controllers = NULL; int ncontrollers = 0; virCapsPtr caps = NULL; + virQEMUCapsPtr qemuCaps = NULL; + virCPUDefPtr hostCPU = NULL; if (!(caps = virQEMUDriverGetCapabilities(driver, false))) goto cleanup; @@ -1355,15 +1357,21 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver, if ((flags & VIR_DOMAIN_XML_UPDATE_CPU) && def_cpu && (def_cpu->mode != VIR_CPU_MODE_CUSTOM || def_cpu->model)) { - if (!caps->host.cpu || - !caps->host.cpu->model) { - virReportError(VIR_ERR_OPERATION_FAILED, - "%s", _("cannot get host CPU capabilities")); - goto cleanup; + if ((qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, + def->emulator))) + hostCPU = virQEMUCapsGetHostCPU(qemuCaps); + + if (!hostCPU) { + if (!caps->host.cpu || !caps->host.cpu->model) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("cannot get host CPU capabilities")); + goto cleanup; + } + hostCPU = caps->host.cpu; } if (!(cpu = virCPUDefCopy(def_cpu)) || - cpuUpdate(cpu, caps->host.cpu) < 0) + cpuUpdate(cpu, hostCPU) < 0) goto cleanup; def->cpu = cpu; } @@ -1445,6 +1453,7 @@ cleanup: def->ncontrollers = ncontrollers; } virObjectUnref(caps); + virObjectUnref(qemuCaps); return ret; } -- 1.8.3.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list