Skip to content

Commit 70eadc7

Browse files
committed
iommufd: Allow a hwpt to be aborted after allocation
During creation the hwpt must have the ioas->mutex held until the object is finalized. This means we need to be able to call iommufd_object_abort_and_destroy() while holding the mutex. Since iommufd_hw_pagetable_destroy() also needs the mutex this is problematic. Fix it by creating a special abort op for the object that can assume the caller is holding the lock, as required by the contract. The next patch will add another iommufd_object_abort_and_destroy() for a hwpt. Fixes: e8d5721 ("iommufd: Add kAPI toward external drivers for physical devices") Link: https://lore.kernel.org/r/10-v8-6659224517ea+532-iommufd_alloc_jgg@nvidia.com Reviewed-by: Kevin Tian <kevin.tian@intel.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
1 parent 17bad52 commit 70eadc7

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

drivers/iommu/iommufd/hw_pagetable.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ void iommufd_hw_pagetable_destroy(struct iommufd_object *obj)
2525
refcount_dec(&hwpt->ioas->obj.users);
2626
}
2727

28+
void iommufd_hw_pagetable_abort(struct iommufd_object *obj)
29+
{
30+
struct iommufd_hw_pagetable *hwpt =
31+
container_of(obj, struct iommufd_hw_pagetable, obj);
32+
33+
/* The ioas->mutex must be held until finalize is called. */
34+
lockdep_assert_held(&hwpt->ioas->mutex);
35+
36+
if (!list_empty(&hwpt->hwpt_item)) {
37+
list_del_init(&hwpt->hwpt_item);
38+
iopt_table_remove_domain(&hwpt->ioas->iopt, hwpt->domain);
39+
}
40+
iommufd_hw_pagetable_destroy(obj);
41+
}
42+
2843
int iommufd_hw_pagetable_enforce_cc(struct iommufd_hw_pagetable *hwpt)
2944
{
3045
if (hwpt->enforce_cache_coherency)
@@ -49,6 +64,10 @@ int iommufd_hw_pagetable_enforce_cc(struct iommufd_hw_pagetable *hwpt)
4964
* Allocate a new iommu_domain and return it as a hw_pagetable. The HWPT
5065
* will be linked to the given ioas and upon return the underlying iommu_domain
5166
* is fully popoulated.
67+
*
68+
* The caller must hold the ioas->mutex until after
69+
* iommufd_object_abort_and_destroy() or iommufd_object_finalize() is called on
70+
* the returned hwpt.
5271
*/
5372
struct iommufd_hw_pagetable *
5473
iommufd_hw_pagetable_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,

drivers/iommu/iommufd/iommufd_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
260260
struct iommufd_hw_pagetable *
261261
iommufd_hw_pagetable_detach(struct iommufd_device *idev);
262262
void iommufd_hw_pagetable_destroy(struct iommufd_object *obj);
263+
void iommufd_hw_pagetable_abort(struct iommufd_object *obj);
263264

264265
static inline void iommufd_hw_pagetable_put(struct iommufd_ctx *ictx,
265266
struct iommufd_hw_pagetable *hwpt)

drivers/iommu/iommufd/main.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
struct iommufd_object_ops {
2626
void (*destroy)(struct iommufd_object *obj);
27+
void (*abort)(struct iommufd_object *obj);
2728
};
2829
static const struct iommufd_object_ops iommufd_object_ops[];
2930
static struct miscdevice vfio_misc_dev;
@@ -95,7 +96,10 @@ void iommufd_object_abort(struct iommufd_ctx *ictx, struct iommufd_object *obj)
9596
void iommufd_object_abort_and_destroy(struct iommufd_ctx *ictx,
9697
struct iommufd_object *obj)
9798
{
98-
iommufd_object_ops[obj->type].destroy(obj);
99+
if (iommufd_object_ops[obj->type].abort)
100+
iommufd_object_ops[obj->type].abort(obj);
101+
else
102+
iommufd_object_ops[obj->type].destroy(obj);
99103
iommufd_object_abort(ictx, obj);
100104
}
101105

@@ -425,6 +429,7 @@ static const struct iommufd_object_ops iommufd_object_ops[] = {
425429
},
426430
[IOMMUFD_OBJ_HW_PAGETABLE] = {
427431
.destroy = iommufd_hw_pagetable_destroy,
432+
.abort = iommufd_hw_pagetable_abort,
428433
},
429434
#ifdef CONFIG_IOMMUFD_TEST
430435
[IOMMUFD_OBJ_SELFTEST] = {

0 commit comments

Comments
 (0)