]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iommufd/device: Only add reserved_iova in non-pasid path
authorYi Liu <yi.l.liu@intel.com>
Fri, 21 Mar 2025 17:19:26 +0000 (10:19 -0700)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 25 Mar 2025 13:18:30 +0000 (10:18 -0300)
As the pasid is passed through the attach/replace/detach helpers, it is
necessary to ensure only the non-pasid path adds reserved_iova.

Link: https://patch.msgid.link/r/20250321171940.7213-5-yi.l.liu@intel.com
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Nicolin Chen <nicolinc@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

index 7051feda2fab0885e2787590496a3293a202951a..4625f084f7d0b3e7d55102d56158d88b6fea1283 100644 (file)
@@ -483,6 +483,7 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
                                struct iommufd_device *idev, ioasid_t pasid)
 {
        struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
+       bool attach_resv = hwpt_paging && pasid == IOMMU_NO_PASID;
        int rc;
 
        mutex_lock(&idev->igroup->lock);
@@ -492,7 +493,7 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
                goto err_unlock;
        }
 
-       if (hwpt_paging) {
+       if (attach_resv) {
                rc = iommufd_device_attach_reserved_iova(idev, hwpt_paging);
                if (rc)
                        goto err_unlock;
@@ -516,7 +517,7 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
        mutex_unlock(&idev->igroup->lock);
        return 0;
 err_unresv:
-       if (hwpt_paging)
+       if (attach_resv)
                iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt, idev->dev);
 err_unlock:
        mutex_unlock(&idev->igroup->lock);
@@ -535,7 +536,7 @@ iommufd_hw_pagetable_detach(struct iommufd_device *idev, ioasid_t pasid)
                iommufd_hwpt_detach_device(hwpt, idev, pasid);
                idev->igroup->hwpt = NULL;
        }
-       if (hwpt_paging)
+       if (hwpt_paging && pasid == IOMMU_NO_PASID)
                iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt, idev->dev);
        mutex_unlock(&idev->igroup->lock);
 
@@ -602,6 +603,7 @@ iommufd_device_do_replace(struct iommufd_device *idev, ioasid_t pasid,
                          struct iommufd_hw_pagetable *hwpt)
 {
        struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
+       bool attach_resv = hwpt_paging && pasid == IOMMU_NO_PASID;
        struct iommufd_hwpt_paging *old_hwpt_paging;
        struct iommufd_group *igroup = idev->igroup;
        struct iommufd_hw_pagetable *old_hwpt;
@@ -626,7 +628,7 @@ iommufd_device_do_replace(struct iommufd_device *idev, ioasid_t pasid,
        }
 
        old_hwpt = igroup->hwpt;
-       if (hwpt_paging) {
+       if (attach_resv) {
                rc = iommufd_group_do_replace_reserved_iova(igroup, hwpt_paging);
                if (rc)
                        goto err_unlock;
@@ -637,7 +639,7 @@ iommufd_device_do_replace(struct iommufd_device *idev, ioasid_t pasid,
                goto err_unresv;
 
        old_hwpt_paging = find_hwpt_paging(old_hwpt);
-       if (old_hwpt_paging &&
+       if (old_hwpt_paging && pasid == IOMMU_NO_PASID &&
            (!hwpt_paging || hwpt_paging->ioas != old_hwpt_paging->ioas))
                iommufd_group_remove_reserved_iova(igroup, old_hwpt_paging);
 
@@ -657,7 +659,7 @@ iommufd_device_do_replace(struct iommufd_device *idev, ioasid_t pasid,
        /* Caller must destroy old_hwpt */
        return old_hwpt;
 err_unresv:
-       if (hwpt_paging)
+       if (attach_resv)
                iommufd_group_remove_reserved_iova(igroup, hwpt_paging);
 err_unlock:
        mutex_unlock(&idev->igroup->lock);