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: CQ Tang <cq.tang@intel.com> Signed-off-by: Ashok Raj <ashok.raj@intel.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
2ea659a9ef
commit
15060aba71
|
@ -489,6 +489,36 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(intel_svm_unbind_mm);
|
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 */
|
/* Page request queue descriptor */
|
||||||
struct page_req_dsc {
|
struct page_req_dsc {
|
||||||
u64 srr:1;
|
u64 srr:1;
|
||||||
|
|
|
@ -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);
|
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 */
|
#else /* CONFIG_INTEL_IOMMU_SVM */
|
||||||
|
|
||||||
static inline int intel_svm_bind_mm(struct device *dev, int *pasid,
|
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();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int intel_svm_is_pasid_valid(struct device *dev, int pasid)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
#endif /* CONFIG_INTEL_IOMMU_SVM */
|
#endif /* CONFIG_INTEL_IOMMU_SVM */
|
||||||
|
|
||||||
#define intel_svm_available(dev) (!intel_svm_bind_mm((dev), NULL, 0, NULL))
|
#define intel_svm_available(dev) (!intel_svm_bind_mm((dev), NULL, 0, NULL))
|
||||||
|
|
Loading…
Reference in New Issue