* [PATCH 0/2] iommu/amd: Honor IVINFO[PAsize] for paging domains
@ 2026-10-19 13:08 Ankit Soni
2026-10-19 13:08 ` [PATCH 1/2] iommu/amd: Move page-table setup into init_pgtable_params() Ankit Soni
2026-10-19 13:08 ` [PATCH 2/2] iommu/amd: Adhere to IVINFO[PAsize] for output address limits Ankit Soni
0 siblings, 2 replies; 3+ messages in thread
From: Ankit Soni @ 2026-10-19 13:08 UTC (permalink / raw)
To: iommu
Cc: vasant.hegde, suravee.suthikulpanit, joro, will, robin.murphy,
linux-kernel
The AMD IOMMU driver hardcodes a 52-bit output address size when it
creates paging domains. This series honors the PAsize reported in ACPI
IVRS IVinfo instead, so maps cannot exceed what firmware or a VM
advertises. Patch 1 moves page-table setup into init_pgtable_params()
after the IVHD walk, with no functional change intended. Patch 2 uses that
helper for PAsize and applies it to paging domains.
Ankit Soni (2):
iommu/amd: Move page-table setup into init_pgtable_params()
iommu/amd: Adhere to IVINFO[PAsize] for output address limits
drivers/iommu/amd/amd_iommu.h | 1 +
drivers/iommu/amd/amd_iommu_types.h | 1 +
drivers/iommu/amd/init.c | 95 ++++++++++++++++-------------
drivers/iommu/amd/iommu.c | 4 +-
4 files changed, 58 insertions(+), 43 deletions(-)
base-commit: 90201351a862182bdabfc1ad1c97b1e1b6ed5931
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] iommu/amd: Move page-table setup into init_pgtable_params()
2026-10-19 13:08 [PATCH 0/2] iommu/amd: Honor IVINFO[PAsize] for paging domains Ankit Soni
@ 2026-10-19 13:08 ` Ankit Soni
2026-10-19 13:08 ` [PATCH 2/2] iommu/amd: Adhere to IVINFO[PAsize] for output address limits Ankit Soni
1 sibling, 0 replies; 3+ messages in thread
From: Ankit Soni @ 2026-10-19 13:08 UTC (permalink / raw)
To: iommu
Cc: vasant.hegde, suravee.suthikulpanit, joro, will, robin.murphy,
linux-kernel
early_amd_iommu_init() currently sets guest page-table level, host
address size, and v1/v2 fallback inline after the IVHD walk. That
clutters the function.
Move the page-table setup into a separate function. No functional
change.
Signed-off-by: Ankit Soni <Ankit.Soni@amd.com>
---
drivers/iommu/amd/init.c | 88 +++++++++++++++++++++-------------------
1 file changed, 47 insertions(+), 41 deletions(-)
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index edcc187b8f14..89da993d7d15 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -3194,6 +3194,52 @@ static void __init ivinfo_init(void *ivrs)
amd_iommu_ivinfo = *((u32 *)(ivrs + IOMMU_IVINFO_OFFSET));
}
+static void __init init_pgtable_params(void)
+{
+ u8 vasize, efr_hats;
+
+ vasize = FIELD_GET(IOMMU_IVINFO_VASIZE, amd_iommu_ivinfo);
+ if (!vasize)
+ vasize = 64;
+
+ /* 5 level guest page table */
+ if (cpu_feature_enabled(X86_FEATURE_LA57) &&
+ FIELD_GET(FEATURE_GATS, amd_iommu_efr) == GUEST_PGTABLE_5_LEVEL)
+ amd_iommu_gpt_level = PAGE_MODE_5_LEVEL;
+
+ efr_hats = FIELD_GET(FEATURE_HATS, amd_iommu_efr);
+ if (efr_hats != 0x3) {
+ /*
+ * efr[HATS] bits specify the maximum host translation level
+ * supported, with LEVEL 4 being initial max level.
+ */
+ amd_iommu_hpt_vasize = min_t(unsigned int, vasize,
+ (efr_hats + PAGE_MODE_4_LEVEL - 1) * 9 + 21);
+ } else {
+ pr_warn_once(FW_BUG "Disable host address translation due to invalid translation level (%#x).\n",
+ efr_hats);
+ amd_iommu_hatdis = true;
+ }
+
+ if (amd_iommu_pgtable == PD_MODE_V2) {
+ if (!amd_iommu_v2_pgtbl_supported()) {
+ pr_warn("Cannot enable v2 page table for DMA-API. Fallback to v1.\n");
+ amd_iommu_pgtable = PD_MODE_V1;
+ }
+ }
+
+ if (amd_iommu_hatdis) {
+ /*
+ * Host (v1) page table is not available. Attempt to use
+ * Guest (v2) page table.
+ */
+ if (amd_iommu_v2_pgtbl_supported())
+ amd_iommu_pgtable = PD_MODE_V2;
+ else
+ amd_iommu_pgtable = PD_MODE_NONE;
+ }
+}
+
/*
* This is the hardware init function for AMD IOMMU in the system.
* This function is called either from amd_iommu_init or from the interrupt
@@ -3226,7 +3272,6 @@ static int __init early_amd_iommu_init(void)
struct acpi_table_header *ivrs_base;
int ret;
acpi_status status;
- u8 efr_hats, max_vasize;
if (!amd_iommu_detected)
return -ENODEV;
@@ -3256,10 +3301,6 @@ static int __init early_amd_iommu_init(void)
ivinfo_init(ivrs_base);
- max_vasize = FIELD_GET(IOMMU_IVINFO_VASIZE, amd_iommu_ivinfo);
- if (!max_vasize)
- max_vasize = 64;
-
amd_iommu_target_ivhd_type = get_highest_supported_ivhd_type(ivrs_base);
DUMP_printk("Using IVHD type %#x\n", amd_iommu_target_ivhd_type);
@@ -3271,42 +3312,7 @@ static int __init early_amd_iommu_init(void)
if (ret)
goto out;
- /* 5 level guest page table */
- if (cpu_feature_enabled(X86_FEATURE_LA57) &&
- FIELD_GET(FEATURE_GATS, amd_iommu_efr) == GUEST_PGTABLE_5_LEVEL)
- amd_iommu_gpt_level = PAGE_MODE_5_LEVEL;
-
- efr_hats = FIELD_GET(FEATURE_HATS, amd_iommu_efr);
- if (efr_hats != 0x3) {
- /*
- * efr[HATS] bits specify the maximum host translation level
- * supported, with LEVEL 4 being initial max level.
- */
- amd_iommu_hpt_vasize = min_t(unsigned int, max_vasize,
- (efr_hats + PAGE_MODE_4_LEVEL - 1) * 9 + 21);
- } else {
- pr_warn_once(FW_BUG "Disable host address translation due to invalid translation level (%#x).\n",
- efr_hats);
- amd_iommu_hatdis = true;
- }
-
- if (amd_iommu_pgtable == PD_MODE_V2) {
- if (!amd_iommu_v2_pgtbl_supported()) {
- pr_warn("Cannot enable v2 page table for DMA-API. Fallback to v1.\n");
- amd_iommu_pgtable = PD_MODE_V1;
- }
- }
-
- if (amd_iommu_hatdis) {
- /*
- * Host (v1) page table is not available. Attempt to use
- * Guest (v2) page table.
- */
- if (amd_iommu_v2_pgtbl_supported())
- amd_iommu_pgtable = PD_MODE_V2;
- else
- amd_iommu_pgtable = PD_MODE_NONE;
- }
+ init_pgtable_params();
/* Disable any previously enabled IOMMUs */
if (!is_kdump_kernel() || amd_iommu_disabled)
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2/2] iommu/amd: Adhere to IVINFO[PAsize] for output address limits
2026-10-19 13:08 [PATCH 0/2] iommu/amd: Honor IVINFO[PAsize] for paging domains Ankit Soni
2026-10-19 13:08 ` [PATCH 1/2] iommu/amd: Move page-table setup into init_pgtable_params() Ankit Soni
@ 2026-10-19 13:08 ` Ankit Soni
1 sibling, 0 replies; 3+ messages in thread
From: Ankit Soni @ 2026-10-19 13:08 UTC (permalink / raw)
To: iommu
Cc: vasant.hegde, suravee.suthikulpanit, joro, will, robin.murphy,
linux-kernel
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@amd.com>
---
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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-19 13:09 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-19 13:08 [PATCH 0/2] iommu/amd: Honor IVINFO[PAsize] for paging domains Ankit Soni
2026-10-19 13:08 ` [PATCH 1/2] iommu/amd: Move page-table setup into init_pgtable_params() Ankit Soni
2026-10-19 13:08 ` [PATCH 2/2] iommu/amd: Adhere to IVINFO[PAsize] for output address limits Ankit Soni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®