Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 15060aba authored by CQ Tang's avatar CQ Tang Committed by Joerg Roedel
Browse files

iommu/vt-d: Helper function to query if a pasid has any active users



A driver would need to know if there are any active references to a
a PASID before cleaning up its resources. This function helps check
if there are any active users of a PASID before it can perform any
recovery on that device.

To: Joerg Roedel <joro@8bytes.org>
To: linux-kernel@vger.kernel.org
To: David Woodhouse <dwmw2@infradead.org>
Cc: Jean-Phillipe Brucker <jean-philippe.brucker@arm.com>
Cc: iommu@lists.linux-foundation.org

Signed-off-by: default avatarCQ Tang <cq.tang@intel.com>
Signed-off-by: default avatarAshok Raj <ashok.raj@intel.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 2ea659a9
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -489,6 +489,36 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
}
EXPORT_SYMBOL_GPL(intel_svm_unbind_mm);

int intel_svm_is_pasid_valid(struct device *dev, int pasid)
{
	struct intel_iommu *iommu;
	struct intel_svm *svm;
	int ret = -EINVAL;

	mutex_lock(&pasid_mutex);
	iommu = intel_svm_device_to_iommu(dev);
	if (!iommu || !iommu->pasid_table)
		goto out;

	svm = idr_find(&iommu->pasid_idr, pasid);
	if (!svm)
		goto out;

	/* init_mm is used in this case */
	if (!svm->mm)
		ret = 1;
	else if (atomic_read(&svm->mm->mm_users) > 0)
		ret = 1;
	else
		ret = 0;

 out:
	mutex_unlock(&pasid_mutex);

	return ret;
}
EXPORT_SYMBOL_GPL(intel_svm_is_pasid_valid);

/* Page request queue descriptor */
struct page_req_dsc {
	u64 srr:1;
+20 −0
Original line number Diff line number Diff line
@@ -102,6 +102,21 @@ extern int intel_svm_bind_mm(struct device *dev, int *pasid, int flags,
 */
extern int intel_svm_unbind_mm(struct device *dev, int pasid);

/**
 * intel_svm_is_pasid_valid() - check if pasid is valid
 * @dev:	Device for which PASID was allocated
 * @pasid:	PASID value to be checked
 *
 * This function checks if the specified pasid is still valid. A
 * valid pasid means the backing mm is still having a valid user.
 * For kernel callers init_mm is always valid. for other mm, if mm->mm_users
 * is non-zero, it is valid.
 *
 * returns -EINVAL if invalid pasid, 0 if pasid ref count is invalid
 * 1 if pasid is valid.
 */
extern int intel_svm_is_pasid_valid(struct device *dev, int pasid);

#else /* CONFIG_INTEL_IOMMU_SVM */

static inline int intel_svm_bind_mm(struct device *dev, int *pasid,
@@ -114,6 +129,11 @@ static inline int intel_svm_unbind_mm(struct device *dev, int pasid)
{
	BUG();
}

static int intel_svm_is_pasid_valid(struct device *dev, int pasid)
{
	return -EINVAL;
}
#endif /* CONFIG_INTEL_IOMMU_SVM */

#define intel_svm_available(dev) (!intel_svm_bind_mm((dev), NULL, 0, NULL))