Commit 4c3f4f43 authored by Yi Liu's avatar Yi Liu Committed by Jason Gunthorpe
Browse files

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: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarNicolin Chen <nicolinc@nvidia.com>
Signed-off-by: default avatarYi Liu <yi.l.liu@intel.com>
Tested-by: default avatarNicolin Chen <nicolinc@nvidia.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 2fb69c60
Loading
Loading
Loading
Loading
+22 −4
Original line number Diff line number Diff line
@@ -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)
	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;