Skip to content

Commit 1e0ea4d

Browse files
committed
Merge tag 'iommu-updates-v7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux
Pull iommu updates from Joerg Roedel: "Core changes: - Rust bindings for IO-pgtable code - IOMMU page allocation debugging support - Disable ATS during PCI resets Intel VT-d changes: - Skip dev-iotlb flush for inaccessible PCIe device - Flush cache for PASID table before using it - Use right invalidation method for SVA and NESTED domains - Ensure atomicity in context and PASID entry updates AMD-Vi changes: - Support for nested translations - Other minor improvements ARM-SMMU-v2 changes: - Configure SoC-specific prefetcher settings for Qualcomm's "MDSS" ARM-SMMU-v3 changes: - Improve CMDQ locking fairness for pathetically small queue sizes - Remove tracking of the IAS as this is only relevant for AArch32 and was causing C_BAD_STE errors - Add device-tree support for NVIDIA's CMDQV extension - Allow some hitless transitions for the 'MEV' and 'EATS' STE fields - Don't disable ATS for nested S1-bypass nested domains - Additions to the kunit selftests" * tag 'iommu-updates-v7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux: (54 commits) iommupt: Always add IOVA range to iotlb_gather in gather_range_pages() iommu/amd: serialize sequence allocation under concurrent TLB invalidations iommu/amd: Fix type of type parameter to amd_iommufd_hw_info() iommu/arm-smmu-v3: Do not set disable_ats unless vSTE is Translate iommu/arm-smmu-v3-test: Add nested s1bypass/s1dssbypass coverage iommu/arm-smmu-v3: Mark EATS_TRANS safe when computing the update sequence iommu/arm-smmu-v3: Mark STE MEV safe when computing the update sequence iommu/arm-smmu-v3: Add update_safe bits to fix STE update sequence iommu/arm-smmu-v3: Add device-tree support for CMDQV driver iommu/tegra241-cmdqv: Decouple driver from ACPI iommu/arm-smmu-qcom: Restore ACTLR settings for MDSS on sa8775p iommu/vt-d: Fix race condition during PASID entry replacement iommu/vt-d: Clear Present bit before tearing down context entry iommu/vt-d: Clear Present bit before tearing down PASID entry iommu/vt-d: Flush piotlb for SVM and Nested domain iommu/vt-d: Flush cache for PASID table before using it iommu/vt-d: Flush dev-IOTLB only when PCIe device is accessible in scalable mode iommu/vt-d: Skip dev-iotlb flush for inaccessible PCIe device without scalable mode rust: iommu: fix `srctree` link warning rust: iommu: fix Rust formatting ...
2 parents c22e26b + ad09563 commit 1e0ea4d

49 files changed

Lines changed: 1996 additions & 498 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2680,6 +2680,15 @@ Kernel parameters
26802680
1 - Bypass the IOMMU for DMA.
26812681
unset - Use value of CONFIG_IOMMU_DEFAULT_PASSTHROUGH.
26822682

2683+
iommu.debug_pagealloc=
2684+
[KNL,EARLY] When CONFIG_IOMMU_DEBUG_PAGEALLOC is set, this
2685+
parameter enables the feature at boot time. By default, it
2686+
is disabled and the system behaves the same way as a kernel
2687+
built without CONFIG_IOMMU_DEBUG_PAGEALLOC.
2688+
Format: { "0" | "1" }
2689+
0 - Sanitizer disabled.
2690+
1 - Sanitizer enabled, expect runtime overhead.
2691+
26832692
io7= [HW] IO7 for Marvel-based Alpha systems
26842693
See comment before marvel_specify_io7 in
26852694
arch/alpha/kernel/core_marvel.c.

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13346,6 +13346,7 @@ F: drivers/iommu/
1334613346
F: include/linux/iommu.h
1334713347
F: include/linux/iova.h
1334813348
F: include/linux/of_iommu.h
13349+
F: rust/kernel/iommu/
1334913350

