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