Skip to content

Commit 64efb3d

Browse files
jgunthorpewilldeacon
authored andcommitted
iommu/arm-smmu-v3: Add ssid to struct arm_smmu_master_domain
Prepare to allow a S1 domain to be attached to a PASID as well. Keep track of the SSID the domain is using on each master in the arm_smmu_master_domain. Tested-by: Nicolin Chen <[email protected]> Tested-by: Shameer Kolothum <[email protected]> Reviewed-by: Michael Shavit <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Reviewed-by: Jerry Snitselaar <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 7497f42 commit 64efb3d

File tree

3 files changed

+43
-19
lines changed

3 files changed

+43
-19
lines changed

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,12 @@ arm_smmu_update_s1_domain_cd_entry(struct arm_smmu_domain *smmu_domain)
4747
struct arm_smmu_master *master = master_domain->master;
4848
struct arm_smmu_cd *cdptr;
4949

50-
/* S1 domains only support RID attachment right now */
51-
cdptr = arm_smmu_get_cd_ptr(master, IOMMU_NO_PASID);
50+
cdptr = arm_smmu_get_cd_ptr(master, master_domain->ssid);
5251
if (WARN_ON(!cdptr))
5352
continue;
5453

5554
arm_smmu_make_s1_cd(&target_cd, master, smmu_domain);
56-
arm_smmu_write_cd_entry(master, IOMMU_NO_PASID, cdptr,
55+
arm_smmu_write_cd_entry(master, master_domain->ssid, cdptr,
5756
&target_cd);
5857
}
5958
spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
@@ -294,8 +293,8 @@ static void arm_smmu_mm_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn,
294293
smmu_domain);
295294
}
296295

297-
arm_smmu_atc_inv_domain(smmu_domain, mm_get_enqcmd_pasid(mm), start,
298-
size);
296+
arm_smmu_atc_inv_domain_sva(smmu_domain, mm_get_enqcmd_pasid(mm), start,
297+
size);
299298
}
300299

301300
static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
@@ -332,7 +331,7 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
332331
spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
333332

334333
arm_smmu_tlb_inv_asid(smmu_domain->smmu, smmu_mn->cd->asid);
335-
arm_smmu_atc_inv_domain(smmu_domain, mm_get_enqcmd_pasid(mm), 0, 0);
334+
arm_smmu_atc_inv_domain_sva(smmu_domain, mm_get_enqcmd_pasid(mm), 0, 0);
336335

337336
smmu_mn->cleared = true;
338337
mutex_unlock(&sva_lock);
@@ -411,8 +410,8 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
411410
*/
412411
if (!smmu_mn->cleared) {
413412
arm_smmu_tlb_inv_asid(smmu_domain->smmu, cd->asid);
414-
arm_smmu_atc_inv_domain(smmu_domain, mm_get_enqcmd_pasid(mm), 0,
415-
0);
413+
arm_smmu_atc_inv_domain_sva(smmu_domain,
414+
mm_get_enqcmd_pasid(mm), 0, 0);
416415
}
417416

418417
/* Frees smmu_mn */

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

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,8 +2013,8 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
20132013
return arm_smmu_cmdq_batch_submit(master->smmu, &cmds);
20142014
}
20152015

