iommufd: Remove unnecessary IOMMU_DEV_FEAT_IOPF
authorLu Baolu <baolu.lu@linux.intel.com>
Fri, 18 Apr 2025 08:01:29 +0000 (16:01 +0800)
committerJoerg Roedel <jroedel@suse.de>
Mon, 28 Apr 2025 11:04:34 +0000 (13:04 +0200)
The iopf enablement has been moved to the iommu drivers. It is unnecessary
for iommufd to handle iopf enablement. Remove the iopf enablement logic to
avoid duplication.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Link: https://lore.kernel.org/r/20250418080130.1844424-8-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/iommufd/device.c
drivers/iommu/iommufd/eventq.c
drivers/iommu/iommufd/iommufd_private.h

index 2111bad..8624440 100644 (file)
@@ -221,7 +221,6 @@ struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx,
        refcount_inc(&idev->obj.users);
        /* igroup refcount moves into iommufd_device */
        idev->igroup = igroup;
-       mutex_init(&idev->iopf_lock);
 
        /*
         * If the caller fails after this success it must call
@@ -425,6 +424,25 @@ static int iommufd_hwpt_pasid_compat(struct iommufd_hw_pagetable *hwpt,
        return 0;
 }
 
+static bool iommufd_hwpt_compatible_device(struct iommufd_hw_pagetable *hwpt,
+                                          struct iommufd_device *idev)
+{
+       struct pci_dev *pdev;
+
+       if (!hwpt->fault || !dev_is_pci(idev->dev))
+               return true;
+
+       /*
+        * Once we turn on PCI/PRI support for VF, the response failure code
+        * should not be forwarded to the hardware due to PRI being a shared
+        * resource between PF and VFs. There is no coordination for this
+        * shared capability. This waits for a vPRI reset to recover.
+        */
+       pdev = to_pci_dev(idev->dev);
+
+       return (!pdev->is_virtfn || !pci_pri_supported(pdev));
+}
+
 static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
                                      struct iommufd_device *idev,
                                      ioasid_t pasid)
@@ -432,6 +450,9 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
        struct iommufd_attach_handle *handle;
        int rc;
 
+       if (!iommufd_hwpt_compatible_device(hwpt, idev))
+               return -EINVAL;
+
        rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid);
        if (rc)
                return rc;
@@ -440,12 +461,6 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
        if (!handle)
                return -ENOMEM;
 
-       if (hwpt->fault) {
-               rc = iommufd_fault_iopf_enable(idev);
-               if (rc)
-                       goto out_free_handle;
-       }
-
        handle->idev = idev;
        if (pasid == IOMMU_NO_PASID)
                rc = iommu_attach_group_handle(hwpt->domain, idev->igroup->group,
@@ -454,13 +469,10 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
                rc = iommu_attach_device_pasid(hwpt->domain, idev->dev, pasid,
                                               &handle->handle);
        if (rc)
-               goto out_disable_iopf;
+               goto out_free_handle;
 
        return 0;
 
-out_disable_iopf:
-       if (hwpt->fault)
-               iommufd_fault_iopf_disable(idev);
 out_free_handle:
        kfree(handle);
        return rc;
@@ -492,10 +504,7 @@ static void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
        else
                iommu_detach_device_pasid(hwpt->domain, idev->dev, pasid);
 
-       if (hwpt->fault) {
-               iommufd_auto_response_faults(hwpt, handle);
-               iommufd_fault_iopf_disable(idev);
-       }
+       iommufd_auto_response_faults(hwpt, handle);
        kfree(handle);
 }
 
@@ -507,6 +516,9 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
        struct iommufd_attach_handle *handle, *old_handle;
        int rc;
 
+       if (!iommufd_hwpt_compatible_device(hwpt, idev))
+               return -EINVAL;
+
        rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid);
        if (rc)
                return rc;
@@ -517,12 +529,6 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
        if (!handle)
                return -ENOMEM;
 
