Skip to content

Commit ceba6f6

Browse files
committed
Merge tag 'iommu-updates-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux
Pull iommu updates from Joerg Roedel: "Core Updates: - Convert call-sites using iommu_domain_alloc() to more specific versions and remove function - Introduce iommu_paging_domain_alloc_flags() - Extend support for allocating PASID-capable domains to more drivers - Remove iommu_present() - Some smaller improvements New IOMMU driver for RISC-V Intel VT-d Updates: - Add domain_alloc_paging support - Enable user space IOPFs in non-PASID and non-svm cases - Small code refactoring and cleanups - Add domain replacement support for pasid AMD-Vi Updates: - Adapt to iommu_paging_domain_alloc_flags() interface and alloc V2 page-tables by default - Replace custom domain ID allocator with IDA allocator - Add ops->release_domain() support - Other improvements to device attach and domain allocation code paths ARM-SMMU Updates: - SMMUv2: - Return -EPROBE_DEFER for client devices probing before their SMMU - Devicetree binding updates for Qualcomm MMU-500 implementations - SMMUv3: - Minor fixes and cleanup for NVIDIA's virtual command queue driver - IO-PGTable: - Fix indexing of concatenated PGDs and extend selftest coverage - Remove unused block-splitting support S390 IOMMU: - Implement support for blocking domain Mediatek IOMMU: - Enable 35-bit physical address support for mt8186 OMAP IOMMU driver: - Adapt to recent IOMMU core changes and unbreak driver" * tag 'iommu-updates-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux: (92 commits) iommu/tegra241-cmdqv: Fix alignment failure at max_n_shift iommu: Make set_dev_pasid op support domain replacement iommu/arm-smmu-v3: Make set_dev_pasid() op support replace iommu/vt-d: Add set_dev_pasid callback for nested domain iommu/vt-d: Make identity_domain_set_dev_pasid() to handle domain replacement iommu/vt-d: Make intel_svm_set_dev_pasid() support domain replacement iommu/vt-d: Limit intel_iommu_set_dev_pasid() for paging domain iommu/vt-d: Make intel_iommu_set_dev_pasid() to handle domain replacement iommu/vt-d: Add iommu_domain_did() to get did iommu/vt-d: Consolidate the struct dev_pasid_info add/remove iommu/vt-d: Add pasid replace helpers iommu/vt-d: Refactor the pasid setup helpers iommu/vt-d: Add a helper to flush cache for updating present pasid entry iommu: Pass old domain to set_dev_pasid op iommu/iova: Fix typo 'adderss' iommu: Add a kdoc to iommu_unmap() iommu/io-pgtable-arm-v7s: Remove split on unmap behavior iommu/io-pgtable-arm: Remove split on unmap behavior iommu/vt-d: Drain PRQs when domain removed from RID iommu/vt-d: Drop pasid requirement for prq initialization ...
2 parents eb78332 + 42f0cbb commit ceba6f6

Some content is hidden

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

51 files changed

+4610
-1624
lines changed