2016-
int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
2017-
unsigned long iova, size_t size)
2016+
static int __arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain,
2017+
ioasid_t ssid, unsigned long iova, size_t size)
20182018
{
20192019
struct arm_smmu_master_domain *master_domain;
20202020
int i;
@@ -2042,8 +2042,6 @@ int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
20422042
if (!atomic_read(&smmu_domain->nr_ats_masters))
20432043
return 0;
20442044

2045-
arm_smmu_atc_inv_to_cmd(ssid, iova, size, &cmd);
2046-
20472045
cmds.num = 0;
20482046

20492047
spin_lock_irqsave(&smmu_domain->devices_lock, flags);
@@ -2054,6 +2052,16 @@ int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
20542052
if (!master->ats_enabled)
20552053
continue;
20562054

2055+
/*
2056+
* Non-zero ssid means SVA is co-opting the S1 domain to issue
2057+
* invalidations for SVA PASIDs.
2058+
*/
2059+
if (ssid != IOMMU_NO_PASID)
2060+
arm_smmu_atc_inv_to_cmd(ssid, iova, size, &cmd);
2061+
else
2062+
arm_smmu_atc_inv_to_cmd(master_domain->ssid, iova, size,
2063+
&cmd);
2064+
20572065
for (i = 0; i < master->num_streams; i++) {
20582066
cmd.atc.sid = master->streams[i].id;
20592067
arm_smmu_cmdq_batch_add(smmu_domain->smmu, &cmds, &cmd);
@@ -2064,6 +2072,19 @@ int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
20642072
return arm_smmu_cmdq_batch_submit(smmu_domain->smmu, &cmds);
20652073
}
20662074

2075+
static int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain,
2076+
unsigned long iova, size_t size)
2077+
{
2078+
return __arm_smmu_atc_inv_domain(smmu_domain, IOMMU_NO_PASID, iova,
2079+
size);
2080+
}
2081+
2082+
int arm_smmu_atc_inv_domain_sva(struct arm_smmu_domain *smmu_domain,
2083+
ioasid_t ssid, unsigned long iova, size_t size)
2084+
{
2085+
return __arm_smmu_atc_inv_domain(smmu_domain, ssid, iova, size);
2086+
}
2087+
20672088
/* IO_PGTABLE API */
20682089
static void arm_smmu_tlb_inv_context(void *cookie)
20692090
{
@@ -2085,7 +2106,7 @@ static void arm_smmu_tlb_inv_context(void *cookie)
20852106
cmd.tlbi.vmid = smmu_domain->s2_cfg.vmid;
20862107
arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
20872108
}
2088-
arm_smmu_atc_inv_domain(smmu_domain, IOMMU_NO_PASID, 0, 0);
2109+
arm_smmu_atc_inv_domain(smmu_domain, 0, 0);
20892110
}
20902111

20912112
static void __arm_smmu_tlb_inv_range(struct arm_smmu_cmdq_ent *cmd,
@@ -2183,7 +2204,7 @@ static void arm_smmu_tlb_inv_range_domain(unsigned long iova, size_t size,
21832204
* Unfortunately, this can't be leaf-only since we may have
21842205
* zapped an entire table.
21852206
*/
2186-
arm_smmu_atc_inv_domain(smmu_domain, IOMMU_NO_PASID, iova, size);
2207+
arm_smmu_atc_inv_domain(smmu_domain, iova, size);
21872208
}
21882209

21892210
void arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid,
@@ -2518,15 +2539,17 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
25182539

25192540
static struct arm_smmu_master_domain *
25202541
arm_smmu_find_master_domain(struct arm_smmu_domain *smmu_domain,
2521-
struct arm_smmu_master *master)
2542+
struct arm_smmu_master *master,
2543+
ioasid_t ssid)
25222544
{
25232545
struct arm_smmu_master_domain *master_domain;
25242546

25252547
lockdep_assert_held(&smmu_domain->devices_lock);
25262548

25272549
list_for_each_entry(master_domain, &smmu_domain->devices,
25282550
devices_elm) {
2529-
if (master_domain->master == master)
2551+
if (master_domain->master == master &&
2552+
master_domain->ssid == ssid)
25302553
return master_domain;
25312554
}
25322555
return NULL;
@@ -2559,7 +2582,8 @@ static void arm_smmu_remove_master_domain(struct arm_smmu_master *master,
25592582
return;
25602583

25612584
spin_lock_irqsave(&smmu_domain->devices_lock, flags);
2562-
master_domain = arm_smmu_find_master_domain(smmu_domain, master);
2585+
master_domain = arm_smmu_find_master_domain(smmu_domain, master,
2586+
IOMMU_NO_PASID);
25632587
if (master_domain) {
25642588
list_del(&master_domain->devices_elm);
25652589
kfree(master_domain);

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,7 @@ void arm_smmu_make_sva_cd(struct arm_smmu_cd *target,
772772
struct arm_smmu_master_domain {
773773
struct list_head devices_elm;
774774
struct arm_smmu_master *master;
775+
ioasid_t ssid;
775776
};
776777

777778
static inline struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
@@ -803,8 +804,8 @@ void arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid,
803804
size_t granule, bool leaf,
804805
struct arm_smmu_domain *smmu_domain);
805806
bool arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd);
806-
int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
807-
unsigned long iova, size_t size);
807+
int arm_smmu_atc_inv_domain_sva(struct arm_smmu_domain *smmu_domain,
808+
ioasid_t ssid, unsigned long iova, size_t size);
808809

809810
#ifdef CONFIG_ARM_SMMU_V3_SVA
810811
bool arm_smmu_sva_supported(struct arm_smmu_device *smmu);

0 commit comments

Comments
 (0)