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
© 2016 - 2026 Red Hat, Inc.