Skip to content

Commit 4298780

Browse files
Jacob Panjoergroedel
authored andcommitted
iommu: Generalize PASID 0 for normal DMA w/o PASID
PCIe Process address space ID (PASID) is used to tag DMA traffic, it provides finer grained isolation than requester ID (RID). For each device/RID, 0 is a special PASID for the normal DMA (no PASID). This is universal across all architectures that supports PASID, therefore warranted to be reserved globally and declared in the common header. Consequently, we can avoid the conflict between different PASID use cases in the generic code. e.g. SVA and DMA API with PASIDs. This paved away for device drivers to choose global PASID policy while continue doing normal DMA. Noting that VT-d could support none-zero RID/NO_PASID, but currently not used. Reviewed-by: Lu Baolu <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Jean-Philippe Brucker <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Signed-off-by: Jacob Pan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Lu Baolu <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent 52a93d3 commit 4298780

File tree

6 files changed

+23
-24
lines changed

6 files changed

+23
-24
lines changed

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ arm_smmu_share_asid(struct mm_struct *mm, u16 asid)
8080
* be some overlap between use of both ASIDs, until we invalidate the
8181
* TLB.
8282
*/
83-
arm_smmu_write_ctx_desc(smmu_domain, 0, cd);
83+
arm_smmu_write_ctx_desc(smmu_domain, IOMMU_NO_PASID, cd);
8484

8585
/* Invalidate TLB entries previously associated with that context */
8686
arm_smmu_tlb_inv_asid(smmu, asid);

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
10591059
/*
10601060
* This function handles the following cases:
10611061
*
1062-
* (1) Install primary CD, for normal DMA traffic (SSID = 0).
1062+
* (1) Install primary CD, for normal DMA traffic (SSID = IOMMU_NO_PASID = 0).
10631063
* (2) Install a secondary CD, for SID+SSID traffic.
10641064
* (3) Update ASID of a CD. Atomically write the first 64 bits of the
10651065
* CD, then invalidate the old entry and mappings.
@@ -1607,7 +1607,7 @@ static void arm_smmu_handle_ppr(struct arm_smmu_device *smmu, u64 *evt)
16071607

16081608
sid = FIELD_GET(PRIQ_0_SID, evt[0]);
16091609
ssv = FIELD_GET(PRIQ_0_SSID_V, evt[0]);
1610-
ssid = ssv ? FIELD_GET(PRIQ_0_SSID, evt[0]) : 0;
1610+
ssid = ssv ? FIELD_GET(PRIQ_0_SSID, evt[0]) : IOMMU_NO_PASID;
16111611
last = FIELD_GET(PRIQ_0_PRG_LAST, evt[0]);
16121612
grpid = FIELD_GET(PRIQ_1_PRG_IDX, evt[1]);
16131613

@@ -1748,7 +1748,7 @@ arm_smmu_atc_inv_to_cmd(int ssid, unsigned long iova, size_t size,
17481748
*/
17491749
*cmd = (struct arm_smmu_cmdq_ent) {
17501750
.opcode = CMDQ_OP_ATC_INV,
1751-
.substream_valid = !!ssid,
1751+
.substream_valid = (ssid != IOMMU_NO_PASID),
17521752
.atc.ssid = ssid,
17531753
};
17541754

@@ -1795,7 +1795,7 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
17951795
struct arm_smmu_cmdq_ent cmd;
17961796
struct arm_smmu_cmdq_batch cmds;
17971797

1798-
arm_smmu_atc_inv_to_cmd(0, 0, 0, &cmd);
1798+
arm_smmu_atc_inv_to_cmd(IOMMU_NO_PASID, 0, 0, &cmd);
17991799

18001800
cmds.num = 0;
18011801
for (i = 0; i < master->num_streams; i++) {
@@ -1875,7 +1875,7 @@ static void arm_smmu_tlb_inv_context(void *cookie)
18751875
cmd.tlbi.vmid = smmu_domain->s2_cfg.vmid;
18761876
arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
18771877
}
1878-
arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0);
1878+
arm_smmu_atc_inv_domain(smmu_domain, IOMMU_NO_PASID, 0, 0);
18791879
}
18801880

