[PATCH v3 2/3] iommu/amd: Disallow implicit START_STATE => IVRS_DETECTED transition

From: Rong Zhang

Date: Sat Aug 22 2026 - 18:21:24 EST


Xen PV intentionally skips calling amd_iommu_detect() in order to gate
IOMMU initialization, as the Xen hypervisor has taken over the hardware.
However, due to amd_iommu_prepare() requesting ACPI_FINISHED while
setting up APIC, the state machine is still progressed, only to be
stopped midway due to the `!amd_iommu_detected' check in
early_amd_iommu_init(). This is worthless and fragile. It unnecessarily
calls detect_ivrs(), which leads to extra overhead, i.e., getting the
IVRS table and accessing the PCI config space.

Disallow implicit START_STATE => IVRS_DETECTED transition, so that
amd_iommu_prepare() and other paths no longer progress the state machine
accidentally. This should also help prevent potential bugs if more
housekeeping work is added to amd_iommu_detect() in the future.

Signed-off-by: Rong Zhang <i@xxxxxxxx>
---
drivers/iommu/amd/init.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index 0fd0801a873f..72b5b11b9d75 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -3571,6 +3571,19 @@ static int __init iommu_go_to_state(enum iommu_init_state state)
{
int ret = -EINVAL;

+ /*
+ * Some essential housekeeping work is done by amd_iommu_detect().
+ * Skipping calling it implies that the platform (e.g., Xen hypervisor)
+ * has taken over the hardware. Progressing the state machine in this
+ * case is worthless and fragile.
+ *
+ * There are several paths requesting later states, so disallow implicit
+ * START_STATE => IVRS_DETECTED transition to prevent these paths from
+ * accidentally progressing the state machine.
+ */
+ if (init_state == IOMMU_START_STATE && state != IOMMU_IVRS_DETECTED)
+ goto out;
+
while (init_state != state) {
if (init_state == IOMMU_NOT_FOUND ||
init_state == IOMMU_INIT_ERROR ||
@@ -3579,6 +3592,7 @@ static int __init iommu_go_to_state(enum iommu_init_state state)
ret = state_next();
}

+out:
/*
* SNP platform initilazation requires IOMMUs to be fully configured.
* If the SNP support on IOMMUs has NOT been checked, simply mark SNP

--
2.55.0