* [PATCH v2 0/8] Refactor the SMMU's CD table ownership
@ 2023-07-31 10:48 Michael Shavit
2023-07-31 10:48 ` [PATCH v2 1/8] iommu/arm-smmu-v3: Move ctx_desc out of s1_cfg Michael Shavit
` (7 more replies)
0 siblings, 8 replies; 24+ messages in thread
From: Michael Shavit @ 2023-07-31 10:48 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: will, robin.murphy, nicolinc, jgg, jean-philippe, Michael Shavit
Hi all,
This series refactors stage 1 domains so that they describe a single CD
entry. These entries are now inserted into a CD table that is owned by
the arm_smmu_master instead of the domain.
This is conceptually cleaner and unblocks other features, such as
attaching domains with PASID (for unmanaged/dma domains).
This patch series was originally part of a larger patch series that
implemented the set_dev_pasid callback for non-SVA domains but is now
split into a distinct series.
This patch series is also available on gerrit with Jean's SMMU test
engine patches cherry-picked on top for testing:
https://linux-review.googlesource.com/c/linux/kernel/git/torvalds/linux/+/24742/1
Thanks,
Michael Shavit
Changes in v2:
- Allocate CD table when it's first needed instead of on probe.
- Minor changes
- Added commit to rename remaining usages of cdcfg to cd_table
Changes in v1:
- Replace s1_cfg with arm_smmu_ctx_desc_cfg representing the CD table
- Assume that the CD table is owned by the SMMU master for most
operations. This is forward-compatible with the nested patch series as
these operations wouldn't be called when the installed CD table comes
from nested domains.
- Split off as a distinct patch series from https://lore.kernel.org/all/20230621063825.268890-1-mshavit@google.com/
Michael Shavit (8):
iommu/arm-smmu-v3: Move ctx_desc out of s1_cfg
iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg
iommu/arm-smmu-v3: Encapsulate ctx_desc_cfg init in alloc_cd_tables
iommu/arm-smmu-v3: move stall_enabled to the cd table
iommu/arm-smmu-v3: Skip cd sync if CD table isn't active
iommu/arm-smmu-v3: Refactor write_ctx_desc
iommu/arm-smmu-v3: Move CD table to arm_smmu_master
iommu/arm-smmu-v3: Rename cdcfg to cd_table
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 35 ++-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 219 ++++++++----------
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 21 +-
3 files changed, 142 insertions(+), 133 deletions(-)
base-commit: 57012c57536f8814dec92e74197ee96c3498d24e
--
2.41.0.585.gd2178a4bd4-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 1/8] iommu/arm-smmu-v3: Move ctx_desc out of s1_cfg
2023-07-31 10:48 [PATCH v2 0/8] Refactor the SMMU's CD table ownership Michael Shavit
@ 2023-07-31 10:48 ` Michael Shavit
2023-08-01 14:08 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 2/8] iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg Michael Shavit
` (6 subsequent siblings)
7 siblings, 1 reply; 24+ messages in thread
From: Michael Shavit @ 2023-07-31 10:48 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: will, robin.murphy, nicolinc, jgg, jean-philippe, Michael Shavit
s1_cfg describes the CD table that is inserted into an SMMU's STEs. It's
weird for s1_cfg to also own ctx_desc which describes a CD that is
inserted into that table. It is more appropriate for arm_smmu_domain to
own ctx_desc.
Signed-off-by: Michael Shavit <mshavit@google.com>
---
Changes in v2:
- Undo over-reaching column alignment change
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 2 +-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 23 ++++++++++---------
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 6 +++--
3 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
index a5a63b1c947eb..968559d625c40 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -62,7 +62,7 @@ arm_smmu_share_asid(struct mm_struct *mm, u16 asid)
return cd;
}
- smmu_domain = container_of(cd, struct arm_smmu_domain, s1_cfg.cd);
+ smmu_domain = container_of(cd, struct arm_smmu_domain, cd);
smmu = smmu_domain->smmu;
ret = xa_alloc(&arm_smmu_asid_xa, &new_asid, cd,
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 9b0dc35056019..bb277ff86f65f 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1869,7 +1869,7 @@ static void arm_smmu_tlb_inv_context(void *cookie)
* careful, 007.
*/
if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
- arm_smmu_tlb_inv_asid(smmu, smmu_domain->s1_cfg.cd.asid);
+ arm_smmu_tlb_inv_asid(smmu, smmu_domain->cd.asid);
} else {
cmd.opcode = CMDQ_OP_TLBI_S12_VMALL;
cmd.tlbi.vmid = smmu_domain->s2_cfg.vmid;
@@ -1957,7 +1957,7 @@ static void arm_smmu_tlb_inv_range_domain(unsigned long iova, size_t size,
if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
cmd.opcode = smmu_domain->smmu->features & ARM_SMMU_FEAT_E2H ?
CMDQ_OP_TLBI_EL2_VA : CMDQ_OP_TLBI_NH_VA;
- cmd.tlbi.asid = smmu_domain->s1_cfg.cd.asid;
+ cmd.tlbi.asid = smmu_domain->cd.asid;
} else {
cmd.opcode = CMDQ_OP_TLBI_S2_IPA;
cmd.tlbi.vmid = smmu_domain->s2_cfg.vmid;
@@ -2088,7 +2088,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
mutex_lock(&arm_smmu_asid_lock);
if (cfg->cdcfg.cdtab)
arm_smmu_free_cd_tables(smmu_domain);
- arm_smmu_free_asid(&cfg->cd);
+ arm_smmu_free_asid(&smmu_domain->cd);
mutex_unlock(&arm_smmu_asid_lock);
} else {
struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
@@ -2107,13 +2107,14 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
u32 asid;
struct arm_smmu_device *smmu = smmu_domain->smmu;
struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
+ struct arm_smmu_ctx_desc *cd = &smmu_domain->cd;
typeof(&pgtbl_cfg->arm_lpae_s1_cfg.tcr) tcr = &pgtbl_cfg->arm_lpae_s1_cfg.tcr;
- refcount_set(&cfg->cd.refs, 1);
+ refcount_set(&cd->refs, 1);
/* Prevent SVA from modifying the ASID until it is written to the CD */
mutex_lock(&arm_smmu_asid_lock);
- ret = xa_alloc(&arm_smmu_asid_xa, &asid, &cfg->cd,
+ ret = xa_alloc(&arm_smmu_asid_xa, &asid, cd,
XA_LIMIT(1, (1 << smmu->asid_bits) - 1), GFP_KERNEL);
if (ret)
goto out_unlock;
@@ -2126,23 +2127,23 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
if (ret)
goto out_free_asid;
- cfg->cd.asid = (u16)asid;
- cfg->cd.ttbr = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
- cfg->cd.tcr = FIELD_PREP(CTXDESC_CD_0_TCR_T0SZ, tcr->tsz) |
+ cd->asid = (u16)asid;
+ cd->ttbr = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
+ cd->tcr = FIELD_PREP(CTXDESC_CD_0_TCR_T0SZ, tcr->tsz) |
FIELD_PREP(CTXDESC_CD_0_TCR_TG0, tcr->tg) |
FIELD_PREP(CTXDESC_CD_0_TCR_IRGN0, tcr->irgn) |
FIELD_PREP(CTXDESC_CD_0_TCR_ORGN0, tcr->orgn) |
FIELD_PREP(CTXDESC_CD_0_TCR_SH0, tcr->sh) |
FIELD_PREP(CTXDESC_CD_0_TCR_IPS, tcr->ips) |
CTXDESC_CD_0_TCR_EPD1 | CTXDESC_CD_0_AA64;
- cfg->cd.mair = pgtbl_cfg->arm_lpae_s1_cfg.mair;
+ cd->mair = pgtbl_cfg->arm_lpae_s1_cfg.mair;
/*
* Note that this will end up calling arm_smmu_sync_cd() before
* the master has been added to the devices list for this domain.
* This isn't an issue because the STE hasn't been installed yet.
*/
- ret = arm_smmu_write_ctx_desc(smmu_domain, 0, &cfg->cd);
+ ret = arm_smmu_write_ctx_desc(smmu_domain, 0, cd);
if (ret)
goto out_free_cd_tables;
@@ -2152,7 +2153,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
out_free_cd_tables:
arm_smmu_free_cd_tables(smmu_domain);
out_free_asid:
- arm_smmu_free_asid(&cfg->cd);
+ arm_smmu_free_asid(cd);
out_unlock:
mutex_unlock(&arm_smmu_asid_lock);
return ret;
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 dcab85698a4e2..f841383a55a35 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -599,7 +599,6 @@ struct arm_smmu_ctx_desc_cfg {
struct arm_smmu_s1_cfg {
struct arm_smmu_ctx_desc_cfg cdcfg;
- struct arm_smmu_ctx_desc cd;
u8 s1fmt;
u8 s1cdmax;
};
@@ -724,7 +723,10 @@ struct arm_smmu_domain {
enum arm_smmu_domain_stage stage;
union {
- struct arm_smmu_s1_cfg s1_cfg;
+ struct {
+ struct arm_smmu_ctx_desc cd;
+ struct arm_smmu_s1_cfg s1_cfg;
+ };
struct arm_smmu_s2_cfg s2_cfg;
};
--
2.41.0.585.gd2178a4bd4-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 2/8] iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg
2023-07-31 10:48 [PATCH v2 0/8] Refactor the SMMU's CD table ownership Michael Shavit
2023-07-31 10:48 ` [PATCH v2 1/8] iommu/arm-smmu-v3: Move ctx_desc out of s1_cfg Michael Shavit
@ 2023-07-31 10:48 ` Michael Shavit
2023-08-01 4:14 ` Nicolin Chen
2023-08-01 13:43 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 3/8] iommu/arm-smmu-v3: Encapsulate ctx_desc_cfg init in alloc_cd_tables Michael Shavit
` (5 subsequent siblings)
7 siblings, 2 replies; 24+ messages in thread
From: Michael Shavit @ 2023-07-31 10:48 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: will, robin.murphy, nicolinc, jgg, jean-philippe, Michael Shavit
arm_smmu_ctx_desc_cfg is renamed to arm_smmu_cdtab_cfg to make it more
obvious that it represents a cd table. The max number of CDs that can be
represented by the CD table is stored in this truct in its log2 form
since it is more useful for users of the CD table, and replaces the
s1cdmax field in s1_cfg. Instead of storing s1_cfg.s1fmt, it can also be
trivially computed from the cdtab_cfg, and is therefore removed from
s1_cfg.
Signed-off-by: Michael Shavit <mshavit@google.com>
---
Changes in v2:
- Updated commit message
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 45 +++++++++++----------
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 10 ++---
2 files changed, 26 insertions(+), 29 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 bb277ff86f65f..8cf4987dd9ec7 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1033,9 +1033,9 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_domain *smmu_domain,
unsigned int idx;
struct arm_smmu_l1_ctx_desc *l1_desc;
struct arm_smmu_device *smmu = smmu_domain->smmu;
- struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg;
+ struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
- if (smmu_domain->s1_cfg.s1fmt == STRTAB_STE_0_S1FMT_LINEAR)
+ if (!cdcfg->l1_desc)
return cdcfg->cdtab + ssid * CTXDESC_CD_DWORDS;
idx = ssid >> CTXDESC_SPLIT;
@@ -1071,7 +1071,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
bool cd_live;
__le64 *cdptr;
- if (WARN_ON(ssid >= (1 << smmu_domain->s1_cfg.s1cdmax)))
+ if (WARN_ON(ssid >= (1 << smmu_domain->cd_table.max_cds_bits)))
return -E2BIG;
cdptr = arm_smmu_get_cd_ptr(smmu_domain, ssid);
@@ -1138,19 +1138,16 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain)
size_t l1size;
size_t max_contexts;
struct arm_smmu_device *smmu = smmu_domain->smmu;
- struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
- struct arm_smmu_ctx_desc_cfg *cdcfg = &cfg->cdcfg;
+ struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
- max_contexts = 1 << cfg->s1cdmax;
+ max_contexts = 1 << cdcfg->max_cds_bits;
if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB) ||
max_contexts <= CTXDESC_L2_ENTRIES) {
- cfg->s1fmt = STRTAB_STE_0_S1FMT_LINEAR;
cdcfg->num_l1_ents = max_contexts;
l1size = max_contexts * (CTXDESC_CD_DWORDS << 3);
} else {
- cfg->s1fmt = STRTAB_STE_0_S1FMT_64K_L2;
cdcfg->num_l1_ents = DIV_ROUND_UP(max_contexts,
CTXDESC_L2_ENTRIES);
@@ -1186,7 +1183,7 @@ static void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain)
int i;
size_t size, l1size;
struct arm_smmu_device *smmu = smmu_domain->smmu;
- struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg;
+ struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
if (cdcfg->l1_desc) {
size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3);
@@ -1276,7 +1273,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
u64 val = le64_to_cpu(dst[0]);
bool ste_live = false;
struct arm_smmu_device *smmu = NULL;
- struct arm_smmu_s1_cfg *s1_cfg = NULL;
+ struct arm_smmu_ctx_desc_cfg *cd_table = NULL;
struct arm_smmu_s2_cfg *s2_cfg = NULL;
struct arm_smmu_domain *smmu_domain = NULL;
struct arm_smmu_cmdq_ent prefetch_cmd = {
@@ -1294,7 +1291,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
if (smmu_domain) {
switch (smmu_domain->stage) {
case ARM_SMMU_DOMAIN_S1:
- s1_cfg = &smmu_domain->s1_cfg;
+ cd_table = &smmu_domain->cd_table;
break;
case ARM_SMMU_DOMAIN_S2:
case ARM_SMMU_DOMAIN_NESTED:
@@ -1325,7 +1322,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
val = STRTAB_STE_0_V;
/* Bypass/fault */
- if (!smmu_domain || !(s1_cfg || s2_cfg)) {
+ if (!smmu_domain || !(cd_table || s2_cfg)) {
if (!smmu_domain && disable_bypass)
val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT);
else
@@ -1344,7 +1341,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
return;
}
- if (s1_cfg) {
+ if (cd_table) {
u64 strw = smmu->features & ARM_SMMU_FEAT_E2H ?
STRTAB_STE_1_STRW_EL2 : STRTAB_STE_1_STRW_NSEL1;
@@ -1360,10 +1357,14 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
!master->stall_enabled)
dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
- val |= (s1_cfg->cdcfg.cdtab_dma & STRTAB_STE_0_S1CTXPTR_MASK) |
- FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS) |
- FIELD_PREP(STRTAB_STE_0_S1CDMAX, s1_cfg->s1cdmax) |
- FIELD_PREP(STRTAB_STE_0_S1FMT, s1_cfg->s1fmt);
+ val |= (cd_table->cdtab_dma & STRTAB_STE_0_S1CTXPTR_MASK) |
+ FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS) |
+ FIELD_PREP(STRTAB_STE_0_S1CDMAX,
+ cd_table->max_cds_bits) |
+ FIELD_PREP(STRTAB_STE_0_S1FMT,
+ cd_table->l1_desc ?
+ STRTAB_STE_0_S1FMT_64K_L2 :
+ STRTAB_STE_0_S1FMT_LINEAR);
}
if (s2_cfg) {
@@ -2082,11 +2083,11 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
/* Free the CD and ASID, if we allocated them */
if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
- struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
+ struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
/* Prevent SVA from touching the CD while we're freeing it */
mutex_lock(&arm_smmu_asid_lock);
- if (cfg->cdcfg.cdtab)
+ if (cdcfg->cdtab)
arm_smmu_free_cd_tables(smmu_domain);
arm_smmu_free_asid(&smmu_domain->cd);
mutex_unlock(&arm_smmu_asid_lock);
@@ -2106,7 +2107,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
int ret;
u32 asid;
struct arm_smmu_device *smmu = smmu_domain->smmu;
- struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
+ struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
struct arm_smmu_ctx_desc *cd = &smmu_domain->cd;
typeof(&pgtbl_cfg->arm_lpae_s1_cfg.tcr) tcr = &pgtbl_cfg->arm_lpae_s1_cfg.tcr;
@@ -2119,7 +2120,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
if (ret)
goto out_unlock;
- cfg->s1cdmax = master->ssid_bits;
+ cdcfg->max_cds_bits = master->ssid_bits;
smmu_domain->stall_enabled = master->stall_enabled;
@@ -2457,7 +2458,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
ret = -EINVAL;
goto out_unlock;
} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
- master->ssid_bits != smmu_domain->s1_cfg.s1cdmax) {
+ master->ssid_bits != smmu_domain->cd_table.max_cds_bits) {
ret = -EINVAL;
goto out_unlock;
} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
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 f841383a55a35..35a93e8858872 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -595,12 +595,8 @@ struct arm_smmu_ctx_desc_cfg {
dma_addr_t cdtab_dma;
struct arm_smmu_l1_ctx_desc *l1_desc;
unsigned int num_l1_ents;
-};
-
-struct arm_smmu_s1_cfg {
- struct arm_smmu_ctx_desc_cfg cdcfg;
- u8 s1fmt;
- u8 s1cdmax;
+ /* log2 of the maximum number of CDs supported by this table */
+ u8 max_cds_bits;
};
struct arm_smmu_s2_cfg {
@@ -725,7 +721,7 @@ struct arm_smmu_domain {
union {
struct {
struct arm_smmu_ctx_desc cd;
- struct arm_smmu_s1_cfg s1_cfg;
+ struct arm_smmu_ctx_desc_cfg cd_table;
};
struct arm_smmu_s2_cfg s2_cfg;
};
--
2.41.0.585.gd2178a4bd4-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 3/8] iommu/arm-smmu-v3: Encapsulate ctx_desc_cfg init in alloc_cd_tables
2023-07-31 10:48 [PATCH v2 0/8] Refactor the SMMU's CD table ownership Michael Shavit
2023-07-31 10:48 ` [PATCH v2 1/8] iommu/arm-smmu-v3: Move ctx_desc out of s1_cfg Michael Shavit
2023-07-31 10:48 ` [PATCH v2 2/8] iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg Michael Shavit
@ 2023-07-31 10:48 ` Michael Shavit
2023-08-01 14:09 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table Michael Shavit
` (4 subsequent siblings)
7 siblings, 1 reply; 24+ messages in thread
From: Michael Shavit @ 2023-07-31 10:48 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: will, robin.murphy, nicolinc, jgg, jean-philippe, Michael Shavit
This is slighlty cleaner: arm_smmu_ctx_desc_cfg is initialized in a
single function instead of having pieces set ahead-of time by its caller.
Signed-off-by: Michael Shavit <mshavit@google.com>
---
(no changes since v1)
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 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 8cf4987dd9ec7..8a286e3838d70 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1132,7 +1132,8 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
return 0;
}
-static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain)
+static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain,
+ struct arm_smmu_master *master)
{
int ret;
size_t l1size;
@@ -1140,6 +1141,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain)
struct arm_smmu_device *smmu = smmu_domain->smmu;
struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
+ cdcfg->max_cds_bits = master->ssid_bits;
max_contexts = 1 << cdcfg->max_cds_bits;
if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB) ||
@@ -2107,7 +2109,6 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
int ret;
u32 asid;
struct arm_smmu_device *smmu = smmu_domain->smmu;
- struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
struct arm_smmu_ctx_desc *cd = &smmu_domain->cd;
typeof(&pgtbl_cfg->arm_lpae_s1_cfg.tcr) tcr = &pgtbl_cfg->arm_lpae_s1_cfg.tcr;
@@ -2120,11 +2121,9 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
if (ret)
goto out_unlock;
- cdcfg->max_cds_bits = master->ssid_bits;
-
smmu_domain->stall_enabled = master->stall_enabled;
- ret = arm_smmu_alloc_cd_tables(smmu_domain);
+ ret = arm_smmu_alloc_cd_tables(smmu_domain, master);
if (ret)
goto out_free_asid;
--
2.41.0.585.gd2178a4bd4-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table
2023-07-31 10:48 [PATCH v2 0/8] Refactor the SMMU's CD table ownership Michael Shavit
` (2 preceding siblings ...)
2023-07-31 10:48 ` [PATCH v2 3/8] iommu/arm-smmu-v3: Encapsulate ctx_desc_cfg init in alloc_cd_tables Michael Shavit
@ 2023-07-31 10:48 ` Michael Shavit
2023-08-01 4:28 ` Nicolin Chen
2023-08-01 14:12 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 5/8] iommu/arm-smmu-v3: Skip cd sync if CD table isn't active Michael Shavit
` (3 subsequent siblings)
7 siblings, 2 replies; 24+ messages in thread
From: Michael Shavit @ 2023-07-31 10:48 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: will, robin.murphy, nicolinc, jgg, jean-philippe, Michael Shavit
This controls whether CD entries will have the stall bit set when
writing entries into the table.
Signed-off-by: Michael Shavit <mshavit@google.com>
---
Changes in v2:
- Use a bitfield instead of a bool for stall_enabled
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 ++++----
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 3 ++-
2 files changed, 6 insertions(+), 5 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 8a286e3838d70..654acf6002bf3 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1114,7 +1114,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid) |
CTXDESC_CD_0_V;
- if (smmu_domain->stall_enabled)
+ if (smmu_domain->cd_table.stall_enabled)
val |= CTXDESC_CD_0_S;
}
@@ -1141,6 +1141,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain,
struct arm_smmu_device *smmu = smmu_domain->smmu;
struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
+ cdcfg->stall_enabled = master->stall_enabled;
cdcfg->max_cds_bits = master->ssid_bits;
max_contexts = 1 << cdcfg->max_cds_bits;
@@ -2121,8 +2122,6 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
if (ret)
goto out_unlock;
- smmu_domain->stall_enabled = master->stall_enabled;
-
ret = arm_smmu_alloc_cd_tables(smmu_domain, master);
if (ret)
goto out_free_asid;
@@ -2461,7 +2460,8 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
ret = -EINVAL;
goto out_unlock;
} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
- smmu_domain->stall_enabled != master->stall_enabled) {
+ smmu_domain->cd_table.stall_enabled !=
+ master->stall_enabled) {
ret = -EINVAL;
goto out_unlock;
}
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 35a93e8858872..05b1f0ee60808 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -597,6 +597,8 @@ struct arm_smmu_ctx_desc_cfg {
unsigned int num_l1_ents;
/* log2 of the maximum number of CDs supported by this table */
u8 max_cds_bits;
+ /* Whether CD entries in this table have the stall bit set. */
+ u8 stall_enabled:1;
};
struct arm_smmu_s2_cfg {
@@ -714,7 +716,6 @@ struct arm_smmu_domain {
struct mutex init_mutex; /* Protects smmu pointer */
struct io_pgtable_ops *pgtbl_ops;
- bool stall_enabled;
atomic_t nr_ats_masters;
enum arm_smmu_domain_stage stage;
--
2.41.0.585.gd2178a4bd4-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 5/8] iommu/arm-smmu-v3: Skip cd sync if CD table isn't active
2023-07-31 10:48 [PATCH v2 0/8] Refactor the SMMU's CD table ownership Michael Shavit
` (3 preceding siblings ...)
2023-07-31 10:48 ` [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table Michael Shavit
@ 2023-07-31 10:48 ` Michael Shavit
2023-08-01 14:13 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 6/8] iommu/arm-smmu-v3: Refactor write_ctx_desc Michael Shavit
` (2 subsequent siblings)
7 siblings, 1 reply; 24+ messages in thread
From: Michael Shavit @ 2023-07-31 10:48 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: will, robin.murphy, nicolinc, jgg, jean-philippe, Michael Shavit
This commit explicitly keeps track of whether a CD table is installed in
an STE so that arm_smmu_sync_cd can skip the sync when unnecessary. This
was previously achieved through the domain->devices list, but we are
moving to a model where arm_smmu_sync_cd directly operates on a master
and the master's CD table instead of a domain.
Signed-off-by: Michael Shavit <mshavit@google.com>
---
Changes in v2:
- Store field as a bit instead of a bool. Fix comment about STE being
live before the sync in write_ctx_desc().
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 6 +++++-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
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 654acf6002bf3..4f7fe19d88fda 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -987,6 +987,9 @@ static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
},
};
+ if (!smmu_domain->cd_table.installed)
+ return;
+
cmds.num = 0;
spin_lock_irqsave(&smmu_domain->devices_lock, flags);
@@ -1098,7 +1101,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
cdptr[3] = cpu_to_le64(cd->mair);
/*
- * STE is live, and the SMMU might read dwords of this CD in any
+ * STE may be live, and the SMMU might read dwords of this CD in any
* order. Ensure that it observes valid values before reading
* V=1.
*/
@@ -1368,6 +1371,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
cd_table->l1_desc ?
STRTAB_STE_0_S1FMT_64K_L2 :
STRTAB_STE_0_S1FMT_LINEAR);
+ cd_table->installed = true;
}
if (s2_cfg) {
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 05b1f0ee60808..3a56987a5fd0b 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -599,6 +599,8 @@ struct arm_smmu_ctx_desc_cfg {
u8 max_cds_bits;
/* Whether CD entries in this table have the stall bit set. */
u8 stall_enabled:1;
+ /* Whether this CD table is installed in any STE */
+ u8 installed:1;
};
struct arm_smmu_s2_cfg {
--
2.41.0.585.gd2178a4bd4-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 6/8] iommu/arm-smmu-v3: Refactor write_ctx_desc
2023-07-31 10:48 [PATCH v2 0/8] Refactor the SMMU's CD table ownership Michael Shavit
` (4 preceding siblings ...)
2023-07-31 10:48 ` [PATCH v2 5/8] iommu/arm-smmu-v3: Skip cd sync if CD table isn't active Michael Shavit
@ 2023-07-31 10:48 ` Michael Shavit
2023-08-01 14:18 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 7/8] iommu/arm-smmu-v3: Move CD table to arm_smmu_master Michael Shavit
2023-07-31 10:48 ` [PATCH v2 8/8] iommu/arm-smmu-v3: Rename cdcfg to cd_table Michael Shavit
7 siblings, 1 reply; 24+ messages in thread
From: Michael Shavit @ 2023-07-31 10:48 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: will, robin.murphy, nicolinc, jgg, jean-philippe, Michael Shavit
Update arm_smmu_write_ctx_desc and downstream functions to operate on
a master instead of an smmu domain. We expect arm_smmu_write_ctx_desc()
to only be called to write a CD entry into a CD table owned by the
master. Under the hood, arm_smmu_write_ctx_desc still fetches the CD
table from the domain that is attached to the master, but a subsequent
commit will move that table's ownership to the master.
Note that this change isn't a nop refactor since SVA will call
arm_smmu_write_ctx_desc in a loop for every master the domain is
attached to despite the fact that they all share the same CD table. This
loop may look weird but becomes necessary when the CD table becomes
per-master in a subsequent commit.
Signed-off-by: Michael Shavit <mshavit@google.com>
---
Changes in v2:
- minor style fixes
Changes in v1:
- arm_smmu_write_ctx_desc now get's the CD table to write to from the
master parameter instead of a distinct parameter. This works well
because the CD table being written to should always be owned by the
master by the end of this series. This version no longer allows master
to be NULL.
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 33 +++++++++--
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 59 ++++++++-----------
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 2 +-
3 files changed, 53 insertions(+), 41 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
index 968559d625c40..8242ee3405f2d 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -45,9 +45,11 @@ static struct arm_smmu_ctx_desc *
arm_smmu_share_asid(struct mm_struct *mm, u16 asid)
{
int ret;
+ unsigned long flags;
u32 new_asid;
struct arm_smmu_ctx_desc *cd;
struct arm_smmu_device *smmu;
+ struct arm_smmu_master *master;
struct arm_smmu_domain *smmu_domain;
cd = xa_load(&arm_smmu_asid_xa, asid);
@@ -80,7 +82,11 @@ arm_smmu_share_asid(struct mm_struct *mm, u16 asid)
* be some overlap between use of both ASIDs, until we invalidate the
* TLB.
*/
- arm_smmu_write_ctx_desc(smmu_domain, 0, cd);
+ spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+ list_for_each_entry(master, &smmu_domain->devices, domain_head) {
+ arm_smmu_write_ctx_desc(master, 0, cd);
+ }
+ spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
/* Invalidate TLB entries previously associated with that context */
arm_smmu_tlb_inv_asid(smmu, asid);
@@ -211,6 +217,8 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
{
struct arm_smmu_mmu_notifier *smmu_mn = mn_to_smmu(mn);
struct arm_smmu_domain *smmu_domain = smmu_mn->domain;
+ struct arm_smmu_master *master;
+ unsigned long flags;
mutex_lock(&sva_lock);
if (smmu_mn->cleared) {
@@ -222,7 +230,11 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
* DMA may still be running. Keep the cd valid to avoid C_BAD_CD events,
* but disable translation.
*/
- arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, &quiet_cd);
+ spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+ list_for_each_entry(master, &smmu_domain->devices, domain_head) {
+ arm_smmu_write_ctx_desc(master, mm->pasid, &quiet_cd);
+ }
+ spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
arm_smmu_tlb_inv_asid(smmu_domain->smmu, smmu_mn->cd->asid);
arm_smmu_atc_inv_domain(smmu_domain, mm->pasid, 0, 0);
@@ -248,7 +260,9 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
struct mm_struct *mm)
{
int ret;
+ unsigned long flags;
struct arm_smmu_ctx_desc *cd;
+ struct arm_smmu_master *master;
struct arm_smmu_mmu_notifier *smmu_mn;
list_for_each_entry(smmu_mn, &smmu_domain->mmu_notifiers, list) {
@@ -279,7 +293,11 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
goto err_free_cd;
}
- ret = arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, cd);
+ spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+ list_for_each_entry(master, &smmu_domain->devices, domain_head) {
+ ret = arm_smmu_write_ctx_desc(master, mm->pasid, cd);
+ }
+ spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
if (ret)
goto err_put_notifier;
@@ -296,6 +314,8 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
{
+ unsigned long flags;
+ struct arm_smmu_master *master;
struct mm_struct *mm = smmu_mn->mn.mm;
struct arm_smmu_ctx_desc *cd = smmu_mn->cd;
struct arm_smmu_domain *smmu_domain = smmu_mn->domain;
@@ -304,7 +324,12 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
return;
list_del(&smmu_mn->list);
- arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, NULL);
+
+ spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+ list_for_each_entry(master, &smmu_domain->devices, domain_head) {
+ arm_smmu_write_ctx_desc(master, mm->pasid, NULL);
+ }
+ spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
/*
* If we went through clear(), we've already invalidated, and no
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 4f7fe19d88fda..f1d480a391511 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -971,14 +971,12 @@ void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid)
arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
}
-static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
+static void arm_smmu_sync_cd(struct arm_smmu_master *master,
int ssid, bool leaf)
{
size_t i;
- unsigned long flags;
- struct arm_smmu_master *master;
struct arm_smmu_cmdq_batch cmds;
- struct arm_smmu_device *smmu = smmu_domain->smmu;
+ struct arm_smmu_device *smmu = master->smmu;
struct arm_smmu_cmdq_ent cmd = {
.opcode = CMDQ_OP_CFGI_CD,
.cfgi = {
@@ -987,19 +985,14 @@ static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
},
};
- if (!smmu_domain->cd_table.installed)
+ if (!master->domain->cd_table.installed)
return;
cmds.num = 0;
-
- spin_lock_irqsave(&smmu_domain->devices_lock, flags);
- list_for_each_entry(master, &smmu_domain->devices, domain_head) {
- for (i = 0; i < master->num_streams; i++) {
- cmd.cfgi.sid = master->streams[i].id;
- arm_smmu_cmdq_batch_add(smmu, &cmds, &cmd);
- }
+ for (i = 0; i < master->num_streams; i++) {
+ cmd.cfgi.sid = master->streams[i].id;
+ arm_smmu_cmdq_batch_add(smmu, &cmds, &cmd);
}
- spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
arm_smmu_cmdq_batch_submit(smmu, &cmds);
}
@@ -1029,14 +1022,13 @@ static void arm_smmu_write_cd_l1_desc(__le64 *dst,
WRITE_ONCE(*dst, cpu_to_le64(val));
}
-static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_domain *smmu_domain,
- u32 ssid)
+static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
{
__le64 *l1ptr;
unsigned int idx;
struct arm_smmu_l1_ctx_desc *l1_desc;
- struct arm_smmu_device *smmu = smmu_domain->smmu;
- struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
+ struct arm_smmu_device *smmu = master->smmu;
+ struct arm_smmu_ctx_desc_cfg *cdcfg = &master->domain->cd_table;
if (!cdcfg->l1_desc)
return cdcfg->cdtab + ssid * CTXDESC_CD_DWORDS;
@@ -1050,13 +1042,13 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_domain *smmu_domain,
l1ptr = cdcfg->cdtab + idx * CTXDESC_L1_DESC_DWORDS;
arm_smmu_write_cd_l1_desc(l1ptr, l1_desc);
/* An invalid L1CD can be cached */
- arm_smmu_sync_cd(smmu_domain, ssid, false);
+ arm_smmu_sync_cd(master, ssid, false);
}
idx = ssid & (CTXDESC_L2_ENTRIES - 1);
return l1_desc->l2ptr + idx * CTXDESC_CD_DWORDS;
}
-int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
+int arm_smmu_write_ctx_desc(struct arm_smmu_master *master, int ssid,
struct arm_smmu_ctx_desc *cd)
{
/*
@@ -1073,11 +1065,12 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
u64 val;
bool cd_live;
__le64 *cdptr;
+ struct arm_smmu_ctx_desc_cfg *cd_table = &master->domain->cd_table;
- if (WARN_ON(ssid >= (1 << smmu_domain->cd_table.max_cds_bits)))
+ if (WARN_ON(ssid >= (1 << cd_table->max_cds_bits)))
return -E2BIG;
- cdptr = arm_smmu_get_cd_ptr(smmu_domain, ssid);
+ cdptr = arm_smmu_get_cd_ptr(master, ssid);
if (!cdptr)
return -ENOMEM;
@@ -1101,11 +1094,11 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
cdptr[3] = cpu_to_le64(cd->mair);
/*
- * STE may be live, and the SMMU might read dwords of this CD in any
- * order. Ensure that it observes valid values before reading
- * V=1.
+ * STE may be live, and the SMMU might read dwords of this CD
+ * in any order. Ensure that it observes valid values before
+ * reading V=1.
*/
- arm_smmu_sync_cd(smmu_domain, ssid, true);
+ arm_smmu_sync_cd(master, ssid, true);
val = cd->tcr |
#ifdef __BIG_ENDIAN
@@ -1117,7 +1110,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid) |
CTXDESC_CD_0_V;
- if (smmu_domain->cd_table.stall_enabled)
+ if (cd_table->stall_enabled)
val |= CTXDESC_CD_0_S;
}
@@ -1131,7 +1124,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
* without first making the structure invalid.
*/
WRITE_ONCE(cdptr[0], cpu_to_le64(val));
- arm_smmu_sync_cd(smmu_domain, ssid, true);
+ arm_smmu_sync_cd(master, ssid, true);
return 0;
}
@@ -1141,7 +1134,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain,
int ret;
size_t l1size;
size_t max_contexts;
- struct arm_smmu_device *smmu = smmu_domain->smmu;
+ struct arm_smmu_device *smmu = master->smmu;
struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
cdcfg->stall_enabled = master->stall_enabled;
@@ -2141,12 +2134,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
CTXDESC_CD_0_TCR_EPD1 | CTXDESC_CD_0_AA64;
cd->mair = pgtbl_cfg->arm_lpae_s1_cfg.mair;
- /*
- * Note that this will end up calling arm_smmu_sync_cd() before
- * the master has been added to the devices list for this domain.
- * This isn't an issue because the STE hasn't been installed yet.
- */
- ret = arm_smmu_write_ctx_desc(smmu_domain, 0, cd);
+ ret = arm_smmu_write_ctx_desc(master, 0, cd);
if (ret)
goto out_free_cd_tables;
@@ -2464,8 +2452,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
ret = -EINVAL;
goto out_unlock;
} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
- smmu_domain->cd_table.stall_enabled !=
- master->stall_enabled) {
+ smmu_domain->cd_table.stall_enabled != master->stall_enabled) {
ret = -EINVAL;
goto out_unlock;
}
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 3a56987a5fd0b..c7e8684fd887d 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -746,7 +746,7 @@ extern struct xarray arm_smmu_asid_xa;
extern struct mutex arm_smmu_asid_lock;
extern struct arm_smmu_ctx_desc quiet_cd;
-int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
+int arm_smmu_write_ctx_desc(struct arm_smmu_master *smmu_master, int ssid,
struct arm_smmu_ctx_desc *cd);
void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid);
void arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid,
--
2.41.0.585.gd2178a4bd4-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 7/8] iommu/arm-smmu-v3: Move CD table to arm_smmu_master
2023-07-31 10:48 [PATCH v2 0/8] Refactor the SMMU's CD table ownership Michael Shavit
` (5 preceding siblings ...)
2023-07-31 10:48 ` [PATCH v2 6/8] iommu/arm-smmu-v3: Refactor write_ctx_desc Michael Shavit
@ 2023-07-31 10:48 ` Michael Shavit
2023-08-01 14:42 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 8/8] iommu/arm-smmu-v3: Rename cdcfg to cd_table Michael Shavit
7 siblings, 1 reply; 24+ messages in thread
From: Michael Shavit @ 2023-07-31 10:48 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: will, robin.murphy, nicolinc, jgg, jean-philippe, Michael Shavit
With this change, each master will now own its own CD table instead of
sharing one with other masters attached to the same domain. Attaching a
stage 1 domain installs CD entries into the master's CD table. SVA
writes its CD entries into each master's CD table if the domain is
shared across masters.
Signed-off-by: Michael Shavit <mshavit@google.com>
---
Changes in v2:
- Allocate CD table when it's first needed instead of on probe.
Changes in v1:
- The master's CD table allocation was previously split to a different
commit. This change now atomically allocates the new CD table, uses
it, and removes the old one.
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 67 +++++++++------------
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 6 +-
2 files changed, 32 insertions(+), 41 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 f1d480a391511..2949e1ad3914a 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -985,7 +985,7 @@ static void arm_smmu_sync_cd(struct arm_smmu_master *master,
},
};
- if (!master->domain->cd_table.installed)
+ if (!master->cd_table.installed)
return;
cmds.num = 0;
@@ -1028,7 +1028,7 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
unsigned int idx;
struct arm_smmu_l1_ctx_desc *l1_desc;
struct arm_smmu_device *smmu = master->smmu;
- struct arm_smmu_ctx_desc_cfg *cdcfg = &master->domain->cd_table;
+ struct arm_smmu_ctx_desc_cfg *cdcfg = &master->cd_table;
if (!cdcfg->l1_desc)
return cdcfg->cdtab + ssid * CTXDESC_CD_DWORDS;
@@ -1065,7 +1065,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_master *master, int ssid,
u64 val;
bool cd_live;
__le64 *cdptr;
- struct arm_smmu_ctx_desc_cfg *cd_table = &master->domain->cd_table;
+ struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
if (WARN_ON(ssid >= (1 << cd_table->max_cds_bits)))
return -E2BIG;
@@ -1128,14 +1128,13 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_master *master, int ssid,
return 0;
}
-static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain,
- struct arm_smmu_master *master)
+static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master)
{
int ret;
size_t l1size;
size_t max_contexts;
struct arm_smmu_device *smmu = master->smmu;
- struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
+ struct arm_smmu_ctx_desc_cfg *cdcfg = &master->cd_table;
cdcfg->stall_enabled = master->stall_enabled;
cdcfg->max_cds_bits = master->ssid_bits;
@@ -1177,12 +1176,12 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain,
return ret;
}
-static void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain)
+static void arm_smmu_free_cd_tables(struct arm_smmu_master *master)
{
int i;
size_t size, l1size;
- struct arm_smmu_device *smmu = smmu_domain->smmu;
- struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
+ struct arm_smmu_device *smmu = master->smmu;
+ struct arm_smmu_ctx_desc_cfg *cdcfg = &master->cd_table;
if (cdcfg->l1_desc) {
size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3);
@@ -1290,7 +1289,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
if (smmu_domain) {
switch (smmu_domain->stage) {
case ARM_SMMU_DOMAIN_S1:
- cd_table = &smmu_domain->cd_table;
+ cd_table = &master->cd_table;
break;
case ARM_SMMU_DOMAIN_S2:
case ARM_SMMU_DOMAIN_NESTED:
@@ -2081,14 +2080,10 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
free_io_pgtable_ops(smmu_domain->pgtbl_ops);
- /* Free the CD and ASID, if we allocated them */
+ /* Free the ASID or VMID */
if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
- struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
-
/* Prevent SVA from touching the CD while we're freeing it */
mutex_lock(&arm_smmu_asid_lock);
- if (cdcfg->cdtab)
- arm_smmu_free_cd_tables(smmu_domain);
arm_smmu_free_asid(&smmu_domain->cd);
mutex_unlock(&arm_smmu_asid_lock);
} else {
@@ -2100,7 +2095,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
kfree(smmu_domain);
}
-static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
+static int arm_smmu_domain_finalise_cd(struct arm_smmu_domain *smmu_domain,
struct arm_smmu_master *master,
struct io_pgtable_cfg *pgtbl_cfg)
{
@@ -2119,10 +2114,6 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
if (ret)
goto out_unlock;
- ret = arm_smmu_alloc_cd_tables(smmu_domain, master);
- if (ret)
- goto out_free_asid;
-
cd->asid = (u16)asid;
cd->ttbr = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
cd->tcr = FIELD_PREP(CTXDESC_CD_0_TCR_T0SZ, tcr->tsz) |
@@ -2134,17 +2125,9 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
CTXDESC_CD_0_TCR_EPD1 | CTXDESC_CD_0_AA64;
cd->mair = pgtbl_cfg->arm_lpae_s1_cfg.mair;
- ret = arm_smmu_write_ctx_desc(master, 0, cd);
- if (ret)
- goto out_free_cd_tables;
-
mutex_unlock(&arm_smmu_asid_lock);
return 0;
-out_free_cd_tables:
- arm_smmu_free_cd_tables(smmu_domain);
-out_free_asid:
- arm_smmu_free_asid(cd);
out_unlock:
mutex_unlock(&arm_smmu_asid_lock);
return ret;
@@ -2207,7 +2190,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain,
ias = min_t(unsigned long, ias, VA_BITS);
oas = smmu->ias;
fmt = ARM_64_LPAE_S1;
- finalise_stage_fn = arm_smmu_domain_finalise_s1;
+ finalise_stage_fn = arm_smmu_domain_finalise_cd;
break;
case ARM_SMMU_DOMAIN_NESTED:
case ARM_SMMU_DOMAIN_S2:
@@ -2447,14 +2430,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
} else if (smmu_domain->smmu != smmu) {
ret = -EINVAL;
goto out_unlock;
- } else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
- master->ssid_bits != smmu_domain->cd_table.max_cds_bits) {
- ret = -EINVAL;
- goto out_unlock;
- } else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
- smmu_domain->cd_table.stall_enabled != master->stall_enabled) {
- ret = -EINVAL;
- goto out_unlock;
}
master->domain = smmu_domain;
@@ -2469,6 +2444,22 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
if (smmu_domain->stage != ARM_SMMU_DOMAIN_BYPASS)
master->ats_enabled = arm_smmu_ats_supported(master);
+ if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
+ if (!master->cd_table.cdtab) {
+ ret = arm_smmu_alloc_cd_tables(master);
+ if (ret) {
+ master->domain = NULL;
+ goto out_unlock;
+ }
+ }
+
+ ret = arm_smmu_write_ctx_desc(master, 0, &smmu_domain->cd);
+ if (ret) {
+ master->domain = NULL;
+ goto out_unlock;
+ }
+ }
+
arm_smmu_install_ste_for_dev(master);
spin_lock_irqsave(&smmu_domain->devices_lock, flags);
@@ -2723,6 +2714,8 @@ static void arm_smmu_release_device(struct device *dev)
arm_smmu_detach_dev(master);
arm_smmu_disable_pasid(master);
arm_smmu_remove_master(master);
+ if (master->cd_table.cdtab_dma)
+ arm_smmu_free_cd_tables(master);
kfree(master);
}
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 c7e8684fd887d..0ee3dc7291a15 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -696,6 +696,7 @@ struct arm_smmu_master {
struct arm_smmu_domain *domain;
struct list_head domain_head;
struct arm_smmu_stream *streams;
+ struct arm_smmu_ctx_desc_cfg cd_table;
unsigned int num_streams;
bool ats_enabled;
bool stall_enabled;
@@ -722,11 +723,8 @@ struct arm_smmu_domain {
enum arm_smmu_domain_stage stage;
union {
- struct {
struct arm_smmu_ctx_desc cd;
- struct arm_smmu_ctx_desc_cfg cd_table;
- };
- struct arm_smmu_s2_cfg s2_cfg;
+ struct arm_smmu_s2_cfg s2_cfg;
};
struct iommu_domain domain;
--
2.41.0.585.gd2178a4bd4-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 8/8] iommu/arm-smmu-v3: Rename cdcfg to cd_table
2023-07-31 10:48 [PATCH v2 0/8] Refactor the SMMU's CD table ownership Michael Shavit
` (6 preceding siblings ...)
2023-07-31 10:48 ` [PATCH v2 7/8] iommu/arm-smmu-v3: Move CD table to arm_smmu_master Michael Shavit
@ 2023-07-31 10:48 ` Michael Shavit
2023-08-01 14:44 ` Jason Gunthorpe
7 siblings, 1 reply; 24+ messages in thread
From: Michael Shavit @ 2023-07-31 10:48 UTC (permalink / raw)
To: iommu, linux-arm-kernel, linux-kernel
Cc: will, robin.murphy, nicolinc, jgg, jean-philippe, Michael Shavit
since cdcfg sounds like it represents a CD entry when it's in fact a CD
table.
Signed-off-by: Michael Shavit <mshavit@google.com>
---
Changes in v2:
- New commit
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 66 ++++++++++-----------
1 file changed, 33 insertions(+), 33 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 2949e1ad3914a..b8e6f056bf36d 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1028,18 +1028,18 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_master *master, u32 ssid)
unsigned int idx;
struct arm_smmu_l1_ctx_desc *l1_desc;
struct arm_smmu_device *smmu = master->smmu;
- struct arm_smmu_ctx_desc_cfg *cdcfg = &master->cd_table;
+ struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
- if (!cdcfg->l1_desc)
- return cdcfg->cdtab + ssid * CTXDESC_CD_DWORDS;
+ if (!cd_table->l1_desc)
+ return cd_table->cdtab + ssid * CTXDESC_CD_DWORDS;
idx = ssid >> CTXDESC_SPLIT;
- l1_desc = &cdcfg->l1_desc[idx];
+ l1_desc = &cd_table->l1_desc[idx];
if (!l1_desc->l2ptr) {
if (arm_smmu_alloc_cd_leaf_table(smmu, l1_desc))
return NULL;
- l1ptr = cdcfg->cdtab + idx * CTXDESC_L1_DESC_DWORDS;
+ l1ptr = cd_table->cdtab + idx * CTXDESC_L1_DESC_DWORDS;
arm_smmu_write_cd_l1_desc(l1ptr, l1_desc);
/* An invalid L1CD can be cached */
arm_smmu_sync_cd(master, ssid, false);
@@ -1134,33 +1134,33 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master)
size_t l1size;
size_t max_contexts;
struct arm_smmu_device *smmu = master->smmu;
- struct arm_smmu_ctx_desc_cfg *cdcfg = &master->cd_table;
+ struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
- cdcfg->stall_enabled = master->stall_enabled;
- cdcfg->max_cds_bits = master->ssid_bits;
- max_contexts = 1 << cdcfg->max_cds_bits;
+ cd_table->stall_enabled = master->stall_enabled;
+ cd_table->max_cds_bits = master->ssid_bits;
+ max_contexts = 1 << cd_table->max_cds_bits;
if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB) ||
max_contexts <= CTXDESC_L2_ENTRIES) {
- cdcfg->num_l1_ents = max_contexts;
+ cd_table->num_l1_ents = max_contexts;
l1size = max_contexts * (CTXDESC_CD_DWORDS << 3);
} else {
- cdcfg->num_l1_ents = DIV_ROUND_UP(max_contexts,
+ cd_table->num_l1_ents = DIV_ROUND_UP(max_contexts,
CTXDESC_L2_ENTRIES);
- cdcfg->l1_desc = devm_kcalloc(smmu->dev, cdcfg->num_l1_ents,
- sizeof(*cdcfg->l1_desc),
+ cd_table->l1_desc = devm_kcalloc(smmu->dev, cd_table->num_l1_ents,
+ sizeof(*cd_table->l1_desc),
GFP_KERNEL);
- if (!cdcfg->l1_desc)
+ if (!cd_table->l1_desc)
return -ENOMEM;
- l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
+ l1size = cd_table->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
}
- cdcfg->cdtab = dmam_alloc_coherent(smmu->dev, l1size, &cdcfg->cdtab_dma,
+ cd_table->cdtab = dmam_alloc_coherent(smmu->dev, l1size, &cd_table->cdtab_dma,
GFP_KERNEL);
- if (!cdcfg->cdtab) {
+ if (!cd_table->cdtab) {
dev_warn(smmu->dev, "failed to allocate context descriptor\n");
ret = -ENOMEM;
goto err_free_l1;
@@ -1169,9 +1169,9 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master)
return 0;
err_free_l1:
- if (cdcfg->l1_desc) {
- devm_kfree(smmu->dev, cdcfg->l1_desc);
- cdcfg->l1_desc = NULL;
+ if (cd_table->l1_desc) {
+ devm_kfree(smmu->dev, cd_table->l1_desc);
+ cd_table->l1_desc = NULL;
}
return ret;
}
@@ -1181,30 +1181,30 @@ static void arm_smmu_free_cd_tables(struct arm_smmu_master *master)
int i;
size_t size, l1size;
struct arm_smmu_device *smmu = master->smmu;
- struct arm_smmu_ctx_desc_cfg *cdcfg = &master->cd_table;
+ struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
- if (cdcfg->l1_desc) {
+ if (cd_table->l1_desc) {
size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3);
- for (i = 0; i < cdcfg->num_l1_ents; i++) {
- if (!cdcfg->l1_desc[i].l2ptr)
+ for (i = 0; i < cd_table->num_l1_ents; i++) {
+ if (!cd_table->l1_desc[i].l2ptr)
continue;
dmam_free_coherent(smmu->dev, size,
- cdcfg->l1_desc[i].l2ptr,
- cdcfg->l1_desc[i].l2ptr_dma);
+ cd_table->l1_desc[i].l2ptr,
+ cd_table->l1_desc[i].l2ptr_dma);
}
- devm_kfree(smmu->dev, cdcfg->l1_desc);
- cdcfg->l1_desc = NULL;
+ devm_kfree(smmu->dev, cd_table->l1_desc);
+ cd_table->l1_desc = NULL;
- l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
+ l1size = cd_table->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
} else {
- l1size = cdcfg->num_l1_ents * (CTXDESC_CD_DWORDS << 3);
+ l1size = cd_table->num_l1_ents * (CTXDESC_CD_DWORDS << 3);
}
- dmam_free_coherent(smmu->dev, l1size, cdcfg->cdtab, cdcfg->cdtab_dma);
- cdcfg->cdtab_dma = 0;
- cdcfg->cdtab = NULL;
+ dmam_free_coherent(smmu->dev, l1size, cd_table->cdtab, cd_table->cdtab_dma);
+ cd_table->cdtab_dma = 0;
+ cd_table->cdtab = NULL;
}
bool arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd)
--
2.41.0.585.gd2178a4bd4-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 2/8] iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg
2023-07-31 10:48 ` [PATCH v2 2/8] iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg Michael Shavit
@ 2023-08-01 4:14 ` Nicolin Chen
2023-08-01 8:00 ` Michael Shavit
2023-08-01 13:43 ` Jason Gunthorpe
1 sibling, 1 reply; 24+ messages in thread
From: Nicolin Chen @ 2023-08-01 4:14 UTC (permalink / raw)
To: Michael Shavit
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy, jgg,
jean-philippe
On Mon, Jul 31, 2023 at 06:48:12PM +0800, Michael Shavit wrote:
> arm_smmu_ctx_desc_cfg is renamed to arm_smmu_cdtab_cfg to make it more
There seems to be no change of renaming "arm_smmu_ctx_desc_cfg" to
"arm_smmu_cdtab_cfg". Even PATCH-8 only renames the local variable
"cdcfg" to "cd_table". Also, we should not use PATCH-8 to justify
this change, because it makes this patch less convincing since the
PATCH-8 might not get applied at all.
> obvious that it represents a cd table. The max number of CDs that can be
> represented by the CD table is stored in this truct in its log2 form
> since it is more useful for users of the CD table, and replaces the
> s1cdmax field in s1_cfg. Instead of storing s1_cfg.s1fmt, it can also be
> trivially computed from the cdtab_cfg, and is therefore removed from
> s1_cfg.
The commit message does not quite well describe why "replace s1_cfg
with cd_table" in the subject. It could mention that the goal here
is to move cdtab to the master structure. And "unwrap s1_cfg" might
be more fitting in the subject, IMHO.
Thanks
Nicolin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table
2023-07-31 10:48 ` [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table Michael Shavit
@ 2023-08-01 4:28 ` Nicolin Chen
2023-08-01 4:52 ` Nicolin Chen
2023-08-01 14:12 ` Jason Gunthorpe
1 sibling, 1 reply; 24+ messages in thread
From: Nicolin Chen @ 2023-08-01 4:28 UTC (permalink / raw)
To: Michael Shavit
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy, jgg,
jean-philippe
On Mon, Jul 31, 2023 at 06:48:14PM +0800, Michael Shavit wrote:
> This controls whether CD entries will have the stall bit set when
> writing entries into the table.
>
> Signed-off-by: Michael Shavit <mshavit@google.com>
> ---
>
> Changes in v2:
> - Use a bitfield instead of a bool for stall_enabled
>
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 ++++----
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 3 ++-
> 2 files changed, 6 insertions(+), 5 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 8a286e3838d70..654acf6002bf3 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1114,7 +1114,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
> FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid) |
> CTXDESC_CD_0_V;
>
> - if (smmu_domain->stall_enabled)
> + if (smmu_domain->cd_table.stall_enabled)
> val |= CTXDESC_CD_0_S;
This cd_table->stall_enabled comes from master->stall_enabled, and
cd_table will be in master structure. Also, struct arm_smmu_master
pointer will be passed in to arm_smmu_write_ctx_desc(). So, there
seems to be no need of master->cd_table.stall_enabled in the end;
just use master->stall_enabled directly?
Thanks
Nicolin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table
2023-08-01 4:28 ` Nicolin Chen
@ 2023-08-01 4:52 ` Nicolin Chen
2023-08-01 8:09 ` Michael Shavit
0 siblings, 1 reply; 24+ messages in thread
From: Nicolin Chen @ 2023-08-01 4:52 UTC (permalink / raw)
To: Michael Shavit
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy, jgg,
jean-philippe
On Mon, Jul 31, 2023 at 09:28:40PM -0700, Nicolin Chen wrote:
> On Mon, Jul 31, 2023 at 06:48:14PM +0800, Michael Shavit wrote:
> > This controls whether CD entries will have the stall bit set when
> > writing entries into the table.
> >
> > Signed-off-by: Michael Shavit <mshavit@google.com>
> > ---
> >
> > Changes in v2:
> > - Use a bitfield instead of a bool for stall_enabled
> >
> > drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 ++++----
> > drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 3 ++-
> > 2 files changed, 6 insertions(+), 5 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 8a286e3838d70..654acf6002bf3 100644
> > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > @@ -1114,7 +1114,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
> > FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid) |
> > CTXDESC_CD_0_V;
> >
> > - if (smmu_domain->stall_enabled)
> > + if (smmu_domain->cd_table.stall_enabled)
> > val |= CTXDESC_CD_0_S;
>
> This cd_table->stall_enabled comes from master->stall_enabled, and
> cd_table will be in master structure. Also, struct arm_smmu_master
> pointer will be passed in to arm_smmu_write_ctx_desc(). So, there
> seems to be no need of master->cd_table.stall_enabled in the end;
> just use master->stall_enabled directly?
Actually the stall_enabled might still need to be per-CD/domain.
If a domain is attached by two masters. The domain->stall_enabled
is initialized with the first master->stall_enabled. Then, the
second master->stall_enabled would be required to match with the
domain->stall_enabled. arm_smmu_attach_dev() has such a sanity.
So, I think we might not need this patch.
Nicolin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 2/8] iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg
2023-08-01 4:14 ` Nicolin Chen
@ 2023-08-01 8:00 ` Michael Shavit
0 siblings, 0 replies; 24+ messages in thread
From: Michael Shavit @ 2023-08-01 8:00 UTC (permalink / raw)
To: Nicolin Chen
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy, jgg,
jean-philippe
On Tue, Aug 1, 2023 at 12:15 PM Nicolin Chen <nicolinc@nvidia.com> wrote:
>
> On Mon, Jul 31, 2023 at 06:48:12PM +0800, Michael Shavit wrote:
>
> > arm_smmu_ctx_desc_cfg is renamed to arm_smmu_cdtab_cfg to make it more
>
> There seems to be no change of renaming "arm_smmu_ctx_desc_cfg" to
> "arm_smmu_cdtab_cfg". Even PATCH-8 only renames the local variable
> "cdcfg" to "cd_table". Also, we should not use PATCH-8 to justify
> this change, because it makes this patch less convincing since the
> PATCH-8 might not get applied at all.
Oof sorry for the mixup. I made the change described in the changelog
but then undid it based on the last few messages of the last thread.
This commit is identical to the v1 change where cdcfg is only renamed
to cd_table in places that we touch.
Will fix the message.
>
> > obvious that it represents a cd table. The max number of CDs that can be
> > represented by the CD table is stored in this truct in its log2 form
> > since it is more useful for users of the CD table, and replaces the
> > s1cdmax field in s1_cfg. Instead of storing s1_cfg.s1fmt, it can also be
> > trivially computed from the cdtab_cfg, and is therefore removed from
> > s1_cfg.
>
> The commit message does not quite well describe why "replace s1_cfg
> with cd_table" in the subject. It could mention that the goal here
> is to move cdtab to the master structure. And "unwrap s1_cfg" might
> be more fitting in the subject, IMHO.
>
> Thanks
> Nicolin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table
2023-08-01 4:52 ` Nicolin Chen
@ 2023-08-01 8:09 ` Michael Shavit
2023-08-01 13:31 ` Jason Gunthorpe
0 siblings, 1 reply; 24+ messages in thread
From: Michael Shavit @ 2023-08-01 8:09 UTC (permalink / raw)
To: Nicolin Chen
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy, jgg,
jean-philippe
> On Mon, Jul 31, 2023 at 09:28:40PM -0700, Nicolin Chen wrote:
> > This cd_table->stall_enabled comes from master->stall_enabled, and
> > cd_table will be in master structure. Also, struct arm_smmu_master
> > pointer will be passed in to arm_smmu_write_ctx_desc(). So, there
> > seems to be no need of master->cd_table.stall_enabled in the end;
> > just use master->stall_enabled directly?
Yes it's correct that this change isn't strictly necessary. Thoughts jgg@ ?
On Tue, Aug 1, 2023 at 12:52 PM Nicolin Chen <nicolinc@nvidia.com> wrote:
> Actually the stall_enabled might still need to be per-CD/domain.
> If a domain is attached by two masters. The domain->stall_enabled
> is initialized with the first master->stall_enabled. Then, the
> second master->stall_enabled would be required to match with the
> domain->stall_enabled. arm_smmu_attach_dev() has such a sanity.
>
> So, I think we might not need this patch.
But why force domains attached to different masters to have the same
stall_enabled setting? Whether stall is enabled is strictly a property
of the master, not the domain. IMO the fact that it was stored in
domain and checked in attach_dev was only because the previous design
required it, not because it's more appropriate.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table
2023-08-01 8:09 ` Michael Shavit
@ 2023-08-01 13:31 ` Jason Gunthorpe
0 siblings, 0 replies; 24+ messages in thread
From: Jason Gunthorpe @ 2023-08-01 13:31 UTC (permalink / raw)
To: Michael Shavit
Cc: Nicolin Chen, iommu, linux-arm-kernel, linux-kernel, will,
robin.murphy, jean-philippe
On Tue, Aug 01, 2023 at 04:09:52PM +0800, Michael Shavit wrote:
> > On Mon, Jul 31, 2023 at 09:28:40PM -0700, Nicolin Chen wrote:
> > > This cd_table->stall_enabled comes from master->stall_enabled, and
> > > cd_table will be in master structure. Also, struct arm_smmu_master
> > > pointer will be passed in to arm_smmu_write_ctx_desc(). So, there
> > > seems to be no need of master->cd_table.stall_enabled in the end;
> > > just use master->stall_enabled directly?
>
> Yes it's correct that this change isn't strictly necessary. Thoughts jgg@ ?
I don't have a strong feeling here
The stall bits in the STE/CDTE should be set only for masters that
operate in stall mode.
I would hope a a single domain should be mixable between stall and PRI
masters?
If the cd_table is 1:1 with a master then keeping it in the master is
logical enough. If we ever imagine a CD table with multiple masters
then we'd need to have a bit in the cd_table too.
> On Tue, Aug 1, 2023 at 12:52 PM Nicolin Chen <nicolinc@nvidia.com> wrote:
> > Actually the stall_enabled might still need to be per-CD/domain.
> > If a domain is attached by two masters. The domain->stall_enabled
> > is initialized with the first master->stall_enabled. Then, the
> > second master->stall_enabled would be required to match with the
> > domain->stall_enabled. arm_smmu_attach_dev() has such a sanity.
> >
> > So, I think we might not need this patch.
>
> But why force domains attached to different masters to have the same
> stall_enabled setting? Whether stall is enabled is strictly a property
> of the master, not the domain. IMO the fact that it was stored in
> domain and checked in attach_dev was only because the previous design
> required it, not because it's more appropriate.
Yes, definately remove stall from the domains, the faulting flow
should learn the faulting mode based on the master that triggered the
fault, not the domain that received it.
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 2/8] iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg
2023-07-31 10:48 ` [PATCH v2 2/8] iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg Michael Shavit
2023-08-01 4:14 ` Nicolin Chen
@ 2023-08-01 13:43 ` Jason Gunthorpe
1 sibling, 0 replies; 24+ messages in thread
From: Jason Gunthorpe @ 2023-08-01 13:43 UTC (permalink / raw)
To: Michael Shavit
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy,
nicolinc, jean-philippe
On Mon, Jul 31, 2023 at 06:48:12PM +0800, Michael Shavit wrote:
> arm_smmu_ctx_desc_cfg is renamed to arm_smmu_cdtab_cfg to make it more
> obvious that it represents a cd table. The max number of CDs that can be
> represented by the CD table is stored in this truct in its log2 form
> since it is more useful for users of the CD table, and replaces the
> s1cdmax field in s1_cfg. Instead of storing s1_cfg.s1fmt, it can also be
> trivially computed from the cdtab_cfg, and is therefore removed from
> s1_cfg.
To Nicolin's suggestion, how about
Remove struct arm_smmu_s1_cfg. This is really just a CD table with a
bit of extra information. Enhance the existing CD table structure,
struct arm_smmu_ctx_desc_cfg, with max_cds_bits and replace all usage
of arm_smmu_s1_cfg with arm_smmu_ctx_desc_cfg.
Compute the other values that were stored in s1cfg directly from
existing arm_smmu_ctx_desc_cfg.
For clarity the name "cd_table" for the variables pointing to
arm_smmu_ctx_desc_cfg in the new code. A later patch will make this
fully consistent.
> @@ -2082,11 +2083,11 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
>
> /* Free the CD and ASID, if we allocated them */
> if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
> - struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
> + struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
Use cd_table here
> /* Prevent SVA from touching the CD while we're freeing it */
> mutex_lock(&arm_smmu_asid_lock);
> - if (cfg->cdcfg.cdtab)
> + if (cdcfg->cdtab)
> arm_smmu_free_cd_tables(smmu_domain);
> arm_smmu_free_asid(&smmu_domain->cd);
> mutex_unlock(&arm_smmu_asid_lock);
> @@ -2106,7 +2107,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
> int ret;
> u32 asid;
> struct arm_smmu_device *smmu = smmu_domain->smmu;
> - struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
> + struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->cd_table;
And here
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 1/8] iommu/arm-smmu-v3: Move ctx_desc out of s1_cfg
2023-07-31 10:48 ` [PATCH v2 1/8] iommu/arm-smmu-v3: Move ctx_desc out of s1_cfg Michael Shavit
@ 2023-08-01 14:08 ` Jason Gunthorpe
0 siblings, 0 replies; 24+ messages in thread
From: Jason Gunthorpe @ 2023-08-01 14:08 UTC (permalink / raw)
To: Michael Shavit
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy,
nicolinc, jean-philippe
On Mon, Jul 31, 2023 at 06:48:11PM +0800, Michael Shavit wrote:
> s1_cfg describes the CD table that is inserted into an SMMU's STEs. It's
> weird for s1_cfg to also own ctx_desc which describes a CD that is
> inserted into that table. It is more appropriate for arm_smmu_domain to
> own ctx_desc.
>
> Signed-off-by: Michael Shavit <mshavit@google.com>
> ---
> Changes in v2:
> - Undo over-reaching column alignment change
>
> .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 2 +-
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 23 ++++++++++---------
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 6 +++--
> 3 files changed, 17 insertions(+), 14 deletions(-)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 3/8] iommu/arm-smmu-v3: Encapsulate ctx_desc_cfg init in alloc_cd_tables
2023-07-31 10:48 ` [PATCH v2 3/8] iommu/arm-smmu-v3: Encapsulate ctx_desc_cfg init in alloc_cd_tables Michael Shavit
@ 2023-08-01 14:09 ` Jason Gunthorpe
0 siblings, 0 replies; 24+ messages in thread
From: Jason Gunthorpe @ 2023-08-01 14:09 UTC (permalink / raw)
To: Michael Shavit
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy,
nicolinc, jean-philippe
On Mon, Jul 31, 2023 at 06:48:13PM +0800, Michael Shavit wrote:
> This is slighlty cleaner: arm_smmu_ctx_desc_cfg is initialized in a
> single function instead of having pieces set ahead-of time by its caller.
>
> Signed-off-by: Michael Shavit <mshavit@google.com>
> ---
>
> (no changes since v1)
>
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 9 ++++-----
> 1 file changed, 4 insertions(+), 5 deletions(-)
Yeah, this is the right direction, make a self-contained API around
'struct arm_smmu_ctx_desc_cfg'
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table
2023-07-31 10:48 ` [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table Michael Shavit
2023-08-01 4:28 ` Nicolin Chen
@ 2023-08-01 14:12 ` Jason Gunthorpe
1 sibling, 0 replies; 24+ messages in thread
From: Jason Gunthorpe @ 2023-08-01 14:12 UTC (permalink / raw)
To: Michael Shavit
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy,
nicolinc, jean-philippe
On Mon, Jul 31, 2023 at 06:48:14PM +0800, Michael Shavit wrote:
> This controls whether CD entries will have the stall bit set when
> writing entries into the table.
>
> Signed-off-by: Michael Shavit <mshavit@google.com>
> ---
>
> Changes in v2:
> - Use a bitfield instead of a bool for stall_enabled
>
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 ++++----
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 3 ++-
> 2 files changed, 6 insertions(+), 5 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 8a286e3838d70..654acf6002bf3 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1114,7 +1114,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
> FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid) |
> CTXDESC_CD_0_V;
>
> - if (smmu_domain->stall_enabled)
> + if (smmu_domain->cd_table.stall_enabled)
> val |= CTXDESC_CD_0_S;
> }
Since patch 6 makes arm_smmu_write_ctx_desc() take in the master
parameter, it does make sense to just refer to the stall in the master
at this point. Can you defer this until after patch 6?
> 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 35a93e8858872..05b1f0ee60808 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -597,6 +597,8 @@ struct arm_smmu_ctx_desc_cfg {
> unsigned int num_l1_ents;
> /* log2 of the maximum number of CDs supported by this table */
> u8 max_cds_bits;
> + /* Whether CD entries in this table have the stall bit set. */
> + u8 stall_enabled:1;
> };
>
> struct arm_smmu_s2_cfg {
> @@ -714,7 +716,6 @@ struct arm_smmu_domain {
> struct mutex init_mutex; /* Protects smmu pointer */
>
> struct io_pgtable_ops *pgtbl_ops;
> - bool stall_enabled;
> atomic_t nr_ats_masters;
>
> enum arm_smmu_domain_stage stage;
But this also makes sense, and removing stall_enabled from the domain
is important, so
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
If you keep it this way
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 5/8] iommu/arm-smmu-v3: Skip cd sync if CD table isn't active
2023-07-31 10:48 ` [PATCH v2 5/8] iommu/arm-smmu-v3: Skip cd sync if CD table isn't active Michael Shavit
@ 2023-08-01 14:13 ` Jason Gunthorpe
0 siblings, 0 replies; 24+ messages in thread
From: Jason Gunthorpe @ 2023-08-01 14:13 UTC (permalink / raw)
To: Michael Shavit
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy,
nicolinc, jean-philippe
On Mon, Jul 31, 2023 at 06:48:15PM +0800, Michael Shavit wrote:
> This commit explicitly keeps track of whether a CD table is installed in
> an STE so that arm_smmu_sync_cd can skip the sync when unnecessary. This
> was previously achieved through the domain->devices list, but we are
> moving to a model where arm_smmu_sync_cd directly operates on a master
> and the master's CD table instead of a domain.
>
> Signed-off-by: Michael Shavit <mshavit@google.com>
> ---
>
> Changes in v2:
> - Store field as a bit instead of a bool. Fix comment about STE being
> live before the sync in write_ctx_desc().
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 6/8] iommu/arm-smmu-v3: Refactor write_ctx_desc
2023-07-31 10:48 ` [PATCH v2 6/8] iommu/arm-smmu-v3: Refactor write_ctx_desc Michael Shavit
@ 2023-08-01 14:18 ` Jason Gunthorpe
2023-08-01 17:03 ` Michael Shavit
0 siblings, 1 reply; 24+ messages in thread
From: Jason Gunthorpe @ 2023-08-01 14:18 UTC (permalink / raw)
To: Michael Shavit
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy,
nicolinc, jean-philippe
On Mon, Jul 31, 2023 at 06:48:16PM +0800, Michael Shavit wrote:
> Update arm_smmu_write_ctx_desc and downstream functions to operate on
> a master instead of an smmu domain. We expect arm_smmu_write_ctx_desc()
> to only be called to write a CD entry into a CD table owned by the
> master. Under the hood, arm_smmu_write_ctx_desc still fetches the CD
> table from the domain that is attached to the master, but a subsequent
> commit will move that table's ownership to the master.
>
> Note that this change isn't a nop refactor since SVA will call
> arm_smmu_write_ctx_desc in a loop for every master the domain is
> attached to despite the fact that they all share the same CD table. This
> loop may look weird but becomes necessary when the CD table becomes
> per-master in a subsequent commit.
>
> Signed-off-by: Michael Shavit <mshavit@google.com>
> ---
>
> Changes in v2:
> - minor style fixes
>
> Changes in v1:
> - arm_smmu_write_ctx_desc now get's the CD table to write to from the
> master parameter instead of a distinct parameter. This works well
> because the CD table being written to should always be owned by the
> master by the end of this series. This version no longer allows master
> to be NULL.
>
> .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 33 +++++++++--
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 59 ++++++++-----------
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 2 +-
> 3 files changed, 53 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> index 968559d625c40..8242ee3405f2d 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> @@ -45,9 +45,11 @@ static struct arm_smmu_ctx_desc *
> arm_smmu_share_asid(struct mm_struct *mm, u16 asid)
> {
> int ret;
> + unsigned long flags;
> u32 new_asid;
> struct arm_smmu_ctx_desc *cd;
> struct arm_smmu_device *smmu;
> + struct arm_smmu_master *master;
> struct arm_smmu_domain *smmu_domain;
>
> cd = xa_load(&arm_smmu_asid_xa, asid);
> @@ -80,7 +82,11 @@ arm_smmu_share_asid(struct mm_struct *mm, u16 asid)
> * be some overlap between use of both ASIDs, until we invalidate the
> * TLB.
> */
> - arm_smmu_write_ctx_desc(smmu_domain, 0, cd);
> + spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> + list_for_each_entry(master, &smmu_domain->devices, domain_head) {
> + arm_smmu_write_ctx_desc(master, 0, cd);
> + }
I think it is typical kernel style to not include the single statement
{}
> + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
>
> /* Invalidate TLB entries previously associated with that context */
> arm_smmu_tlb_inv_asid(smmu, asid);
> @@ -211,6 +217,8 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
> {
> struct arm_smmu_mmu_notifier *smmu_mn = mn_to_smmu(mn);
> struct arm_smmu_domain *smmu_domain = smmu_mn->domain;
> + struct arm_smmu_master *master;
> + unsigned long flags;
>
> mutex_lock(&sva_lock);
> if (smmu_mn->cleared) {
> @@ -222,7 +230,11 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
> * DMA may still be running. Keep the cd valid to avoid C_BAD_CD events,
> * but disable translation.
> */
> - arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, &quiet_cd);
> + spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> + list_for_each_entry(master, &smmu_domain->devices, domain_head) {
> + arm_smmu_write_ctx_desc(master, mm->pasid, &quiet_cd);
> + }
> + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
And here
> arm_smmu_tlb_inv_asid(smmu_domain->smmu, smmu_mn->cd->asid);
> arm_smmu_atc_inv_domain(smmu_domain, mm->pasid, 0, 0);
> @@ -248,7 +260,9 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
> struct mm_struct *mm)
> {
> int ret;
> + unsigned long flags;
> struct arm_smmu_ctx_desc *cd;
> + struct arm_smmu_master *master;
> struct arm_smmu_mmu_notifier *smmu_mn;
>
> list_for_each_entry(smmu_mn, &smmu_domain->mmu_notifiers, list) {
> @@ -279,7 +293,11 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
> goto err_free_cd;
> }
>
> - ret = arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, cd);
> + spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> + list_for_each_entry(master, &smmu_domain->devices, domain_head) {
> + ret = arm_smmu_write_ctx_desc(master, mm->pasid, cd);
> + }
> + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
And here..
> if (ret)
> goto err_put_notifier;
>
> @@ -296,6 +314,8 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
>
> static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
> {
> + unsigned long flags;
> + struct arm_smmu_master *master;
> struct mm_struct *mm = smmu_mn->mn.mm;
> struct arm_smmu_ctx_desc *cd = smmu_mn->cd;
> struct arm_smmu_domain *smmu_domain = smmu_mn->domain;
> @@ -304,7 +324,12 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
> return;
>
> list_del(&smmu_mn->list);
> - arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, NULL);
> +
> + spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> + list_for_each_entry(master, &smmu_domain->devices, domain_head) {
> + arm_smmu_write_ctx_desc(master, mm->pasid, NULL);
> + }
> + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
And here..
You know, you should try to keep the function instead of duplicating
these
arm_smmu_write_ctx_desc_devices()
And put the four lines in there?
> @@ -987,19 +985,14 @@ static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
> },
> };
>
> - if (!smmu_domain->cd_table.installed)
> + if (!master->domain->cd_table.installed)
> return;
BTW, do you have locking for this? I didn't check carefully
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 7/8] iommu/arm-smmu-v3: Move CD table to arm_smmu_master
2023-07-31 10:48 ` [PATCH v2 7/8] iommu/arm-smmu-v3: Move CD table to arm_smmu_master Michael Shavit
@ 2023-08-01 14:42 ` Jason Gunthorpe
0 siblings, 0 replies; 24+ messages in thread
From: Jason Gunthorpe @ 2023-08-01 14:42 UTC (permalink / raw)
To: Michael Shavit
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy,
nicolinc, jean-philippe
On Mon, Jul 31, 2023 at 06:48:17PM +0800, Michael Shavit wrote:
> With this change, each master will now own its own CD table instead of
> sharing one with other masters attached to the same domain. Attaching a
> stage 1 domain installs CD entries into the master's CD table. SVA
> writes its CD entries into each master's CD table if the domain is
> shared across masters.
>
> Signed-off-by: Michael Shavit <mshavit@google.com>
> ---
>
> Changes in v2:
> - Allocate CD table when it's first needed instead of on probe.
>
> Changes in v1:
> - The master's CD table allocation was previously split to a different
> commit. This change now atomically allocates the new CD table, uses
> it, and removes the old one.
>
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 67 +++++++++------------
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 6 +-
> 2 files changed, 32 insertions(+), 41 deletions(-)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 8/8] iommu/arm-smmu-v3: Rename cdcfg to cd_table
2023-07-31 10:48 ` [PATCH v2 8/8] iommu/arm-smmu-v3: Rename cdcfg to cd_table Michael Shavit
@ 2023-08-01 14:44 ` Jason Gunthorpe
0 siblings, 0 replies; 24+ messages in thread
From: Jason Gunthorpe @ 2023-08-01 14:44 UTC (permalink / raw)
To: Michael Shavit
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy,
nicolinc, jean-philippe
On Mon, Jul 31, 2023 at 06:48:18PM +0800, Michael Shavit wrote:
> since cdcfg sounds like it represents a CD entry when it's in fact a CD
> table.
>
> Signed-off-by: Michael Shavit <mshavit@google.com>
> ---
>
> Changes in v2:
> - New commit
>
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 66 ++++++++++-----------
> 1 file changed, 33 insertions(+), 33 deletions(-)
I think more generally it is confusing what 'cfg' means in the context
of this driver.
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 6/8] iommu/arm-smmu-v3: Refactor write_ctx_desc
2023-08-01 14:18 ` Jason Gunthorpe
@ 2023-08-01 17:03 ` Michael Shavit
0 siblings, 0 replies; 24+ messages in thread
From: Michael Shavit @ 2023-08-01 17:03 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: iommu, linux-arm-kernel, linux-kernel, will, robin.murphy,
nicolinc, jean-philippe
On Tue, Aug 1, 2023 at 10:18 PM Jason Gunthorpe <jgg@nvidia.com> wrote:
> You know, you should try to keep the function instead of duplicating
> these
>
> arm_smmu_write_ctx_desc_devices()
>
> And put the four lines in there?
Urhhh yes, I thought I had a reason for this but probably just a lapse
of judgement. Done.
> - ret = arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, cd);
> + spin_lock_irqsave(&smmu_domain->devices_lock, flags);
> + list_for_each_entry(master, &smmu_domain->devices, domain_head) {
> + ret = arm_smmu_write_ctx_desc(master, mm->pasid, cd);
> + }
> + spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
Just noticed that this is problematic; we may not notice a failure if
it occurs on an earlier iteration of the loop. Will fix.
>
> > @@ -987,19 +985,14 @@ static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
> > },
> > };
> >
> > - if (!smmu_domain->cd_table.installed)
> > + if (!master->domain->cd_table.installed)
> > return;
>
> BTW, do you have locking for this? I didn't check carefully
This is one of the reasons I wanted to take this as a parameter to the
function. This relies on callers guaranteeing that the cd table not be
attached/detached while this call is in progress. This works now
because:
1. No domain may be attached/detached while SVA is enabled, which is
most of the calls that lead to arm_smmu_sync_cd
2. The other call to arm_smmu_write_ctx_desc in arm-smmu-v3.c is more
obviously serialized with operations that detach/attach the cd table.
Maybe this should at least be a comment on arm_smmu_write_ctx_desc, if
not a lock?
Speaking of.... I should probably flip this bit to false in patch 5
when the cd table is detached.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2023-08-01 17:04 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-31 10:48 [PATCH v2 0/8] Refactor the SMMU's CD table ownership Michael Shavit
2023-07-31 10:48 ` [PATCH v2 1/8] iommu/arm-smmu-v3: Move ctx_desc out of s1_cfg Michael Shavit
2023-08-01 14:08 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 2/8] iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg Michael Shavit
2023-08-01 4:14 ` Nicolin Chen
2023-08-01 8:00 ` Michael Shavit
2023-08-01 13:43 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 3/8] iommu/arm-smmu-v3: Encapsulate ctx_desc_cfg init in alloc_cd_tables Michael Shavit
2023-08-01 14:09 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 4/8] iommu/arm-smmu-v3: move stall_enabled to the cd table Michael Shavit
2023-08-01 4:28 ` Nicolin Chen
2023-08-01 4:52 ` Nicolin Chen
2023-08-01 8:09 ` Michael Shavit
2023-08-01 13:31 ` Jason Gunthorpe
2023-08-01 14:12 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 5/8] iommu/arm-smmu-v3: Skip cd sync if CD table isn't active Michael Shavit
2023-08-01 14:13 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 6/8] iommu/arm-smmu-v3: Refactor write_ctx_desc Michael Shavit
2023-08-01 14:18 ` Jason Gunthorpe
2023-08-01 17:03 ` Michael Shavit
2023-07-31 10:48 ` [PATCH v2 7/8] iommu/arm-smmu-v3: Move CD table to arm_smmu_master Michael Shavit
2023-08-01 14:42 ` Jason Gunthorpe
2023-07-31 10:48 ` [PATCH v2 8/8] iommu/arm-smmu-v3: Rename cdcfg to cd_table Michael Shavit
2023-08-01 14:44 ` Jason Gunthorpe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).