iommufd: Verify object in iommufd_object_finalize/abort()

To support driver-allocated vIOMMU objects, it's required for IOMMU driver
to call the provided iommufd_viommu_alloc helper to embed the core struct.
However, there is no guarantee that every driver will call it and allocate
objects properly.

Make the iommufd_object_finalize/abort functions more robust to verify if
the xarray slot indexed by the input obj->id is having an XA_ZERO_ENTRY,
which is the reserved value stored by xa_alloc via iommufd_object_alloc.

Link: https://patch.msgid.link/r/334bd4dde8e0a88eb30fa67eeef61827cdb546f9.1730836219.git.nicolinc@nvidia.com
Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
Nicolin Chen 2024-11-05 12:04:20 -08:00 committed by Jason Gunthorpe
parent 6b22d562fc
commit d56d1e8405

View File

@ -41,20 +41,26 @@ static struct miscdevice vfio_misc_dev;
void iommufd_object_finalize(struct iommufd_ctx *ictx,
struct iommufd_object *obj)
{
XA_STATE(xas, &ictx->objects, obj->id);
void *old;
old = xa_store(&ictx->objects, obj->id, obj, GFP_KERNEL);
/* obj->id was returned from xa_alloc() so the xa_store() cannot fail */
WARN_ON(old);
xa_lock(&ictx->objects);
old = xas_store(&xas, obj);
xa_unlock(&ictx->objects);
/* obj->id was returned from xa_alloc() so the xas_store() cannot fail */
WARN_ON(old != XA_ZERO_ENTRY);
}
/* Undo _iommufd_object_alloc() if iommufd_object_finalize() was not called */
void iommufd_object_abort(struct iommufd_ctx *ictx, struct iommufd_object *obj)
{
XA_STATE(xas, &ictx->objects, obj->id);
void *old;
old = xa_erase(&ictx->objects, obj->id);
WARN_ON(old);
xa_lock(&ictx->objects);
old = xas_store(&xas, NULL);
xa_unlock(&ictx->objects);
WARN_ON(old != XA_ZERO_ENTRY);
kfree(obj);
}