18811881
static void __arm_smmu_tlb_inv_range(struct arm_smmu_cmdq_ent *cmd,
@@ -1968,7 +1968,7 @@ static void arm_smmu_tlb_inv_range_domain(unsigned long iova, size_t size,
19681968
* Unfortunately, this can't be leaf-only since we may have
19691969
* zapped an entire table.
19701970
*/
1971-
arm_smmu_atc_inv_domain(smmu_domain, 0, iova, size);
1971+
arm_smmu_atc_inv_domain(smmu_domain, IOMMU_NO_PASID, iova, size);
19721972
}
19731973

19741974
void arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid,
@@ -2142,7 +2142,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
21422142
* the master has been added to the devices list for this domain.
21432143
* This isn't an issue because the STE hasn't been installed yet.
21442144
*/
2145-
ret = arm_smmu_write_ctx_desc(smmu_domain, 0, &cfg->cd);
2145+
ret = arm_smmu_write_ctx_desc(smmu_domain, IOMMU_NO_PASID, &cfg->cd);
21462146
if (ret)
21472147
goto out_free_cd_tables;
21482148

@@ -2328,7 +2328,7 @@ static void arm_smmu_enable_ats(struct arm_smmu_master *master)
23282328
pdev = to_pci_dev(master->dev);
23292329

23302330
atomic_inc(&smmu_domain->nr_ats_masters);
2331-
arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0);
2331+
arm_smmu_atc_inv_domain(smmu_domain, IOMMU_NO_PASID, 0, 0);
23322332
if (pci_enable_ats(pdev, stu))
23332333
dev_err(master->dev, "Failed to enable ATS (STU %zu)\n", stu);
23342334
}

drivers/iommu/intel/iommu.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
877877
}
878878
/* For request-without-pasid, get the pasid from context entry */
879879
if (intel_iommu_sm && pasid == IOMMU_PASID_INVALID)
880-
pasid = PASID_RID2PASID;
880+
pasid = IOMMU_NO_PASID;
881881

882882
dir_index = pasid >> PASID_PDE_SHIFT;
883883
pde = &dir[dir_index];
@@ -1449,7 +1449,7 @@ static void __iommu_flush_dev_iotlb(struct device_domain_info *info,
14491449
qdep = info->ats_qdep;
14501450
qi_flush_dev_iotlb(info->iommu, sid, info->pfsid,
14511451
qdep, addr, mask);
1452-
quirk_extra_dev_tlb_flush(info, addr, mask, PASID_RID2PASID, qdep);
1452+
quirk_extra_dev_tlb_flush(info, addr, mask, IOMMU_NO_PASID, qdep);
14531453
}
14541454

14551455
static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
@@ -1484,7 +1484,7 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
14841484
ih = 1 << 6;
14851485

