The fault handler will need to find a process given its PASID. This is
the reason we have an IDR for storing processes, so hook it up.

Signed-off-by: Jean-Philippe Brucker <[email protected]>
---
 drivers/iommu/iommu-process.c | 35 +++++++++++++++++++++++++++++++++++
 include/linux/iommu.h         | 12 ++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/drivers/iommu/iommu-process.c b/drivers/iommu/iommu-process.c
index 61ca0bd707c0..8f4c98632d58 100644
--- a/drivers/iommu/iommu-process.c
+++ b/drivers/iommu/iommu-process.c
@@ -145,6 +145,41 @@ static void iommu_process_put_locked(struct iommu_process 
*process)
        kref_put(&process->kref, iommu_process_release);
 }
 
+/**
+ * iommu_process_put - Put reference to process, freeing it if necessary.
+ */
+void iommu_process_put(struct iommu_process *process)
+{
+       spin_lock(&iommu_process_lock);
+       iommu_process_put_locked(process);
+       spin_unlock(&iommu_process_lock);
+}
+EXPORT_SYMBOL_GPL(iommu_process_put);
+
+/**
+ * iommu_process_find - Find process associated to the given PASID
+ *
+ * Returns the IOMMU process corresponding to this PASID, or NULL if not found.
+ * A reference to the iommu_process is kept, and must be released with
+ * iommu_process_put.
+ */
+struct iommu_process *iommu_process_find(int pasid)
+{
+       struct iommu_process *process;
+
+       spin_lock(&iommu_process_lock);
+       process = idr_find(&iommu_process_idr, pasid);
+       if (process) {
+               if (!iommu_process_get_locked(process))
+                       /* kref is 0, process is defunct */
+                       process = NULL;
+       }
+       spin_unlock(&iommu_process_lock);
+
+       return process;
+}
+EXPORT_SYMBOL_GPL(iommu_process_find);
+
 static int iommu_process_attach(struct iommu_domain *domain, struct device 
*dev,
                                struct iommu_process *process)
 {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 8d74f9058f30..e9528fcacab1 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -733,12 +733,24 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct 
fwnode_handle *fwnode)
 extern void iommu_set_process_exit_handler(struct device *dev,
                                           iommu_process_exit_handler_t cb,
                                           void *token);
+extern struct iommu_process *iommu_process_find(int pasid);
+extern void iommu_process_put(struct iommu_process *process);
+
 #else /* CONFIG_IOMMU_PROCESS */
 static inline void iommu_set_process_exit_handler(struct device *dev,
                                                  iommu_process_exit_handler_t 
cb,
                                                  void *token)
 {
 }
+
+static inline struct iommu_process *iommu_process_find(int pasid)
+{
+       return NULL;
+}
+
+static inline void iommu_process_put(struct iommu_process *process)
+{
+}
 #endif /* CONFIG_IOMMU_PROCESS */
 
 #endif /* __LINUX_IOMMU_H */
-- 
2.13.3

_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to