@@ -1061,7 +1061,7 @@ struct arm_vsmmu {
void *arm_smmu_hw_info(struct device *dev, u32 *length, u32 *type);
struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
struct iommu_domain *parent,
- struct iommufd_ctx *ictx,
+ struct iommufd_ucmd *ucmd,
unsigned int viommu_type);
int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state,
struct arm_smmu_nested_domain *nested_domain);
@@ -43,7 +43,7 @@ struct iommu_sva;
struct iommu_dma_cookie;
struct iommu_dma_msi_cookie;
struct iommu_fault_param;
-struct iommufd_ctx;
+struct iommufd_ucmd;
struct iommufd_viommu;
struct msi_desc;
struct msi_msg;
@@ -609,7 +609,7 @@ iommu_copy_struct_from_full_user_array(void *kdst, size_t kdst_entry_size,
* include/uapi/linux/iommufd.h
* It is required to call iommufd_viommu_alloc() helper for
* a bundled allocation of the core and the driver structures,
- * using the given @ictx pointer.
+ * using the given @ucmd pointer.
* @pgsize_bitmap: bitmap of all possible supported page sizes
* @owner: Driver module providing these ops
* @identity_domain: An always available, always attachable identity
@@ -662,7 +662,7 @@ struct iommu_ops {
struct iommufd_viommu *(*viommu_alloc)(
struct device *dev, struct iommu_domain *parent_domain,
- struct iommufd_ctx *ictx, unsigned int viommu_type);
+ struct iommufd_ucmd *ucmd, unsigned int viommu_type);
const struct iommu_domain_ops *default_domain_ops;
unsigned long pgsize_bitmap;
@@ -256,15 +256,12 @@ static inline int iommufd_viommu_report_event(struct iommufd_viommu *viommu,
* Helpers for IOMMU driver to allocate driver structures that will be freed by
* the iommufd core. The free op will be called prior to freeing the memory.
*/
-#define iommufd_viommu_alloc(ictx, drv_struct, member, viommu_ops) \
+#define iommufd_viommu_alloc(ucmd, drv_struct, member, viommu_ops) \
({ \
drv_struct *ret; \
\
- static_assert(__same_type(struct iommufd_viommu, \
- ((drv_struct *)NULL)->member)); \
- static_assert(offsetof(drv_struct, member.obj) == 0); \
- ret = (drv_struct *)_iommufd_object_alloc( \
- ictx, sizeof(drv_struct), IOMMUFD_OBJ_VIOMMU); \
+ ret = (drv_struct *)__iommufd_object_alloc_ucmd( \
+ ucmd, ret, IOMMUFD_OBJ_VIOMMU, member.obj); \
if (!IS_ERR(ret)) \
ret->member.ops = viommu_ops; \
ret; \
@@ -384,7 +384,7 @@ static const struct iommufd_viommu_ops arm_vsmmu_ops = {
struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
struct iommu_domain *parent,
- struct iommufd_ctx *ictx,
+ struct iommufd_ucmd *ucmd,
unsigned int viommu_type)
{
struct arm_smmu_device *smmu =
@@ -422,7 +422,7 @@ struct iommufd_viommu *arm_vsmmu_alloc(struct device *dev,
!(smmu->features & ARM_SMMU_FEAT_S2FWB))
return ERR_PTR(-EOPNOTSUPP);
- vsmmu = iommufd_viommu_alloc(ictx, struct arm_vsmmu, core,
+ vsmmu = iommufd_viommu_alloc(ucmd, struct arm_vsmmu, core,
&arm_vsmmu_ops);
if (IS_ERR(vsmmu))
return ERR_CAST(vsmmu);
@@ -473,8 +473,8 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
if (cmd->flags)
return -EOPNOTSUPP;
- fault = __iommufd_object_alloc(ucmd->ictx, fault, IOMMUFD_OBJ_FAULT,
- common.obj);
+ fault = __iommufd_object_alloc_ucmd(ucmd, fault, IOMMUFD_OBJ_FAULT,
+ common.obj);
if (IS_ERR(fault))
return PTR_ERR(fault);
@@ -483,10 +483,8 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
fdno = iommufd_eventq_init(&fault->common, "[iommufd-pgfault]",
ucmd->ictx, &iommufd_fault_fops);
- if (fdno < 0) {
- rc = fdno;
- goto out_abort;
- }
+ if (fdno < 0)
+ return fdno;
cmd->out_fault_id = fault->common.obj.id;
cmd->out_fault_fd = fdno;
@@ -494,7 +492,6 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
if (rc)
goto out_put_fdno;
- iommufd_object_finalize(ucmd->ictx, &fault->common.obj);
fd_install(fdno, fault->common.filep);
@@ -502,9 +499,6 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd)
out_put_fdno:
put_unused_fd(fdno);
fput(fault->common.filep);
-out_abort:
- iommufd_object_abort_and_destroy(ucmd->ictx, &fault->common.obj);
-
return rc;
}
@@ -735,7 +735,7 @@ static struct iommufd_viommu_ops mock_viommu_ops = {
static struct iommufd_viommu *mock_viommu_alloc(struct device *dev,
struct iommu_domain *domain,
- struct iommufd_ctx *ictx,
+ struct iommufd_ucmd *ucmd,
unsigned int viommu_type)
{
struct mock_iommu_device *mock_iommu =
@@ -745,7 +745,7 @@ static struct iommufd_viommu *mock_viommu_alloc(struct device *dev,
if (viommu_type != IOMMU_VIOMMU_TYPE_SELFTEST)
return ERR_PTR(-EOPNOTSUPP);
- mock_viommu = iommufd_viommu_alloc(ictx, struct mock_viommu, core,
+ mock_viommu = iommufd_viommu_alloc(ucmd, struct mock_viommu, core,
&mock_viommu_ops);
if (IS_ERR(mock_viommu))
return ERR_CAST(mock_viommu);
@@ -47,8 +47,8 @@ int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd)
goto out_put_hwpt;
}
- viommu = ops->viommu_alloc(idev->dev, hwpt_paging->common.domain,
- ucmd->ictx, cmd->type);
+ viommu = ops->viommu_alloc(idev->dev, hwpt_paging->common.domain, ucmd,
+ cmd->type);
if (IS_ERR(viommu)) {
rc = PTR_ERR(viommu);
goto out_put_hwpt;
@@ -70,13 +70,7 @@ int iommufd_viommu_alloc_ioctl(struct iommufd_ucmd *ucmd)
cmd->out_viommu_id = viommu->obj.id;
rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
- if (rc)
- goto out_abort;
- iommufd_object_finalize(ucmd->ictx, &viommu->obj);
- goto out_put_hwpt;
-out_abort:
- iommufd_object_abort_and_destroy(ucmd->ictx, &viommu->obj);
out_put_hwpt:
iommufd_put_object(ucmd->ictx, &hwpt_paging->common.obj);
out_put_idev:
@@ -124,7 +118,7 @@ int iommufd_vdevice_alloc_ioctl(struct iommufd_ucmd *ucmd)
goto out_put_idev;
}
- vdev = iommufd_object_alloc(ucmd->ictx, vdev, IOMMUFD_OBJ_VDEVICE);
+ vdev = iommufd_object_alloc_ucmd(ucmd, vdev, IOMMUFD_OBJ_VDEVICE);
if (IS_ERR(vdev)) {
rc = PTR_ERR(vdev);
goto out_put_idev;
@@ -139,18 +133,12 @@ int iommufd_vdevice_alloc_ioctl(struct iommufd_ucmd *ucmd)
curr = xa_cmpxchg(&viommu->vdevs, virt_id, NULL, vdev, GFP_KERNEL);
if (curr) {
rc = xa_err(curr) ?: -EEXIST;
- goto out_abort;
+ goto out_put_idev;
}
cmd->out_vdevice_id = vdev->obj.id;
rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
- if (rc)
- goto out_abort;
- iommufd_object_finalize(ucmd->ictx, &vdev->obj);
- goto out_put_idev;
-out_abort:
- iommufd_object_abort_and_destroy(ucmd->ictx, &vdev->obj);
out_put_idev:
iommufd_put_object(ucmd->ictx, &idev->obj);
out_put_viommu:
Now the new ucmd-based object allocator eases the finalize/abort routine, apply this to all existing allocators that aren't protected by any lock. Upgrade the for-driver vIOMMU alloctor too, and pass down to all existing viommu_alloc op accordingly. Note that __iommufd_object_alloc_ucmd() builds in some static tests that cover both static_asserts in the iommufd_viommu_alloc(). Thus drop them. Suggested-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 2 +- include/linux/iommu.h | 6 +++--- include/linux/iommufd.h | 9 +++------ .../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 4 ++-- drivers/iommu/iommufd/eventq.c | 14 ++++--------- drivers/iommu/iommufd/selftest.c | 4 ++-- drivers/iommu/iommufd/viommu.c | 20 ++++--------------- 7 files changed, 19 insertions(+), 40 deletions(-)