diff options
Diffstat (limited to 'include/linux/highmem.h')
-rw-r--r-- | include/linux/highmem.h | 79 |
1 files changed, 57 insertions, 22 deletions
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 3a93f73a8acc..6549ed75e0a7 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h | |||
@@ -55,12 +55,12 @@ static inline void kunmap(struct page *page) | |||
55 | { | 55 | { |
56 | } | 56 | } |
57 | 57 | ||
58 | static inline void *__kmap_atomic(struct page *page) | 58 | static inline void *kmap_atomic(struct page *page) |
59 | { | 59 | { |
60 | pagefault_disable(); | 60 | pagefault_disable(); |
61 | return page_address(page); | 61 | return page_address(page); |
62 | } | 62 | } |
63 | #define kmap_atomic_prot(page, prot) __kmap_atomic(page) | 63 | #define kmap_atomic_prot(page, prot) kmap_atomic(page) |
64 | 64 | ||
65 | static inline void __kunmap_atomic(void *addr) | 65 | static inline void __kunmap_atomic(void *addr) |
66 | { | 66 | { |
@@ -109,27 +109,62 @@ static inline void kmap_atomic_idx_pop(void) | |||
109 | #endif | 109 | #endif |
110 | 110 | ||
111 | /* | 111 | /* |
112 | * Make both: kmap_atomic(page, idx) and kmap_atomic(page) work. | 112 | * NOTE: |
113 | * kmap_atomic() and kunmap_atomic() with two arguments are deprecated. | ||
114 | * We only keep them for backward compatibility, any usage of them | ||
115 | * are now warned. | ||
113 | */ | 116 | */ |
114 | #define kmap_atomic(page, args...) __kmap_atomic(page) | 117 | |
118 | #define PASTE(a, b) a ## b | ||
119 | #define PASTE2(a, b) PASTE(a, b) | ||
120 | |||
121 | #define NARG_(_2, _1, n, ...) n | ||
122 | #define NARG(...) NARG_(__VA_ARGS__, 2, 1, :) | ||
123 | |||
124 | static inline void __deprecated *kmap_atomic_deprecated(struct page *page, | ||
125 | enum km_type km) | ||
126 | { | ||
127 | return kmap_atomic(page); | ||
128 | } | ||
129 | |||
130 | #define kmap_atomic1(...) kmap_atomic(__VA_ARGS__) | ||
131 | #define kmap_atomic2(...) kmap_atomic_deprecated(__VA_ARGS__) | ||
132 | #define kmap_atomic(...) PASTE2(kmap_atomic, NARG(__VA_ARGS__)(__VA_ARGS__)) | ||
133 | |||
134 | static inline void __deprecated __kunmap_atomic_deprecated(void *addr, | ||
135 | enum km_type km) | ||
136 | { | ||
137 | __kunmap_atomic(addr); | ||
138 | } | ||
115 | 139 | ||
116 | /* | 140 | /* |
117 | * Prevent people trying to call kunmap_atomic() as if it were kunmap() | 141 | * Prevent people trying to call kunmap_atomic() as if it were kunmap() |
118 | * kunmap_atomic() should get the return value of kmap_atomic, not the page. | 142 | * kunmap_atomic() should get the return value of kmap_atomic, not the page. |
119 | */ | 143 | */ |
120 | #define kunmap_atomic(addr, args...) \ | 144 | #define kunmap_atomic_deprecated(addr, km) \ |
121 | do { \ | 145 | do { \ |
122 | BUILD_BUG_ON(__same_type((addr), struct page *)); \ | 146 | BUILD_BUG_ON(__same_type((addr), struct page *)); \ |
123 | __kunmap_atomic(addr); \ | 147 | __kunmap_atomic_deprecated(addr, km); \ |
124 | } while (0) | 148 | } while (0) |
125 | 149 | ||
150 | #define kunmap_atomic_withcheck(addr) \ | ||
151 | do { \ | ||
152 | BUILD_BUG_ON(__same_type((addr), struct page *)); \ | ||
153 | __kunmap_atomic(addr); \ | ||
154 | } while (0) | ||
155 | |||
156 | #define kunmap_atomic1(...) kunmap_atomic_withcheck(__VA_ARGS__) | ||
157 | #define kunmap_atomic2(...) kunmap_atomic_deprecated(__VA_ARGS__) | ||
158 | #define kunmap_atomic(...) PASTE2(kunmap_atomic, NARG(__VA_ARGS__)(__VA_ARGS__)) | ||
159 | /**** End of C pre-processor tricks for deprecated macros ****/ | ||
160 | |||
126 | /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */ | 161 | /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */ |
127 | #ifndef clear_user_highpage | 162 | #ifndef clear_user_highpage |
128 | static inline void clear_user_highpage(struct page *page, unsigned long vaddr) | 163 | static inline void clear_user_highpage(struct page *page, unsigned long vaddr) |
129 | { | 164 | { |
130 | void *addr = kmap_atomic(page, KM_USER0); | 165 | void *addr = kmap_atomic(page); |
131 | clear_user_page(addr, vaddr, page); | 166 | clear_user_page(addr, vaddr, page); |
132 | kunmap_atomic(addr, KM_USER0); | 167 | kunmap_atomic(addr); |
133 | } | 168 | } |
134 | #endif | 169 | #endif |
135 | 170 | ||
@@ -180,16 +215,16 @@ alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma, | |||
180 | 215 | ||
181 | static inline void clear_highpage(struct page *page) | 216 | static inline void clear_highpage(struct page *page) |
182 | { | 217 | { |
183 | void *kaddr = kmap_atomic(page, KM_USER0); | 218 | void *kaddr = kmap_atomic(page); |
184 | clear_page(kaddr); | 219 | clear_page(kaddr); |
185 | kunmap_atomic(kaddr, KM_USER0); | 220 | kunmap_atomic(kaddr); |
186 | } | 221 | } |
187 | 222 | ||
188 | static inline void zero_user_segments(struct page *page, | 223 | static inline void zero_user_segments(struct page *page, |
189 | unsigned start1, unsigned end1, | 224 | unsigned start1, unsigned end1, |
190 | unsigned start2, unsigned end2) | 225 | unsigned start2, unsigned end2) |
191 | { | 226 | { |
192 | void *kaddr = kmap_atomic(page, KM_USER0); | 227 | void *kaddr = kmap_atomic(page); |
193 | 228 | ||
194 | BUG_ON(end1 > PAGE_SIZE || end2 > PAGE_SIZE); | 229 | BUG_ON(end1 > PAGE_SIZE || end2 > PAGE_SIZE); |
195 | 230 | ||
@@ -199,7 +234,7 @@ static inline void zero_user_segments(struct page *page, | |||
199 | if (end2 > start2) | 234 | if (end2 > start2) |
200 | memset(kaddr + start2, 0, end2 - start2); | 235 | memset(kaddr + start2, 0, end2 - start2); |
201 | 236 | ||
202 | kunmap_atomic(kaddr, KM_USER0); | 237 | kunmap_atomic(kaddr); |
203 | flush_dcache_page(page); | 238 | flush_dcache_page(page); |
204 | } | 239 | } |
205 | 240 | ||
@@ -228,11 +263,11 @@ static inline void copy_user_highpage(struct page *to, struct page *from, | |||
228 | { | 263 | { |
229 | char *vfrom, *vto; | 264 | char *vfrom, *vto; |
230 | 265 | ||
231 | vfrom = kmap_atomic(from, KM_USER0); | 266 | vfrom = kmap_atomic(from); |
232 | vto = kmap_atomic(to, KM_USER1); | 267 | vto = kmap_atomic(to); |
233 | copy_user_page(vto, vfrom, vaddr, to); | 268 | copy_user_page(vto, vfrom, vaddr, to); |
234 | kunmap_atomic(vto, KM_USER1); | 269 | kunmap_atomic(vto); |
235 | kunmap_atomic(vfrom, KM_USER0); | 270 | kunmap_atomic(vfrom); |
236 | } | 271 | } |
237 | 272 | ||
238 | #endif | 273 | #endif |
@@ -241,11 +276,11 @@ static inline void copy_highpage(struct page *to, struct page *from) | |||
241 | { | 276 | { |
242 | char *vfrom, *vto; | 277 | char *vfrom, *vto; |
243 | 278 | ||
244 | vfrom = kmap_atomic(from, KM_USER0); | 279 | vfrom = kmap_atomic(from); |
245 | vto = kmap_atomic(to, KM_USER1); | 280 | vto = kmap_atomic(to); |
246 | copy_page(vto, vfrom); | 281 | copy_page(vto, vfrom); |
247 | kunmap_atomic(vto, KM_USER1); | 282 | kunmap_atomic(vto); |
248 | kunmap_atomic(vfrom, KM_USER0); | 283 | kunmap_atomic(vfrom); |
249 | } | 284 | } |
250 | 285 | ||
251 | #endif /* _LINUX_HIGHMEM_H */ | 286 | #endif /* _LINUX_HIGHMEM_H */ |