Skip to content

Commit 0468be8

Browse files
committed
Merge tag 'iommu-updates-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu updates from Joerg Roedel: "Core changes: - Consolidate probe_device path - Make the PCI-SAC IOVA allocation trick PCI-only AMD IOMMU: - Consolidate PPR log handling - Interrupt handling improvements - Refcount fixes for amd_iommu_v2 driver Intel VT-d driver: - Enable idxd device DMA with pasid through iommu dma ops - Lift RESV_DIRECT check from VT-d driver to core - Miscellaneous cleanups and fixes ARM-SMMU drivers: - Device-tree binding updates: - Add additional compatible strings for Qualcomm SoCs - Allow ASIDs to be configured in the DT to work around Qualcomm's broken hypervisor - Fix clocks for Qualcomm's MSM8998 SoC - SMMUv2: - Support for Qualcomm's legacy firmware implementation featured on at least MSM8956 and MSM8976 - Match compatible strings for Qualcomm SM6350 and SM6375 SoC variants - SMMUv3: - Use 'ida' instead of a bitmap for VMID allocation - Rockchip IOMMU: - Lift page-table allocation restrictions on newer hardware - Mediatek IOMMU: - Add MT8188 IOMMU Support - Renesas IOMMU: - Allow PCIe devices .. and the usual set of cleanups an smaller fixes" * tag 'iommu-updates-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: (64 commits) iommu: Explicitly include correct DT includes iommu/amd: Remove unused declarations iommu/arm-smmu-qcom: Add SM6375 SMMUv2 iommu/arm-smmu-qcom: Add SM6350 DPU compatible iommu/arm-smmu-qcom: Add SM6375 DPU compatible iommu/arm-smmu-qcom: Sort the compatible list alphabetically dt-bindings: arm-smmu: Fix MSM8998 clocks description iommu/vt-d: Remove unused extern declaration dmar_parse_dev_scope() iommu/vt-d: Fix to convert mm pfn to dma pfn iommu/vt-d: Fix to flush cache of PASID directory table iommu/vt-d: Remove rmrr check in domain attaching device path iommu: Prevent RESV_DIRECT devices from blocking domains dmaengine/idxd: Re-enable kernel workqueue under DMA API iommu/vt-d: Add set_dev_pasid callback for dma domain iommu/vt-d: Prepare for set_dev_pasid callback iommu/vt-d: Make prq draining code generic iommu/vt-d: Remove pasid_mutex iommu/vt-d: Add domain_flush_pasid_iotlb() iommu: Move global PASID allocation from SVA to core iommu: Generalize PASID 0 for normal DMA w/o PASID ...
2 parents f7e97ce + d8fe59f commit 0468be8

Some content is hidden

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

45 files changed

