1
2
3
4
5
6
7
8
9#ifndef _IOVA_H_
10#define _IOVA_H_
11
12#include <linux/types.h>
13#include <linux/kernel.h>
14#include <linux/rbtree.h>
15#include <linux/dma-mapping.h>
16
17
18struct iova {
19 struct rb_node node;
20 unsigned long pfn_hi;
21 unsigned long pfn_lo;
22};
23
24struct iova_magazine;
25struct iova_cpu_rcache;
26
27#define IOVA_RANGE_CACHE_MAX_SIZE 6
28#define MAX_GLOBAL_MAGS 32
29
30struct iova_rcache {
31 spinlock_t lock;
32 unsigned long depot_size;
33 struct iova_magazine *depot[MAX_GLOBAL_MAGS];
34 struct iova_cpu_rcache __percpu *cpu_rcaches;
35};
36
37
38struct iova_domain {
39 spinlock_t iova_rbtree_lock;
40 struct rb_root rbroot;
41 struct rb_node *cached_node;
42 struct rb_node *cached32_node;
43 unsigned long granule;
44 unsigned long start_pfn;
45 unsigned long dma_32bit_pfn;
46 unsigned long max32_alloc_size;
47 struct iova anchor;
48
49 struct iova_rcache rcaches[IOVA_RANGE_CACHE_MAX_SIZE];
50 struct hlist_node cpuhp_dead;
51};
52
53static inline unsigned long iova_size(struct iova *iova)
54{
55 return iova->pfn_hi - iova->pfn_lo + 1;
56}
57
58static inline unsigned long iova_shift(struct iova_domain *iovad)
59{
60 return __ffs(iovad->granule);
61}
62
63static inline unsigned long iova_mask(struct iova_domain *iovad)
64{
65 return iovad->granule - 1;
66}
67
68static inline size_t iova_offset(struct iova_domain *iovad, dma_addr_t iova)
69{
70 return iova & iova_mask(iovad);
71}
72
73static inline size_t iova_align(struct iova_domain *iovad, size_t size)
74{
75 return ALIGN(size, iovad->granule);
76}
77
78static inline dma_addr_t iova_dma_addr(struct iova_domain *iovad, struct iova *iova)
79{
80 return (dma_addr_t)iova->pfn_lo << iova_shift(iovad);
81}
82
83static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)
84{
85 return iova >> iova_shift(iovad);
86}
87
88#if IS_ENABLED(CONFIG_IOMMU_IOVA)
89int iova_cache_get(void);
90void iova_cache_put(void);
91
92void free_iova(struct iova_domain *iovad, unsigned long pfn);
93void __free_iova(struct iova_domain *iovad, struct iova *iova);
94struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size,
95 unsigned long limit_pfn,
96 bool size_aligned);
97void free_iova_fast(struct iova_domain *iovad, unsigned long pfn,
98 unsigned long size);
99unsigned long alloc_iova_fast(struct iova_domain *iovad, unsigned long size,
100 unsigned long limit_pfn, bool flush_rcache);
101struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo,
102 unsigned long pfn_hi);
103void init_iova_domain(struct iova_domain *iovad, unsigned long granule,
104 unsigned long start_pfn);
105struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
106void put_iova_domain(struct iova_domain *iovad);
107#else
108static inline int iova_cache_get(void)
109{
110 return -ENOTSUPP;
111}
112
113static inline void iova_cache_put(void)
114{
115}
116
117static inline void free_iova(struct iova_domain *iovad, unsigned long pfn)
118{
119}
120
121static inline void __free_iova(struct iova_domain *iovad, struct iova *iova)
122{
123}
124
125static inline struct iova *alloc_iova(struct iova_domain *iovad,
126 unsigned long size,
127 unsigned long limit_pfn,
128 bool size_aligned)
129{
130 return NULL;
131}
132
133static inline void free_iova_fast(struct iova_domain *iovad,
134 unsigned long pfn,
135 unsigned long size)
136{
137}
138
139static inline unsigned long alloc_iova_fast(struct iova_domain *iovad,
140 unsigned long size,
141 unsigned long limit_pfn,
142 bool flush_rcache)
143{
144 return 0;
145}
146
147static inline struct iova *reserve_iova(struct iova_domain *iovad,
148 unsigned long pfn_lo,
149 unsigned long pfn_hi)
150{
151 return NULL;
152}
153
154static inline void init_iova_domain(struct iova_domain *iovad,
155 unsigned long granule,
156 unsigned long start_pfn)
157{
158}
159
160static inline struct iova *find_iova(struct iova_domain *iovad,
161 unsigned long pfn)
162{
163 return NULL;
164}
165
166static inline void put_iova_domain(struct iova_domain *iovad)
167{
168}
169
170#endif
171
172#endif
173