1335013351
IOMMUFD
1335113352
M: Jason Gunthorpe <jgg@nvidia.com>

drivers/iommu/Kconfig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,25 @@ config SPRD_IOMMU
384384

385385
Say Y here if you want to use the multimedia devices listed above.
386386

387+
config IOMMU_DEBUG_PAGEALLOC
388+
bool "Debug IOMMU mappings against page allocations"
389+
depends on DEBUG_PAGEALLOC && IOMMU_API && PAGE_EXTENSION
390+
help
391+
This enables a consistency check between the kernel page allocator and
392+
the IOMMU subsystem. It verifies that pages being allocated or freed
393+
are not currently mapped in any IOMMU domain.
394+
395+
This helps detect DMA use-after-free bugs where a driver frees a page
396+
but forgets to unmap it from the IOMMU, potentially allowing a device
397+
to overwrite memory that the kernel has repurposed.
398+
399+
These checks are best-effort and may not detect all problems.
400+
401+
Due to performance overhead, this feature is disabled by default.
402+
You must enable "iommu.debug_pagealloc" from the kernel command
403+
line to activate the runtime checks.
404+
405+
If unsure, say N.
387406
endif # IOMMU_SUPPORT
388407

389408
source "drivers/iommu/generic_pt/Kconfig"

drivers/iommu/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ obj-$(CONFIG_IOMMU_SVA) += iommu-sva.o
3636
obj-$(CONFIG_IOMMU_IOPF) += io-pgfault.o
3737
obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o
3838
obj-$(CONFIG_APPLE_DART) += apple-dart.o
39+
obj-$(CONFIG_IOMMU_DEBUG_PAGEALLOC) += iommu-debug-pagealloc.o

drivers/iommu/amd/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ config AMD_IOMMU
3030
your BIOS for an option to enable it or if you have an IVRS ACPI
3131
table.
3232

33+
config AMD_IOMMU_IOMMUFD
34+
bool "Enable IOMMUFD features for AMD IOMMU (EXPERIMENTAL)"
35+
depends on IOMMUFD
36+
depends on AMD_IOMMU
37+
help
38+
Support for IOMMUFD features intended to support virtual machines
39+
with accelerated virtual IOMMUs.
40+
41+
Say Y here if you are doing development and testing on this feature.
42+
3343
config AMD_IOMMU_DEBUGFS
3444
bool "Enable AMD IOMMU internals in DebugFS"
3545
depends on AMD_IOMMU && IOMMU_DEBUGFS

drivers/iommu/amd/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
obj-y += iommu.o init.o quirks.o ppr.o pasid.o
3+
obj-$(CONFIG_AMD_IOMMU_IOMMUFD) += iommufd.o nested.o
34
obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += debugfs.o

drivers/iommu/amd/amd_iommu.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,37 @@ void amd_iommu_domain_set_pgtable(struct protection_domain *domain,
189189
struct dev_table_entry *get_dev_table(struct amd_iommu *iommu);
190190
struct iommu_dev_data *search_dev_data(struct amd_iommu *iommu, u16 devid);
191191

192+
void amd_iommu_set_dte_v1(struct iommu_dev_data *dev_data,
193+
struct protection_domain *domain, u16 domid,
194+
struct pt_iommu_amdv1_hw_info *pt_info,
195+
struct dev_table_entry *new);
196+
void amd_iommu_update_dte(struct amd_iommu *iommu,
197+
struct iommu_dev_data *dev_data,
198+
struct dev_table_entry *new);
199+
200+
static inline void
201+
amd_iommu_make_clear_dte(struct iommu_dev_data *dev_data, struct dev_table_entry *new)
202+
{
203+
struct dev_table_entry *initial_dte;
204+
struct amd_iommu *iommu = get_amd_iommu_from_dev(dev_data->dev);
205+
206+
/* All existing DTE must have V bit set */
207+
new->data128[0] = DTE_FLAG_V;
208+
new->data128[1] = 0;
209+
210+
/*
211+
* Restore cached persistent DTE bits, which can be set by information
212+
* in IVRS table. See set_dev_entry_from_acpi().
213+
*/
214+
initial_dte = amd_iommu_get_ivhd_dte_flags(iommu->pci_seg->id, dev_data->devid);
215+
if (initial_dte) {
216+
new->data128[0] |= initial_dte->data128[0];
217+
new->data128[1] |= initial_dte->data128[1];
218+
}
219+
}
220+
221+
/* NESTED */
222+
struct iommu_domain *
223+
amd_iommu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags,
224+
const struct iommu_user_data *user_data);
192225
#endif /* AMD_IOMMU_H */

