diff options
Diffstat (limited to 'include/linux/iommu.h')
| -rw-r--r-- | include/linux/iommu.h | 76 |
1 files changed, 66 insertions, 10 deletions
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 */ |
