@@ -1399,6 +1399,9 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev,
struct mm_struct *mm);
void iommu_sva_unbind_device(struct iommu_sva *handle);
u32 iommu_sva_get_pasid(struct iommu_sva *handle);
+enum iommu_page_response_code
+iommu_sva_handle_iopf(struct iommu_fault *fault,
+ struct device *dev, void *data);
#else
static inline struct iommu_sva *
iommu_sva_bind_device(struct device *dev, struct mm_struct *mm)
@@ -1417,6 +1420,11 @@ static inline u32 iommu_sva_get_pasid(struct iommu_sva *handle)
static inline void mm_pasid_init(struct mm_struct *mm) {}
static inline bool mm_valid_pasid(struct mm_struct *mm) { return false; }
static inline void mm_pasid_drop(struct mm_struct *mm) {}
+static inline enum iommu_page_response_code
+iommu_sva_handle_iopf(struct iommu_fault *fault, struct device *dev, void *data)
+{
+ return IOMMU_PAGE_RESP_INVALID;
+}
#endif /* CONFIG_IOMMU_SVA */
#endif /* __LINUX_IOMMU_H */
similarity index 69%
rename from drivers/iommu/iommu-sva.h
rename to drivers/iommu/io-pgfault.h
@@ -1,18 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * SVA library for IOMMU drivers
+ * I/O page fault helpers for IOMMU drivers
*/
-#ifndef _IOMMU_SVA_H
-#define _IOMMU_SVA_H
+#ifndef _IOMMU_PGFAULT_H
+#define _IOMMU_PGFAULT_H
-#include <linux/mm_types.h>
-
-/* I/O Page fault */
struct device;
struct iommu_fault;
struct iopf_queue;
-#ifdef CONFIG_IOMMU_SVA
+#ifdef CONFIG_IOMMU_PGFAULT
int iommu_queue_iopf(struct iommu_fault *fault, void *cookie);
int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev);
@@ -22,11 +19,8 @@ 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,
- struct device *dev, void *data);
-#else /* CONFIG_IOMMU_SVA */
+#else /* CONFIG_IOMMU_PGFAULT */
static inline int iommu_queue_iopf(struct iommu_fault *fault, void *cookie)
{
return -ENODEV;
@@ -62,11 +56,5 @@ 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, struct device *dev, void *data)
-{
- return IOMMU_PAGE_RESP_INVALID;
-}
-#endif /* CONFIG_IOMMU_SVA */
-#endif /* _IOMMU_SVA_H */
+#endif /* CONFIG_IOMMU_PGFAULT */
+#endif /* _IOMMU_PGFAULT_H */
@@ -10,7 +10,7 @@
#include <linux/slab.h>
#include "arm-smmu-v3.h"
-#include "../../iommu-sva.h"
+#include "../../io-pgfault.h"
#include "../../io-pgtable-arm.h"
struct arm_smmu_mmu_notifier {
@@ -30,7 +30,7 @@
#include "arm-smmu-v3.h"
#include "../../dma-iommu.h"
-#include "../../iommu-sva.h"
+#include "../../io-pgfault.h"
static bool disable_bypass = true;
module_param(disable_bypass, bool, 0444);
@@ -26,7 +26,7 @@
#include "iommu.h"
#include "../dma-iommu.h"
#include "../irq_remapping.h"
-#include "../iommu-sva.h"
+#include "../io-pgfault.h"
#include "pasid.h"
#include "cap_audit.h"
#include "perfmon.h"
@@ -22,7 +22,7 @@
#include "iommu.h"
#include "pasid.h"
#include "perf.h"
-#include "../iommu-sva.h"
+#include "../io-pgfault.h"
#include "trace.h"
static irqreturn_t prq_event_thread(int irq, void *d);
@@ -11,7 +11,7 @@
#include <linux/slab.h>
#include <linux/workqueue.h>
-#include "iommu-sva.h"
+#include "io-pgfault.h"
/**
* struct iopf_queue - IO Page Fault queue
@@ -7,7 +7,7 @@
#include <linux/sched/mm.h>
#include <linux/iommu.h>
-#include "iommu-sva.h"
+#include "io-pgfault.h"
static DEFINE_MUTEX(iommu_sva_lock);
static DEFINE_IDA(iommu_global_pasid_ida);
@@ -36,7 +36,7 @@
#include "dma-iommu.h"
#include "iommu-priv.h"
-#include "iommu-sva.h"
+#include "io-pgfault.h"
#include "iommu-priv.h"
@@ -157,6 +157,9 @@ config IOMMU_DMA
config IOMMU_SVA
bool
+config IOMMU_PGFAULT
+ bool
+
config FSL_PAMU
bool "Freescale IOMMU support"
depends on PCI
@@ -402,6 +405,7 @@ config ARM_SMMU_V3_SVA
bool "Shared Virtual Addressing support for the ARM SMMUv3"
depends on ARM_SMMU_V3
select IOMMU_SVA
+ select IOMMU_PGFAULT
select MMU_NOTIFIER
help
Support for sharing process address spaces with devices using the
@@ -27,6 +27,7 @@ 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.o io-pgfault.o
+obj-$(CONFIG_IOMMU_SVA) += iommu-sva.o
+obj-$(CONFIG_IOMMU_PGFAULT) += io-pgfault.o
obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o
obj-$(CONFIG_APPLE_DART) += apple-dart.o
@@ -15,6 +15,7 @@ config INTEL_IOMMU
select DMA_OPS
select IOMMU_API
select IOMMU_IOVA
+ select IOMMU_PGFAULT
select NEED_DMA_MAP_STATE
select DMAR_TABLE
select SWIOTLB
The current IO page fault handling framework is tightly coupled with the SVA implementation, as SVA is the only use case that requires IO page fault handling. However, with the introduction of nested translation, the first level page table is now managed by userspace. This means that any IO page fault generated for this first level IO address should be routed to userspace and handled there. To support this, we need to split the IO page fault handling framework from the SVA implementation, and make it generic for all use cases. Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> --- include/linux/iommu.h | 8 ++++++ drivers/iommu/{iommu-sva.h => io-pgfault.h} | 26 +++++-------------- .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 2 +- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +- drivers/iommu/intel/iommu.c | 2 +- drivers/iommu/intel/svm.c | 2 +- drivers/iommu/io-pgfault.c | 2 +- drivers/iommu/iommu-sva.c | 2 +- drivers/iommu/iommu.c | 2 +- drivers/iommu/Kconfig | 4 +++ drivers/iommu/Makefile | 3 ++- drivers/iommu/intel/Kconfig | 1 + 12 files changed, 29 insertions(+), 27 deletions(-) rename drivers/iommu/{iommu-sva.h => io-pgfault.h} (69%)