[PATCH 2/2] iommu/amd: Adhere to IVINFO[PAsize] for output address limits
From: Ankit Soni
Date: Mon Oct 19 2026 - 09:15:29 EST
ACPI IVRS IVinfo reports the maximum physical address size (PAsize)
supported by the IOMMU. The AMD IOMMU driver currently hardcodes 52
bits when configuring paging domains. On systems where firmware or a
VM advertises a smaller limit, the driver may over-advertise
capabilities and create domains outside the hardware's actual bounds.
Signed-off-by: Ankit Soni <Ankit.Soni@xxxxxxx>
---
drivers/iommu/amd/amd_iommu.h | 1 +
drivers/iommu/amd/amd_iommu_types.h | 1 +
drivers/iommu/amd/init.c | 9 ++++++++-
drivers/iommu/amd/iommu.c | 4 ++--
4 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h
index 71113e860859..e90fdcc2f4a8 100644
--- a/drivers/iommu/amd/amd_iommu.h
+++ b/drivers/iommu/amd/amd_iommu.h
@@ -45,6 +45,7 @@ extern int amd_iommu_guest_ir;
extern enum protection_domain_mode amd_iommu_pgtable;
extern int amd_iommu_gpt_level;
extern u8 amd_iommu_hpt_vasize;
+extern u8 amd_iommu_pasize;
extern unsigned long amd_iommu_pgsize_bitmap;
extern bool amd_iommu_hatdis;
diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
index 4a15b16bd2ca..35ffeb16c1a3 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -382,6 +382,7 @@
#define IOMMU_IVINFO_EFRSUP BIT(0)
#define IOMMU_IVINFO_DMA_REMAP BIT(1)
#define IOMMU_IVINFO_VASIZE GENMASK_ULL(21, 15)
+#define IOMMU_IVINFO_PASIZE GENMASK_ULL(14, 8)
/* IOMMU Feature Reporting Field (for IVHD type 10h */
#define IOMMU_FEAT_GASUP_SHIFT 6
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index 89da993d7d15..136e35362631 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -157,6 +157,8 @@ bool amd_iommu_irq_remap __read_mostly;
enum protection_domain_mode amd_iommu_pgtable = PD_MODE_V1;
/* Virtual address size */
u8 amd_iommu_hpt_vasize;
+/* Physical address size */
+u8 amd_iommu_pasize __ro_after_init;
/* Guest page table level */
int amd_iommu_gpt_level = PAGE_MODE_4_LEVEL;
@@ -3196,7 +3198,12 @@ static void __init ivinfo_init(void *ivrs)
static void __init init_pgtable_params(void)
{
- u8 vasize, efr_hats;
+ u8 pasize, vasize, efr_hats;
+
+ pasize = FIELD_GET(IOMMU_IVINFO_PASIZE, amd_iommu_ivinfo);
+ if (!pasize)
+ pasize = 52;
+ amd_iommu_pasize = min_t(u8, pasize, 52);
vasize = FIELD_GET(IOMMU_IVINFO_VASIZE, amd_iommu_ivinfo);
if (!vasize)
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 893cd2be11a2..a64045f5a54a 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2760,7 +2760,7 @@ static struct iommu_domain *amd_iommu_domain_alloc_paging_v1(struct device *dev,
cfg.common.features |= BIT(PT_FEAT_FLUSH_RANGE);
cfg.common.hw_max_vasz_lg2 = amd_iommu_hpt_vasize;
- cfg.common.hw_max_oasz_lg2 = 52;
+ cfg.common.hw_max_oasz_lg2 = amd_iommu_pasize;
cfg.starting_level = 2;
domain->domain.ops = &amdv1_ops;
@@ -2835,7 +2835,7 @@ static struct iommu_domain *amd_iommu_domain_alloc_paging_v2(struct device *dev,
cfg.common.hw_max_vasz_lg2 = 47;
cfg.top_level = 3;
}
- cfg.common.hw_max_oasz_lg2 = 52;
+ cfg.common.hw_max_oasz_lg2 = amd_iommu_pasize;
domain->domain.ops = &amdv2_ops;
ret = pt_iommu_x86_64_init(&domain->amdv2, &cfg, GFP_KERNEL);
--
2.43.0