Skip to content

Commit f1d26d7

Browse files
committed
Merge tag 'iommu-updates-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux
Pull iommu updates from Joerg Roedel: "Core: - Support for RISC-V IO-page-table format in generic iommupt code ARM-SMMU Updates: - Introduction of an "invalidation array" for SMMUv3, which enables future scalability work and optimisations for devices with a large number of SMMUv3 instances - Update the conditions under which the SMMUv3 driver works around hardware errata for invalidation on MMU-700 implementations - Fix broken command filtering for the host view of NVIDIA's "cmdqv" SMMUv3 extension - MMU-500 device-tree binding additions for Qualcomm Eliza & Hawi SoCs Intel VT-d: - Support for dirty tracking on domains attached to PASID - Removal of unnecessary read*()/write*() wrappers - Improvements to the invalidation paths AMD Vi: - Race-condition fixed in debugfs code - Make log buffer allocation NUMA aware RISC-V: - IO-TLB flushing improvements - Minor fixes" * tag 'iommu-updates-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux: (48 commits) iommu/vt-d: Restore IOMMU_CAP_CACHE_COHERENCY dt-bindings: arm-smmu: qcom: Add compatible for Hawi SoC iommu/amd: Invalidate IRT cache for DMA aliases iommu/riscv: Remove overflows on the invalidation path iommu/amd: Fix clone_alias() to use the original device's devid iommu/vt-d: Remove the remaining pages along the invalidation path iommu/vt-d: Pass size_order to qi_desc_piotlb() not npages iommu/vt-d: Split piotlb invalidation into range and all iommu/vt-d: Remove dmar_writel() and dmar_writeq() iommu/vt-d: Remove dmar_readl() and dmar_readq() iommufd/selftest: Test dirty tracking on PASID iommu/vt-d: Support dirty tracking on PASID iommu/vt-d: Rename device_set_dirty_tracking() and pass dmar_domain pointer iommu/vt-d: Block PASID attachment to nested domain with dirty tracking iommu/dma: Always allow DMA-FQ when iommupt provides the iommu_domain iommu/riscv: Fix signedness bug iommu/amd: Fix illegal cap/mmio access in IOMMU debugfs iommu/amd: Fix illegal device-id access in IOMMU debugfs iommu/tegra241-cmdqv: Update uAPI to clarify HYP_OWN requirement iommu/tegra241-cmdqv: Set supports_cmd op in tegra241_vcmdq_hw_init() ...
2 parents 5a69195 + f8d5e70 commit f1d26d7

42 files changed

Lines changed: 2156 additions & 795 deletions

Some content is hidden

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

Documentation/arch/arm64/silicon-errata.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,14 @@ stable kernels.
207207
+----------------+-----------------+-----------------+-----------------------------+
208208
| ARM | MMU-600 | #1076982,1209401| N/A |
209209
+----------------+-----------------+-----------------+-----------------------------+
210-
| ARM | MMU-700 | #2268618,2812531| N/A |
210+
| ARM | MMU-700 | #2133013, | N/A |
211+
| | | #2268618, | |
212+
| | | #2812531, | |
213+
| | | #3777127 | |
211214
+----------------+-----------------+-----------------+-----------------------------+
215+
| ARM | MMU L1 | #3878312 | N/A |
216+
+----------------+-----------------+-----------------+-----------------------------+
217+
| ARM | MMU S3 | #3995052 | N/A |
212218
+----------------+-----------------+-----------------+-----------------------------+
213219
| ARM | GIC-700 | #2941627 | ARM64_ERRATUM_2941627 |
214220
+----------------+-----------------+-----------------+-----------------------------+

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ properties:
3535
- description: Qcom SoCs implementing "qcom,smmu-500" and "arm,mmu-500"
3636
items:
3737
- enum:
38+
- qcom,eliza-smmu-500
3839
- qcom,glymur-smmu-500
3940
- qcom,kaanapali-smmu-500
4041
- qcom,milos-smmu-500
@@ -92,6 +93,7 @@ properties:
9293
items:
9394
- enum:
9495
- qcom,glymur-smmu-500
96+
- qcom,hawi-smmu-500
9597
- qcom,kaanapali-smmu-500
9698
- qcom,milos-smmu-500
9799
- qcom,qcm2290-smmu-500

