iommu: Rename iommu-sva-lib.{c,h}
authorLu Baolu <baolu.lu@linux.intel.com>
Mon, 31 Oct 2022 00:59:17 +0000 (08:59 +0800)
committerJoerg Roedel <jroedel@suse.de>
Thu, 3 Nov 2022 14:47:54 +0000 (15:47 +0100)
Rename iommu-sva-lib.c[h] to iommu-sva.c[h] as it contains all code
for SVA implementation in iommu core.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Tested-by: Tony Zhu <tony.zhu@intel.com>
Link: https://lore.kernel.org/r/20221031005917.45690-14-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/Makefile
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
drivers/iommu/intel/iommu.c
drivers/iommu/intel/svm.c
drivers/iommu/io-pgfault.c
drivers/iommu/iommu-sva-lib.c [deleted file]
drivers/iommu/iommu-sva-lib.h [deleted file]
drivers/iommu/iommu-sva.c [new file with mode: 0644]
drivers/iommu/iommu-sva.h [new file with mode: 0644]
drivers/iommu/iommu.c

index cc9f381013c35fd1fcc44a9f280dad8cdf48730b..7fbf6a3376620e26131a03b71a9df585e202c975 100644 (file)
@@ -28,6 +28,6 @@ obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
 obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
 obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o
 obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
-obj-$(CONFIG_IOMMU_SVA) += iommu-sva-lib.o io-pgfault.o
+obj-$(CONFIG_IOMMU_SVA) += iommu-sva.o io-pgfault.o
 obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o
 obj-$(CONFIG_APPLE_DART) += apple-dart.o
index 9541afbba73c5687e4b6b9feaa64ff3ce87808ed..a5a63b1c947eb1daaec72db4ba7c6ca6f5d5c6a4 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/slab.h>
 
 #include "arm-smmu-v3.h"
