[PATCH RFC v6 5/5] iommu/arm-smmu-v3: Wire up shared-SID STE ordering and feature gating
Nicolin Chen
nicolinc at nvidia.com
Mon Oct 12 16:54:47 PDT 2026
On Mon, Oct 12, 2026 at 09:23:32PM +0800, Peng Fan wrote:
> >+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) {
> >+ stream->ste_installed = false;
> >+ return true;
> >+ }
> >+ if (stream->ste_installed)
> >+ return true;
> >+ stream->ste_installed = true;
> >+ return false;
>
> sashiko has comments: https://sashiko.dev/#/patchset/20261011-smmu-shared-sid-v6-0-cb76b89dc612%40nxp.com
>
> We just need to support a simple case that platform devices(single SID) which
> could share there SIDs, such as MMC-0 and MMC-1 share one SID.
>
> Shared-SID masters are restricted to platform devices sharing a single SID.
> SVA, IOPF, and vSMMU nesting are all rejected for shared-SID masters (patch 5),
> so VFIO passthrough and direct domain replacement scenarios do not apply.
> The only domain transitions are the default DMA domain attach at probe time
> and ABORT on unbind. Or I may miss something.
Domain can be switched between DMA and IDENTITY via sysfs.
I think there should be a way to support that. But, without a concrete
use case, it might be easier to add this into the attach_dev callbacks
(except arm_smmu_attach_dev_blocked):
if (arm_smmu_master_shares_sid(master) &&
old_domain && old_domain != domain &&
old_domain != &arm_smmu_blocked_domain)
return -EBUSY;
And Sashiko's second remark does reveal a real bug:
"Additionally, when devices are detached from a domain, is_abort is true.
arm_smmu_skip_shared_ste() clears ste_installed but unconditionally returns
true for all masters. Will this cause the ABORT STE to never be written to
hardware?"
Given that your use case always group SID-sharing masters in the same
iommu_group and attach/replace a domain on those masters together, I
think a simpler solution can be to always let stream->master install
the shared STE.
One pitfall would be the release domain's attach_dev, which would go
through arm_smmu_attach_dev_blocked() just like a blocked domain. So,
it has to skip correctly if the shared stream->master == master. This
means we might have to add a separate arm_smmu_attach_dev_release().
And I realized that there is another problem in your design: the CD
table is still allocated per master; see arm_smmu_alloc_cd_ptr(). If
STE is shared, its CD table must be shared too.
You'd need to redirect all the master->cd_table with something like:
static struct arm_smmu_master *arm_smmu_cd_owner(struct arm_smmu_master *master)
{
if (arm_smmu_master_shares_sid(master)) {
int i;
for (i = 0; i < master->num_streams; i++) {
struct arm_smmu_stream *stream = master->streams[i];
if (!list_empty(&stream->shared_masters))
return stream->master;
}
}
return master;
}
> >@@ -4360,9 +4391,11 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
> I am thinking to simplify reject if stall_enabled is true:
> if (list_empty(&stream->shared_masters)) {
> + if (stream->master->stall_enabled) {
> + dev_warn(master->dev,
> + "Shared StreamID 0x%x rejected: existing master has stall enabled\n",
> + sid);
> + ret = -EBUSY;
> + break;
> + }
I'd move it upwards: next to the existing "num_streams != 1" guard.
Nicolin
More information about the linux-arm-kernel
mailing list