+1518
-672
lines changed

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,47 @@ allOf:
270270
contains:
271271
enum:
272272
- qcom,msm8998-smmu-v2
273+
then:
274+
anyOf:
275+
- properties:
276+
clock-names:
277+
items:
278+
- const: bus
279+
clocks:
280+
items:
281+
- description: bus clock required for downstream bus access and for
282+
the smmu ptw
283+
- properties:
284+
clock-names:
285+
items:
286+
- const: iface
287+
- const: mem
288+
- const: mem_iface
289+
clocks:
290+
items:
291+
- description: interface clock required to access smmu's registers
292+
through the TCU's programming interface.
293+
- description: bus clock required for memory access
294+
- description: bus clock required for GPU memory access
295+
- properties:
296+
clock-names:
297+
items:
298+
- const: iface-mm
299+
- const: iface-smmu
300+
- const: bus-smmu
301+
clocks:
302+
items:
303+
- description: interface clock required to access mnoc's registers
304+
through the TCU's programming interface.
305+
- description: interface clock required to access smmu's registers
306+
through the TCU's programming interface.
307+
- description: bus clock required for the smmu ptw
308+
309+
- if:
310+
properties:
311+
compatible:
312+
contains:
313+
enum:
273314
- qcom,sdm630-smmu-v2
274315
- qcom,sm6375-smmu-v2
275316
then:

Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ properties:
7878
- mediatek,mt8173-m4u # generation two
7979
- mediatek,mt8183-m4u # generation two
8080
- mediatek,mt8186-iommu-mm # generation two
81+
- mediatek,mt8188-iommu-vdo # generation two
82+
- mediatek,mt8188-iommu-vpp # generation two
83+
- mediatek,mt8188-iommu-infra # generation two
8184
- mediatek,mt8192-m4u # generation two
8285
- mediatek,mt8195-iommu-vdo # generation two
8386
- mediatek,mt8195-iommu-vpp # generation two
@@ -123,6 +126,7 @@ properties:
123126
description: |
124127
This is the mtk_m4u_id according to the HW. Specifies the mtk_m4u_id as
125128
defined in
129+
dt-binding/memory/mediatek,mt8188-memory-port.h for mt8188,
126130
dt-binding/memory/mt2701-larb-port.h for mt2701 and mt7623,
127131
dt-binding/memory/mt2712-larb-port.h for mt2712,
128132
dt-binding/memory/mt6779-larb-port.h for mt6779,
@@ -155,6 +159,8 @@ allOf:
155159
- mediatek,mt6795-m4u
156160
- mediatek,mt8173-m4u
157161
- mediatek,mt8186-iommu-mm
162+
- mediatek,mt8188-iommu-vdo
163+
- mediatek,mt8188-iommu-vpp
158164
- mediatek,mt8192-m4u
159165
- mediatek,mt8195-iommu-vdo
160166
- mediatek,mt8195-iommu-vpp
@@ -168,6 +174,8 @@ allOf:
168174
compatible:
169175
enum:
170176
- mediatek,mt8186-iommu-mm
177+
- mediatek,mt8188-iommu-vdo
178+
- mediatek,mt8188-iommu-vpp
171179
- mediatek,mt8192-m4u
172180
- mediatek,mt8195-iommu-vdo
173181
- mediatek,mt8195-iommu-vpp
@@ -194,7 +202,9 @@ allOf:
194202
properties:
195203
compatible:
196204
contains:
197-
const: mediatek,mt8195-iommu-infra
205+
enum:
206+
- mediatek,mt8188-iommu-infra
207+
- mediatek,mt8195-iommu-infra
198208

199209
then:
200210
required:

Documentation/devicetree/bindings/iommu/qcom,iommu.yaml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@ description: |
1717
1818
properties:
1919
compatible:
20-
items:
21-
- enum:
22-
- qcom,msm8916-iommu
23-
- qcom,msm8953-iommu
24-
- const: qcom,msm-iommu-v1
20+
oneOf:
21+
- items:
22+
- enum:
23+
- qcom,msm8916-iommu
24+
- qcom,msm8953-iommu
25+
- const: qcom,msm-iommu-v1
26+
- items:
27+
- enum:
28+
- qcom,msm8976-iommu
29+
- const: qcom,msm-iommu-v2
2530

2631
clocks:
2732
items:
@@ -64,13 +69,20 @@ patternProperties:
6469
enum:
6570
- qcom,msm-iommu-v1-ns
6671
- qcom,msm-iommu-v1-sec
72+
- qcom,msm-iommu-v2-ns
73+
- qcom,msm-iommu-v2-sec
6774

6875
interrupts:
6976
maxItems: 1
7077

7178
reg:
7279
maxItems: 1
7380

81+
qcom,ctx-asid:
82+
$ref: /schemas/types.yaml#/definitions/uint32
83+
description:
84+
The ASID number associated to the context bank.
85+
7486
required:
7587
- compatible
7688
- interrupts

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13356,6 +13356,7 @@ L: [email protected] (moderated for non-subscribers)
1335613356
S: Supported
1335713357
F: Documentation/devicetree/bindings/iommu/mediatek*
1335813358
F: drivers/iommu/mtk_iommu*
13359+
F: include/dt-bindings/memory/mediatek,mt*-port.h
1335913360
F: include/dt-bindings/memory/mt*-port.h
1336013361

1336113362
MEDIATEK JPEG DRIVER

drivers/acpi/scan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1584,7 +1584,7 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev,
15841584
* If we have reason to believe the IOMMU driver missed the initial
15851585
* iommu_probe_device() call for dev, replay it to get things in order.
15861586
*/
1587-
if (!err && dev->bus && !device_iommu_mapped(dev))
1587+
if (!err && dev->bus)
15881588
err = iommu_probe_device(dev);
15891589

