Add QEMU_CAPS_AMD_IOMMU_XTSUP capability and enable xtsup by default for AMD IOMMU when a Q35 domain has >255 vCPUs, similar to Intel EIM auto-enable logic. Also ensure intremap is turned on when required. Signed-off-by: Xiaotian Feng <xiaotian.feng@amd.com> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Tested-by: Ankit Soni <Ankit.Soni@amd.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_postparse.c | 38 ++++++++++++++++++++++++------------ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 5d75c23072..c8667fd77c 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -762,6 +762,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "scsi-block.migrate-pr", /* QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR */ "iommufd", /* QEMU_CAPS_OBJECT_IOMMUFD */ "uefi-vars", /* QEMU_CAPS_DEVICE_UEFI_VARS */ + "amd-iommu.xtsup", /* QEMU_CAPS_AMD_IOMMU_XTSUP */ ); @@ -1632,6 +1633,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsVirtioBlkCCW[] = static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsAMDIOMMU[] = { { "pci-id", QEMU_CAPS_AMD_IOMMU_PCI_ID, NULL }, + { "xtsup", QEMU_CAPS_AMD_IOMMU_XTSUP, NULL }, }; /* see documentation for virQEMUQAPISchemaPathGet for the query format */ diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index a48e1d0367..5662c81e71 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -736,6 +736,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR, /* persistent reservation migration support */ QEMU_CAPS_OBJECT_IOMMUFD, /* -object iommufd */ QEMU_CAPS_DEVICE_UEFI_VARS, /* -device uefi-vars-{x64,sysbus} */ + QEMU_CAPS_AMD_IOMMU_XTSUP, /* amd-iommu.xtsup */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c index 58bd70c741..79e02e34ac 100644 --- a/src/qemu/qemu_postparse.c +++ b/src/qemu/qemu_postparse.c @@ -794,7 +794,7 @@ qemuDomainPstoreDefPostParse(virDomainPstoreDef *pstore, static bool -qemuDomainNeedsIOMMUWithEIM(const virDomainDef *def) +qemuDomainNeedsIOMMUWithx2APIC(const virDomainDef *def) { return ARCH_IS_X86(def->os.arch) && virDomainDefGetVcpusMax(def) > QEMU_MAX_VCPUS_WITHOUT_X2APIC && @@ -808,22 +808,34 @@ qemuDomainIOMMUDefPostParse(virDomainIOMMUDef *iommu, virQEMUCaps *qemuCaps, unsigned int parseFlags) { - /* In case domain has huge number of vCPUS and Extended Interrupt Mode - * (EIM) is not explicitly turned off, let's enable it. If we didn't then + /* In case domain has huge number of vCPUS and x2APIC (intel EIM or AMD + * XTSUP) is not explicitly turned off, let's enable it. If we didn't then * guest will have troubles with interrupts. */ if (parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE && - qemuDomainNeedsIOMMUWithEIM(def) && - iommu && iommu->model == VIR_DOMAIN_IOMMU_MODEL_INTEL) { + qemuDomainNeedsIOMMUWithx2APIC(def) && iommu) { + if (iommu->model == VIR_DOMAIN_IOMMU_MODEL_INTEL) { + /* eim requires intremap. */ + if (iommu->intremap == VIR_TRISTATE_SWITCH_ABSENT && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_INTREMAP)) { + iommu->intremap = VIR_TRISTATE_SWITCH_ON; + } - /* eim requires intremap. */ - if (iommu->intremap == VIR_TRISTATE_SWITCH_ABSENT && - virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_INTREMAP)) { - iommu->intremap = VIR_TRISTATE_SWITCH_ON; + if (iommu->eim == VIR_TRISTATE_SWITCH_ABSENT && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_EIM)) { + iommu->eim = VIR_TRISTATE_SWITCH_ON; + } } - if (iommu->eim == VIR_TRISTATE_SWITCH_ABSENT && - virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_EIM)) { - iommu->eim = VIR_TRISTATE_SWITCH_ON; + if (iommu->model == VIR_DOMAIN_IOMMU_MODEL_AMD) { + if (iommu->intremap == VIR_TRISTATE_SWITCH_ABSENT && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_INTREMAP)) { + iommu->intremap = VIR_TRISTATE_SWITCH_ON; + } + + if (iommu->xtsup == VIR_TRISTATE_SWITCH_ABSENT && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_AMD_IOMMU_XTSUP)) { + iommu->xtsup = VIR_TRISTATE_SWITCH_ON; + } } } @@ -1544,7 +1556,7 @@ qemuDomainDefEnableDefaultFeatures(virDomainDef *def, * modified so change it now. */ if (def->iommus && def->iommus[0]->pci_bus < 0 && (def->iommus[0]->intremap == VIR_TRISTATE_SWITCH_ON || - qemuDomainNeedsIOMMUWithEIM(def)) && + qemuDomainNeedsIOMMUWithx2APIC(def)) && def->features[VIR_DOMAIN_FEATURE_IOAPIC] == VIR_DOMAIN_IOAPIC_NONE) { def->features[VIR_DOMAIN_FEATURE_IOAPIC] = VIR_DOMAIN_IOAPIC_QEMU; } -- 2.34.1