Commit be2a2432 authored by Lu Baolu's avatar Lu Baolu Committed by Joerg Roedel
Browse files

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: default avatarLu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Tested-by: default avatarZhangfei Gao <zhangfei.gao@linaro.org>
Link: https://lore.kernel.org/r/20250418080130.1844424-8-baolu.lu@linux.intel.com


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent ec027bf7
Loading
Loading
Loading
Loading
+29 −30
Original line number Diff line number Diff line
@@ -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;
+1 −47
Original line number Diff line number Diff line
@@ -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);

+0 −6
Original line number Diff line number Diff line
@@ -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);