15901590
/* Ignore all other errors apart from EPROBE_DEFER */

drivers/dma/idxd/device.c

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -299,21 +299,6 @@ void idxd_wqs_unmap_portal(struct idxd_device *idxd)
299299
}
300300
}
301301

302-
static void __idxd_wq_set_priv_locked(struct idxd_wq *wq, int priv)
303-
{
304-
struct idxd_device *idxd = wq->idxd;
305-
union wqcfg wqcfg;
306-
unsigned int offset;
307-
308-
offset = WQCFG_OFFSET(idxd, wq->id, WQCFG_PRIVL_IDX);
309-
spin_lock(&idxd->dev_lock);
310-
wqcfg.bits[WQCFG_PRIVL_IDX] = ioread32(idxd->reg_base + offset);
311-
wqcfg.priv = priv;
312-
wq->wqcfg->bits[WQCFG_PRIVL_IDX] = wqcfg.bits[WQCFG_PRIVL_IDX];
313-
iowrite32(wqcfg.bits[WQCFG_PRIVL_IDX], idxd->reg_base + offset);
314-
spin_unlock(&idxd->dev_lock);
315-
}
316-
317302
static void __idxd_wq_set_pasid_locked(struct idxd_wq *wq, int pasid)
318303
{
319304
struct idxd_device *idxd = wq->idxd;
@@ -1421,26 +1406,21 @@ int drv_enable_wq(struct idxd_wq *wq)
14211406
}
14221407

14231408
/*
1424-
* In the event that the WQ is configurable for pasid and priv bits.
1425-
* For kernel wq, the driver should setup the pasid, pasid_en, and priv bit.
1426-
* However, for non-kernel wq, the driver should only set the pasid_en bit for
1427-
* shared wq. A dedicated wq that is not 'kernel' type will configure pasid and
1409+
* In the event that the WQ is configurable for pasid, the driver
1410+
* should setup the pasid, pasid_en bit. This is true for both kernel
1411+
* and user shared workqueues. There is no need to setup priv bit in
1412+
* that in-kernel DMA will also do user privileged requests.
1413+
* A dedicated wq that is not 'kernel' type will configure pasid and
14281414
* pasid_en later on so there is no need to setup.
14291415
*/
14301416
if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) {
1431-
int priv = 0;
1432-
14331417
if (wq_pasid_enabled(wq)) {
14341418
if (is_idxd_wq_kernel(wq) || wq_shared(wq)) {
14351419
u32 pasid = wq_dedicated(wq) ? idxd->pasid : 0;
14361420

14371421
__idxd_wq_set_pasid_locked(wq, pasid);
14381422
}
14391423
}
1440-
1441-
if (is_idxd_wq_kernel(wq))
1442-
priv = 1;
1443-
__idxd_wq_set_priv_locked(wq, priv);
14441424
}
14451425

14461426
rc = 0;
@@ -1548,6 +1528,15 @@ int idxd_device_drv_probe(struct idxd_dev *idxd_dev)
15481528
if (rc < 0)
15491529
return -ENXIO;
15501530

1531+
/*
1532+
* System PASID is preserved across device disable/enable cycle, but
1533+
* genconfig register content gets cleared during device reset. We
1534+
* need to re-enable user interrupts for kernel work queue completion
1535+
* IRQ to function.
1536+
*/
1537+
if (idxd->pasid != IOMMU_PASID_INVALID)
1538+
idxd_set_user_intr(idxd, 1);
1539+
15511540
rc = idxd_device_evl_setup(idxd);
15521541
if (rc < 0) {
15531542
idxd->cmd_status = IDXD_SCMD_DEV_EVL_ERR;

drivers/dma/idxd/dma.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,10 @@ static inline void idxd_prep_desc_common(struct idxd_wq *wq,
7575
hw->xfer_size = len;
7676
/*
7777
* For dedicated WQ, this field is ignored and HW will use the WQCFG.priv
78-
* field instead. This field should be set to 1 for kernel descriptors.
78+
* field instead. This field should be set to 0 for kernel descriptors
79+
* since kernel DMA on VT-d supports "user" privilege only.
7980
*/
80-
hw->priv = 1;
81+
hw->priv = 0;
8182
hw->completion_addr = compl;
8283
}
8384

drivers/dma/idxd/idxd.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,15 @@ static inline struct idxd_device *ie_to_idxd(struct idxd_irq_entry *ie)
473473
return container_of(ie, struct idxd_device, ie);
474474
}
475475

