mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Peng Fan (OSS)" <peng.fan@oss.nxp.com>
To: Will Deacon <will@kernel.org>,
	Robin Murphy <robin.murphy@arm.com>,
	 Jason Gunthorpe <jgg@ziepe.ca>,
	Nicolin Chen <nicolinc@nvidia.com>,
	 "Joerg Roedel (AMD)" <joro@8bytes.org>,
	 Thierry Reding <thierry.reding@kernel.org>,
	 Krishna Reddy <vdumpa@nvidia.com>,
	Jonathan Hunter <jonathanh@nvidia.com>,
	 Jean-Philippe Brucker <jpb@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org, iommu@lists.linux.dev,
	 linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org,
	 Peng Fan <peng.fan@nxp.com>
Subject: [PATCH RFC v7 3/7] iommu/arm-smmu-v3: Plumb the CD table into the CD helpers
Date: Fri, 30 Oct 2026 20:09:35 +0800	[thread overview]
Message-ID: <20261030-smmu-shared-sid-ver7-2026-10-26-v7-3-961726ebd6ab@Example.Com> (raw)
In-Reply-To: <20261030-smmu-shared-sid-ver7-2026-10-26-v7-0-961726ebd6ab@Example.Com>

From: Peng Fan <peng.fan@nxp.com>

Refactor the CD table allocation, freeing, lookup and STE-building helpers
to take a struct arm_smmu_ctx_desc_cfg pointer instead of always deriving
it from struct arm_smmu_master. Add master wrappers so existing callers
keep the same behaviour.

Prepare for domain-owned CD tables, where non-PASID streams will point
their STE at a CD table stored in the IOMMU domain rather than in the
master.

No functional change.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c |  3 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c      | 63 +++++++++++++++---------
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h      |  5 +-
 3 files changed, 46 insertions(+), 25 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c
index 5a4e45e151258..864d9f2350bc1 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c
@@ -215,7 +215,8 @@ static void arm_smmu_test_make_cdtable_ste(struct arm_smmu_ste *ste,
 		.stall_enabled = stall_enabled,
 	};
 
-	arm_smmu_make_cdtable_ste(ste, &master, ats_enabled, s1dss);
+	arm_smmu_make_cdtable_ste(ste, &master, &master.cd_table, ats_enabled,
+				  s1dss);
 	if (feat & ARM_SMMU_MASTER_TEST_NESTED) {
 		struct arm_smmu_ste s2ste;
 		int i;
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 0ea755ea82192..51de3a0b8e76b 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -122,7 +122,7 @@ static const char * const event_class_str[] = {
 	[3] = "Reserved",
 };
 
-static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master);
+static int arm_smmu_alloc_master_cd_tables(struct arm_smmu_master *master);
 static bool arm_smmu_ats_supported(struct arm_smmu_master *master);
 
 static void parse_driver_options(struct arm_smmu_device *smmu)
@@ -1545,11 +1545,10 @@ static dma_addr_t arm_smmu_cd_l1_get_desc(const struct arm_smmu_cdtab_l1 *src)
 	return le64_to_cpu(src->l2ptr) & CTXDESC_L1_DESC_L2PTR_MASK;
 }
 
