From: Nicolin Chen <nicolinc@nvidia.com>
To: <will@kernel.org>, <robin.murphy@arm.com>, <jgg@nvidia.com>
Cc: <joro@8bytes.org>, <jpb@kernel.org>, <praan@google.com>,
<miko.lenczewski@arm.com>, <linux-arm-kernel@lists.infradead.org>,
<iommu@lists.linux.dev>, <linux-kernel@vger.kernel.org>,
<patches@lists.linux.dev>
Subject: [PATCH v1 0/9] iommu/arm-smmu-v3: Share domain across SMMU/vSMMU instances
Date: Thu, 18 Dec 2025 12:26:46 -0800 [thread overview]
Message-ID: <cover.1766088962.git.nicolinc@nvidia.com> (raw)
In a system with multiple physical SMMU instances, multiple devices can be
passed through to a VM. Currently, a VM would allocate one domain per SMMU
instance that might be shared across devices that sit behind the same SMMU
instance. However, the gPA->PA mappings (either an S1 unmanaged domain or
an S2 nesting parent domain) can be shared across all the devices that sit
behind different SMMU instances as well, provided that the shared I/O page
table is compatible with all the SMMU instances.
The major difficulty in sharing the domain has been invalidation, since a
change to the shared I/O page table results in an invalidation on all SMMU
instances. A traditional approach involves building a linked list of SMMUs
within the domain, which is very inefficient for the invalidation path as
the linked list has to be locked.
To address this, the SMMUv3 driver now uses an RCU-protected invalidation
array. Any new device (and its SMMU) is preloaded into the array during a
device attachment. This array maintains all necessary information, such as
ASID/VMID and which SMMU instance (CMDQ) to issue the command to.
The second issue concerns the lifecycle of the iotlb tag. Currently, ASID
or VMID is allocated per domain and kept in the domain structure (cd->asid
or s2_cfg->vmid). This does not work ideally when the domain (e.g. S2) is
shared, as the VMID will have to be global across all SMMU instances, even
if a VM is not using all of them. This results in wasted VMID resources in
the bitmaps of unused SMMU instances.
Instead, an iotlb tag should be allocated per SMMU instance. Consequently,
these tags must be allocated and maintained separately. Since ASID or VMID
is only used when a CD or STE is installed to the HW (which happens during
device attachment), and the invalidation array is built right before that,
arm_smmu_invs_merge() is the ideal place to allocate a new iotlb tag:
- when a device attaches, the driver first searches for an existing iotlb
tag for the SMMU the device sits behind
- If a match is found, the "users" counter is incremented
- otherwise, a new tag is allocated.
As ASID/VMID are programmed to CD/STE that belong to a device, it's natural
to store the ASID/VMID in the master structure.
Given the above, this series reworks the driver further:
- Add ASID/VMID allocation/free ops to the arm_smmu_invs data structure
- Store the allocated ASID/VMID in the arm_smmu_master structure
- Replace cd->asid and s2_cfg->vmid with the tags stored in the master
structure, when installing them to the CD and STE
- Deprecate cd->asid and s2_cfg->vmid.
Finally, allow sharing a domain across the SMMU instances, so long as they
passes a compatibility test.
This is on Github:
https://github.com/nicolinc/iommufd/commits/smmuv3_share_domain-v1
This is based on the series "Introduce an RCU-protected invalidation array"
https://lore.kernel.org/all/cover.1766013662.git.nicolinc@nvidia.com/
So the whole implementation follows the path Jason envisioned initially.
A earlier effort to share S2 domain can be found:
https://lore.kernel.org/all/cover.1744692494.git.nicolinc@nvidia.com/
Thanks
Nicolin
Nicolin Chen (9):
iommu/arm-smmu-v3: Pass in ssid to arm_smmu_make_s1_cd()
iommu/arm-smmu-v3: Add alloc_id/free_id functions to arm_smmu_invs
iommu/arm-smmu-v3: Store ASIDs and VMID in arm_smmu_master
iommu/arm-smmu-v3: Use alloc_id/free_id ops in
arm_smmu_invs_merge/unref
iommu/arm-smmu-v3: Install to CD/STE the ASID/VMID stored in the
master
iommu/arm-smmu-v3: Use dummy ASID/VMID in arm_smmu_master_build_invs()
iommu/arm-smmu-v3: Remove free_fn argument from arm_smmu_invs_unref()
iommu/arm-smmu-v3: Remove ASID/VMID from arm_smmu_domain
iommu/arm-smmu-v3: Allow sharing domain across SMMUs
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 47 ++-
.../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 17 +-
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 27 +-
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c | 24 +-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 307 +++++++++++-------
5 files changed, 265 insertions(+), 157 deletions(-)
--
2.43.0
next reply other threads:[~2025-12-18 20:27 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-18 20:26 Nicolin Chen [this message]
2025-12-18 20:26 ` [PATCH v1 1/9] iommu/arm-smmu-v3: Pass in ssid to arm_smmu_make_s1_cd() Nicolin Chen
2025-12-18 20:26 ` [PATCH v1 2/9] iommu/arm-smmu-v3: Add alloc_id/free_id functions to arm_smmu_invs Nicolin Chen
2025-12-19 17:05 ` Jason Gunthorpe
2025-12-19 20:56 ` Nicolin Chen
2025-12-30 18:52 ` Nicolin Chen
2025-12-18 20:26 ` [PATCH v1 3/9] iommu/arm-smmu-v3: Store ASIDs and VMID in arm_smmu_master Nicolin Chen
2025-12-19 15:16 ` Jason Gunthorpe
2025-12-19 19:17 ` Nicolin Chen
2025-12-18 20:26 ` [PATCH v1 4/9] iommu/arm-smmu-v3: Use alloc_id/free_id ops in arm_smmu_invs_merge/unref Nicolin Chen
2025-12-18 20:26 ` [PATCH v1 5/9] iommu/arm-smmu-v3: Install to CD/STE the ASID/VMID stored in the master Nicolin Chen
2025-12-18 20:26 ` [PATCH v1 6/9] iommu/arm-smmu-v3: Use dummy ASID/VMID in arm_smmu_master_build_invs() Nicolin Chen
2025-12-18 20:26 ` [PATCH v1 7/9] iommu/arm-smmu-v3: Remove free_fn argument from arm_smmu_invs_unref() Nicolin Chen
2025-12-18 20:26 ` [PATCH v1 8/9] iommu/arm-smmu-v3: Remove ASID/VMID from arm_smmu_domain Nicolin Chen
2025-12-18 20:26 ` [PATCH v1 9/9] iommu/arm-smmu-v3: Allow sharing domain across SMMUs 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=cover.1766088962.git.nicolinc@nvidia.com \
--to=nicolinc@nvidia.com \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=jpb@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=miko.lenczewski@arm.com \
--cc=patches@lists.linux.dev \
--cc=praan@google.com \
--cc=robin.murphy@arm.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;
as well as URLs for NNTP newsgroup(s).