Documentation/devicetree/bindings/iommu/arm,smmu.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ properties:
3636
items:
3737
- enum:
3838
- qcom,qcm2290-smmu-500
39+
- qcom,qcs615-smmu-500
3940
- qcom,qcs8300-smmu-500
4041
- qcom,qdu1000-smmu-500
4142
- qcom,sa8255p-smmu-500
4243
- qcom,sa8775p-smmu-500
44+
- qcom,sar2130p-smmu-500
4345
- qcom,sc7180-smmu-500
4446
- qcom,sc7280-smmu-500
4547
- qcom,sc8180x-smmu-500
@@ -88,6 +90,7 @@ properties:
8890
- qcom,qcm2290-smmu-500
8991
- qcom,sa8255p-smmu-500
9092
- qcom,sa8775p-smmu-500
93+
- qcom,sar2130p-smmu-500
9194
- qcom,sc7280-smmu-500
9295
- qcom,sc8180x-smmu-500
9396
- qcom,sc8280xp-smmu-500
@@ -524,6 +527,7 @@ allOf:
524527
compatible:
525528
items:
526529
- enum:
530+
- qcom,sar2130p-smmu-500
527531
- qcom,sm8550-smmu-500
528532
- qcom,sm8650-smmu-500
529533
- qcom,x1e80100-smmu-500
@@ -555,6 +559,7 @@ allOf:
555559
- cavium,smmu-v2
556560
- marvell,ap806-smmu-500
557561
- nvidia,smmu-500
562+
- qcom,qcs615-smmu-500
558563
- qcom,qcs8300-smmu-500
559564
- qcom,qdu1000-smmu-500
560565
- qcom,sa8255p-smmu-500
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/iommu/riscv,iommu.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: RISC-V IOMMU Architecture Implementation
8+
9+
maintainers:
10+
- Tomasz Jeznach <[email protected]>
11+
12+
description: |
13+
The RISC-V IOMMU provides memory address translation and isolation for
14+
input and output devices, supporting per-device translation context,
15+
shared process address spaces including the ATS and PRI components of
16+
the PCIe specification, two stage address translation and MSI remapping.
17+
It supports identical translation table format to the RISC-V address
18+
translation tables with page level access and protection attributes.
19+
Hardware uses in-memory command and fault reporting queues with wired
20+
interrupt or MSI notifications.
21+
22+
Visit https://github.com/riscv-non-isa/riscv-iommu for more details.
23+
24+
For information on assigning RISC-V IOMMU to its peripheral devices,
25+
see generic IOMMU bindings.
26+
27+
properties:
28+
# For PCIe IOMMU hardware compatible property should contain the vendor
29+
# and device ID according to the PCI Bus Binding specification.
30+
# Since PCI provides built-in identification methods, compatible is not
31+
# actually required. For non-PCIe hardware implementations 'riscv,iommu'
32+
# should be specified along with 'reg' property providing MMIO location.
33+
compatible:
34+
oneOf:
35+
- items:
36+
- enum:
37+
- qemu,riscv-iommu
38+
- const: riscv,iommu
39+
- items:
40+
- enum:
41+
- pci1efd,edf1
42+
- const: riscv,pci-iommu
43+
44+
reg:
45+
maxItems: 1
46+
description:
47+
For non-PCI devices this represents base address and size of for the
48+
IOMMU memory mapped registers interface.
49+
For PCI IOMMU hardware implementation this should represent an address
50+
of the IOMMU, as defined in the PCI Bus Binding reference.
51+
52+
'#iommu-cells':
53+
const: 1
54+
description:
55+
The single cell describes the requester id emitted by a master to the
56+
IOMMU.
57+
58+
interrupts:
59+
minItems: 1
60+
maxItems: 4
61+
description:
62+
Wired interrupt vectors available for RISC-V IOMMU to notify the
63+
RISC-V HARTS. The cause to interrupt vector is software defined
64+
using IVEC IOMMU register.
65+
66+
msi-parent: true
67+
68+
power-domains:
69+
maxItems: 1
70+
71+
required:
72+
- compatible
73+
- reg
74+
- '#iommu-cells'
75+
76+
additionalProperties: false
77+
78+
examples:
79+
- |+
80+
/* Example 1 (IOMMU device with wired interrupts) */
81+
#include <dt-bindings/interrupt-controller/irq.h>
82+
83+
iommu1: iommu@1bccd000 {
84+
compatible = "qemu,riscv-iommu", "riscv,iommu";
85+
reg = <0x1bccd000 0x1000>;
86+
interrupt-parent = <&aplic_smode>;
87+
interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
88+
<33 IRQ_TYPE_LEVEL_HIGH>,
89+
<34 IRQ_TYPE_LEVEL_HIGH>,
90+
<35 IRQ_TYPE_LEVEL_HIGH>;
91+
#iommu-cells = <1>;
92+
};
93+
94+
/* Device with two IOMMU device IDs, 0 and 7 */
95+
master1 {
96+
iommus = <&iommu1 0>, <&iommu1 7>;
97+
};
98+
99+
- |+
100+
/* Example 2 (IOMMU device with shared wired interrupt) */
101+
#include <dt-bindings/interrupt-controller/irq.h>
102+
103+
iommu2: iommu@1bccd000 {
104+
compatible = "qemu,riscv-iommu", "riscv,iommu";
105+
reg = <0x1bccd000 0x1000>;
106+
interrupt-parent = <&aplic_smode>;
107+
interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
108+
#iommu-cells = <1>;
109+
};
110+
111+
- |+
112+
/* Example 3 (IOMMU device with MSIs) */
113+
iommu3: iommu@1bcdd000 {
114+
compatible = "qemu,riscv-iommu", "riscv,iommu";
115+
reg = <0x1bccd000 0x1000>;
116+
msi-parent = <&imsics_smode>;
117+
#iommu-cells = <1>;
118+
};
119+
120+
- |+
121+
/* Example 4 (IOMMU PCIe device with MSIs) */
122+
bus {
123+
#address-cells = <2>;
124+
#size-cells = <2>;
125+
126+
pcie@30000000 {
127+
device_type = "pci";
128+
#address-cells = <3>;
129+
#size-cells = <2>;
130+
reg = <0x0 0x30000000 0x0 0x1000000>;
131+
ranges = <0x02000000 0x0 0x41000000 0x0 0x41000000 0x0 0x0f000000>;
132+
133+
/*
134+
* The IOMMU manages all functions in this PCI domain except
135+
* itself. Omit BDF 00:01.0.
136+
*/
137+
iommu-map = <0x0 &iommu0 0x0 0x8>,
138+
<0x9 &iommu0 0x9 0xfff7>;
139+
140+
/* The IOMMU programming interface uses slot 00:01.0 */
141+
iommu0: iommu@1,0 {
142+
compatible = "pci1efd,edf1", "riscv,pci-iommu";
143+
reg = <0x800 0 0 0 0>;
144+
#iommu-cells = <1>;
145+
};
146+
};
147+
};

