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);
|
refcount_inc(&idev->obj.users);
|
||||||
/* igroup refcount moves into iommufd_device */
|
/* igroup refcount moves into iommufd_device */
|
||||||
idev->igroup = igroup;
|
idev->igroup = igroup;
|
||||||
mutex_init(&idev->iopf_lock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the caller fails after this success it must call
|
* 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;
|
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,
|
static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
|
||||||
struct iommufd_device *idev,
|
struct iommufd_device *idev,
|
||||||
ioasid_t pasid)
|
ioasid_t pasid)
|
||||||
|
|
@ -432,6 +450,9 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
|
||||||
struct iommufd_attach_handle *handle;
|
struct iommufd_attach_handle *handle;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (!iommufd_hwpt_compatible_device(hwpt, idev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid);
|
rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -440,12 +461,6 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
|
||||||
if (!handle)
|
if (!handle)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (hwpt->fault) {
|
|
||||||
rc = iommufd_fault_iopf_enable(idev);
|
|
||||||
if (rc)
|
|
||||||
goto out_free_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
handle->idev = idev;
|
handle->idev = idev;
|
||||||
if (pasid == IOMMU_NO_PASID)
|
if (pasid == IOMMU_NO_PASID)
|
||||||
rc = iommu_attach_group_handle(hwpt->domain, idev->igroup->group,
|
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,
|
rc = iommu_attach_device_pasid(hwpt->domain, idev->dev, pasid,
|
||||||
&handle->handle);
|
&handle->handle);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_disable_iopf;
|
goto out_free_handle;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_disable_iopf:
|
|
||||||
if (hwpt->fault)
|
|
||||||
iommufd_fault_iopf_disable(idev);
|
|
||||||
out_free_handle:
|
out_free_handle:
|
||||||
kfree(handle);
|
kfree(handle);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -492,10 +504,7 @@ static void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
|
||||||
else
|
else
|
||||||
iommu_detach_device_pasid(hwpt->domain, idev->dev, pasid);
|
iommu_detach_device_pasid(hwpt->domain, idev->dev, pasid);
|
||||||
|
|
||||||
if (hwpt->fault) {
|
|
||||||
iommufd_auto_response_faults(hwpt, handle);
|
iommufd_auto_response_faults(hwpt, handle);
|
||||||
iommufd_fault_iopf_disable(idev);
|
|
||||||
}
|
|
||||||
kfree(handle);
|
kfree(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -507,6 +516,9 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
|
||||||
struct iommufd_attach_handle *handle, *old_handle;
|
struct iommufd_attach_handle *handle, *old_handle;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (!iommufd_hwpt_compatible_device(hwpt, idev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid);
|
rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
@ -517,12 +529,6 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
|
||||||
if (!handle)
|
if (!handle)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (hwpt->fault && !old->fault) {
|
|
||||||
rc = iommufd_fault_iopf_enable(idev);
|
|
||||||
if (rc)
|
|
||||||
goto out_free_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
handle->idev = idev;
|
handle->idev = idev;
|
||||||
if (pasid == IOMMU_NO_PASID)
|
if (pasid == IOMMU_NO_PASID)
|
||||||
rc = iommu_replace_group_handle(idev->igroup->group,
|
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,
|
rc = iommu_replace_device_pasid(hwpt->domain, idev->dev,
|
||||||
pasid, &handle->handle);
|
pasid, &handle->handle);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_disable_iopf;
|
goto out_free_handle;
|
||||||
|
|
||||||
if (old->fault) {
|
|
||||||
iommufd_auto_response_faults(hwpt, old_handle);
|
iommufd_auto_response_faults(hwpt, old_handle);
|
||||||
if (!hwpt->fault)
|
|
||||||
iommufd_fault_iopf_disable(idev);
|
|
||||||
}
|
|
||||||
kfree(old_handle);
|
kfree(old_handle);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_disable_iopf:
|
|
||||||
if (hwpt->fault && !old->fault)
|
|
||||||
iommufd_fault_iopf_disable(idev);
|
|
||||||
out_free_handle:
|
out_free_handle:
|
||||||
kfree(handle);
|
kfree(handle);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@
|
||||||
#include <linux/iommufd.h>
|
#include <linux/iommufd.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <linux/pci-ats.h>
|
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
#include <uapi/linux/iommufd.h>
|
#include <uapi/linux/iommufd.h>
|
||||||
|
|
||||||
|
|
@ -18,50 +16,6 @@
|
||||||
#include "iommufd_private.h"
|
#include "iommufd_private.h"
|
||||||
|
|
||||||
/* IOMMUFD_OBJ_FAULT Functions */
|
/* 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,
|
void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
|
||||||
struct iommufd_attach_handle *handle)
|
struct iommufd_attach_handle *handle)
|
||||||
{
|
{
|
||||||
|
|
@ -70,7 +24,7 @@ void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
|
||||||
struct list_head free_list;
|
struct list_head free_list;
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
|
|
||||||
if (!fault)
|
if (!fault || !handle)
|
||||||
return;
|
return;
|
||||||
INIT_LIST_HEAD(&free_list);
|
INIT_LIST_HEAD(&free_list);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -425,9 +425,6 @@ struct iommufd_device {
|
||||||
/* always the physical device */
|
/* always the physical device */
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
bool enforce_cache_coherency;
|
bool enforce_cache_coherency;
|
||||||
/* protect iopf_enabled counter */
|
|
||||||
struct mutex iopf_lock;
|
|
||||||
unsigned int iopf_enabled;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct iommufd_device *
|
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);
|
int iommufd_fault_alloc(struct iommufd_ucmd *ucmd);
|
||||||
void iommufd_fault_destroy(struct iommufd_object *obj);
|
void iommufd_fault_destroy(struct iommufd_object *obj);
|
||||||
int iommufd_fault_iopf_handler(struct iopf_group *group);
|
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,
|
void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,
|
||||||
struct iommufd_attach_handle *handle);
|
struct iommufd_attach_handle *handle);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue