]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iommufd: Enforce PASID-compatible domain in PASID path
authorYi Liu <yi.l.liu@intel.com>
Fri, 21 Mar 2025 17:19:32 +0000 (10:19 -0700)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 25 Mar 2025 13:18:31 +0000 (10:18 -0300)
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>
drivers/iommu/iommufd/device.c
drivers/iommu/iommufd/hw_pagetable.c
drivers/iommu/iommufd/iommufd_private.h

index 175f3d39baaadc94de67a6cb05acb8a5e78d2978..ba21b81e43bc3538b552d33a5f227f63c27e6abc 100644 (file)
@@ -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);
index bd9dd26a52950a72f25cda987156f35230945ac5..3724533a23c966921b33aa5c63982847a5fb527e 100644 (file)
@@ -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);
index 85467f53bdb290122ed54927d9442db07382c139..80e8c76d25f234c6fb52ea674dde913dfc2d1ce6 100644 (file)
@@ -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 {