From eb29b7bbc8ba28bbb0b9fdd655e931e1d1fa625c Mon Sep 17 00:00:00 2001 From: Vasant Hegde Date: Mon, 24 Aug 2026 06:29:07 +0000 Subject: [PATCH] iommu/amd: Fix premature break in init_iommu_one() again Commit 283d245468a2 ("iommu/amd: Fix premature break in init_iommu_one()") unintentionally broke older platforms - such as the ASRockRack B550D4-4L - where the BIOS advertises incorrect IOMMU features. Move the HATDis check ahead of the GASup check, and re-introduce the break inside the GASup check to restore correct behavior on affected platforms. This is a short-term fix to resolve the regression. Longer term, we should rework how EFRs are tracked and prioritize the MMIO-advertised EFR over the one reported via IVRS. That requires more extensive changes and will be addressed separately. Fixes: 283d245468a2 ("iommu/amd: Fix premature break in init_iommu_one()") Reported-by: Andreas Juch Closes: https://lore.kernel.org/linux-iommu/07b2d390-f7a0-47e2-bc2c-eb0853acf52e@juch.cc/ Tested-by: Andreas Juch Signed-off-by: Vasant Hegde Signed-off-by: Joerg Roedel --- drivers/iommu/amd/init.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index c6b106d5921e..edcc187b8f14 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -1922,19 +1922,20 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h, else iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET; - /* XT and GAM require GA mode. */ - if ((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0) { - amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY; - } else { - if (h->efr_reg & BIT(IOMMU_EFR_XTSUP_SHIFT)) - amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE; - } - if (h->efr_attr & BIT(IOMMU_IVHD_ATTR_HATDIS_SHIFT)) { pr_warn_once("Host Address Translation is not supported.\n"); amd_iommu_hatdis = true; } + /* XT and GAM require GA mode. */ + if ((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0) { + amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY; + break; + } else { + if (h->efr_reg & BIT(IOMMU_EFR_XTSUP_SHIFT)) + amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE; + } + early_iommu_features_init(iommu, h); break;