-struct arm_smmu_cd *arm_smmu_get_cd_ptr(struct arm_smmu_master *master,
-					u32 ssid)
+static struct arm_smmu_cd *
+arm_smmu_get_cd_ptr_in(struct arm_smmu_ctx_desc_cfg *cd_table, u32 ssid)
 {
 	struct arm_smmu_cdtab_l2 *l2;
-	struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
 
 	if (!arm_smmu_cdtab_allocated(cd_table))
 		return NULL;
@@ -1563,6 +1562,12 @@ struct arm_smmu_cd *arm_smmu_get_cd_ptr(struct arm_smmu_master *master,
 	return &l2->cds[arm_smmu_cdtab_l2_idx(ssid)];
 }
 
+struct arm_smmu_cd *arm_smmu_get_cd_ptr(struct arm_smmu_master *master,
+					u32 ssid)
+{
+	return arm_smmu_get_cd_ptr_in(&master->cd_table, ssid);
+}
+
 static struct arm_smmu_cd *arm_smmu_alloc_cd_ptr(struct arm_smmu_master *master,
 						 u32 ssid)
 {
@@ -1573,7 +1578,7 @@ static struct arm_smmu_cd *arm_smmu_alloc_cd_ptr(struct arm_smmu_master *master,
 	iommu_group_mutex_assert(master->dev);
 
 	if (!arm_smmu_cdtab_allocated(cd_table)) {
-		if (arm_smmu_alloc_cd_tables(master))
+		if (arm_smmu_alloc_master_cd_tables(master))
 			return NULL;
 	}
 
@@ -1595,7 +1600,7 @@ static struct arm_smmu_cd *arm_smmu_alloc_cd_ptr(struct arm_smmu_master *master,
 			arm_smmu_sync_cd(master, ssid, false);
 		}
 	}
-	return arm_smmu_get_cd_ptr(master, ssid);
+	return arm_smmu_get_cd_ptr_in(cd_table, ssid);
 }
 
 struct arm_smmu_cd_writer {
@@ -1721,15 +1726,15 @@ void arm_smmu_clear_cd(struct arm_smmu_master *master, ioasid_t ssid)
 	arm_smmu_write_cd_entry(master, ssid, cdptr, &target);
 }
 
-static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master)
+static int arm_smmu_alloc_cd_tables(struct arm_smmu_device *smmu,
+				    struct arm_smmu_ctx_desc_cfg *cd_table,
+				    u8 ssid_bits, bool ats_always_on)
 {
 	int ret;
 	size_t l1size;
 	size_t max_contexts;
-	struct arm_smmu_device *smmu = master->smmu;
-	struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
 
-	cd_table->s1cdmax = master->ssid_bits;
+	cd_table->s1cdmax = ssid_bits;
 
 	/*
 	 * When a device doesn't support PASID (non default SSID), ssid_bits is
@@ -1744,7 +1749,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master)
 	 * Set S1CDMAX no lower than 1. This would add a dummy substream in the
 	 * CD table but it should never be used by an actual CD.
 	 */
-	if (master->ats_always_on)
+	if (ats_always_on)
 		cd_table->s1cdmax = max_t(u8, cd_table->s1cdmax, 1);
 	max_contexts = 1 << cd_table->s1cdmax;
 
@@ -1786,11 +1791,17 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master)
 	return ret;
 }
 
-static void arm_smmu_free_cd_tables(struct arm_smmu_master *master)
+static int arm_smmu_alloc_master_cd_tables(struct arm_smmu_master *master)
+{
+	return arm_smmu_alloc_cd_tables(master->smmu, &master->cd_table,
+					master->ssid_bits,
+					master->ats_always_on);
+}
+
+static void arm_smmu_free_cd_tables(struct arm_smmu_device *smmu,
+				    struct arm_smmu_ctx_desc_cfg *cd_table)
 {
 	int i;
-	struct arm_smmu_device *smmu = master->smmu;
-	struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
 
 	if (cd_table->s1fmt != STRTAB_STE_0_S1FMT_LINEAR) {
 		for (i = 0; i < cd_table->l2.num_l1_ents; i++) {
@@ -1816,6 +1827,11 @@ static void arm_smmu_free_cd_tables(struct arm_smmu_master *master)
 	}
 }
 
+static void arm_smmu_free_master_cd_tables(struct arm_smmu_master *master)
+{
+	arm_smmu_free_cd_tables(master->smmu, &master->cd_table);
+}
+
 /* Stream table manipulation functions */
 static void arm_smmu_write_strtab_l1_desc(struct arm_smmu_strtab_l1 *dst,
 					  dma_addr_t l2ptr_dma)
@@ -1900,10 +1916,10 @@ EXPORT_SYMBOL_IF_KUNIT(arm_smmu_make_bypass_ste);
 
 VISIBLE_IF_KUNIT
 void arm_smmu_make_cdtable_ste(struct arm_smmu_ste *target,
-			       struct arm_smmu_master *master, bool ats_enabled,
-			       unsigned int s1dss)
+			       struct arm_smmu_master *master,
+			       struct arm_smmu_ctx_desc_cfg *cd_table,
+			       bool ats_enabled, unsigned int s1dss)
 {
-	struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
 	struct arm_smmu_device *smmu = master->smmu;
 
 	memset(target, 0, sizeof(*target));
@@ -3865,7 +3881,8 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev,
 		arm_smmu_make_s1_cd(&target_cd, master, smmu_domain);
 		arm_smmu_write_cd_entry(master, IOMMU_NO_PASID, cdptr,
 					&target_cd);
-		arm_smmu_make_cdtable_ste(&target, master, state.ats_enabled,
+		arm_smmu_make_cdtable_ste(&target, master, &master->cd_table,
+					  state.ats_enabled,
 					  STRTAB_STE_1_S1DSS_SSID0);
 		arm_smmu_install_ste_for_dev(master, &target);
 		break;
@@ -3932,7 +3949,8 @@ static void arm_smmu_update_ste(struct arm_smmu_master *master,
 	 * the S1DSS is correct and this will just update the EATS. Otherwise it
 	 * installs the entire thing. This will be hitless.
 	 */
-	arm_smmu_make_cdtable_ste(&ste, master, ats_enabled, s1dss);
+	arm_smmu_make_cdtable_ste(&ste, master, &master->cd_table, ats_enabled,
+				  s1dss);
 	arm_smmu_install_ste_for_dev(master, &ste);
 }
 
@@ -4065,7 +4083,8 @@ static void arm_smmu_attach_dev_ste(struct iommu_domain *domain,
 		 */
 		state.cd_needs_ats = true;
 		arm_smmu_attach_prepare(&state, domain);
-		arm_smmu_make_cdtable_ste(ste, master, state.ats_enabled, s1dss);
+		arm_smmu_make_cdtable_ste(ste, master, &master->cd_table,
+					  state.ats_enabled, s1dss);
 	} else {
 		arm_smmu_attach_prepare(&state, domain);
 	}
@@ -4436,7 +4455,7 @@ static int arm_smmu_master_prepare_ats(struct arm_smmu_master *master)
 
 	master->ats_always_on = true;
 
-	return arm_smmu_alloc_cd_tables(master);
+	return arm_smmu_alloc_master_cd_tables(master);
 }
 
 static struct iommu_device *arm_smmu_probe_device(struct device *dev)
@@ -4510,7 +4529,7 @@ static void arm_smmu_release_device(struct device *dev)
 	arm_smmu_disable_pasid(master);
 	arm_smmu_remove_master(master);
 	if (arm_smmu_cdtab_allocated(&master->cd_table))
-		arm_smmu_free_cd_tables(master);
+		arm_smmu_free_master_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 56ed6ad1dd523..0256119e9c137 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -1143,8 +1143,9 @@ void arm_smmu_get_cd_used(const __le64 *ent, __le64 *used_bits);
 void arm_smmu_make_bypass_ste(struct arm_smmu_device *smmu,
 			      struct arm_smmu_ste *target);
 void arm_smmu_make_cdtable_ste(struct arm_smmu_ste *target,
-			       struct arm_smmu_master *master, bool ats_enabled,
-			       unsigned int s1dss);
+			       struct arm_smmu_master *master,
+			       struct arm_smmu_ctx_desc_cfg *cd_table,
+			       bool ats_enabled, unsigned int s1dss);
 void arm_smmu_make_sva_cd(struct arm_smmu_cd *target,
 			  struct arm_smmu_master *master, struct mm_struct *mm,
 			  u16 asid);

