Skip to content

Commit 5cedc05

Browse files
nicolincjamieNguyenNVIDIA
authored andcommitted
NVIDIA: SAUCE: iommu/arm-smmu-v3: Allow default substream bypass with a pasid support
When an iommu_domain is set to IOMMU_DOMAIN_IDENTITY, the driver would skip the allocation of a CD table and set the CONFIG field of the STE to STRTAB_STE_0_CFG_BYPASS. This works well for devices that only have one substream, i.e. PASID disabled. However, there could be a use case, for a pasid capable device, that allows bypassing the translation at the default substream while still enabling the pasid feature, which means the driver should not skip the allocation of a CD table nor simply bypass the CONFIG field. Instead, the S1DSS field should be set to STRTAB_STE_1_S1DSS_BYPASS and the SHCFG field should be set to STRTAB_STE_1_SHCFG_INCOMING. Add s1dss in struct arm_smmu_s1_cfg, to allow a configuration in the finalise() to support this use case. Also, according to "13.5 Summary of attribute/permission configuration fields" in the reference manual, the SHCFG field value is irrelevant. So, set the SHCFG field of the STE always to STRTAB_STE_1_SHCFG_INCOMING for simplification. Change-Id: I3b6f42d4b6a7c53b80e22f2579ff8b9efcd6bb01 Signed-off-by: Nicolin Chen <[email protected]> Reviewed-by: Pritesh Raithatha <[email protected]> Acked-by: Jamie Nguyen <[email protected]> Acked-by: Nicolin Chen <[email protected]>
1 parent bf650bd commit 5cedc05

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,7 +1332,8 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
13321332

13331333
BUG_ON(ste_live);
13341334
dst[1] = cpu_to_le64(
1335-
FIELD_PREP(STRTAB_STE_1_S1DSS, STRTAB_STE_1_S1DSS_SSID0) |
1335+
FIELD_PREP(STRTAB_STE_1_S1DSS, s1_cfg->s1dss) |
1336+
FIELD_PREP(STRTAB_STE_1_SHCFG, STRTAB_STE_1_SHCFG_INCOMING) |
13361337
FIELD_PREP(STRTAB_STE_1_S1CIR, STRTAB_STE_1_S1C_CACHE_WBRA) |
13371338
FIELD_PREP(STRTAB_STE_1_S1COR, STRTAB_STE_1_S1C_CACHE_WBRA) |
13381339
FIELD_PREP(STRTAB_STE_1_S1CSH, ARM_SMMU_SH_ISH) |
@@ -2099,6 +2100,10 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
20992100
goto out_unlock;
21002101

21012102
cfg->s1cdmax = master->ssid_bits;
2103+
if (smmu_domain->domain.type == IOMMU_DOMAIN_IDENTITY)
2104+
cfg->s1dss = STRTAB_STE_1_S1DSS_BYPASS;
2105+
else
2106+
cfg->s1dss = STRTAB_STE_1_S1DSS_SSID0;
21022107

21032108
smmu_domain->stall_enabled = master->stall_enabled;
21042109

@@ -2178,7 +2183,11 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain,
21782183
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
21792184
struct arm_smmu_device *smmu = smmu_domain->smmu;
21802185

2181-
if (domain->type == IOMMU_DOMAIN_IDENTITY) {
2186+
/*
2187+
* A master with a pasid capability might need a CD table, so only set
2188+
* ARM_SMMU_DOMAIN_BYPASS if IOMMU_DOMAIN_IDENTITY and non-pasid master
2189+
*/
2190+
if (domain->type == IOMMU_DOMAIN_IDENTITY && !master->ssid_bits) {
21822191
smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
21832192
return 0;
21842193
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,7 @@ struct arm_smmu_s1_cfg {
595595
struct arm_smmu_ctx_desc_cfg cdcfg;
596596
struct arm_smmu_ctx_desc cd;
597597
u8 s1fmt;
598+
u8 s1dss;
598599
u8 s1cdmax;
599600
};
600601

0 commit comments

Comments
 (0)