From: "Peng Fan (OSS)" <peng.fan@oss.nxp.com>
To: Will Deacon <will@kernel.org>,
Robin Murphy <robin.murphy@arm.com>,
"Joerg Roedel (AMD)" <joro@8bytes.org>,
Jean-Philippe Brucker <jpb@kernel.org>,
Nicolin Chen <nicolinc@nvidia.com>,
Jason Gunthorpe <jgg@ziepe.ca>,
Thierry Reding <thierry.reding@kernel.org>,
Krishna Reddy <vdumpa@nvidia.com>,
Jonathan Hunter <jonathanh@nvidia.com>,
Jason Gunthorpe <jgg@ziepe.ca>
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 v5 6/6] iommu/arm-smmu-v3: Wire up shared-SID STE ordering and feature gating
Date: Tue, 06 Oct 2026 20:19:12 +0800 [thread overview]
Message-ID: <20261006-smmu-shared-sid-v5-6-169a59c671d3@nxp.com> (raw)
In-Reply-To: <20261006-smmu-shared-sid-v5-0-169a59c671d3@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
For shared SIDs, only the first master to attach writes the STE
(tracked by ste_installed under streams_mutex); subsequent masters
skip the write. On teardown, skip the ABORT STE write while other
masters still share the SID.
Fault events on shared SIDs cannot be attributed to a specific
master, so arm_smmu_find_master() returns NULL when the stream's
shared_masters list is non-empty.
Disable SVA, IOPF/stall, and vSMMU nesting for shared-SID masters
since all three require unambiguous SID-to-device mapping. Clear
stall_enabled at probe time so the STE is not programmed with the
stall bit, which would cause unrecoverable bus lockups since
CMD_RESUME cannot be issued without a unique SID-to-device mapping.
Assisted-by: LLM
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 2 +-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 3 ++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 47 ++++++++++++++++++++--
3 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 0934a6bbd3e08..9f13154f832c1 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -309,7 +309,7 @@ static int arm_vsmmu_vdevice_init(struct iommufd_vdevice *vdev)
* arm_vsmmu_vsid_to_sid() maps a vSID to master->streams[0] alone, so
* more streams would leave the rest stale and none reads out of bounds.
*/
- if (master->num_streams != 1)
+ if (master->num_streams != 1 || !list_empty(&master->shared_masters_elm))
return -EOPNOTSUPP;
return 0;
}
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 0a429c64fbf3e..54a0a65669ac2 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
@@ -271,6 +271,9 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
if (!(master->smmu->features & ARM_SMMU_FEAT_SVA))
return -EOPNOTSUPP;
+ if (!list_empty(&master->shared_masters_elm))
+ return -EOPNOTSUPP;
+
/* Prevent arm_smmu_mm_release from being called while we are attaching */
if (!mmget_not_zero(domain->mm))
return -EINVAL;
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 c4cfe609ae93d..bf09c02538381 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2977,11 +2977,36 @@ arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
}
}
+static bool arm_smmu_is_shared_sid(struct arm_smmu_master *master)
+{
+ return !list_empty(&master->shared_masters_elm);
+}
+
+static bool arm_smmu_skip_shared_ste(struct arm_smmu_device *smmu,
+ u32 sid, bool is_abort)
+{
+ struct arm_smmu_stream *stream;
+
+ lockdep_assert_held(&smmu->streams_mutex);
+
+ stream = arm_smmu_find_stream(smmu, sid);
+ if (!stream || list_empty(&stream->shared_masters))
+ return false;
+
+ if (is_abort)
+ return true;
+ if (stream->ste_installed)
+ return true;
+ stream->ste_installed = true;
+ return false;
+}
+
void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master,
const struct arm_smmu_ste *target)
{
int i, j;
struct arm_smmu_device *smmu = master->smmu;
+ bool is_abort;
master->cd_table.in_ste =
FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(target->data[0])) ==
@@ -2990,10 +3015,12 @@ void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master,
FIELD_GET(STRTAB_STE_1_EATS, le64_to_cpu(target->data[1])) ==
STRTAB_STE_1_EATS_TRANS;
+ is_abort = FIELD_GET(STRTAB_STE_0_CFG, le64_to_cpu(target->data[0])) ==
+ STRTAB_STE_0_CFG_ABORT;
+
for (i = 0; i < master->num_streams; ++i) {
u32 sid = master->streams[i]->id;
- struct arm_smmu_ste *step =
- arm_smmu_get_step_for_sid(smmu, sid);
+ struct arm_smmu_ste *step;
/* Bridged PCI devices may end up with duplicated IDs */
for (j = 0; j < i; j++)
@@ -3002,6 +3029,16 @@ void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master,
if (j < i)
continue;
+ if (arm_smmu_is_shared_sid(master)) {
+ mutex_lock(&smmu->streams_mutex);
+ if (arm_smmu_skip_shared_ste(smmu, sid, is_abort)) {
+ mutex_unlock(&smmu->streams_mutex);
+ continue;
+ }
+ mutex_unlock(&smmu->streams_mutex);
+ }
+
+ step = arm_smmu_get_step_for_sid(smmu, sid);
arm_smmu_write_ste(master, sid, step, target);
}
}
@@ -3149,8 +3186,7 @@ static int arm_smmu_enable_iopf(struct arm_smmu_master *master,
if (!master->stall_enabled)
return 0;
- /* We're not keeping track of SIDs in fault events */
- if (master->num_streams != 1)
+ if (master->num_streams != 1 || arm_smmu_is_shared_sid(master))
return -EOPNOTSUPP;
if (master->iopf_refcount) {
@@ -4331,6 +4367,9 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
smmu->features & ARM_SMMU_FEAT_STALL_FORCE)
master->stall_enabled = true;
+ if (arm_smmu_is_shared_sid(master))
+ master->stall_enabled = false;
+
ret = arm_smmu_master_prepare_ats(master);
if (ret)
goto err_disable_pasid;
--
2.34.1
next prev parent reply other threads:[~2026-10-06 12:15 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-06 12:19 [PATCH RFC v5 0/6] iommu/arm-smmu-v3: Support shared Stream IDs Peng Fan (OSS)
2026-10-06 12:19 ` [PATCH RFC v5 1/6] iommu/arm-smmu-v3: Don't rb_erase() a never-inserted stream node Peng Fan (OSS)
2026-10-06 12:19 ` [PATCH RFC v5 2/6] iommu/arm-smmu-v3: Allocate streams individually Peng Fan (OSS)
2026-10-07 23:17 ` Nicolin Chen
2026-10-08 13:21 ` Robin Murphy
2026-10-08 17:32 ` Nicolin Chen
2026-10-06 12:19 ` [PATCH RFC v5 3/6] iommu/arm-smmu-v3: Delay stream allocation to inside the mutex Peng Fan (OSS)
2026-10-07 23:55 ` Nicolin Chen
2026-10-08 13:50 ` Peng Fan
2026-10-08 12:55 ` Robin Murphy
2026-10-08 13:49 ` Peng Fan
2026-10-06 12:19 ` [PATCH RFC v5 4/6] iommu/arm-smmu-v3: Support shared SIDs in insert/remove_master Peng Fan (OSS)
2026-10-08 1:02 ` Nicolin Chen
2026-10-08 14:07 ` Peng Fan
2026-10-06 12:19 ` [PATCH RFC v5 5/6] iommu/arm-smmu-v3: Group aliasing devices into the same IOMMU group Peng Fan (OSS)
2026-10-06 12:19 ` Peng Fan (OSS) [this message]
2026-10-08 1:29 ` [PATCH RFC v5 6/6] iommu/arm-smmu-v3: Wire up shared-SID STE ordering and feature gating Nicolin Chen
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=20261006-smmu-shared-sid-v5-6-169a59c671d3@nxp.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.