drivers/iommu/amd/debugfs.c

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,37 +26,36 @@ static ssize_t iommu_mmio_write(struct file *filp, const char __user *ubuf,
2626
{
2727
struct seq_file *m = filp->private_data;
2828
struct amd_iommu *iommu = m->private;
29-
int ret;
30-
31-
iommu->dbg_mmio_offset = -1;
29+
int ret, dbg_mmio_offset = iommu->dbg_mmio_offset = -1;
3230

3331
if (cnt > OFS_IN_SZ)
3432
return -EINVAL;
3533

36-
ret = kstrtou32_from_user(ubuf, cnt, 0, &iommu->dbg_mmio_offset);
34+
ret = kstrtou32_from_user(ubuf, cnt, 0, &dbg_mmio_offset);
3735
if (ret)
3836
return ret;
3937

40-
if (iommu->dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64)) {
41-
iommu->dbg_mmio_offset = -1;
42-
return -EINVAL;
43-
}
38+
if (dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64))
39+
return -EINVAL;
4440

41+
iommu->dbg_mmio_offset = dbg_mmio_offset;
4542
return cnt;
4643
}
4744

4845
static int iommu_mmio_show(struct seq_file *m, void *unused)
4946
{
5047
struct amd_iommu *iommu = m->private;
5148
u64 value;
49+
int dbg_mmio_offset = iommu->dbg_mmio_offset;
5250

53-
if (iommu->dbg_mmio_offset < 0) {
51+
if (dbg_mmio_offset < 0 || dbg_mmio_offset >
52+
iommu->mmio_phys_end - sizeof(u64)) {
5453
seq_puts(m, "Please provide mmio register's offset\n");
5554
return 0;
5655
}
5756

58-
value = readq(iommu->mmio_base + iommu->dbg_mmio_offset);
59-
seq_printf(m, "Offset:0x%x Value:0x%016llx\n", iommu->dbg_mmio_offset, value);
57+
value = readq(iommu->mmio_base + dbg_mmio_offset);
58+
seq_printf(m, "Offset:0x%x Value:0x%016llx\n", dbg_mmio_offset, value);
6059

6160
return 0;
6261
}
@@ -67,45 +66,42 @@ static ssize_t iommu_capability_write(struct file *filp, const char __user *ubuf
6766
{
6867
struct seq_file *m = filp->private_data;
6968
struct amd_iommu *iommu = m->private;
70-
int ret;
71-
72-
iommu->dbg_cap_offset = -1;
69+
int ret, dbg_cap_offset = iommu->dbg_cap_offset = -1;
7370

7471
if (cnt > OFS_IN_SZ)
7572
return -EINVAL;
7673

77-
ret = kstrtou32_from_user(ubuf, cnt, 0, &iommu->dbg_cap_offset);
74+
ret = kstrtou32_from_user(ubuf, cnt, 0, &dbg_cap_offset);
7875
if (ret)
7976
return ret;
8077

8178
/* Capability register at offset 0x14 is the last IOMMU capability register. */
82-
if (iommu->dbg_cap_offset > 0x14) {
83-
iommu->dbg_cap_offset = -1;
79+
if (dbg_cap_offset > 0x14)
8480
return -EINVAL;
85-
}
8681

82+
iommu->dbg_cap_offset = dbg_cap_offset;
8783
return cnt;
8884
}
8985

9086
static int iommu_capability_show(struct seq_file *m, void *unused)
9187
{
9288
struct amd_iommu *iommu = m->private;
9389
u32 value;
94-
int err;
90+
int err, dbg_cap_offset = iommu->dbg_cap_offset;
9591

96-
if (iommu->dbg_cap_offset < 0) {
92+
if (dbg_cap_offset < 0 || dbg_cap_offset > 0x14) {
9793
seq_puts(m, "Please provide capability register's offset in the range [0x00 - 0x14]\n");
9894
return 0;
9995
}
10096

101-
err = pci_read_config_dword(iommu->dev, iommu->cap_ptr + iommu->dbg_cap_offset, &value);
97+
err = pci_read_config_dword(iommu->dev, iommu->cap_ptr + dbg_cap_offset, &value);
10298
if (err) {
10399
seq_printf(m, "Not able to read capability register at 0x%x\n",
104-
iommu->dbg_cap_offset);
100+
dbg_cap_offset);
105101
return 0;
106102
}
107103

108-
seq_printf(m, "Offset:0x%x Value:0x%08x\n", iommu->dbg_cap_offset, value);
104+
seq_printf(m, "Offset:0x%x Value:0x%08x\n", dbg_cap_offset, value);
109105

110106
return 0;
111107
}
@@ -197,10 +193,11 @@ static ssize_t devid_write(struct file *filp, const char __user *ubuf,
197193
static int devid_show(struct seq_file *m, void *unused)
198194
{
199195
u16 devid;
196+
int sbdf_shadow = sbdf;
200197

201-
if (sbdf >= 0) {
202-
devid = PCI_SBDF_TO_DEVID(sbdf);
203-
seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf),
198+
if (sbdf_shadow >= 0) {
199+
devid = PCI_SBDF_TO_DEVID(sbdf_shadow);
200+
seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf_shadow),
204201
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid));
205202
} else
206203
seq_puts(m, "No or Invalid input provided\n");
@@ -237,13 +234,14 @@ static int iommu_devtbl_show(struct seq_file *m, void *unused)
237234
{
238235
struct amd_iommu_pci_seg *pci_seg;
239236
u16 seg, devid;
237+
int sbdf_shadow = sbdf;
240238

241-
if (sbdf < 0) {
239+
if (sbdf_shadow < 0) {
242240
seq_puts(m, "Enter a valid device ID to 'devid' file\n");
243241
return 0;
244242
}
245-
seg = PCI_SBDF_TO_SEGID(sbdf);
246-
devid = PCI_SBDF_TO_DEVID(sbdf);
243+
seg = PCI_SBDF_TO_SEGID(sbdf_shadow);
244+
devid = PCI_SBDF_TO_DEVID(sbdf_shadow);
247245

248246
for_each_pci_segment(pci_seg) {
249247
if (pci_seg->id != seg)
@@ -336,19 +334,20 @@ static int iommu_irqtbl_show(struct seq_file *m, void *unused)
336334
{
337335
struct amd_iommu_pci_seg *pci_seg;
338336
u16 devid, seg;
337+
int sbdf_shadow = sbdf;
339338

340339
if (!irq_remapping_enabled) {
341340
seq_puts(m, "Interrupt remapping is disabled\n");
342341
return 0;
343342
}
344343

345-
if (sbdf < 0) {
344+
if (sbdf_shadow < 0) {
346345
seq_puts(m, "Enter a valid device ID to 'devid' file\n");
347346
return 0;
348347
}
349348

350-
seg = PCI_SBDF_TO_SEGID(sbdf);
351-
devid = PCI_SBDF_TO_DEVID(sbdf);
349+
seg = PCI_SBDF_TO_SEGID(sbdf_shadow);
350+
devid = PCI_SBDF_TO_DEVID(sbdf_shadow);
352351

353352
for_each_pci_segment(pci_seg) {
354353
if (pci_seg->id != seg)

drivers/iommu/amd/init.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -848,10 +848,11 @@ static void __init free_command_buffer(struct amd_iommu *iommu)
848848
void *__init iommu_alloc_4k_pages(struct amd_iommu *iommu, gfp_t gfp,
849849
size_t size)
850850
{
851+
int nid = iommu->dev ? dev_to_node(&iommu->dev->dev) : NUMA_NO_NODE;
851852
void *buf;
852853

853854
size = PAGE_ALIGN(size);
854-
buf = iommu_alloc_pages_sz(gfp, size);
855+
buf = iommu_alloc_pages_node_sz(nid, gfp, size);
855856
if (!buf)
856857
return NULL;
857858
if (check_feature(FEATURE_SNP) &&
@@ -954,14 +955,16 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu)
954955

955956
static int iommu_init_ga_log(struct amd_iommu *iommu)
956957
{
958+
int nid = iommu->dev ? dev_to_node(&iommu->dev->dev) : NUMA_NO_NODE;
959+
957960
if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir))
958961
return 0;
959962

960-
iommu->ga_log = iommu_alloc_pages_sz(GFP_KERNEL, GA_LOG_SIZE);
963+
iommu->ga_log = iommu_alloc_pages_node_sz(nid, GFP_KERNEL, GA_LOG_SIZE);
961964
if (!iommu->ga_log)
962965
goto err_out;
963966

964-
iommu->ga_log_tail = iommu_alloc_pages_sz(GFP_KERNEL, 8);
967+
iommu->ga_log_tail = iommu_alloc_pages_node_sz(nid, GFP_KERNEL, 8);
965968
if (!iommu->ga_log_tail)
966969
goto err_out;
967970

drivers/iommu/amd/iommu.c

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -403,11 +403,12 @@ struct iommu_dev_data *search_dev_data(struct amd_iommu *iommu, u16 devid)
403403
return NULL;
404404
}
405405

406-
static int clone_alias(struct pci_dev *pdev, u16 alias, void *data)
406+
static int clone_alias(struct pci_dev *pdev_origin, u16 alias, void *data)
407407
{
408408
struct dev_table_entry new;
409409
struct amd_iommu *iommu;
410410
struct iommu_dev_data *dev_data, *alias_data;
411+
struct pci_dev *pdev = data;
411412
u16 devid = pci_dev_id(pdev);
412413
int ret = 0;
413414

@@ -454,9 +455,9 @@ static void clone_aliases(struct amd_iommu *iommu, struct device *dev)
454455
* part of the PCI DMA aliases if it's bus differs
455456
* from the original device.
456457
*/
457-
clone_alias(pdev, iommu->pci_seg->alias_table[pci_dev_id(pdev)], NULL);
458+
clone_alias(pdev, iommu->pci_seg->alias_table[pci_dev_id(pdev)], pdev);
458459

459-
pci_for_each_dma_alias(pdev, clone_alias, NULL);
460+
pci_for_each_dma_alias(pdev, clone_alias, pdev);
460461
}
461462

462463
static void setup_aliases(struct amd_iommu *iommu, struct device *dev)
@@ -2991,13 +2992,17 @@ static bool amd_iommu_capable(struct device *dev, enum iommu_cap cap)
29912992
return amdr_ivrs_remap_support;
29922993
case IOMMU_CAP_ENFORCE_CACHE_COHERENCY:
29932994
return true;
2994-
case IOMMU_CAP_DEFERRED_FLUSH:
2995-
return true;
29962995
case IOMMU_CAP_DIRTY_TRACKING: {
29972996
struct amd_iommu *iommu = get_amd_iommu_from_dev(dev);
29982997

29992998
return amd_iommu_hd_support(iommu);
30002999
}
3000+
case IOMMU_CAP_PCI_ATS_SUPPORTED: {
3001+
struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
3002+
3003+
return amd_iommu_iotlb_sup &&
3004+
(dev_data->flags & AMD_IOMMU_DEVICE_FLAG_ATS_SUP);
3005+
}
30013006
default:
30023007
break;
30033008
}
@@ -3179,26 +3184,44 @@ const struct iommu_ops amd_iommu_ops = {
31793184
static struct irq_chip amd_ir_chip;
31803185
static DEFINE_SPINLOCK(iommu_table_lock);
31813186

3187+
static int iommu_flush_dev_irt(struct pci_dev *unused, u16 devid, void *data)
3188+
{
3189+
int ret;
3190+
struct iommu_cmd cmd;
3191+
struct amd_iommu *iommu = data;
3192+
3193+
build_inv_irt(&cmd, devid);
3194+
ret = __iommu_queue_command_sync(iommu, &cmd, true);
3195+
return ret;
3196+
}
3197+
31823198
static void iommu_flush_irt_and_complete(struct amd_iommu *iommu, u16 devid)
31833199
{
31843200
int ret;
31853201
u64 data;
31863202
unsigned long flags;
3187-
struct iommu_cmd cmd, cmd2;
3203+
struct iommu_cmd cmd;
3204+
struct pci_dev *pdev = NULL;
3205+
struct iommu_dev_data *dev_data = search_dev_data(iommu, devid);
31883206

31893207
if (iommu->irtcachedis_enabled)
31903208
return;
31913209

3192-
build_inv_irt(&cmd, devid);
3210+
if (dev_data && dev_data->dev && dev_is_pci(dev_data->dev))
3211+
pdev = to_pci_dev(dev_data->dev);
31933212

31943213
raw_spin_lock_irqsave(&iommu->lock, flags);
31953214
data = get_cmdsem_val(iommu);
3196-
build_completion_wait(&cmd2, iommu, data);
3215+
build_completion_wait(&cmd, iommu, data);
31973216

3198-
ret = __iommu_queue_command_sync(iommu, &cmd, true);
3217+
if (pdev)
3218+
ret = pci_for_each_dma_alias(pdev, iommu_flush_dev_irt, iommu);
3219+
else
3220+
ret = iommu_flush_dev_irt(NULL, devid, iommu);
31993221
if (ret)
32003222
goto out_err;
3201-
ret = __iommu_queue_command_sync(iommu, &cmd2, false);
3223+
3224+
ret = __iommu_queue_command_sync(iommu, &cmd, false);
32023225
if (ret)
32033226
goto out_err;
32043227
raw_spin_unlock_irqrestore(&iommu->lock, flags);

0 commit comments

Comments
 (0)