-#include "../../iommu-sva-lib.h"
+#include "../../iommu-sva.h"
 #include "../../io-pgtable-arm.h"
 
 struct arm_smmu_mmu_notifier {
index 891e87ea54dbe238e6bfe0378badad8635351ddc..94a2e53368af9506e2d55312ac13972c8b5f8813 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "arm-smmu-v3.h"
 #include "../../dma-iommu.h"
-#include "../../iommu-sva-lib.h"
+#include "../../iommu-sva.h"
 
 static bool disable_bypass = true;
 module_param(disable_bypass, bool, 0444);
index 5a41b10593b7a5608729c479af219bebee938f40..a934a46bb9e65f2059dd2a3872fdcdb3952e0e12 100644 (file)
@@ -27,7 +27,7 @@
 #include "iommu.h"
 #include "../dma-iommu.h"
 #include "../irq_remapping.h"
-#include "../iommu-sva-lib.h"
+#include "../iommu-sva.h"
 #include "pasid.h"
 #include "cap_audit.h"
 
index fceae93870189407ad715c022a96c14276b35eb3..f32de15da61a2325e49cac38ad9c890fb40a239f 100644 (file)
@@ -24,7 +24,7 @@
 #include "iommu.h"
 #include "pasid.h"
 #include "perf.h"
-#include "../iommu-sva-lib.h"
+#include "../iommu-sva.h"
 #include "trace.h"
 
 static irqreturn_t prq_event_thread(int irq, void *d);
index d046d89cec553dfef0c70b734cbea408fa6cea93..e5b8b9110c132aa88444e52fd75585aba1945bab 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 
-#include "iommu-sva-lib.h"
+#include "iommu-sva.h"
 
 /**
  * struct iopf_queue - IO Page Fault queue
diff --git a/drivers/iommu/iommu-sva-lib.c b/drivers/iommu/iommu-sva-lib.c
deleted file mode 100644 (file)
index 089fd61..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Helpers for IOMMU drivers implementing SVA
- */
-#include <linux/mutex.h>
-#include <linux/sched/mm.h>
-#include <linux/iommu.h>
-
-#include "iommu-sva-lib.h"
-
-static DEFINE_MUTEX(iommu_sva_lock);
-static DECLARE_IOASID_SET(iommu_sva_pasid);
-
-/**
- * iommu_sva_alloc_pasid - Allocate a PASID for the mm
- * @mm: the mm
- * @min: minimum PASID value (inclusive)
- * @max: maximum PASID value (inclusive)
- *
- * Try to allocate a PASID for this mm, or take a reference to the existing one
- * provided it fits within the [@min, @max] range. On success the PASID is
- * available in mm->pasid and will be available for the lifetime of the mm.
- *
- * Returns 0 on success and < 0 on error.
- */
-int iommu_sva_alloc_pasid(struct mm_struct *mm, ioasid_t min, ioasid_t max)
-{
-       int ret = 0;
-       ioasid_t pasid;
-
-       if (min == INVALID_IOASID || max == INVALID_IOASID ||
-           min == 0 || max < min)
-               return -EINVAL;
-
-       mutex_lock(&iommu_sva_lock);
-       /* Is a PASID already associated with this mm? */
-       if (pasid_valid(mm->pasid)) {
-               if (mm->pasid < min || mm->pasid >= max)
-                       ret = -EOVERFLOW;
-               goto out;
-       }
-
-       pasid = ioasid_alloc(&iommu_sva_pasid, min, max, mm);
-       if (!pasid_valid(pasid))
-               ret = -ENOMEM;
-       else
-               mm_pasid_set(mm, pasid);
-out:
-       mutex_unlock(&iommu_sva_lock);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(iommu_sva_alloc_pasid);
-
-/* ioasid_find getter() requires a void * argument */
-static bool __mmget_not_zero(void *mm)
-{
-       return mmget_not_zero(mm);
-}
-
-/**
- * iommu_sva_find() - Find mm associated to the given PASID
- * @pasid: Process Address Space ID assigned to the mm
- *
- * On success a reference to the mm is taken, and must be released with mmput().
- *
- * Returns the mm corresponding to this PASID, or an error if not found.
- */
-struct mm_struct *iommu_sva_find(ioasid_t pasid)
-{
-       return ioasid_find(&iommu_sva_pasid, pasid, __mmget_not_zero);
-}
-EXPORT_SYMBOL_GPL(iommu_sva_find);
-
-/**
- * iommu_sva_bind_device() - Bind a process address space to a device
- * @dev: the device
- * @mm: the mm to bind, caller must hold a reference to mm_users
- *
- * Create a bond between device and address space, allowing the device to
- * access the mm using the PASID returned by iommu_sva_get_pasid(). If a
- * bond already exists between @device and @mm, an additional internal
- * reference is taken. Caller must call iommu_sva_unbind_device()
- * to release each reference.
- *
- * iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA) must be called first, to
- * initialize the required SVA features.
- *
- * On error, returns an ERR_PTR value.
- */
-struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm)
-{
-       struct iommu_domain *domain;
-       struct iommu_sva *handle;
-       ioasid_t max_pasids;
-       int ret;
-
-       max_pasids = dev->iommu->max_pasids;
-       if (!max_pasids)
-               return ERR_PTR(-EOPNOTSUPP);
-
-       /* Allocate mm->pasid if necessary. */
-       ret = iommu_sva_alloc_pasid(mm, 1, max_pasids - 1);
-       if (ret)
-               return ERR_PTR(ret);
-
-       handle = kzalloc(sizeof(*handle), GFP_KERNEL);
-       if (!handle)
-               return ERR_PTR(-ENOMEM);
-
-       mutex_lock(&iommu_sva_lock);
-       /* Search for an existing domain. */
-       domain = iommu_get_domain_for_dev_pasid(dev, mm->pasid,
-                                               IOMMU_DOMAIN_SVA);
-       if (IS_ERR(domain)) {
-               ret = PTR_ERR(domain);
-               goto out_unlock;
-       }
-
-       if (domain) {
-               domain->users++;
-               goto out;
-       }
-
-       /* Allocate a new domain and set it on device pasid. */
-       domain = iommu_sva_domain_alloc(dev, mm);
-       if (!domain) {
-               ret = -ENOMEM;
-               goto out_unlock;
-       }
-
-       ret = iommu_attach_device_pasid(domain, dev, mm->pasid);
-       if (ret)
-               goto out_free_domain;
-       domain->users = 1;
-out:
-       mutex_unlock(&iommu_sva_lock);
-       handle->dev = dev;
-       handle->domain = domain;
-
-       return handle;
-
-out_free_domain:
-       iommu_domain_free(domain);
-out_unlock:
-       mutex_unlock(&iommu_sva_lock);
-       kfree(handle);
-
-       return ERR_PTR(ret);
-}
-EXPORT_SYMBOL_GPL(iommu_sva_bind_device);
-
-/**
- * iommu_sva_unbind_device() - Remove a bond created with iommu_sva_bind_device
- * @handle: the handle returned by iommu_sva_bind_device()
- *
- * Put reference to a bond between device and address space. The device should
- * not be issuing any more transaction for this PASID. All outstanding page
- * requests for this PASID must have been flushed to the IOMMU.
- */
-void iommu_sva_unbind_device(struct iommu_sva *handle)
-{
-       struct iommu_domain *domain = handle->domain;
-       ioasid_t pasid = domain->mm->pasid;
-       struct device *dev = handle->dev;
-
-       mutex_lock(&iommu_sva_lock);
-       if (--domain->users == 0) {
-               iommu_detach_device_pasid(domain, dev, pasid);
-               iommu_domain_free(domain);
-       }
-       mutex_unlock(&iommu_sva_lock);
-       kfree(handle);
-}
-EXPORT_SYMBOL_GPL(iommu_sva_unbind_device);
-
-u32 iommu_sva_get_pasid(struct iommu_sva *handle)
-{
-       struct iommu_domain *domain = handle->domain;
-
-       return domain->mm->pasid;
-}
-EXPORT_SYMBOL_GPL(iommu_sva_get_pasid);
-
-/*
- * I/O page fault handler for SVA
- */
-enum iommu_page_response_code
-iommu_sva_handle_iopf(struct iommu_fault *fault, void *data)
-{
-       vm_fault_t ret;
-       struct vm_area_struct *vma;
-       struct mm_struct *mm = data;
-       unsigned int access_flags = 0;
-       unsigned int fault_flags = FAULT_FLAG_REMOTE;
-       struct iommu_fault_page_request *prm = &fault->prm;
-       enum iommu_page_response_code status = IOMMU_PAGE_RESP_INVALID;
-
-       if (!(prm->flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID))
-               return status;
-
-       if (!mmget_not_zero(mm))
-               return status;
-
-       mmap_read_lock(mm);
-
-       vma = find_extend_vma(mm, prm->addr);
-       if (!vma)
-               /* Unmapped area */
-               goto out_put_mm;
-
-       if (prm->perm & IOMMU_FAULT_PERM_READ)
-               access_flags |= VM_READ;
-
-       if (prm->perm & IOMMU_FAULT_PERM_WRITE) {
-               access_flags |= VM_WRITE;
-               fault_flags |= FAULT_FLAG_WRITE;
-       }
-
-       if (prm->perm & IOMMU_FAULT_PERM_EXEC) {
-               access_flags |= VM_EXEC;
-               fault_flags |= FAULT_FLAG_INSTRUCTION;
-       }
-
-       if (!(prm->perm & IOMMU_FAULT_PERM_PRIV))
-               fault_flags |= FAULT_FLAG_USER;
-
-       if (access_flags & ~vma->vm_flags)
-               /* Access fault */
-               goto out_put_mm;
-
-       ret = handle_mm_fault(vma, prm->addr, fault_flags, NULL);
-       status = ret & VM_FAULT_ERROR ? IOMMU_PAGE_RESP_INVALID :
-               IOMMU_PAGE_RESP_SUCCESS;
-
-out_put_mm:
-       mmap_read_unlock(mm);
-       mmput(mm);
-
-       return status;
-}
diff --git a/drivers/iommu/iommu-sva-lib.h b/drivers/iommu/iommu-sva-lib.h
deleted file mode 100644 (file)
index 1b3ace4..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * SVA library for IOMMU drivers
- */
-#ifndef _IOMMU_SVA_LIB_H
-#define _IOMMU_SVA_LIB_H
-
-#include <linux/ioasid.h>
-#include <linux/mm_types.h>
-
-int iommu_sva_alloc_pasid(struct mm_struct *mm, ioasid_t min, ioasid_t max);
-struct mm_struct *iommu_sva_find(ioasid_t pasid);
-
-/* I/O Page fault */
-struct device;
-struct iommu_fault;
-struct iopf_queue;
-
-#ifdef CONFIG_IOMMU_SVA
-int iommu_queue_iopf(struct iommu_fault *fault, void *cookie);
-
-int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev);
-int iopf_queue_remove_device(struct iopf_queue *queue,
-                            struct device *dev);
-int iopf_queue_flush_dev(struct device *dev);
-struct iopf_queue *iopf_queue_alloc(const char *name);
-void iopf_queue_free(struct iopf_queue *queue);
-int iopf_queue_discard_partial(struct iopf_queue *queue);
-enum iommu_page_response_code
-iommu_sva_handle_iopf(struct iommu_fault *fault, void *data);
-
-#else /* CONFIG_IOMMU_SVA */
-static inline int iommu_queue_iopf(struct iommu_fault *fault, void *cookie)
-{
-       return -ENODEV;
-}
-
-static inline int iopf_queue_add_device(struct iopf_queue *queue,
-                                       struct device *dev)
-{
-       return -ENODEV;
-}
-
-static inline int iopf_queue_remove_device(struct iopf_queue *queue,
-                                          struct device *dev)
-{
-       return -ENODEV;
-}
-
-static inline int iopf_queue_flush_dev(struct device *dev)
-{
-       return -ENODEV;
-}
-
-static inline struct iopf_queue *iopf_queue_alloc(const char *name)
-{
-       return NULL;
-}
-
-static inline void iopf_queue_free(struct iopf_queue *queue)
-{
-}
-
-static inline int iopf_queue_discard_partial(struct iopf_queue *queue)
-{
-       return -ENODEV;
-}
-
-static inline enum iommu_page_response_code
-iommu_sva_handle_iopf(struct iommu_fault *fault, void *data)
-{
-       return IOMMU_PAGE_RESP_INVALID;
-}
-#endif /* CONFIG_IOMMU_SVA */
-#endif /* _IOMMU_SVA_LIB_H */
diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
new file mode 100644 (file)
index 0000000..24bf9b2
--- /dev/null
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Helpers for IOMMU drivers implementing SVA
+ */
+#include <linux/mutex.h>
+#include <linux/sched/mm.h>
+#include <linux/iommu.h>
+
+#include "iommu-sva.h"
+
+static DEFINE_MUTEX(iommu_sva_lock);
+static DECLARE_IOASID_SET(iommu_sva_pasid);
+
+/**
+ * iommu_sva_alloc_pasid - Allocate a PASID for the mm
+ * @mm: the mm
+ * @min: minimum PASID value (inclusive)
+ * @max: maximum PASID value (inclusive)
+ *
+ * Try to allocate a PASID for this mm, or take a reference to the existing one
+ * provided it fits within the [@min, @max] range. On success the PASID is
+ * available in mm->pasid and will be available for the lifetime of the mm.
+ *
+ * Returns 0 on success and < 0 on error.
+ */
+int iommu_sva_alloc_pasid(struct mm_struct *mm, ioasid_t min, ioasid_t max)
+{
+       int ret = 0;
+       ioasid_t pasid;
+
+       if (min == INVALID_IOASID || max == INVALID_IOASID ||
+           min == 0 || max < min)
+               return -EINVAL;
+
+       mutex_lock(&iommu_sva_lock);
+       /* Is a PASID already associated with this mm? */
+       if (pasid_valid(mm->pasid)) {
+               if (mm->pasid < min || mm->pasid >= max)
+                       ret = -EOVERFLOW;
+               goto out;
+       }
+
+       pasid = ioasid_alloc(&iommu_sva_pasid, min, max, mm);
+       if (!pasid_valid(pasid))
+               ret = -ENOMEM;
+       else
+               mm_pasid_set(mm, pasid);
+out:
+       mutex_unlock(&iommu_sva_lock);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_sva_alloc_pasid);
+
+/* ioasid_find getter() requires a void * argument */
+static bool __mmget_not_zero(void *mm)
+{
+       return mmget_not_zero(mm);
+}
+
+/**
+ * iommu_sva_find() - Find mm associated to the given PASID
+ * @pasid: Process Address Space ID assigned to the mm
+ *
+ * On success a reference to the mm is taken, and must be released with mmput().
+ *
+ * Returns the mm corresponding to this PASID, or an error if not found.
+ */
+struct mm_struct *iommu_sva_find(ioasid_t pasid)
+{
+       return ioasid_find(&iommu_sva_pasid, pasid, __mmget_not_zero);
+}
+EXPORT_SYMBOL_GPL(iommu_sva_find);
+
+/**
+ * iommu_sva_bind_device() - Bind a process address space to a device
+ * @dev: the device
+ * @mm: the mm to bind, caller must hold a reference to mm_users
+ *
+ * Create a bond between device and address space, allowing the device to
+ * access the mm using the PASID returned by iommu_sva_get_pasid(). If a
+ * bond already exists between @device and @mm, an additional internal
+ * reference is taken. Caller must call iommu_sva_unbind_device()
+ * to release each reference.
+ *
+ * iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA) must be called first, to
+ * initialize the required SVA features.
+ *
+ * On error, returns an ERR_PTR value.
+ */
+struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm)
+{
+       struct iommu_domain *domain;
+       struct iommu_sva *handle;
+       ioasid_t max_pasids;
+       int ret;
+
+       max_pasids = dev->iommu->max_pasids;
+       if (!max_pasids)
+               return ERR_PTR(-EOPNOTSUPP);
+
+       /* Allocate mm->pasid if necessary. */
+       ret = iommu_sva_alloc_pasid(mm, 1, max_pasids - 1);
+       if (ret)
+               return ERR_PTR(ret);
+
+       handle = kzalloc(sizeof(*handle), GFP_KERNEL);
+       if (!handle)
+               return ERR_PTR(-ENOMEM);
+
+       mutex_lock(&iommu_sva_lock);
+       /* Search for an existing domain. */
+       domain = iommu_get_domain_for_dev_pasid(dev, mm->pasid,
+                                               IOMMU_DOMAIN_SVA);
+       if (IS_ERR(domain)) {
+               ret = PTR_ERR(domain);
+               goto out_unlock;
+       }
+
+       if (domain) {
+               domain->users++;
+               goto out;
+       }
+
+       /* Allocate a new domain and set it on device pasid. */
+       domain = iommu_sva_domain_alloc(dev, mm);
+       if (!domain) {
+               ret = -ENOMEM;
+               goto out_unlock;
+       }
+
+       ret = iommu_attach_device_pasid(domain, dev, mm->pasid);
+       if (ret)
+               goto out_free_domain;
+       domain->users = 1;
+out:
+       mutex_unlock(&iommu_sva_lock);
+       handle->dev = dev;
+       handle->domain = domain;
+
+       return handle;
+
+out_free_domain:
+       iommu_domain_free(domain);
+out_unlock:
+       mutex_unlock(&iommu_sva_lock);
+       kfree(handle);
+
+       return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(iommu_sva_bind_device);
+
+/**
+ * iommu_sva_unbind_device() - Remove a bond created with iommu_sva_bind_device
+ * @handle: the handle returned by iommu_sva_bind_device()
+ *
+ * Put reference to a bond between device and address space. The device should
+ * not be issuing any more transaction for this PASID. All outstanding page
+ * requests for this PASID must have been flushed to the IOMMU.
+ */
+void iommu_sva_unbind_device(struct iommu_sva *handle)
+{
+       struct iommu_domain *domain = handle->domain;
+       ioasid_t pasid = domain->mm->pasid;
+       struct device *dev = handle->dev;
+
+       mutex_lock(&iommu_sva_lock);
+       if (--domain->users == 0) {
+               iommu_detach_device_pasid(domain, dev, pasid);
+               iommu_domain_free(domain);
+       }
+       mutex_unlock(&iommu_sva_lock);
+       kfree(handle);
+}
+EXPORT_SYMBOL_GPL(iommu_sva_unbind_device);
+
+u32 iommu_sva_get_pasid(struct iommu_sva *handle)
+{
+       struct iommu_domain *domain = handle->domain;
+
+       return domain->mm->pasid;
+}
+EXPORT_SYMBOL_GPL(iommu_sva_get_pasid);
+
+/*
+ * I/O page fault handler for SVA
+ */
+enum iommu_page_response_code
+iommu_sva_handle_iopf(struct iommu_fault *fault, void *data)
+{
+       vm_fault_t ret;
+       struct vm_area_struct *vma;
+       struct mm_struct *mm = data;
+       unsigned int access_flags = 0;
+       unsigned int fault_flags = FAULT_FLAG_REMOTE;
+       struct iommu_fault_page_request *prm = &fault->prm;
+       enum iommu_page_response_code status = IOMMU_PAGE_RESP_INVALID;
+
+       if (!(prm->flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID))
+               return status;
+
+       if (!mmget_not_zero(mm))
+               return status;
+
+       mmap_read_lock(mm);
+
+       vma = find_extend_vma(mm, prm->addr);
+       if (!vma)
+               /* Unmapped area */
+               goto out_put_mm;
+
+       if (prm->perm & IOMMU_FAULT_PERM_READ)
+               access_flags |= VM_READ;
+
+       if (prm->perm & IOMMU_FAULT_PERM_WRITE) {
+               access_flags |= VM_WRITE;
+               fault_flags |= FAULT_FLAG_WRITE;
+       }
+
+       if (prm->perm & IOMMU_FAULT_PERM_EXEC) {
+               access_flags |= VM_EXEC;
+               fault_flags |= FAULT_FLAG_INSTRUCTION;
+       }
+
+       if (!(prm->perm & IOMMU_FAULT_PERM_PRIV))
+               fault_flags |= FAULT_FLAG_USER;
+
+       if (access_flags & ~vma->vm_flags)
+               /* Access fault */
+               goto out_put_mm;
+
+       ret = handle_mm_fault(vma, prm->addr, fault_flags, NULL);
+       status = ret & VM_FAULT_ERROR ? IOMMU_PAGE_RESP_INVALID :
+               IOMMU_PAGE_RESP_SUCCESS;
+
+out_put_mm:
+       mmap_read_unlock(mm);
+       mmput(mm);
+
+       return status;
+}
diff --git a/drivers/iommu/iommu-sva.h b/drivers/iommu/iommu-sva.h
new file mode 100644 (file)
index 0000000..7215a76
--- /dev/null
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * SVA library for IOMMU drivers
+ */
+#ifndef _IOMMU_SVA_H
+#define _IOMMU_SVA_H
+
+#include <linux/ioasid.h>
+#include <linux/mm_types.h>
+
+int iommu_sva_alloc_pasid(struct mm_struct *mm, ioasid_t min, ioasid_t max);
+struct mm_struct *iommu_sva_find(ioasid_t pasid);
+
+/* I/O Page fault */
+struct device;
+struct iommu_fault;
+struct iopf_queue;
+
+#ifdef CONFIG_IOMMU_SVA
+int iommu_queue_iopf(struct iommu_fault *fault, void *cookie);
+
+int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev);
+int iopf_queue_remove_device(struct iopf_queue *queue,
+                            struct device *dev);
+int iopf_queue_flush_dev(struct device *dev);
+struct iopf_queue *iopf_queue_alloc(const char *name);
+void iopf_queue_free(struct iopf_queue *queue);
+int iopf_queue_discard_partial(struct iopf_queue *queue);
+enum iommu_page_response_code
+iommu_sva_handle_iopf(struct iommu_fault *fault, void *data);
+
+#else /* CONFIG_IOMMU_SVA */
+static inline int iommu_queue_iopf(struct iommu_fault *fault, void *cookie)
+{
+       return -ENODEV;
+}
+
+static inline int iopf_queue_add_device(struct iopf_queue *queue,
+                                       struct device *dev)
+{
+       return -ENODEV;
+}
+
+static inline int iopf_queue_remove_device(struct iopf_queue *queue,
+                                          struct device *dev)
+{
+       return -ENODEV;
+}
+
+static inline int iopf_queue_flush_dev(struct device *dev)
+{
+       return -ENODEV;
+}
+
+static inline struct iopf_queue *iopf_queue_alloc(const char *name)
+{
+       return NULL;
+}
+
+static inline void iopf_queue_free(struct iopf_queue *queue)
+{
+}
+
+static inline int iopf_queue_discard_partial(struct iopf_queue *queue)
+{
+       return -ENODEV;
+}
+
+static inline enum iommu_page_response_code
+iommu_sva_handle_iopf(struct iommu_fault *fault, void *data)
+{
+       return IOMMU_PAGE_RESP_INVALID;
+}
+#endif /* CONFIG_IOMMU_SVA */
+#endif /* _IOMMU_SVA_H */
index 9e0fb18e1b34687c0b5a886826a88e3622a4445e..c50f68b2b656ee99702f0467fd30fb836d192bd4 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "dma-iommu.h"
 
-#include "iommu-sva-lib.h"
+#include "iommu-sva.h"
 
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);