diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/device.h | 6 | ||||
-rw-r--r-- | include/linux/iommu.h | 76 |
2 files changed, 72 insertions, 10 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index c20dfbfc49b4..e838e143baa7 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -33,6 +33,7 @@ struct class; | |||
33 | struct subsys_private; | 33 | struct subsys_private; |
34 | struct bus_type; | 34 | struct bus_type; |
35 | struct device_node; | 35 | struct device_node; |
36 | struct iommu_ops; | ||
36 | 37 | ||
37 | struct bus_attribute { | 38 | struct bus_attribute { |
38 | struct attribute attr; | 39 | struct attribute attr; |
@@ -67,6 +68,9 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); | |||
67 | * @resume: Called to bring a device on this bus out of sleep mode. | 68 | * @resume: Called to bring a device on this bus out of sleep mode. |
68 | * @pm: Power management operations of this bus, callback the specific | 69 | * @pm: Power management operations of this bus, callback the specific |
69 | * device driver's pm-ops. | 70 | * device driver's pm-ops. |
71 | * @iommu_ops IOMMU specific operations for this bus, used to attach IOMMU | ||
72 | * driver implementations to a bus and allow the driver to do | ||
73 | * bus-specific setup | ||
70 | * @p: The private data of the driver core, only the driver core can | 74 | * @p: The private data of the driver core, only the driver core can |
71 | * touch this. | 75 | * touch this. |
72 | * | 76 | * |
@@ -96,6 +100,8 @@ struct bus_type { | |||
96 | 100 | ||
97 | const struct dev_pm_ops *pm; | 101 | const struct dev_pm_ops *pm; |
98 | 102 | ||
103 | struct iommu_ops *iommu_ops; | ||
104 | |||
99 | struct subsys_private *p; | 105 | struct subsys_private *p; |
100 | }; | 106 | }; |
101 | 107 | ||
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 9940319d6f9d..432acc4c054d 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h | |||
@@ -25,15 +25,29 @@ | |||
25 | #define IOMMU_WRITE (2) | 25 | #define IOMMU_WRITE (2) |
26 | #define IOMMU_CACHE (4) /* DMA cache coherency */ | 26 | #define IOMMU_CACHE (4) /* DMA cache coherency */ |
27 | 27 | ||
28 | struct iommu_ops; | ||
29 | struct bus_type; | ||
28 | struct device; | 30 | struct device; |
31 | struct iommu_domain; | ||
32 | |||
33 | /* iommu fault flags */ | ||
34 | #define IOMMU_FAULT_READ 0x0 | ||
35 | #define IOMMU_FAULT_WRITE 0x1 | ||
36 | |||
37 | typedef int (*iommu_fault_handler_t)(struct iommu_domain *, | ||
38 | struct device *, unsigned long, int); | ||
29 | 39 | ||
30 | struct iommu_domain { | 40 | struct iommu_domain { |
41 | struct iommu_ops *ops; | ||
31 | void *priv; | 42 | void *priv; |
43 | iommu_fault_handler_t handler; | ||
32 | }; | 44 | }; |
33 | 45 | ||
34 | #define IOMMU_CAP_CACHE_COHERENCY 0x1 | 46 | #define IOMMU_CAP_CACHE_COHERENCY 0x1 |
35 | #define IOMMU_CAP_INTR_REMAP 0x2 /* isolates device intrs */ | 47 | #define IOMMU_CAP_INTR_REMAP 0x2 /* isolates device intrs */ |
36 | 48 | ||
49 | #ifdef CONFIG_IOMMU_API | ||
50 | |||
37 | struct iommu_ops { | 51 | struct iommu_ops { |
38 | int (*domain_init)(struct iommu_domain *domain); | 52 | int (*domain_init)(struct iommu_domain *domain); |
39 | void (*domain_destroy)(struct iommu_domain *domain); | 53 | void (*domain_destroy)(struct iommu_domain *domain); |
@@ -49,11 +63,9 @@ struct iommu_ops { | |||
49 | unsigned long cap); | 63 | unsigned long cap); |
50 | }; | 64 | }; |
51 | 65 | ||
52 | #ifdef CONFIG_IOMMU_API | 66 | extern int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops); |
53 | 67 | extern bool iommu_present(struct bus_type *bus); | |
54 | extern void register_iommu(struct iommu_ops *ops); | 68 | extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus); |
55 | extern bool iommu_found(void); | ||
56 | extern struct iommu_domain *iommu_domain_alloc(void); | ||
57 | extern void iommu_domain_free(struct iommu_domain *domain); | 69 | extern void iommu_domain_free(struct iommu_domain *domain); |
58 | extern int iommu_attach_device(struct iommu_domain *domain, | 70 | extern int iommu_attach_device(struct iommu_domain *domain, |
59 | struct device *dev); | 71 | struct device *dev); |
@@ -67,19 +79,58 @@ extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, | |||
67 | unsigned long iova); | 79 | unsigned long iova); |
68 | extern int iommu_domain_has_cap(struct iommu_domain *domain, | 80 | extern int iommu_domain_has_cap(struct iommu_domain *domain, |
69 | unsigned long cap); | 81 | unsigned long cap); |
82 | extern void iommu_set_fault_handler(struct iommu_domain *domain, | ||
83 | iommu_fault_handler_t handler); | ||
84 | |||
85 | /** | ||
86 | * report_iommu_fault() - report about an IOMMU fault to the IOMMU framework | ||
87 | * @domain: the iommu domain where the fault has happened | ||
88 | * @dev: the device where the fault has happened | ||
89 | * @iova: the faulting address | ||
90 | * @flags: mmu fault flags (e.g. IOMMU_FAULT_READ/IOMMU_FAULT_WRITE/...) | ||
91 | * | ||
92 | * This function should be called by the low-level IOMMU implementations | ||
93 | * whenever IOMMU faults happen, to allow high-level users, that are | ||
94 | * interested in such events, to know about them. | ||
95 | * | ||
96 | * This event may be useful for several possible use cases: | ||
97 | * - mere logging of the event | ||
98 | * - dynamic TLB/PTE loading | ||
99 | * - if restarting of the faulting device is required | ||
100 | * | ||
101 | * Returns 0 on success and an appropriate error code otherwise (if dynamic | ||
102 | * PTE/TLB loading will one day be supported, implementations will be able | ||
103 | * to tell whether it succeeded or not according to this return value). | ||
104 | * | ||
105 | * Specifically, -ENOSYS is returned if a fault handler isn't installed | ||
106 | * (though fault handlers can also return -ENOSYS, in case they want to | ||
107 | * elicit the default behavior of the IOMMU drivers). | ||
108 | */ | ||
109 | static inline int report_iommu_fault(struct iommu_domain *domain, | ||
110 | struct device *dev, unsigned long iova, int flags) | ||
111 | { | ||
112 | int ret = -ENOSYS; | ||
70 | 113 | ||
71 | #else /* CONFIG_IOMMU_API */ | 114 | /* |
115 | * if upper layers showed interest and installed a fault handler, | ||
116 | * invoke it. | ||
117 | */ | ||
118 | if (domain->handler) | ||
119 | ret = domain->handler(domain, dev, iova, flags); | ||
72 | 120 | ||
73 | static inline void register_iommu(struct iommu_ops *ops) | 121 | return ret; |
74 | { | ||
75 | } | 122 | } |
76 | 123 | ||
77 | static inline bool iommu_found(void) | 124 | #else /* CONFIG_IOMMU_API */ |
125 | |||
126 | struct iommu_ops {}; | ||
127 | |||
128 | static inline bool iommu_present(struct bus_type *bus) | ||
78 | { | 129 | { |
79 | return false; | 130 | return false; |
80 | } | 131 | } |
81 | 132 | ||
82 | static inline struct iommu_domain *iommu_domain_alloc(void) | 133 | static inline struct iommu_domain *iommu_domain_alloc(struct bus_type *bus) |
83 | { | 134 | { |
84 | return NULL; | 135 | return NULL; |
85 | } | 136 | } |
@@ -123,6 +174,11 @@ static inline int domain_has_cap(struct iommu_domain *domain, | |||
123 | return 0; | 174 | return 0; |
124 | } | 175 | } |
125 | 176 | ||
177 | static inline void iommu_set_fault_handler(struct iommu_domain *domain, | ||
178 | iommu_fault_handler_t handler) | ||
179 | { | ||
180 | } | ||
181 | |||
126 | #endif /* CONFIG_IOMMU_API */ | 182 | #endif /* CONFIG_IOMMU_API */ |
127 | 183 | ||
128 | #endif /* __LINUX_IOMMU_H */ | 184 | #endif /* __LINUX_IOMMU_H */ |