-       if (hwpt->fault && !old->fault) {
-               rc = iommufd_fault_iopf_enable(idev);
-               if (rc)
-                       goto out_free_handle;
-       }
-
        handle->idev = idev;
        if (pasid == IOMMU_NO_PASID)
                rc = iommu_replace_group_handle(idev->igroup->group,
@@ -531,20 +537,13 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
                rc = iommu_replace_device_pasid(hwpt->domain, idev->dev,
                                                pasid, &handle->handle);
        if (rc)
-               goto out_disable_iopf;
+               goto out_free_handle;
 
-       if (old->fault) {
-               iommufd_auto_response_faults(hwpt, old_handle);
-               if (!hwpt->fault)
-                       iommufd_fault_iopf_disable(idev);
-       }
+       iommufd_auto_response_faults(hwpt, old_handle);
        kfree(old_handle);
 
        return 0;
 
-out_disable_iopf:
-       if (hwpt->fault && !old->fault)
-               iommufd_fault_iopf_disable(idev);
 out_free_handle:
        kfree(handle);
        return rc;
index f39cf07..e373b9e 100644 (file)
@@ -9,8 +9,6 @@
 #include <linux/iommufd.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
-#include <linux/pci.h>
-#include <linux/pci-ats.h>
 #include <linux/poll.h>
 #include <uapi/linux/iommufd.h>
 
 #include "iommufd_private.h"
 
 /* IOMMUFD_OBJ_FAULT Functions */
-
-int iommufd_fault_iopf_enable(struct iommufd_device *idev)
-{
-       struct device *dev = idev->dev;
-       int ret;
-
-       /*
-        * Once we turn on PCI/PRI support for VF, the response failure code
-        * should not be forwarded to the hardware due to PRI being a shared
-        * resource between PF and VFs. There is no coordination for this
-        * shared capability. This waits for a vPRI reset to recover.
-        */
-       if (dev_is_pci(dev)) {
-               struct pci_dev *pdev = to_pci_dev(dev);
-
-               if (pdev->is_virtfn && pci_pri_supported(pdev))
-                       return -EINVAL;
-       }
-
-       mutex_lock(&idev->iopf_lock);
-       /* Device iopf has already been on. */
-       if (++idev->iopf_enabled > 1) {
-               mutex_unlock(&idev->iopf_lock);
-               return 0;
-       }
-
-       ret = iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_IOPF);
-       if (ret)
-               --idev->iopf_enabled;
-       mutex_unlock(&idev->iopf_lock);
-
-       return ret;
-}
-
-void iommufd_fault_iopf_disable(struct iommufd_device *idev)
-{
-       mutex_lock(&idev->iopf_lock);
-       if (!WARN_ON(idev->iopf_enabled == 0)) {
-               if (--idev->iopf_enabled == 0)
-                       iommu_dev_disable_feature(idev->dev, IOMMU_DEV_FEAT_IOPF);
-       }
-       mutex_unlock(&idev->iopf_lock);
-}
-
 void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
                                  struct iommufd_attach_handle *handle)
 {
@@ -70,7 +24,7 @@ void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
        struct list_head free_list;
        unsigned long index;
 
-       if (!fault)
+       if (!fault || !handle)
                return;
        INIT_LIST_HEAD(&free_list);
 
index 80e8c76..9ccc833 100644 (file)
@@ -425,9 +425,6 @@ struct iommufd_device {
        /* always the physical device */
        struct device *dev;
        bool enforce_cache_coherency;
-       /* protect iopf_enabled counter */
-       struct mutex iopf_lock;
-       unsigned int iopf_enabled;
 };
 
 static inline struct iommufd_device *
@@ -506,9 +503,6 @@ iommufd_get_fault(struct iommufd_ucmd *ucmd, u32 id)
 int iommufd_fault_alloc(struct iommufd_ucmd *ucmd);
 void iommufd_fault_destroy(struct iommufd_object *obj);
 int iommufd_fault_iopf_handler(struct iopf_group *group);
-
-int iommufd_fault_iopf_enable(struct iommufd_device *idev);
-void iommufd_fault_iopf_disable(struct iommufd_device *idev);
 void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
                                  struct iommufd_attach_handle *handle);