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@xxxxxxxxxx> --- 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