Add IOMMU_SVA_FEAT_AUXD and small helpers to SVA, to setup PASID with
the sva_init_device() IOMMU op and allocate PASIDs.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.bruc...@arm.com>
---
 drivers/iommu/iommu-sva.c | 33 ++++++++++++++++++++++++++++++++-
 include/linux/iommu.h     | 12 ++++++++++++
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
index 28eaa617b4f0..7c5176e2e113 100644
--- a/drivers/iommu/iommu-sva.c
+++ b/drivers/iommu/iommu-sva.c
@@ -117,6 +117,7 @@ struct iommu_bond {
 };
 
 static DECLARE_IOASID_SET(ioasid_shared);
+static DECLARE_IOASID_SET(ioasid_private);
 
 /*
  * For the moment this is an all-purpose lock. It serializes
@@ -663,6 +664,36 @@ struct mm_struct *iommu_sva_find(int pasid)
 }
 EXPORT_SYMBOL_GPL(iommu_sva_find);
 
+int iommu_sva_alloc_pasid(struct device *dev)
+{
+       int ret;
+       struct iommu_sva_param *param;
+
+       if (!dev->iommu_param)
+               return -EINVAL;
+
+       mutex_lock(&dev->iommu_param->sva_lock);
+       param = dev->iommu_param->sva_param;
+       if (!param) {
+               ret = -EINVAL;
+               goto out_unlock;
+       }
+
+       ret = ioasid_alloc(&ioasid_private, param->min_pasid,
+                          param->max_pasid + 1, NULL);
+out_unlock:
+       mutex_unlock(&dev->iommu_param->sva_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_sva_alloc_pasid);
+
+void iommu_sva_free_pasid(int pasid)
+{
+       ioasid_free(pasid);
+}
+EXPORT_SYMBOL_GPL(iommu_sva_free_pasid);
+
 /**
  * iommu_sva_init_device() - Initialize Shared Virtual Addressing for a device
  * @dev: the device
@@ -711,7 +742,7 @@ int iommu_sva_init_device(struct device *dev, unsigned long 
features,
        if (!dev->iommu_param || !ops || !ops->sva_init_device)
                return -ENODEV;
 
-       if (features & ~IOMMU_SVA_FEAT_IOPF)
+       if (features & ~(IOMMU_SVA_FEAT_IOPF | IOMMU_SVA_FEAT_AUXD))
                return -EINVAL;
 
        param = kzalloc(sizeof(*param), GFP_KERNEL);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 67bbc5320c9d..bfa70b1f8897 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -66,6 +66,7 @@ typedef int (*iommu_mm_exit_handler_t)(struct device *dev, 
int pasid, void *);
 #define IOMMU_PASID_INVALID            (-1)
 
 #define IOMMU_SVA_FEAT_IOPF            (1 << 0)
+#define IOMMU_SVA_FEAT_AUXD            (1 << 1)
 
 struct iommu_domain_geometry {
        dma_addr_t aperture_start; /* First address that can be mapped    */
@@ -1035,6 +1036,8 @@ extern int __iommu_sva_bind_device(struct device *dev, 
struct mm_struct *mm,
 extern int __iommu_sva_unbind_device(struct device *dev, int pasid);
 extern void iommu_sva_unbind_device_all(struct device *dev);
 extern struct mm_struct *iommu_sva_find(int pasid);
+extern int iommu_sva_alloc_pasid(struct device *dev);
+extern void iommu_sva_free_pasid(int pasid);
 
 #else /* CONFIG_IOMMU_SVA */
 static inline int iommu_sva_init_device(struct device *dev,
@@ -1070,6 +1073,15 @@ static inline struct mm_struct *iommu_sva_find(int pasid)
 {
        return NULL;
 }
+
+static inline int iommu_sva_alloc_pasid(struct device *dev)
+{
+       return -ENODEV;
+}
+
+static inline void iommu_sva_free_pasid(int pasid)
+{
+}
 #endif /* CONFIG_IOMMU_SVA */
 
 #ifdef CONFIG_IOMMU_PAGE_FAULT
-- 
2.19.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to