476+
static inline void idxd_set_user_intr(struct idxd_device *idxd, bool enable)
477+
{
478+
union gencfg_reg reg;
479+
480+
reg.bits = ioread32(idxd->reg_base + IDXD_GENCFG_OFFSET);
481+
reg.user_int_en = enable;
482+
iowrite32(reg.bits, idxd->reg_base + IDXD_GENCFG_OFFSET);
483+
}
484+
476485
extern struct bus_type dsa_bus_type;
477486

478487
extern bool support_enqcmd;

drivers/dma/idxd/init.c

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -550,14 +550,59 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d
550550

551551
static int idxd_enable_system_pasid(struct idxd_device *idxd)
552552
{
553-
return -EOPNOTSUPP;
553+
struct pci_dev *pdev = idxd->pdev;
554+
struct device *dev = &pdev->dev;
555+
struct iommu_domain *domain;
556+
ioasid_t pasid;
557+
int ret;
558+
559+
/*
560+
* Attach a global PASID to the DMA domain so that we can use ENQCMDS
561+
* to submit work on buffers mapped by DMA API.
562+
*/
563+
domain = iommu_get_domain_for_dev(dev);
564+
if (!domain)
565+
return -EPERM;
566+
567+
pasid = iommu_alloc_global_pasid(dev);
568+
if (pasid == IOMMU_PASID_INVALID)
569+
return -ENOSPC;
570+
571+
/*
572+
* DMA domain is owned by the driver, it should support all valid
573+
* types such as DMA-FQ, identity, etc.
574+
*/
575+
ret = iommu_attach_device_pasid(domain, dev, pasid);
576+
if (ret) {
577+
dev_err(dev, "failed to attach device pasid %d, domain type %d",
578+
pasid, domain->type);
579+
iommu_free_global_pasid(pasid);
580+
return ret;
581+
}
582+
583+
/* Since we set user privilege for kernel DMA, enable completion IRQ */
584+
idxd_set_user_intr(idxd, 1);
585+
idxd->pasid = pasid;
586+
587+
return ret;
554588
}
555589

556590
static void idxd_disable_system_pasid(struct idxd_device *idxd)
557591
{
592+
struct pci_dev *pdev = idxd->pdev;
593+
struct device *dev = &pdev->dev;
594+
struct iommu_domain *domain;
595+
596+
domain = iommu_get_domain_for_dev(dev);
597+
if (!domain)
598+
return;
599+
600+
iommu_detach_device_pasid(domain, dev, idxd->pasid);
601+
iommu_free_global_pasid(idxd->pasid);
558602

559-
iommu_sva_unbind_device(idxd->sva);
603+
idxd_set_user_intr(idxd, 0);
560604
idxd->sva = NULL;
605+
idxd->pasid = IOMMU_PASID_INVALID;
561606
}
562607

563608
static int idxd_enable_sva(struct pci_dev *pdev)
@@ -600,8 +645,9 @@ static int idxd_probe(struct idxd_device *idxd)
600645
} else {
601646
set_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags);
602647

603-
if (idxd_enable_system_pasid(idxd))
604-
dev_warn(dev, "No in-kernel DMA with PASID.\n");
648+
rc = idxd_enable_system_pasid(idxd);
649+
if (rc)
650+
dev_warn(dev, "No in-kernel DMA with PASID. %d\n", rc);
605651
else
606652
set_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags);
607653
}

drivers/dma/idxd/sysfs.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -948,13 +948,6 @@ static ssize_t wq_name_store(struct device *dev,
948948
if (strlen(buf) > WQ_NAME_SIZE || strlen(buf) == 0)
949949
return -EINVAL;
950950

951-
/*
952-
* This is temporarily placed here until we have SVM support for
953-
* dmaengine.
954-
*/
955-
if (wq->type == IDXD_WQT_KERNEL && device_pasid_enabled(wq->idxd))
956-
return -EOPNOTSUPP;
957-
958951
input = kstrndup(buf, count, GFP_KERNEL);
959952
if (!input)
960953
return -ENOMEM;

0 commit comments

Comments
 (0)