The new qemuDomainCheckCPU function is used as a replacement for
virCPUCompare to make sure all callers use the same comparison
algorithm. As a side effect qemuConnectCompareHypervisorCPU now properly
reports CPU compatibility for CPU model that are considered runnable by
QEMU even if our definition of the model disagrees.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_domain.c | 40 ++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 7 +++++++
src/qemu/qemu_driver.c | 7 +++++--
src/qemu/qemu_process.c | 7 ++-----
4 files changed, 54 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index fda4439b0b..8ada3db115 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -13223,3 +13223,43 @@ qemuDomainStorageUpdatePhysical(virQEMUDriverConfig *cfg,
return ret;
}
+
+
+/**
+ * qemuDomainCheckCPU:
+ * @arch: CPU architecture
+ * @virtType: domain type (KVM vs. TCG)
+ * @qemuCaps: QEMU capabilities
+ * @cpu: CPU definition to check against "host CPU"
+ * @compatCPU: type of CPU used for old style check
+ * @failIncompatible: return an error instead of VIR_CPU_COMPARE_INCOMPATIBLE
+ *
+ * Perform a "partial" check of the @cpu against a "host CPU". Old
style check
+ * used with all existing CPU models uses cpu_map definition of the model in
+ * @cpu and compares it to the host CPU fetched @qemuCaps according to
+ * @compatCPU.
+ *
+ * Returns VIR_CPU_COMPARE_ERROR on error, VIR_CPU_COMPARE_INCOMPATIBLE when
+ * the two CPUs are incompatible, VIR_CPU_COMPARE_IDENTICAL when the two CPUs
+ * are identical, VIR_CPU_COMPARE_SUPERSET when the @cpu CPU is a superset of
+ * the @host CPU. If @failIncompatible is true, the function will return
+ * VIR_CPU_COMPARE_ERROR (and set VIR_ERR_CPU_INCOMPATIBLE error) when the
+ * two CPUs are incompatible.
+ */
+virCPUCompareResult
+qemuDomainCheckCPU(virArch arch,
+ virDomainVirtType virtType,
+ virQEMUCaps *qemuCaps,
+ virCPUDef *cpu,
+ virQEMUCapsHostCPUType compatCPU,
+ bool failIncompatible)
+{
+ virCPUDef *host;
+
+ if (virQEMUCapsIsCPUUsable(qemuCaps, virtType, cpu))
+ return VIR_CPU_COMPARE_SUPERSET;
+
+ host = virQEMUCapsGetHostModel(qemuCaps, virtType, compatCPU);
+
+ return virCPUCompare(arch, host, cpu, failIncompatible);
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index c29ecdf238..a19314b48b 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1176,3 +1176,10 @@ int
qemuDomainStorageUpdatePhysical(virQEMUDriverConfig *cfg,
virDomainObj *vm,
virStorageSource *src);
+virCPUCompareResult
+qemuDomainCheckCPU(virArch arch,
+ virDomainVirtType virtType,
+ virQEMUCaps *qemuCaps,
+ virCPUDef *cpu,
+ virQEMUCapsHostCPUType compatCPU,
+ bool failIncompatible);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 36ec0c0590..72211da137 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11641,8 +11641,11 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn,
validateXML) < 0)
return VIR_CPU_COMPARE_ERROR;
- if (ARCH_IS_X86(arch))
- return virCPUCompare(arch, hvCPU, cpu, failIncompatible);
+ if (ARCH_IS_X86(arch)) {
+ return qemuDomainCheckCPU(arch, virttype, qemuCaps, cpu,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED,
+ failIncompatible);
+ }
if (ARCH_IS_S390(arch) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON)) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 72fc750d28..0815bffe3c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6268,11 +6268,8 @@ qemuProcessUpdateGuestCPU(virDomainDef *def,
virCPUFeaturePolicy removedPolicy = VIR_CPU_FEATURE_DISABLE;
if (def->cpu->check == VIR_CPU_CHECK_PARTIAL &&
- !virQEMUCapsIsCPUUsable(qemuCaps, def->virtType, def->cpu) &&
- virCPUCompare(hostarch,
- virQEMUCapsGetHostModel(qemuCaps, def->virtType,
- VIR_QEMU_CAPS_HOST_CPU_FULL),
- def->cpu, true) < 0)
+ qemuDomainCheckCPU(hostarch, def->virtType, qemuCaps, def->cpu,
+ VIR_QEMU_CAPS_HOST_CPU_FULL, true) < 0)
return -1;
/* When starting a fresh domain we disable all features removed from
--
2.47.0