MAINTAINERS

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19992,6 +19992,15 @@ F: arch/riscv/
1999219992
N: riscv
1999319993
K: riscv
1999419994

19995+
RISC-V IOMMU
19996+
M: Tomasz Jeznach <[email protected]>
19997+
19998+
19999+
S: Maintained
20000+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git
20001+
F: Documentation/devicetree/bindings/iommu/riscv,iommu.yaml
20002+
F: drivers/iommu/riscv/
20003+
1999520004
RISC-V MICROCHIP FPGA SUPPORT
1999620005
M: Conor Dooley <[email protected]>
1999720006
M: Daire McNamara <[email protected]>

arch/s390/include/asm/pci.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ struct zpci_bar_struct {
9696
u8 size; /* order 2 exponent */
9797
};
9898

99-
struct s390_domain;
10099
struct kvm_zdev;
101100

102101
#define ZPCI_FUNCTIONS_PER_BUS 256
@@ -186,9 +185,10 @@ struct zpci_dev {
186185
struct dentry *debugfs_dev;
187186

188187
/* IOMMU and passthrough */
189-
struct s390_domain *s390_domain; /* s390 IOMMU domain data */
188+
struct iommu_domain *s390_domain; /* attached IOMMU domain */
190189
struct kvm_zdev *kzdev;
191190
struct mutex kzdev_lock;
191+
spinlock_t dom_lock; /* protect s390_domain change */
192192
};
193193

194194
static inline bool zdev_enabled(struct zpci_dev *zdev)

arch/s390/pci/pci.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev)
161161
u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_SET_MEASURE);
162162
struct zpci_iommu_ctrs *ctrs;
163163
struct zpci_fib fib = {0};
164+
unsigned long flags;
164165
u8 cc, status;
165166

166167
if (zdev->fmb || sizeof(*zdev->fmb) < zdev->fmb_length)
@@ -172,6 +173,7 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev)
172173
WARN_ON((u64) zdev->fmb & 0xf);
173174

174175
/* reset software counters */
176+
spin_lock_irqsave(&zdev->dom_lock, flags);
175177
ctrs = zpci_get_iommu_ctrs(zdev);
176178
if (ctrs) {
177179
atomic64_set(&ctrs->mapped_pages, 0);
@@ -180,6 +182,7 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev)
180182
atomic64_set(&ctrs->sync_map_rpcits, 0);
181183
atomic64_set(&ctrs->sync_rpcits, 0);
182184
}
185+
spin_unlock_irqrestore(&zdev->dom_lock, flags);
183186

184187

185188
fib.fmb_addr = virt_to_phys(zdev->fmb);

arch/s390/pci/pci_debug.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,23 @@ static void pci_fmb_show(struct seq_file *m, char *name[], int length,
7171

7272
static void pci_sw_counter_show(struct seq_file *m)
7373
{
74-
struct zpci_iommu_ctrs *ctrs = zpci_get_iommu_ctrs(m->private);
74+
struct zpci_dev *zdev = m->private;
75+
struct zpci_iommu_ctrs *ctrs;
7576
atomic64_t *counter;
77+
unsigned long flags;
7678
int i;
7779

80+
spin_lock_irqsave(&zdev->dom_lock, flags);
81+
ctrs = zpci_get_iommu_ctrs(m->private);
7882
if (!ctrs)
79-
return;
83+
goto unlock;
8084

8185
counter = &ctrs->mapped_pages;
8286
for (i = 0; i < ARRAY_SIZE(pci_sw_names); i++, counter++)
8387
seq_printf(m, "%26s:\t%llu\n", pci_sw_names[i],
8488
atomic64_read(counter));
89+
unlock:
90+
spin_unlock_irqrestore(&zdev->dom_lock, flags);
8591
}
8692

8793
static int pci_perf_show(struct seq_file *m, void *v)

drivers/iommu/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ config MSM_IOMMU
195195
source "drivers/iommu/amd/Kconfig"
196196
source "drivers/iommu/intel/Kconfig"
197197
source "drivers/iommu/iommufd/Kconfig"
198+
source "drivers/iommu/riscv/Kconfig"
198199

199200
config IRQ_REMAP
200201
bool "Support for Interrupt Remapping"

drivers/iommu/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0
2-
obj-y += amd/ intel/ arm/ iommufd/
2+
obj-y += amd/ intel/ arm/ iommufd/ riscv/
33
obj-$(CONFIG_IOMMU_API) += iommu.o
44
obj-$(CONFIG_IOMMU_API) += iommu-traces.o
55
obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o

drivers/iommu/amd/amd_iommu.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ extern int amd_iommu_gpt_level;
4646
extern unsigned long amd_iommu_pgsize_bitmap;
4747

4848
/* Protection domain ops */
49+
void amd_iommu_init_identity_domain(void);
4950
struct protection_domain *protection_domain_alloc(unsigned int type, int nid);
5051
void protection_domain_free(struct protection_domain *domain);
5152
struct iommu_domain *amd_iommu_domain_alloc_sva(struct device *dev,
5253
struct mm_struct *mm);
5354
void amd_iommu_domain_free(struct iommu_domain *dom);
5455
int iommu_sva_set_dev_pasid(struct iommu_domain *domain,
55-
struct device *dev, ioasid_t pasid);
56+
struct device *dev, ioasid_t pasid,
57+
struct iommu_domain *old);
5658
void amd_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
5759
struct iommu_domain *domain);
5860

