diff options
| author | Yi Liu <yi.l.liu@intel.com> | 2025-03-21 10:19:34 -0700 |
|---|---|---|
| committer | Jason Gunthorpe <jgg@nvidia.com> | 2025-03-25 10:18:31 -0300 |
| commit | 4c3f4f432c2d61ed266c797702bb58659f90bdff (patch) | |
| tree | 40b5003d3528874b2d7eb09b435f19efe4659b21 | |
| parent | 2fb69c602d57f77483b8dcdd12d17408a09f76fe (diff) | |
iommufd: Enforce PASID-compatible domain for RID
Per the definition of IOMMU_HWPT_ALLOC_PASID, iommufd needs to enforce
the RID to use PASID-compatible domain if PASID has been attached, and
vice versa. The PASID path has already enforced it. This adds the
enforcement in the RID path.
This enforcement requires a lock across the RID and PASID attach path,
the idev->igroup->lock is used as both the RID and the PASID path holds
it.
Link: https://patch.msgid.link/r/20250321171940.7213-13-yi.l.liu@intel.com
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
| -rw-r--r-- | drivers/iommu/iommufd/device.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c index 4cc6de03f76e..1605f6c0e1ee 100644 --- a/drivers/iommu/iommufd/device.c +++ b/drivers/iommu/iommufd/device.c @@ -399,8 +399,28 @@ static int iommufd_hwpt_pasid_compat(struct iommufd_hw_pagetable *hwpt, struct iommufd_device *idev, ioasid_t pasid) { - if (pasid != IOMMU_NO_PASID && !hwpt->pasid_compat) - return -EINVAL; + struct iommufd_group *igroup = idev->igroup; + + lockdep_assert_held(&igroup->lock); + + if (pasid == IOMMU_NO_PASID) { + unsigned long start = IOMMU_NO_PASID; + + if (!hwpt->pasid_compat && + xa_find_after(&igroup->pasid_attach, + &start, UINT_MAX, XA_PRESENT)) + return -EINVAL; + } else { + struct iommufd_attach *attach; + + if (!hwpt->pasid_compat) + return -EINVAL; + + attach = xa_load(&igroup->pasid_attach, IOMMU_NO_PASID); + if (attach && attach->hwpt && !attach->hwpt->pasid_compat) + return -EINVAL; + } + return 0; } @@ -411,8 +431,6 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt, struct iommufd_attach_handle *handle; int rc; - lockdep_assert_held(&idev->igroup->lock); - rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid); if (rc) return rc; |