drivers/iommu/amd/amd_iommu_types.h

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
#include <linux/list.h>
1818
#include <linux/spinlock.h>
1919
#include <linux/pci.h>
20+
#include <linux/iommufd.h>
2021
#include <linux/irqreturn.h>
2122
#include <linux/generic_pt/iommu.h>
2223

24+
#include <uapi/linux/iommufd.h>
25+
2326
/*
2427
* Maximum number of IOMMUs supported
2528
*/
@@ -108,6 +111,7 @@
108111

109112
/* Extended Feature 2 Bits */
110113
#define FEATURE_SEVSNPIO_SUP BIT_ULL(1)
114+
#define FEATURE_GCR3TRPMODE BIT_ULL(3)
111115
#define FEATURE_SNPAVICSUP GENMASK_ULL(7, 5)
112116
#define FEATURE_SNPAVICSUP_GAM(x) \
113117
(FIELD_GET(FEATURE_SNPAVICSUP, x) == 0x1)
@@ -186,6 +190,7 @@
186190
#define CONTROL_EPH_EN 45
187191
#define CONTROL_XT_EN 50
188192
#define CONTROL_INTCAPXT_EN 51
193+
#define CONTROL_GCR3TRPMODE 58
189194
#define CONTROL_IRTCACHEDIS 59
190195
#define CONTROL_SNPAVIC_EN 61
191196

@@ -350,6 +355,9 @@
350355
#define DTE_FLAG_V BIT_ULL(0)
351356
#define DTE_FLAG_TV BIT_ULL(1)
352357
#define DTE_FLAG_HAD (3ULL << 7)
358+
#define DTE_MODE_MASK GENMASK_ULL(11, 9)
359+
#define DTE_HOST_TRP GENMASK_ULL(51, 12)
360+
#define DTE_FLAG_PPR BIT_ULL(52)
353361
#define DTE_FLAG_GIOV BIT_ULL(54)
354362
#define DTE_FLAG_GV BIT_ULL(55)
355363
#define DTE_GLX GENMASK_ULL(57, 56)
@@ -358,7 +366,7 @@
358366

359367
#define DTE_FLAG_IOTLB BIT_ULL(32)
360368
#define DTE_FLAG_MASK (0x3ffULL << 32)
361-
#define DEV_DOMID_MASK 0xffffULL
369+
#define DTE_DOMID_MASK GENMASK_ULL(15, 0)
362370

363371
#define DTE_GCR3_14_12 GENMASK_ULL(60, 58)
364372
#define DTE_GCR3_30_15 GENMASK_ULL(31, 16)
@@ -493,6 +501,38 @@ struct pdom_iommu_info {
493501
u32 refcnt; /* Count of attached dev/pasid per domain/IOMMU */
494502
};
495503

