0001
0002
0003
0004
0005 #include <linux/mutex.h>
0006 #include <linux/sched/mm.h>
0007
0008 #include "iommu-sva-lib.h"
0009
0010 static DEFINE_MUTEX(iommu_sva_lock);
0011 static DECLARE_IOASID_SET(iommu_sva_pasid);
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 int iommu_sva_alloc_pasid(struct mm_struct *mm, ioasid_t min, ioasid_t max)
0026 {
0027 int ret = 0;
0028 ioasid_t pasid;
0029
0030 if (min == INVALID_IOASID || max == INVALID_IOASID ||
0031 min == 0 || max < min)
0032 return -EINVAL;
0033
0034 mutex_lock(&iommu_sva_lock);
0035
0036 if (pasid_valid(mm->pasid)) {
0037 if (mm->pasid < min || mm->pasid >= max)
0038 ret = -EOVERFLOW;
0039 goto out;
0040 }
0041
0042 pasid = ioasid_alloc(&iommu_sva_pasid, min, max, mm);
0043 if (!pasid_valid(pasid))
0044 ret = -ENOMEM;
0045 else
0046 mm_pasid_set(mm, pasid);
0047 out:
0048 mutex_unlock(&iommu_sva_lock);
0049 return ret;
0050 }
0051 EXPORT_SYMBOL_GPL(iommu_sva_alloc_pasid);
0052
0053
0054 static bool __mmget_not_zero(void *mm)
0055 {
0056 return mmget_not_zero(mm);
0057 }
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 struct mm_struct *iommu_sva_find(ioasid_t pasid)
0068 {
0069 return ioasid_find(&iommu_sva_pasid, pasid, __mmget_not_zero);
0070 }
0071 EXPORT_SYMBOL_GPL(iommu_sva_find);