-- 
2.34.1


  parent reply	other threads:[~2026-10-30 12:05 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-30 12:09 [PATCH RFC v7 0/7] iommu/arm-smmu-v3: Support shared Stream IDs Peng Fan (OSS)
2026-10-30 12:09 ` [PATCH RFC v7 1/7] iommu/arm-smmu-v3: Allocate streams individually Peng Fan (OSS)
2026-10-30 12:09 ` [PATCH RFC v7 2/7] iommu/arm-smmu-v3: Delay stream allocation to inside the mutex Peng Fan (OSS)
2026-10-30 12:09 ` Peng Fan (OSS) [this message]
2026-10-30 20:54   ` [PATCH RFC v7 3/7] iommu/arm-smmu-v3: Plumb the CD table into the CD helpers Nicolin Chen
2026-10-30 12:09 ` [PATCH RFC v7 4/7] iommu/arm-smmu-v3: Use a per-domain CD table for non-PASID streams Peng Fan (OSS)
2026-10-31  1:07   ` Nicolin Chen
2026-10-30 12:09 ` [PATCH RFC v7 5/7] iommu/arm-smmu-v3: Support shared SIDs in insert/remove_master Peng Fan (OSS)
2026-10-30 12:09 ` [PATCH RFC v7 6/7] iommu/arm-smmu-v3: Group aliasing devices into the same IOMMU group Peng Fan (OSS)
2026-10-30 12:09 ` [PATCH RFC v7 7/7] iommu/arm-smmu-v3: Wire up shared-SID STE ordering and feature gating Peng Fan (OSS)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261030-smmu-shared-sid-ver7-2026-10-26-v7-3-961726ebd6ab@Example.Com \
    --to=peng.fan@oss.nxp.com \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=jonathanh@nvidia.com \
    --cc=joro@8bytes.org \
    --cc=jpb@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=nicolinc@nvidia.com \
    --cc=peng.fan@nxp.com \
    --cc=robin.murphy@arm.com \
    --cc=thierry.reding@kernel.org \
    --cc=vdumpa@nvidia.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®