Thread (12 messages) 12 messages, 5 authors, 2023-09-14

Re: [PATCH v1] iommu/arm-smmu-v3: Allow default substream bypass with a pasid support

From: Aahil Awatramani <hidden>
Date: 2023-09-12 22:13:39
Also in: linux-iommu, lkml

We have a use-case for this patch to help in avoiding the map/unmap
overhead in some cases but still maintaining support for PASIDs.

Thanks.


On Tue, Sep 12, 2023 at 1:30 PM Nicolin Chen [off-list ref] wrote:
quoted hunk ↗ jump to hunk
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 and shcfg in struct arm_smmu_s1_cfg, to allow configurations
in the finalise() to support that use case. Then, set them accordingly
depending on the iommu_domain->type and the master->ssid_bits.

Also, add STRTAB_STE_1_SHCFG_NONSHAREABLE of the default configuration
to distinguish from STRTAB_STE_1_SHCFG_INCOMING of the bypass one.

Signed-off-by: Nicolin Chen <redacted>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 18 +++++++++++++++---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  3 +++
 2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 9b0dc3505601..8dc7934a0175 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1350,11 +1350,12 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,

                BUG_ON(ste_live);
                dst[1] = cpu_to_le64(
-                        FIELD_PREP(STRTAB_STE_1_S1DSS, STRTAB_STE_1_S1DSS_SSID0) |
+                        FIELD_PREP(STRTAB_STE_1_S1DSS, s1_cfg->s1dss) |
                         FIELD_PREP(STRTAB_STE_1_S1CIR, STRTAB_STE_1_S1C_CACHE_WBRA) |
                         FIELD_PREP(STRTAB_STE_1_S1COR, STRTAB_STE_1_S1C_CACHE_WBRA) |
                         FIELD_PREP(STRTAB_STE_1_S1CSH, ARM_SMMU_SH_ISH) |
-                        FIELD_PREP(STRTAB_STE_1_STRW, strw));
+                        FIELD_PREP(STRTAB_STE_1_STRW, strw) |
+                        FIELD_PREP(STRTAB_STE_1_SHCFG, s1_cfg->shcfg));

                if (smmu->features & ARM_SMMU_FEAT_STALLS &&
                    !master->stall_enabled)
@@ -2119,6 +2120,13 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
                goto out_unlock;

        cfg->s1cdmax = master->ssid_bits;
+       if (smmu_domain->domain.type == IOMMU_DOMAIN_IDENTITY) {
+               cfg->s1dss = STRTAB_STE_1_S1DSS_BYPASS;
+               cfg->shcfg = STRTAB_STE_1_SHCFG_INCOMING;
+       } else {
+               cfg->s1dss = STRTAB_STE_1_S1DSS_SSID0;
+               cfg->shcfg = STRTAB_STE_1_SHCFG_NONSHAREABLE;
+       }

        smmu_domain->stall_enabled = master->stall_enabled;
@@ -2198,7 +2206,11 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain,
        struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
        struct arm_smmu_device *smmu = smmu_domain->smmu;

-       if (domain->type == IOMMU_DOMAIN_IDENTITY) {
+       /*
+        * A master with a pasid capability might need a CD table, so only set
+        * ARM_SMMU_DOMAIN_BYPASS if IOMMU_DOMAIN_IDENTITY and non-pasid master
+        */
+       if (domain->type == IOMMU_DOMAIN_IDENTITY && !master->ssid_bits) {
                smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS;
                return 0;
        }
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index dcab85698a4e..8052d02770d0 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -244,6 +244,7 @@
 #define STRTAB_STE_1_STRW_EL2          2UL

 #define STRTAB_STE_1_SHCFG             GENMASK_ULL(45, 44)
+#define STRTAB_STE_1_SHCFG_NONSHAREABLE        0UL
 #define STRTAB_STE_1_SHCFG_INCOMING    1UL

 #define STRTAB_STE_2_S2VMID            GENMASK_ULL(15, 0)
@@ -601,6 +602,8 @@ struct arm_smmu_s1_cfg {
        struct arm_smmu_ctx_desc_cfg    cdcfg;
        struct arm_smmu_ctx_desc        cd;
        u8                              s1fmt;
+       u8                              s1dss;
+       u8                              shcfg;
        u8                              s1cdmax;
 };

--
2.41.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help