Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
1da177e4 LT |
2 | #ifndef _LINUX_HIGHMEM_H |
3 | #define _LINUX_HIGHMEM_H | |
4 | ||
1da177e4 | 5 | #include <linux/fs.h> |
597781f3 | 6 | #include <linux/kernel.h> |
187f1882 | 7 | #include <linux/bug.h> |
522a0032 | 8 | #include <linux/cacheflush.h> |
1da177e4 | 9 | #include <linux/mm.h> |
ad76fb6b | 10 | #include <linux/uaccess.h> |
43b3a0c7 | 11 | #include <linux/hardirq.h> |
1da177e4 | 12 | |
13f876ba | 13 | #include "highmem-internal.h" |
03beb076 | 14 | |
13f876ba TG |
15 | /** |
16 | * kmap - Map a page for long term usage | |
17 | * @page: Pointer to the page to be mapped | |
18 | * | |
19 | * Returns: The virtual address of the mapping | |
20 | * | |
21 | * Can only be invoked from preemptible task context because on 32bit | |
22 | * systems with CONFIG_HIGHMEM enabled this function might sleep. | |
23 | * | |
24 | * For systems with CONFIG_HIGHMEM=n and for pages in the low memory area | |
25 | * this returns the virtual address of the direct kernel mapping. | |
26 | * | |
27 | * The returned virtual address is globally visible and valid up to the | |
28 | * point where it is unmapped via kunmap(). The pointer can be handed to | |
29 | * other contexts. | |
30 | * | |
31 | * For highmem pages on 32bit systems this can be slow as the mapping space | |
32 | * is limited and protected by a global lock. In case that there is no | |
33 | * mapping slot available the function blocks until a slot is released via | |
34 | * kunmap(). | |
298fa1ad | 35 | */ |
13f876ba | 36 | static inline void *kmap(struct page *page); |
525aaf9b | 37 | |
13f876ba TG |
38 | /** |
39 | * kunmap - Unmap the virtual address mapped by kmap() | |
e7392b4e | 40 | * @page: Pointer to the page which was mapped by kmap() |
13f876ba TG |
41 | * |
42 | * Counterpart to kmap(). A NOOP for CONFIG_HIGHMEM=n and for mappings of | |
43 | * pages in the low memory area. | |
78b6d91e | 44 | */ |
13f876ba | 45 | static inline void kunmap(struct page *page); |
298fa1ad | 46 | |
13f876ba TG |
47 | /** |
48 | * kmap_to_page - Get the page for a kmap'ed address | |
49 | * @addr: The address to look up | |
50 | * | |
51 | * Returns: The page which is mapped to @addr. | |
52 | */ | |
53 | static inline struct page *kmap_to_page(void *addr); | |
1da177e4 | 54 | |
13f876ba TG |
55 | /** |
56 | * kmap_flush_unused - Flush all unused kmap mappings in order to | |
57 | * remove stray mappings | |
58 | */ | |
59 | static inline void kmap_flush_unused(void); | |
1da177e4 | 60 | |
13f876ba | 61 | /** |
f3ba3c71 | 62 | * kmap_local_page - Map a page for temporary usage |
13f876ba TG |
63 | * @page: Pointer to the page to be mapped |
64 | * | |
65 | * Returns: The virtual address of the mapping | |
66 | * | |
13f876ba TG |
67 | * Can be invoked from any context. |
68 | * | |
69 | * Requires careful handling when nesting multiple mappings because the map | |
70 | * management is stack based. The unmap has to be in the reverse order of | |
71 | * the map operation: | |
72 | * | |
f3ba3c71 TG |
73 | * addr1 = kmap_local_page(page1); |
74 | * addr2 = kmap_local_page(page2); | |
13f876ba | 75 | * ... |
f3ba3c71 TG |
76 | * kunmap_local(addr2); |
77 | * kunmap_local(addr1); | |
13f876ba TG |
78 | * |
79 | * Unmapping addr1 before addr2 is invalid and causes malfunction. | |
80 | * | |
81 | * Contrary to kmap() mappings the mapping is only valid in the context of | |
82 | * the caller and cannot be handed to other contexts. | |
83 | * | |
84 | * On CONFIG_HIGHMEM=n kernels and for low memory pages this returns the | |
85 | * virtual address of the direct mapping. Only real highmem pages are | |
86 | * temporarily mapped. | |
87 | * | |
f3ba3c71 TG |
88 | * While it is significantly faster than kmap() for the higmem case it |
89 | * comes with restrictions about the pointer validity. Only use when really | |
90 | * necessary. | |
91 | * | |
92 | * On HIGHMEM enabled systems mapping a highmem page has the side effect of | |
93 | * disabling migration in order to keep the virtual address stable across | |
94 | * preemption. No caller of kmap_local_page() can rely on this side effect. | |
95 | */ | |
96 | static inline void *kmap_local_page(struct page *page); | |
97 | ||
53c36de0 MWO |
98 | /** |
99 | * kmap_local_folio - Map a page in this folio for temporary usage | |
100 | * @folio: The folio containing the page. | |
101 | * @offset: The byte offset within the folio which identifies the page. | |
102 | * | |
103 | * Requires careful handling when nesting multiple mappings because the map | |
104 | * management is stack based. The unmap has to be in the reverse order of | |
105 | * the map operation:: | |
106 | * | |
107 | * addr1 = kmap_local_folio(folio1, offset1); | |
108 | * addr2 = kmap_local_folio(folio2, offset2); | |
109 | * ... | |
110 | * kunmap_local(addr2); | |
111 | * kunmap_local(addr1); | |
112 | * | |
113 | * Unmapping addr1 before addr2 is invalid and causes malfunction. | |
114 | * | |
115 | * Contrary to kmap() mappings the mapping is only valid in the context of | |
116 | * the caller and cannot be handed to other contexts. | |
117 | * | |
118 | * On CONFIG_HIGHMEM=n kernels and for low memory pages this returns the | |
119 | * virtual address of the direct mapping. Only real highmem pages are | |
120 | * temporarily mapped. | |
121 | * | |
122 | * While it is significantly faster than kmap() for the higmem case it | |
123 | * comes with restrictions about the pointer validity. Only use when really | |
124 | * necessary. | |
125 | * | |
126 | * On HIGHMEM enabled systems mapping a highmem page has the side effect of | |
127 | * disabling migration in order to keep the virtual address stable across | |
128 | * preemption. No caller of kmap_local_folio() can rely on this side effect. | |
129 | * | |
130 | * Context: Can be invoked from any context. | |
131 | * Return: The virtual address of @offset. | |
132 | */ | |
133 | static inline void *kmap_local_folio(struct folio *folio, size_t offset); | |
134 | ||
f3ba3c71 TG |
135 | /** |
136 | * kmap_atomic - Atomically map a page for temporary usage - Deprecated! | |
137 | * @page: Pointer to the page to be mapped | |
138 | * | |
139 | * Returns: The virtual address of the mapping | |
140 | * | |
e7392b4e FDF |
141 | * In fact a wrapper around kmap_local_page() which also disables pagefaults |
142 | * and, depending on PREEMPT_RT configuration, also CPU migration and | |
143 | * preemption. Therefore users should not count on the latter two side effects. | |
144 | * | |
145 | * Mappings should always be released by kunmap_atomic(). | |
f3ba3c71 TG |
146 | * |
147 | * Do not use in new code. Use kmap_local_page() instead. | |
85a85e76 FDF |
148 | * |
149 | * It is used in atomic context when code wants to access the contents of a | |
150 | * page that might be allocated from high memory (see __GFP_HIGHMEM), for | |
151 | * example a page in the pagecache. The API has two functions, and they | |
cffe57be | 152 | * can be used in a manner similar to the following:: |
85a85e76 | 153 | * |
cffe57be BS |
154 | * // Find the page of interest. |
155 | * struct page *page = find_get_page(mapping, offset); | |
85a85e76 | 156 | * |
cffe57be BS |
157 | * // Gain access to the contents of that page. |
158 | * void *vaddr = kmap_atomic(page); | |
85a85e76 | 159 | * |
cffe57be BS |
160 | * // Do something to the contents of that page. |
161 | * memset(vaddr, 0, PAGE_SIZE); | |
85a85e76 | 162 | * |
cffe57be BS |
163 | * // Unmap that page. |
164 | * kunmap_atomic(vaddr); | |
85a85e76 FDF |
165 | * |
166 | * Note that the kunmap_atomic() call takes the result of the kmap_atomic() | |
167 | * call, not the argument. | |
168 | * | |
169 | * If you need to map two pages because you want to copy from one page to | |
170 | * another you need to keep the kmap_atomic calls strictly nested, like: | |
171 | * | |
172 | * vaddr1 = kmap_atomic(page1); | |
173 | * vaddr2 = kmap_atomic(page2); | |
174 | * | |
175 | * memcpy(vaddr1, vaddr2, PAGE_SIZE); | |
176 | * | |
177 | * kunmap_atomic(vaddr2); | |
178 | * kunmap_atomic(vaddr1); | |
13f876ba TG |
179 | */ |
180 | static inline void *kmap_atomic(struct page *page); | |
5a178119 | 181 | |
13f876ba TG |
182 | /* Highmem related interfaces for management code */ |
183 | static inline unsigned int nr_free_highpages(void); | |
184 | static inline unsigned long totalhigh_pages(void); | |
1da177e4 | 185 | |
13f876ba TG |
186 | #ifndef ARCH_HAS_FLUSH_ANON_PAGE |
187 | static inline void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) | |
e23c4597 IW |
188 | { |
189 | } | |
7438f363 | 190 | #endif |
1da177e4 | 191 | |
f358afc5 | 192 | #ifndef ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE |
13f876ba | 193 | static inline void flush_kernel_vmap_range(void *vaddr, int size) |
298fa1ad | 194 | { |
298fa1ad | 195 | } |
13f876ba | 196 | static inline void invalidate_kernel_vmap_range(void *vaddr, int size) |
298fa1ad | 197 | { |
298fa1ad | 198 | } |
7438f363 | 199 | #endif |
980c19e3 | 200 | |
1da177e4 | 201 | /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */ |
487ff320 | 202 | #ifndef clear_user_highpage |
1da177e4 LT |
203 | static inline void clear_user_highpage(struct page *page, unsigned long vaddr) |
204 | { | |
d2c20e51 | 205 | void *addr = kmap_local_page(page); |
1da177e4 | 206 | clear_user_page(addr, vaddr, page); |
d2c20e51 | 207 | kunmap_local(addr); |
1da177e4 | 208 | } |
487ff320 | 209 | #endif |
1da177e4 | 210 | |
92638b4e | 211 | #ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE_MOVABLE |
769848c0 | 212 | /** |
92638b4e | 213 | * alloc_zeroed_user_highpage_movable - Allocate a zeroed HIGHMEM page for a VMA that the caller knows can move |
769848c0 MG |
214 | * @vma: The VMA the page is to be allocated for |
215 | * @vaddr: The virtual address the page will be inserted into | |
216 | * | |
e7392b4e FDF |
217 | * Returns: The allocated and zeroed HIGHMEM page |
218 | * | |
92638b4e PC |
219 | * This function will allocate a page for a VMA that the caller knows will |
220 | * be able to migrate in the future using move_pages() or reclaimed | |
769848c0 MG |
221 | * |
222 | * An architecture may override this function by defining | |
92638b4e | 223 | * __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE_MOVABLE and providing their own |
769848c0 MG |
224 | * implementation. |
225 | */ | |
1da177e4 | 226 | static inline struct page * |
92638b4e PC |
227 | alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma, |
228 | unsigned long vaddr) | |
1da177e4 | 229 | { |
92638b4e | 230 | struct page *page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr); |
1da177e4 LT |
231 | |
232 | if (page) | |
233 | clear_user_highpage(page, vaddr); | |
234 | ||
235 | return page; | |
236 | } | |
237 | #endif | |
238 | ||
239 | static inline void clear_highpage(struct page *page) | |
240 | { | |
d2c20e51 | 241 | void *kaddr = kmap_local_page(page); |
1da177e4 | 242 | clear_page(kaddr); |
d2c20e51 | 243 | kunmap_local(kaddr); |
1da177e4 LT |
244 | } |
245 | ||
d9da8f6c AK |
246 | static inline void clear_highpage_kasan_tagged(struct page *page) |
247 | { | |
248 | u8 tag; | |
249 | ||
250 | tag = page_kasan_tag(page); | |
251 | page_kasan_tag_reset(page); | |
252 | clear_highpage(page); | |
253 | page_kasan_tag_set(page, tag); | |
254 | } | |
255 | ||
013bb59d PC |
256 | #ifndef __HAVE_ARCH_TAG_CLEAR_HIGHPAGE |
257 | ||
258 | static inline void tag_clear_highpage(struct page *page) | |
259 | { | |
260 | } | |
261 | ||
262 | #endif | |
263 | ||
0060ef3b MWO |
264 | /* |
265 | * If we pass in a base or tail page, we can zero up to PAGE_SIZE. | |
266 | * If we pass in a head page, we can zero up to the size of the compound page. | |
267 | */ | |
c0357139 | 268 | #ifdef CONFIG_HIGHMEM |
0060ef3b MWO |
269 | void zero_user_segments(struct page *page, unsigned start1, unsigned end1, |
270 | unsigned start2, unsigned end2); | |
c0357139 | 271 | #else |
eebd2aa3 | 272 | static inline void zero_user_segments(struct page *page, |
0060ef3b MWO |
273 | unsigned start1, unsigned end1, |
274 | unsigned start2, unsigned end2) | |
eebd2aa3 | 275 | { |
d2c20e51 | 276 | void *kaddr = kmap_local_page(page); |
0060ef3b | 277 | unsigned int i; |
eebd2aa3 | 278 | |
0060ef3b | 279 | BUG_ON(end1 > page_size(page) || end2 > page_size(page)); |
eebd2aa3 CL |
280 | |
281 | if (end1 > start1) | |
282 | memset(kaddr + start1, 0, end1 - start1); | |
283 | ||
284 | if (end2 > start2) | |
285 | memset(kaddr + start2, 0, end2 - start2); | |
286 | ||
d2c20e51 | 287 | kunmap_local(kaddr); |
0060ef3b MWO |
288 | for (i = 0; i < compound_nr(page); i++) |
289 | flush_dcache_page(page + i); | |
eebd2aa3 | 290 | } |
c0357139 | 291 | #endif |
eebd2aa3 CL |
292 | |
293 | static inline void zero_user_segment(struct page *page, | |
294 | unsigned start, unsigned end) | |
295 | { | |
296 | zero_user_segments(page, start, end, 0, 0); | |
297 | } | |
298 | ||
299 | static inline void zero_user(struct page *page, | |
300 | unsigned start, unsigned size) | |
301 | { | |
302 | zero_user_segments(page, start, start + size, 0, 0); | |
303 | } | |
01f2705d | 304 | |
77fff4ae AN |
305 | #ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE |
306 | ||
9de455b2 AN |
307 | static inline void copy_user_highpage(struct page *to, struct page *from, |
308 | unsigned long vaddr, struct vm_area_struct *vma) | |
1da177e4 LT |
309 | { |
310 | char *vfrom, *vto; | |
311 | ||
d2c20e51 IW |
312 | vfrom = kmap_local_page(from); |
313 | vto = kmap_local_page(to); | |
1da177e4 | 314 | copy_user_page(vto, vfrom, vaddr, to); |
d2c20e51 IW |
315 | kunmap_local(vto); |
316 | kunmap_local(vfrom); | |
1da177e4 LT |
317 | } |
318 | ||
77fff4ae AN |
319 | #endif |
320 | ||
a4602b62 KA |
321 | #ifndef __HAVE_ARCH_COPY_HIGHPAGE |
322 | ||
1da177e4 LT |
323 | static inline void copy_highpage(struct page *to, struct page *from) |
324 | { | |
325 | char *vfrom, *vto; | |
326 | ||
d2c20e51 IW |
327 | vfrom = kmap_local_page(from); |
328 | vto = kmap_local_page(to); | |
1da177e4 | 329 | copy_page(vto, vfrom); |
d2c20e51 IW |
330 | kunmap_local(vto); |
331 | kunmap_local(vfrom); | |
1da177e4 LT |
332 | } |
333 | ||
a4602b62 KA |
334 | #endif |
335 | ||
6a0996db IW |
336 | static inline void memcpy_page(struct page *dst_page, size_t dst_off, |
337 | struct page *src_page, size_t src_off, | |
338 | size_t len) | |
339 | { | |
340 | char *dst = kmap_local_page(dst_page); | |
341 | char *src = kmap_local_page(src_page); | |
342 | ||
ca18f6ea | 343 | VM_BUG_ON(dst_off + len > PAGE_SIZE || src_off + len > PAGE_SIZE); |
6a0996db IW |
344 | memcpy(dst + dst_off, src + src_off, len); |
345 | kunmap_local(src); | |
346 | kunmap_local(dst); | |
347 | } | |
348 | ||
6a0996db IW |
349 | static inline void memset_page(struct page *page, size_t offset, int val, |
350 | size_t len) | |
351 | { | |
352 | char *addr = kmap_local_page(page); | |
353 | ||
ca18f6ea | 354 | VM_BUG_ON(offset + len > PAGE_SIZE); |
6a0996db IW |
355 | memset(addr + offset, val, len); |
356 | kunmap_local(addr); | |
357 | } | |
358 | ||
bb90d4bc IW |
359 | static inline void memcpy_from_page(char *to, struct page *page, |
360 | size_t offset, size_t len) | |
361 | { | |
61b205f5 | 362 | char *from = kmap_local_page(page); |
bb90d4bc | 363 | |
ca18f6ea | 364 | VM_BUG_ON(offset + len > PAGE_SIZE); |
bb90d4bc | 365 | memcpy(to, from + offset, len); |
61b205f5 | 366 | kunmap_local(from); |
bb90d4bc IW |
367 | } |
368 | ||
369 | static inline void memcpy_to_page(struct page *page, size_t offset, | |
370 | const char *from, size_t len) | |
371 | { | |
61b205f5 | 372 | char *to = kmap_local_page(page); |
bb90d4bc | 373 | |
ca18f6ea | 374 | VM_BUG_ON(offset + len > PAGE_SIZE); |
bb90d4bc | 375 | memcpy(to + offset, from, len); |
8dad53a1 | 376 | flush_dcache_page(page); |
61b205f5 | 377 | kunmap_local(to); |
bb90d4bc IW |
378 | } |
379 | ||
28961998 IW |
380 | static inline void memzero_page(struct page *page, size_t offset, size_t len) |
381 | { | |
d9a42b53 | 382 | char *addr = kmap_local_page(page); |
f38adfef FDF |
383 | |
384 | VM_BUG_ON(offset + len > PAGE_SIZE); | |
28961998 | 385 | memset(addr + offset, 0, len); |
8dad53a1 | 386 | flush_dcache_page(page); |
d9a42b53 | 387 | kunmap_local(addr); |
28961998 IW |
388 | } |
389 | ||
c0357139 MWO |
390 | /** |
391 | * folio_zero_segments() - Zero two byte ranges in a folio. | |
392 | * @folio: The folio to write to. | |
393 | * @start1: The first byte to zero. | |
394 | * @xend1: One more than the last byte in the first range. | |
395 | * @start2: The first byte to zero in the second range. | |
396 | * @xend2: One more than the last byte in the second range. | |
397 | */ | |
398 | static inline void folio_zero_segments(struct folio *folio, | |
399 | size_t start1, size_t xend1, size_t start2, size_t xend2) | |
400 | { | |
401 | zero_user_segments(&folio->page, start1, xend1, start2, xend2); | |
402 | } | |
403 | ||
404 | /** | |
405 | * folio_zero_segment() - Zero a byte range in a folio. | |
406 | * @folio: The folio to write to. | |
407 | * @start: The first byte to zero. | |
408 | * @xend: One more than the last byte to zero. | |
409 | */ | |
410 | static inline void folio_zero_segment(struct folio *folio, | |
411 | size_t start, size_t xend) | |
412 | { | |
413 | zero_user_segments(&folio->page, start, xend, 0, 0); | |
414 | } | |
415 | ||
416 | /** | |
417 | * folio_zero_range() - Zero a byte range in a folio. | |
418 | * @folio: The folio to write to. | |
419 | * @start: The first byte to zero. | |
420 | * @length: The number of bytes to zero. | |
421 | */ | |
422 | static inline void folio_zero_range(struct folio *folio, | |
423 | size_t start, size_t length) | |
424 | { | |
425 | zero_user_segments(&folio->page, start, start + length, 0, 0); | |
426 | } | |
427 | ||
1da177e4 | 428 | #endif /* _LINUX_HIGHMEM_H */ |