504+
struct amd_iommu_viommu {
505+
struct iommufd_viommu core;
506+
struct protection_domain *parent; /* nest parent domain for this viommu */
507+
struct list_head pdom_list; /* For protection_domain->viommu_list */
508+
509+
/*
510+
* Per-vIOMMU guest domain ID to host domain ID mapping.
511+
* Indexed by guest domain ID.
512+
*/
513+
struct xarray gdomid_array;
514+
};
515+
516+
/*
517+
* Contains guest domain ID mapping info,
518+
* which is stored in the struct xarray gdomid_array.
519+
*/
520+
struct guest_domain_mapping_info {
521+
refcount_t users;
522+
u32 hdom_id; /* Host domain ID */
523+
};
524+
525+
/*
526+
* Nested domain is specifically used for nested translation
527+
*/
528+
struct nested_domain {
529+
struct iommu_domain domain; /* generic domain handle used by iommu core code */
530+
u16 gdom_id; /* domain ID from gDTE */
531+
struct guest_domain_mapping_info *gdom_info;
532+
struct iommu_hwpt_amd_guest gdte; /* Guest vIOMMU DTE */
533+
struct amd_iommu_viommu *viommu; /* AMD hw-viommu this nested domain belong to */
534+
};
535+
496536
/*
497537
* This structure contains generic data for IOMMU protection domains
498538
* independent of their use.
@@ -513,6 +553,12 @@ struct protection_domain {
513553

514554
struct mmu_notifier mn; /* mmu notifier for the SVA domain */
515555
struct list_head dev_data_list; /* List of pdom_dev_data */
556+
557+
/*
558+
* Store reference to list of vIOMMUs, which use this protection domain.
559+
* This will be used to look up host domain ID when flushing this domain.
560+
*/
561+
struct list_head viommu_list;
516562
};
517563
PT_IOMMU_CHECK_DOMAIN(struct protection_domain, iommu, domain);
518564
PT_IOMMU_CHECK_DOMAIN(struct protection_domain, amdv1.iommu, domain);
@@ -706,7 +752,7 @@ struct amd_iommu {
706752

707753
u32 flags;
708754
volatile u64 *cmd_sem;
709-
atomic64_t cmd_sem_val;
755+
u64 cmd_sem_val;
710756
/*
711757
* Track physical address to directly use it in build_completion_wait()
712758
* and avoid adding any special checks and handling for kdump.

drivers/iommu/amd/init.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,14 @@ static void iommu_enable_gt(struct amd_iommu *iommu)
11221122
return;
11231123

11241124
iommu_feature_enable(iommu, CONTROL_GT_EN);
1125+
1126+
/*
1127+
* This feature needs to be enabled prior to a call
1128+
* to iommu_snp_enable(). Since this function is called
1129+
* in early_enable_iommu(), it is safe to enable here.
1130+
*/
1131+
if (check_feature2(FEATURE_GCR3TRPMODE))
1132+
iommu_feature_enable(iommu, CONTROL_GCR3TRPMODE);
11251133
}
11261134

11271135
/* sets a specific bit in the device table entry. */
@@ -1179,7 +1187,7 @@ static bool __reuse_device_table(struct amd_iommu *iommu)
11791187
for (devid = 0; devid <= pci_seg->last_bdf; devid++) {
11801188
old_dev_tbl_entry = &pci_seg->old_dev_tbl_cpy[devid];
11811189
dte_v = FIELD_GET(DTE_FLAG_V, old_dev_tbl_entry->data[0]);
1182-
dom_id = FIELD_GET(DEV_DOMID_MASK, old_dev_tbl_entry->data[1]);
1190+
dom_id = FIELD_GET(DTE_DOMID_MASK, old_dev_tbl_entry->data[1]);
11831191

11841192
if (!dte_v || !dom_id)
11851193
continue;
@@ -1877,7 +1885,7 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h,
18771885
iommu->pci_seg = pci_seg;
18781886

18791887
raw_spin_lock_init(&iommu->lock);
1880-
atomic64_set(&iommu->cmd_sem_val, 0);
1888+
iommu->cmd_sem_val = 0;
18811889

18821890
/* Add IOMMU to internal data structures */
18831891
list_add_tail(&iommu->list, &amd_iommu_list);

0 commit comments

Comments
 (0)