[PATCH v5 11/29] iommufd/driver: Let iommufd_viommu_alloc helper save ictx to viommu->ictx

Nicolin Chen
2025-05-18T03:45:02Z

When an IOMMU driver calls iommufd_viommu_alloc(), it must pass in an ictx
pointer as the underlying _iommufd_object_alloc() helper function requires
that to allocate a new object. However, neither the iommufd_viommu_alloc()
nor its underlying _iommufd_object_alloc() saves the ictx in the allocated
viommu object, although viommu could hold an ictx pointer.

When the IOMMU driver wants to use another iommufd function passing in the
allocated viommu, it could have avoided passing in the ictx pointer again,
if viommu->ictx is valid.

Save ictx to viommu->ictx in the iommufd_viommu_alloc(), in order to ease
a new vIOMMU-based helper that would then get the ictx from viommu->ictx.

Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/iommufd_private.h | 8 --------
include/linux/iommufd.h | 12 +++++++++++-
drivers/iommu/iommufd/viommu.c | 7 ++++++-
3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
index cef3e0e0bbb2..44286216ac5a 100644
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -136,14 +136,6 @@ int iopt_pin_pages(struct io_pagetable *iopt, unsigned long iova,
void iopt_unpin_pages(struct io_pagetable *iopt, unsigned long iova,
unsigned long length, bool is_owner);

-struct iommufd_ucmd {
- struct iommufd_ctx *ictx;
- void __user *ubuffer;
- u32 user_size;
- void *cmd;
- struct iommufd_object *new_obj;
-};
-
int iommufd_vfio_ioctl(struct iommufd_ctx *ictx, unsigned int cmd,
unsigned long arg);

diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index d74c97feb9b5..a07466333c48 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -52,6 +52,14 @@ struct iommufd_object {
unsigned int id;
};

+struct iommufd_ucmd {
+ struct iommufd_ctx *ictx;
+ void __user *ubuffer;
+ u32 user_size;
+ void *cmd;
+ struct iommufd_object *new_obj;
+};
+
#define __iommufd_object_alloc_ucmd(ucmd, ptr, type, obj) \
container_of(_iommufd_object_alloc_ucmd( \
ucmd, \
@@ -262,8 +270,10 @@ static inline int iommufd_viommu_report_event(struct iommufd_viommu *viommu,
\
ret = (drv_struct *)__iommufd_object_alloc_ucmd( \
ucmd, ret, IOMMUFD_OBJ_VIOMMU, member.obj); \
- if (!IS_ERR(ret)) \
+ if (!IS_ERR(ret)) { \
ret->member.ops = viommu_ops; \
+ ret->member.ictx = ucmd->ictx; \
+ } \
ret; \
})
#endif
diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c
index 2b30627d1d8e..662f5c1b1935 100644
--- a/drivers/iommu/iommufd/viommu.c
+++ b/drivers/iommu/iommufd/viommu.c
@@ -60,9 +60,14 @@ int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd)
goto out_put_hwpt;
}

+ /* The iommufd_viommu_alloc helper saves ucmd->ictx in viommu->ictx */
+ if (WARN_ON_ONCE(viommu->ictx != ucmd->ictx)) {
+ rc = -EINVAL;
+ goto out_put_hwpt;
+ }
+
xa_init(&viommu->vdevs);
viommu->type = cmd->type;
- viommu->ictx = ucmd->ictx;
viommu->hwpt = hwpt_paging;
refcount_inc(&viommu->hwpt->common.obj.users);
INIT_LIST_HEAD(&viommu->veventqs);
--
2.43.0