aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/iommu/iommu.c13
-rw-r--r--include/linux/iommu.h51
2 files changed, 64 insertions, 0 deletions
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 6e6b6a11b3ce..b75d9fb2fa91 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -39,6 +39,19 @@ bool iommu_found(void)
39} 39}
40EXPORT_SYMBOL_GPL(iommu_found); 40EXPORT_SYMBOL_GPL(iommu_found);
41 41
42/**
43 * iommu_set_fault_handler() - set a fault handler for an iommu domain
44 * @domain: iommu domain
45 * @handler: fault handler
46 */
47void iommu_set_fault_handler(struct iommu_domain *domain,
48 iommu_fault_handler_t handler)
49{
50 BUG_ON(!domain);
51
52 domain->handler = handler;
53}
54
42struct iommu_domain *iommu_domain_alloc(void) 55struct iommu_domain *iommu_domain_alloc(void)
43{ 56{
44 struct iommu_domain *domain; 57 struct iommu_domain *domain;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 9940319d6f9d..d084e8777e0e 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -26,9 +26,18 @@
26#define IOMMU_CACHE (4) /* DMA cache coherency */ 26#define IOMMU_CACHE (4) /* DMA cache coherency */
27 27
28struct device; 28struct device;
29struct iommu_domain;
30
31/* iommu fault flags */
32#define IOMMU_FAULT_READ 0x0
33#define IOMMU_FAULT_WRITE 0x1
34
35typedef int (*iommu_fault_handler_t)(struct iommu_domain *,
36 struct device *, unsigned long, int);
29 37
30struct iommu_domain { 38struct iommu_domain {
31 void *priv; 39 void *priv;
40 iommu_fault_handler_t handler;
32}; 41};
33 42
34#define IOMMU_CAP_CACHE_COHERENCY 0x1 43#define IOMMU_CAP_CACHE_COHERENCY 0x1
@@ -67,6 +76,43 @@ extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
67 unsigned long iova); 76 unsigned long iova);
68extern int iommu_domain_has_cap(struct iommu_domain *domain, 77extern int iommu_domain_has_cap(struct iommu_domain *domain,
69 unsigned long cap); 78 unsigned long cap);
79extern void iommu_set_fault_handler(struct iommu_domain *domain,
80 iommu_fault_handler_t handler);
81
82/**
83 * report_iommu_fault() - report about an IOMMU fault to the IOMMU framework
84 * @domain: the iommu domain where the fault has happened
85 * @dev: the device where the fault has happened
86 * @iova: the faulting address
87 * @flags: mmu fault flags (e.g. IOMMU_FAULT_READ/IOMMU_FAULT_WRITE/...)
88 *
89 * This function should be called by the low-level IOMMU implementations
90 * whenever IOMMU faults happen, to allow high-level users, that are
91 * interested in such events, to know about them.
92 *
93 * This event may be useful for several possible use cases:
94 * - mere logging of the event
95 * - dynamic TLB/PTE loading
96 * - if restarting of the faulting device is required
97 *
98 * Returns 0 on success and an appropriate error code otherwise (if dynamic
99 * PTE/TLB loading will one day be supported, implementations will be able
100 * to tell whether it succeeded or not according to this return value).
101 */
102static inline int report_iommu_fault(struct iommu_domain *domain,
103 struct device *dev, unsigned long iova, int flags)
104{
105 int ret = 0;
106
107 /*
108 * if upper layers showed interest and installed a fault handler,
109 * invoke it.
110 */
111 if (domain->handler)
112 ret = domain->handler(domain, dev, iova, flags);
113
114 return ret;
115}
70 116
71#else /* CONFIG_IOMMU_API */ 117#else /* CONFIG_IOMMU_API */
72 118
@@ -123,6 +169,11 @@ static inline int domain_has_cap(struct iommu_domain *domain,
123 return 0; 169 return 0;
124} 170}
125 171
172static inline void iommu_set_fault_handler(struct iommu_domain *domain,
173 iommu_fault_handler_t handler)
174{
175}
176
126#endif /* CONFIG_IOMMU_API */ 177#endif /* CONFIG_IOMMU_API */
127 178
128#endif /* __LINUX_IOMMU_H */ 179#endif /* __LINUX_IOMMU_H */