iommufd: Remove unnecessary IOMMU_DEV_FEAT_IOPF
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>pull/1253/head
parent
ec027bf7e8
commit
be2a24322c
|
|
@ -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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
@ -18,50 +16,6 @@
|
|||
#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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue