Skip to content

Commit 4eb646b

Browse files
author
CKI KWF Bot
committed
Merge: [AMDSERVER 10.2 Feature] [Kernel] Advertise Host (v1) Page Table NOT Supported (for QEMU AMD eIOMMU)
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1384 JIRA: https://issues.redhat.com/browse/RHEL-107079 * 7e5516e iommu/amd: Add HATDis feature support * 025d137 iommu/amd: Add efr[HATS] max v1 page table level Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com> --- <small>Created 2025-08-29 15:43 UTC by backporter - [KWF FAQ](https://red.ht/kernel_workflow_doc) - [Slack #team-kernel-workflow](https://redhat-internal.slack.com/archives/C04LRUPMJQ5) - [Source](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/webhook/utils/backporter.py) - [Documentation](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/docs/README.backporter.md) - [Report an issue](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12334433&issuetype=1&priority=4&summary=backporter+webhook+issue&components=kernel-workflow+/+backporter)</small> Approved-by: Eder Zulian <ezulian@redhat.com> Approved-by: Jerry Snitselaar <jsnitsel@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents 07b6603 + 785565d commit 4eb646b

File tree

5 files changed

+69
-6
lines changed

5 files changed

+69
-6
lines changed

drivers/iommu/amd/amd_iommu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ int amd_iommu_enable_faulting(unsigned int cpu);
4242
extern int amd_iommu_guest_ir;
4343
extern enum protection_domain_mode amd_iommu_pgtable;
4444
extern int amd_iommu_gpt_level;
45+
extern u8 amd_iommu_hpt_level;
4546
extern unsigned long amd_iommu_pgsize_bitmap;
47+
extern bool amd_iommu_hatdis;
4648

4749
/* Protection domain ops */
4850
void amd_iommu_init_identity_domain(void);

drivers/iommu/amd/amd_iommu_types.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
#define FEATURE_GA BIT_ULL(7)
9797
#define FEATURE_HE BIT_ULL(8)
9898
#define FEATURE_PC BIT_ULL(9)
99+
#define FEATURE_HATS GENMASK_ULL(11, 10)
99100
#define FEATURE_GATS GENMASK_ULL(13, 12)
100101
#define FEATURE_GLX GENMASK_ULL(15, 14)
101102
#define FEATURE_GAM_VAPIC BIT_ULL(21)
@@ -460,6 +461,9 @@
460461
/* IOMMU Feature Reporting Field (for IVHD type 10h */
461462
#define IOMMU_FEAT_GASUP_SHIFT 6
462463

464+
/* IOMMU HATDIS for IVHD type 11h and 40h */
465+
#define IOMMU_IVHD_ATTR_HATDIS_SHIFT 0
466+
463467
/* IOMMU Extended Feature Register (EFR) */
464468
#define IOMMU_EFR_XTSUP_SHIFT 2
465469
#define IOMMU_EFR_GASUP_SHIFT 7
@@ -558,7 +562,8 @@ struct amd_io_pgtable {
558562
};
559563

560564
enum protection_domain_mode {
561-
PD_MODE_V1 = 1,
565+
PD_MODE_NONE,
566+
PD_MODE_V1,
562567
PD_MODE_V2,
563568
};
564569

drivers/iommu/amd/init.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ bool amd_iommu_dump;
152152
bool amd_iommu_irq_remap __read_mostly;
153153

154154
enum protection_domain_mode amd_iommu_pgtable = PD_MODE_V1;
155+
/* Host page table level */
156+
u8 amd_iommu_hpt_level;
155157
/* Guest page table level */
156158
int amd_iommu_gpt_level = PAGE_MODE_4_LEVEL;
157159

@@ -168,6 +170,9 @@ static int amd_iommu_target_ivhd_type;
168170
u64 amd_iommu_efr;
169171
u64 amd_iommu_efr2;
170172

173+
/* Host (v1) page table is not supported*/
174+
bool amd_iommu_hatdis;
175+
171176
/* SNP is enabled on the system? */
172177
bool amd_iommu_snp_en;
173178
EXPORT_SYMBOL(amd_iommu_snp_en);
@@ -1798,6 +1803,11 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h,
17981803
if (h->efr_reg & BIT(IOMMU_EFR_XTSUP_SHIFT))
17991804
amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE;
18001805

1806+
if (h->efr_attr & BIT(IOMMU_IVHD_ATTR_HATDIS_SHIFT)) {
1807+
pr_warn_once("Host Address Translation is not supported.\n");
1808+
amd_iommu_hatdis = true;
1809+
}
1810+
18011811
early_iommu_features_init(iommu, h);
18021812

18031813
break;
@@ -2118,7 +2128,15 @@ static int __init iommu_init_pci(struct amd_iommu *iommu)
21182128
return ret;
21192129
}
21202130

2121-
iommu_device_register(&iommu->iommu, &amd_iommu_ops, NULL);
2131+
ret = iommu_device_register(&iommu->iommu, &amd_iommu_ops, NULL);
2132+
if (ret || amd_iommu_pgtable == PD_MODE_NONE) {
2133+
/*
2134+
* Remove sysfs if DMA translation is not supported by the
2135+
* IOMMU. Do not return an error to enable IRQ remapping
2136+
* in state_next(), DTE[V, TV] must eventually be set to 0.
2137+
*/
2138+
iommu_device_sysfs_remove(&iommu->iommu);
2139+
}
21222140

21232141
return pci_enable_device(iommu->dev);
21242142
}
@@ -2579,7 +2597,7 @@ static void init_device_table_dma(struct amd_iommu_pci_seg *pci_seg)
25792597
u32 devid;
25802598
struct dev_table_entry *dev_table = pci_seg->dev_table;
25812599