14861486
if (domain->use_first_level) {
1487-
qi_flush_piotlb(iommu, did, PASID_RID2PASID, addr, pages, ih);
1487+
qi_flush_piotlb(iommu, did, IOMMU_NO_PASID, addr, pages, ih);
14881488
} else {
14891489
unsigned long bitmask = aligned_pages - 1;
14901490

@@ -1554,7 +1554,7 @@ static void intel_flush_iotlb_all(struct iommu_domain *domain)
15541554
u16 did = domain_id_iommu(dmar_domain, iommu);
15551555

15561556
if (dmar_domain->use_first_level)
1557-
qi_flush_piotlb(iommu, did, PASID_RID2PASID, 0, -1, 0);
1557+
qi_flush_piotlb(iommu, did, IOMMU_NO_PASID, 0, -1, 0);
15581558
else
15591559
iommu->flush.flush_iotlb(iommu, did, 0, 0,
15601560
DMA_TLB_DSI_FLUSH);
@@ -1940,7 +1940,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
19401940
context_pdts(pds);
19411941

19421942
/* Setup the RID_PASID field: */
1943-
context_set_sm_rid2pasid(context, PASID_RID2PASID);
1943+
context_set_sm_rid2pasid(context, IOMMU_NO_PASID);
19441944

19451945
/*
19461946
* Setup the Device-TLB enable bit and Page request
@@ -2420,13 +2420,13 @@ static int dmar_domain_attach_device(struct dmar_domain *domain,
24202420
/* Setup the PASID entry for requests without PASID: */
24212421
if (hw_pass_through && domain_type_is_si(domain))
24222422
ret = intel_pasid_setup_pass_through(iommu, domain,
2423-
dev, PASID_RID2PASID);
2423+
dev, IOMMU_NO_PASID);
24242424
else if (domain->use_first_level)
24252425
ret = domain_setup_first_level(iommu, domain, dev,
2426-
PASID_RID2PASID);
2426+
IOMMU_NO_PASID);
24272427
else
24282428
ret = intel_pasid_setup_second_level(iommu, domain,
2429-
dev, PASID_RID2PASID);
2429+
dev, IOMMU_NO_PASID);
24302430
if (ret) {
24312431
dev_err(dev, "Setup RID2PASID failed\n");
24322432
device_block_translation(dev);
@@ -3968,7 +3968,7 @@ static void dmar_remove_one_dev_info(struct device *dev)
39683968
if (!dev_is_real_dma_subdevice(info->dev)) {
39693969
if (dev_is_pci(info->dev) && sm_supported(iommu))
39703970
intel_pasid_tear_down_entry(iommu, info->dev,
3971-
PASID_RID2PASID, false);
3971+
IOMMU_NO_PASID, false);
39723972

39733973
iommu_disable_pci_caps(info);
39743974
domain_context_clear(info);
@@ -3997,7 +3997,7 @@ static void device_block_translation(struct device *dev)
39973997
if (!dev_is_real_dma_subdevice(dev)) {
39983998
if (sm_supported(iommu))
39993999
intel_pasid_tear_down_entry(iommu, dev,
4000-
PASID_RID2PASID, false);
4000+
IOMMU_NO_PASID, false);
40014001
else
40024002
domain_context_clear(info);
40034003
}
@@ -4331,7 +4331,7 @@ static void domain_set_force_snooping(struct dmar_domain *domain)
43314331

43324332
list_for_each_entry(info, &domain->devices, link)
43334333
intel_pasid_setup_page_snoop_control(info->iommu, info->dev,
4334-
PASID_RID2PASID);
4334+
IOMMU_NO_PASID);
43354335
}
43364336

43374337
static bool intel_iommu_enforce_cache_coherency(struct iommu_domain *domain)
@@ -4987,7 +4987,7 @@ void quirk_extra_dev_tlb_flush(struct device_domain_info *info,
49874987
return;
49884988

49894989
sid = PCI_DEVID(info->bus, info->devfn);
4990-
if (pasid == PASID_RID2PASID) {
4990+
if (pasid == IOMMU_NO_PASID) {
49914991
qi_flush_dev_iotlb(info->iommu, sid, info->pfsid,
49924992
qdep, address, mask);
49934993
} else {

drivers/iommu/intel/pasid.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ devtlb_invalidation_with_pasid(struct intel_iommu *iommu,
438438
* SVA usage, device could do DMA with multiple PASIDs. It is more
439439
* efficient to flush devTLB specific to the PASID.
440440
*/
441-
if (pasid == PASID_RID2PASID)
441+
if (pasid == IOMMU_NO_PASID)
442442
qi_flush_dev_iotlb(iommu, sid, pfsid, qdep, 0, 64 - VTD_PAGE_SHIFT);
443443
else
444444
qi_flush_dev_iotlb_pasid(iommu, sid, pfsid, pasid, qdep, 0, 64 - VTD_PAGE_SHIFT);

drivers/iommu/intel/pasid.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
#ifndef __INTEL_PASID_H
1111
#define __INTEL_PASID_H
1212

13-
#define PASID_RID2PASID 0x0
14-
#define PASID_MIN 0x1
1513
#define PASID_MAX 0x100000
1614
#define PASID_PTE_MASK 0x3F
1715
#define PASID_PTE_PRESENT 1

include/linux/iommu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ enum iommu_dev_features {
196196
IOMMU_DEV_FEAT_IOPF,
197197
};
198198

199+
#define IOMMU_NO_PASID (0U) /* Reserved for DMA w/o PASID */
199200
#define IOMMU_PASID_INVALID (-1U)
200201
typedef unsigned int ioasid_t;
201202

0 commit comments

Comments
 (0)