qemu: Separate partial CPU check into a function

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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Jiri Denemark 2024-10-10 10:11:25 +02:00
parent 52d2a8eb6c
commit 591b364f49
4 changed files with 54 additions and 7 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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)) {

View File

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