2582-
if (dev_table == NULL)
2600+
if (!dev_table || amd_iommu_pgtable == PD_MODE_NONE)
25832601
return;
25842602

25852603
for (devid = 0; devid <= pci_seg->last_bdf; ++devid) {
@@ -3041,6 +3059,7 @@ static int __init early_amd_iommu_init(void)
30413059
struct acpi_table_header *ivrs_base;
30423060
int ret;
30433061
acpi_status status;
3062+
u8 efr_hats;
30443063

30453064
if (!amd_iommu_detected)
30463065
return -ENODEV;
@@ -3085,13 +3104,37 @@ static int __init early_amd_iommu_init(void)
30853104
FIELD_GET(FEATURE_GATS, amd_iommu_efr) == GUEST_PGTABLE_5_LEVEL)
30863105
amd_iommu_gpt_level = PAGE_MODE_5_LEVEL;
30873106

3107+
efr_hats = FIELD_GET(FEATURE_HATS, amd_iommu_efr);
3108+
if (efr_hats != 0x3) {
3109+
/*
3110+
* efr[HATS] bits specify the maximum host translation level
3111+
* supported, with LEVEL 4 being initial max level.
3112+
*/
3113+
amd_iommu_hpt_level = efr_hats + PAGE_MODE_4_LEVEL;
3114+
} else {
3115+
pr_warn_once(FW_BUG "Disable host address translation due to invalid translation level (%#x).\n",
3116+
efr_hats);
3117+
amd_iommu_hatdis = true;
3118+
}
3119+
30883120
if (amd_iommu_pgtable == PD_MODE_V2) {
30893121
if (!amd_iommu_v2_pgtbl_supported()) {
30903122
pr_warn("Cannot enable v2 page table for DMA-API. Fallback to v1.\n");
30913123
amd_iommu_pgtable = PD_MODE_V1;
30923124
}
30933125
}
30943126

3127+
if (amd_iommu_hatdis) {
3128+
/*
3129+
* Host (v1) page table is not available. Attempt to use
3130+
* Guest (v2) page table.
3131+
*/
3132+
if (amd_iommu_v2_pgtbl_supported())
3133+
amd_iommu_pgtable = PD_MODE_V2;
3134+
else
3135+
amd_iommu_pgtable = PD_MODE_NONE;
3136+
}
3137+
30953138
/* Disable any previously enabled IOMMUs */
30963139
if (!is_kdump_kernel() || amd_iommu_disabled)
30973140
disable_iommus();

drivers/iommu/amd/io_pgtable.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ static bool increase_address_space(struct amd_io_pgtable *pgtable,
132132
goto out;
133133

134134
ret = false;
135-
if (WARN_ON_ONCE(pgtable->mode == PAGE_MODE_6_LEVEL))
135+
if (WARN_ON_ONCE(pgtable->mode == amd_iommu_hpt_level))
136136
goto out;
137137

138138
*pte = PM_LEVEL_PDE(pgtable->mode, iommu_virt_to_phys(pgtable->root));
@@ -531,7 +531,7 @@ static void v1_free_pgtable(struct io_pgtable *iop)
531531

532532
/* Page-table is not visible to IOMMU anymore, so free it */
533533
BUG_ON(pgtable->mode < PAGE_MODE_NONE ||
534-
pgtable->mode > PAGE_MODE_6_LEVEL);
534+
pgtable->mode > amd_iommu_hpt_level);
535535

536536
free_sub_pt(pgtable->root, pgtable->mode, &freelist);
537537
iommu_put_pages_list(&freelist);

drivers/iommu/amd/iommu.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2416,6 +2416,13 @@ static struct iommu_device *amd_iommu_probe_device(struct device *dev)
24162416
pci_max_pasids(to_pci_dev(dev)));
24172417
}
24182418

2419+
if (amd_iommu_pgtable == PD_MODE_NONE) {
2420+
pr_warn_once("%s: DMA translation not supported by iommu.\n",
2421+
__func__);
2422+
iommu_dev = ERR_PTR(-ENODEV);
2423+
goto out_err;
2424+
}
2425+
24192426
out_err:
24202427

24212428
iommu_completion_wait(iommu);
@@ -2503,6 +2510,9 @@ static int pdom_setup_pgtable(struct protection_domain *domain,
25032510
case PD_MODE_V2:
25042511
fmt = AMD_IOMMU_V2;
25052512
break;
2513+
case PD_MODE_NONE:
2514+
WARN_ON_ONCE(1);
2515+
return -EPERM;
25062516
}
25072517

25082518
domain->iop.pgtbl.cfg.amd.nid = dev_to_node(dev);
@@ -2516,14 +2526,17 @@ static int pdom_setup_pgtable(struct protection_domain *domain,
25162526
static inline u64 dma_max_address(enum protection_domain_mode pgtable)
25172527
{
25182528
if (pgtable == PD_MODE_V1)
2519-
return ~0ULL;
2529+
return PM_LEVEL_SIZE(amd_iommu_hpt_level);
25202530

25212531
/* V2 with 4/5 level page table */
25222532
return ((1ULL << PM_LEVEL_SHIFT(amd_iommu_gpt_level)) - 1);
25232533
}
25242534

25252535
static bool amd_iommu_hd_support(struct amd_iommu *iommu)
25262536
{
2537+
if (amd_iommu_hatdis)
2538+
return false;
2539+
25272540
return iommu && (iommu->features & FEATURE_HDSUP);
25282541
}
25292542

0 commit comments

Comments
 (0)