@@ -118,9 +120,14 @@ static inline bool check_feature2(u64 mask)
118120
return (amd_iommu_efr2 & mask);
119121
}
120122

123+
static inline bool amd_iommu_v2_pgtbl_supported(void)
124+
{
125+
return (check_feature(FEATURE_GIOSUP) && check_feature(FEATURE_GT));
126+
}
127+
121128
static inline bool amd_iommu_gt_ppr_supported(void)
122129
{
123-
return (check_feature(FEATURE_GT) &&
130+
return (amd_iommu_v2_pgtbl_supported() &&
124131
check_feature(FEATURE_PPR) &&
125132
check_feature(FEATURE_EPHSUP));
126133
}

drivers/iommu/amd/amd_iommu_types.h

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,12 @@ struct pdom_dev_data {
565565
struct list_head list;
566566
};
567567

568+
/* Keeps track of the IOMMUs attached to protection domain */
569+
struct pdom_iommu_info {
570+
struct amd_iommu *iommu; /* IOMMUs attach to protection domain */
571+
u32 refcnt; /* Count of attached dev/pasid per domain/IOMMU */
572+
};
573+
568574
/*
569575
* This structure contains generic data for IOMMU protection domains
570576
* independent of their use.
@@ -578,8 +584,7 @@ struct protection_domain {
578584
u16 id; /* the domain id written to the device table */
579585
enum protection_domain_mode pd_mode; /* Track page table type */
580586
bool dirty_tracking; /* dirty tracking is enabled in the domain */
581-
unsigned dev_cnt; /* devices assigned to this domain */
582-
unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
587+
struct xarray iommu_array; /* per-IOMMU reference count */
583588

584589
struct mmu_notifier mn; /* mmu notifier for the SVA domain */
585590
struct list_head dev_data_list; /* List of pdom_dev_data */
@@ -831,7 +836,7 @@ struct devid_map {
831836
*/
832837
struct iommu_dev_data {
833838
/*Protect against attach/detach races */
834-
spinlock_t lock;
839+
struct mutex mutex;
835840

836841
struct list_head list; /* For domain->dev_list */
837842
struct llist_node dev_data_list; /* For global dev_data_list */
@@ -872,12 +877,6 @@ extern struct list_head amd_iommu_pci_seg_list;
872877
*/
873878
extern struct list_head amd_iommu_list;
874879

875-
/*
876-
* Array with pointers to each IOMMU struct
877-
* The indices are referenced in the protection domains
878-
*/
879-
extern struct amd_iommu *amd_iommus[MAX_IOMMUS];
880-
881880
/*
882881
* Structure defining one entry in the device table
883882
*/
@@ -912,14 +911,14 @@ struct unity_map_entry {
912911
/* size of the dma_ops aperture as power of 2 */
913912
extern unsigned amd_iommu_aperture_order;
914913

915-
/* allocation bitmap for domain ids */
916-
extern unsigned long *amd_iommu_pd_alloc_bitmap;
917-
918914
extern bool amd_iommu_force_isolation;
919915

920916
/* Max levels of glxval supported */
921917
extern int amd_iommu_max_glx_val;
922918

919+
/* IDA to track protection domain IDs */
920+
extern struct ida pdom_ids;
921+
923922
/* Global EFR and EFR2 registers */
924923
extern u64 amd_iommu_efr;
925924
extern u64 amd_iommu_efr2;

0 commit comments

Comments
 (0)