[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <813abd4f054c21f1bdb4c26999ecb46eb54f266e.1769044718.git.nicolinc@nvidia.com>
Date: Wed, 21 Jan 2026 17:24:25 -0800
From: Nicolin Chen <nicolinc@...dia.com>
To: <will@...nel.org>, <robin.murphy@....com>, <jgg@...dia.com>
CC: <joro@...tes.org>, <jpb@...nel.org>, <praan@...gle.com>,
<miko.lenczewski@....com>, <linux-arm-kernel@...ts.infradead.org>,
<iommu@...ts.linux.dev>, <linux-kernel@...r.kernel.org>,
<patches@...ts.linux.dev>
Subject: [PATCH v2 07/10] iommu/arm-smmu-v3: Pass in vsmmu to arm_smmu_domain_get_iotlb_tag()
When a device attaches to a nested domain, VMID is held by its associated
vSMMU instance. So arm_smmu_domain_get_iotlb_tag() should return the VMID
from the vSMMU instance rather than allocating a new one. Pass in a vsmmu
pointer to arm_smmu_domain_get_iotlb_tag(), to prepare for this.
Signed-off-by: Nicolin Chen <nicolinc@...dia.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 9 +++++++++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 1 +
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 4 ++--
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 7 +++++--
4 files changed, 17 insertions(+), 4 deletions(-)
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 8aecdbceb974..386ac75879c0 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -1124,6 +1124,7 @@ struct arm_smmu_attach_state {
/* Inputs */
struct iommu_domain *old_domain;
struct arm_smmu_master *master;
+ struct arm_vsmmu *vsmmu;
bool cd_needs_ats;
bool disable_ats;
ioasid_t ssid;
@@ -1136,6 +1137,7 @@ struct arm_smmu_attach_state {
int arm_smmu_domain_get_iotlb_tag(struct arm_smmu_domain *smmu_domain,
struct arm_smmu_device *smmu,
+ struct arm_vsmmu *vsmmu,
struct arm_smmu_inv *tag, bool alloc);
int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state,
@@ -1182,6 +1184,13 @@ struct arm_vsmmu {
u16 vmid;
};
+static inline struct arm_vsmmu *to_vsmmu(struct iommu_domain *domain)
+{
+ if (domain->type == IOMMU_DOMAIN_NESTED)
+ return to_smmu_nested_domain(domain)->vsmmu;
+ return NULL;
+}
+
#if IS_ENABLED(CONFIG_ARM_SMMU_V3_IOMMUFD)
void *arm_smmu_hw_info(struct device *dev, u32 *length,
enum iommu_hw_info_type *type);
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 9998871f69a0..33b336d494c3 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
@@ -162,6 +162,7 @@ static int arm_smmu_attach_dev_nested(struct iommu_domain *domain,
struct arm_smmu_master *master = dev_iommu_priv_get(dev);
struct arm_smmu_attach_state state = {
.master = master,
+ .vsmmu = nested_domain->vsmmu,
.old_domain = old_domain,
.ssid = IOMMU_NO_PASID,
};
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 5c8960d31a9b..461ccf4bdb03 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
@@ -31,7 +31,7 @@ arm_smmu_update_s1_domain_cd_entry(struct arm_smmu_domain *smmu_domain)
continue;
if (WARN_ON(arm_smmu_domain_get_iotlb_tag(
- smmu_domain, master->smmu, &tag, false)))
+ smmu_domain, master->smmu, NULL, &tag, false)))
continue;
if (WARN_ON(tag.type != INV_TYPE_S1_ASID))
continue;
@@ -171,7 +171,7 @@ static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
continue;
if (WARN_ON(arm_smmu_domain_get_iotlb_tag(
- smmu_domain, master->smmu, &tag, false)))
+ smmu_domain, master->smmu, NULL, &tag, false)))
continue;
if (WARN_ON(tag.type != INV_TYPE_S1_ASID))
continue;
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 5a7032081553..8323f74c8923 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3137,6 +3137,7 @@ static int __arm_smmu_domain_get_iotlb_tag(struct arm_smmu_domain *smmu_domain,
int arm_smmu_domain_get_iotlb_tag(struct arm_smmu_domain *smmu_domain,
struct arm_smmu_device *smmu,
+ struct arm_vsmmu *vsmmu,
struct arm_smmu_inv *tag, bool alloc)
{
int ret;
@@ -3360,6 +3361,7 @@ static int arm_smmu_attach_prepare_invs(struct arm_smmu_attach_state *state,
*/
if (new_smmu_domain) {
struct arm_smmu_inv_state *invst = &state->new_domain_invst;
+ struct arm_vsmmu *vsmmu = state->vsmmu;
struct arm_smmu_invs *build_invs;
invst->invs_ptr = &new_smmu_domain->invs;
@@ -3368,7 +3370,7 @@ static int arm_smmu_attach_prepare_invs(struct arm_smmu_attach_state *state,
lockdep_is_held(&arm_smmu_asid_lock));
ret = arm_smmu_domain_get_iotlb_tag(new_smmu_domain, smmu,
- &invst->tag, true);
+ vsmmu, &invst->tag, true);
if (ret)
return ret;
@@ -3387,6 +3389,7 @@ static int arm_smmu_attach_prepare_invs(struct arm_smmu_attach_state *state,
if (old_smmu_domain) {
struct arm_smmu_inv_state *invst = &state->old_domain_invst;
+ struct arm_vsmmu *vsmmu = to_vsmmu(state->old_domain);
invst->invs_ptr = &old_smmu_domain->invs;
/* A re-attach case might have a different ats_enabled state */
@@ -3398,7 +3401,7 @@ static int arm_smmu_attach_prepare_invs(struct arm_smmu_attach_state *state,
lockdep_is_held(&arm_smmu_asid_lock));
ret = arm_smmu_domain_get_iotlb_tag(old_smmu_domain, smmu,
- &invst->tag, false);
+ vsmmu, &invst->tag, false);
if (WARN_ON(ret))
return ret;
--
2.43.0
Powered by blists - more mailing lists