mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
iommufd: Enforce PASID-compatible domain in PASID path
AMD IOMMU requires attaching PASID-compatible domains to PASID-capable devices. This includes the domains attached to RID and PASIDs. Related discussions in link [1] and [2]. ARM also has such a requirement, Intel does not need it, but can live up with it. Hence, iommufd is going to enforce this requirement as it is not harmful to vendors that do not need it. Mark the PASID-compatible domains and enforce it in the PASID path. [1] https://lore.kernel.org/linux-iommu/20240709182303.GK14050@ziepe.ca/ [2] https://lore.kernel.org/linux-iommu/20240822124433.GD3468552@ziepe.ca/ Link: https://patch.msgid.link/r/20250321171940.7213-11-yi.l.liu@intel.com Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.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>
This commit is contained in:
parent
c0e301b297
commit
ff3f014ebb
|
|
@ -395,6 +395,15 @@ static bool iommufd_device_is_attached(struct iommufd_device *idev,
|
|||
return xa_load(&attach->device_array, idev->obj.id);
|
||||
}
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
|
||||
struct iommufd_device *idev,
|
||||
ioasid_t pasid)
|
||||
|
|
@ -404,6 +413,10 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
|
|||
|
||||
lockdep_assert_held(&idev->igroup->lock);
|
||||
|
||||
rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
|
||||
if (!handle)
|
||||
return -ENOMEM;
|
||||
|
|
@ -472,6 +485,10 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
|
|||
|
||||
WARN_ON(pasid != IOMMU_NO_PASID);
|
||||
|
||||
rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
old_handle = iommufd_device_get_attach_handle(idev, pasid);
|
||||
|
||||
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
|
|||
if (IS_ERR(hwpt_paging))
|
||||
return ERR_CAST(hwpt_paging);
|
||||
hwpt = &hwpt_paging->common;
|
||||
hwpt->pasid_compat = flags & IOMMU_HWPT_ALLOC_PASID;
|
||||
|
||||
INIT_LIST_HEAD(&hwpt_paging->hwpt_item);
|
||||
/* Pairs with iommufd_hw_pagetable_destroy() */
|
||||
|
|
@ -244,6 +245,7 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx,
|
|||
if (IS_ERR(hwpt_nested))
|
||||
return ERR_CAST(hwpt_nested);
|
||||
hwpt = &hwpt_nested->common;
|
||||
hwpt->pasid_compat = flags & IOMMU_HWPT_ALLOC_PASID;
|
||||
|
||||
refcount_inc(&parent->common.obj.users);
|
||||
hwpt_nested->parent = parent;
|
||||
|
|
@ -300,6 +302,7 @@ iommufd_viommu_alloc_hwpt_nested(struct iommufd_viommu *viommu, u32 flags,
|
|||
if (IS_ERR(hwpt_nested))
|
||||
return ERR_CAST(hwpt_nested);
|
||||
hwpt = &hwpt_nested->common;
|
||||
hwpt->pasid_compat = flags & IOMMU_HWPT_ALLOC_PASID;
|
||||
|
||||
hwpt_nested->viommu = viommu;
|
||||
refcount_inc(&viommu->obj.users);
|
||||
|
|
|
|||
|
|
@ -299,6 +299,7 @@ struct iommufd_hw_pagetable {
|
|||
struct iommufd_object obj;
|
||||
struct iommu_domain *domain;
|
||||
struct iommufd_fault *fault;
|
||||
bool pasid_compat : 1;
|
||||
};
|
||||
|
||||
struct iommufd_hwpt_paging {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user