Commit | Line | Data |
---|---|---|
50acfb2b | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
5d8544e2 PD |
2 | /* |
3 | * Copyright (C) 2012 Regents of the University of California | |
4 | * | |
5d8544e2 PD |
5 | * This file was copied from include/asm-generic/uaccess.h |
6 | */ | |
7 | ||
8 | #ifndef _ASM_RISCV_UACCESS_H | |
9 | #define _ASM_RISCV_UACCESS_H | |
10 | ||
11 | /* | |
12 | * User space memory access functions | |
13 | */ | |
14 | #include <linux/errno.h> | |
15 | #include <linux/compiler.h> | |
16 | #include <linux/thread_info.h> | |
17 | #include <asm/byteorder.h> | |
df720961 | 18 | #include <asm/extable.h> |
5d8544e2 PD |
19 | #include <asm/asm.h> |
20 | ||
21 | #define __enable_user_access() \ | |
22 | __asm__ __volatile__ ("csrs sstatus, %0" : : "r" (SR_SUM) : "memory") | |
23 | #define __disable_user_access() \ | |
24 | __asm__ __volatile__ ("csrc sstatus, %0" : : "r" (SR_SUM) : "memory") | |
25 | ||
26 | /* | |
27 | * The fs value determines whether argument validity checking should be | |
28 | * performed or not. If get_fs() == USER_DS, checking is performed, with | |
29 | * get_fs() == KERNEL_DS, checking is bypassed. | |
30 | * | |
31 | * For historical reasons, these macros are grossly misnamed. | |
32 | */ | |
33 | ||
5cfade5f CH |
34 | #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) |
35 | ||
36 | #define KERNEL_DS MAKE_MM_SEG(~0UL) | |
37 | #define USER_DS MAKE_MM_SEG(TASK_SIZE) | |
5d8544e2 | 38 | |
5d8544e2 PD |
39 | #define get_fs() (current_thread_info()->addr_limit) |
40 | ||
41 | static inline void set_fs(mm_segment_t fs) | |
42 | { | |
43 | current_thread_info()->addr_limit = fs; | |
44 | } | |
45 | ||
5cfade5f | 46 | #define segment_eq(a, b) ((a).seg == (b).seg) |
5d8544e2 | 47 | |
5cfade5f | 48 | #define user_addr_max() (get_fs().seg) |
5d8544e2 PD |
49 | |
50 | ||
5d8544e2 PD |
51 | /** |
52 | * access_ok: - Checks if a user space pointer is valid | |
5d8544e2 PD |
53 | * @addr: User space pointer to start of block to check |
54 | * @size: Size of block to check | |
55 | * | |
56 | * Context: User context only. This function may sleep. | |
57 | * | |
58 | * Checks if a pointer to a block of memory in user space is valid. | |
59 | * | |
60 | * Returns true (nonzero) if the memory block may be valid, false (zero) | |
61 | * if it is definitely invalid. | |
62 | * | |
63 | * Note that, depending on architecture, this function probably just | |
64 | * checks that the pointer is in the user space range - after calling | |
65 | * this function, memory access functions may still return -EFAULT. | |
66 | */ | |
96d4f267 | 67 | #define access_ok(addr, size) ({ \ |
5d8544e2 PD |
68 | __chk_user_ptr(addr); \ |
69 | likely(__access_ok((unsigned long __force)(addr), (size))); \ | |
70 | }) | |
71 | ||
72 | /* | |
73 | * Ensure that the range [addr, addr+size) is within the process's | |
74 | * address space | |
75 | */ | |
76 | static inline int __access_ok(unsigned long addr, unsigned long size) | |
77 | { | |
78 | const mm_segment_t fs = get_fs(); | |
79 | ||
5cfade5f | 80 | return size <= fs.seg && addr <= fs.seg - size; |
5d8544e2 PD |
81 | } |
82 | ||
83 | /* | |
84 | * The exception table consists of pairs of addresses: the first is the | |
85 | * address of an instruction that is allowed to fault, and the second is | |
86 | * the address at which the program should continue. No registers are | |
87 | * modified, so it is entirely up to the continuation code to figure out | |
88 | * what to do. | |
89 | * | |
90 | * All the routines below use bits of fixup code that are out of line | |
91 | * with the main instruction path. This means when everything is well, | |
92 | * we don't even have to jump over them. Further, they do not intrude | |
93 | * on our cache or tlb entries. | |
94 | */ | |
95 | ||
5d8544e2 | 96 | #define __LSW 0 |
e28dcc77 | 97 | #define __MSW 1 |
5d8544e2 PD |
98 | |
99 | /* | |
100 | * The "__xxx" versions of the user access functions do not verify the address | |
101 | * space - it must have been done previously with a separate "access_ok()" | |
102 | * call. | |
103 | */ | |
104 | ||
5d8544e2 PD |
105 | #define __get_user_asm(insn, x, ptr, err) \ |
106 | do { \ | |
107 | uintptr_t __tmp; \ | |
108 | __typeof__(x) __x; \ | |
109 | __enable_user_access(); \ | |
110 | __asm__ __volatile__ ( \ | |
111 | "1:\n" \ | |
112 | " " insn " %1, %3\n" \ | |
113 | "2:\n" \ | |
114 | " .section .fixup,\"ax\"\n" \ | |
115 | " .balign 4\n" \ | |
116 | "3:\n" \ | |
117 | " li %0, %4\n" \ | |
118 | " li %1, 0\n" \ | |
119 | " jump 2b, %2\n" \ | |
120 | " .previous\n" \ | |
121 | " .section __ex_table,\"a\"\n" \ | |
122 | " .balign " RISCV_SZPTR "\n" \ | |
123 | " " RISCV_PTR " 1b, 3b\n" \ | |
124 | " .previous" \ | |
125 | : "+r" (err), "=&r" (__x), "=r" (__tmp) \ | |
126 | : "m" (*(ptr)), "i" (-EFAULT)); \ | |
127 | __disable_user_access(); \ | |
128 | (x) = __x; \ | |
129 | } while (0) | |
5d8544e2 PD |
130 | |
131 | #ifdef CONFIG_64BIT | |
132 | #define __get_user_8(x, ptr, err) \ | |
133 | __get_user_asm("ld", x, ptr, err) | |
134 | #else /* !CONFIG_64BIT */ | |
5d8544e2 PD |
135 | #define __get_user_8(x, ptr, err) \ |
136 | do { \ | |
137 | u32 __user *__ptr = (u32 __user *)(ptr); \ | |
138 | u32 __lo, __hi; \ | |
139 | uintptr_t __tmp; \ | |
140 | __enable_user_access(); \ | |
141 | __asm__ __volatile__ ( \ | |
142 | "1:\n" \ | |
143 | " lw %1, %4\n" \ | |
144 | "2:\n" \ | |
145 | " lw %2, %5\n" \ | |
146 | "3:\n" \ | |
147 | " .section .fixup,\"ax\"\n" \ | |
148 | " .balign 4\n" \ | |
149 | "4:\n" \ | |
150 | " li %0, %6\n" \ | |
151 | " li %1, 0\n" \ | |
152 | " li %2, 0\n" \ | |
153 | " jump 3b, %3\n" \ | |
154 | " .previous\n" \ | |
155 | " .section __ex_table,\"a\"\n" \ | |
156 | " .balign " RISCV_SZPTR "\n" \ | |
157 | " " RISCV_PTR " 1b, 4b\n" \ | |
158 | " " RISCV_PTR " 2b, 4b\n" \ | |
159 | " .previous" \ | |
160 | : "+r" (err), "=&r" (__lo), "=r" (__hi), \ | |
161 | "=r" (__tmp) \ | |
162 | : "m" (__ptr[__LSW]), "m" (__ptr[__MSW]), \ | |
163 | "i" (-EFAULT)); \ | |
164 | __disable_user_access(); \ | |
165 | (x) = (__typeof__(x))((__typeof__((x)-(x)))( \ | |
166 | (((u64)__hi << 32) | __lo))); \ | |
167 | } while (0) | |
5d8544e2 PD |
168 | #endif /* CONFIG_64BIT */ |
169 | ||
170 | ||
171 | /** | |
172 | * __get_user: - Get a simple variable from user space, with less checking. | |
173 | * @x: Variable to store result. | |
174 | * @ptr: Source address, in user space. | |
175 | * | |
176 | * Context: User context only. This function may sleep. | |
177 | * | |
178 | * This macro copies a single simple variable from user space to kernel | |
179 | * space. It supports simple types like char and int, but not larger | |
180 | * data types like structures or arrays. | |
181 | * | |
182 | * @ptr must have pointer-to-simple-variable type, and the result of | |
183 | * dereferencing @ptr must be assignable to @x without a cast. | |
184 | * | |
185 | * Caller must check the pointer with access_ok() before calling this | |
186 | * function. | |
187 | * | |
188 | * Returns zero on success, or -EFAULT on error. | |
189 | * On error, the variable @x is set to zero. | |
190 | */ | |
191 | #define __get_user(x, ptr) \ | |
192 | ({ \ | |
193 | register long __gu_err = 0; \ | |
194 | const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ | |
195 | __chk_user_ptr(__gu_ptr); \ | |
196 | switch (sizeof(*__gu_ptr)) { \ | |
197 | case 1: \ | |
198 | __get_user_asm("lb", (x), __gu_ptr, __gu_err); \ | |
199 | break; \ | |
200 | case 2: \ | |
201 | __get_user_asm("lh", (x), __gu_ptr, __gu_err); \ | |
202 | break; \ | |
203 | case 4: \ | |
204 | __get_user_asm("lw", (x), __gu_ptr, __gu_err); \ | |
205 | break; \ | |
206 | case 8: \ | |
207 | __get_user_8((x), __gu_ptr, __gu_err); \ | |
208 | break; \ | |
209 | default: \ | |
210 | BUILD_BUG(); \ | |
211 | } \ | |
212 | __gu_err; \ | |
213 | }) | |
214 | ||
215 | /** | |
216 | * get_user: - Get a simple variable from user space. | |
217 | * @x: Variable to store result. | |
218 | * @ptr: Source address, in user space. | |
219 | * | |
220 | * Context: User context only. This function may sleep. | |
221 | * | |
222 | * This macro copies a single simple variable from user space to kernel | |
223 | * space. It supports simple types like char and int, but not larger | |
224 | * data types like structures or arrays. | |
225 | * | |
226 | * @ptr must have pointer-to-simple-variable type, and the result of | |
227 | * dereferencing @ptr must be assignable to @x without a cast. | |
228 | * | |
229 | * Returns zero on success, or -EFAULT on error. | |
230 | * On error, the variable @x is set to zero. | |
231 | */ | |
232 | #define get_user(x, ptr) \ | |
233 | ({ \ | |
234 | const __typeof__(*(ptr)) __user *__p = (ptr); \ | |
235 | might_fault(); \ | |
96d4f267 | 236 | access_ok(__p, sizeof(*__p)) ? \ |
5d8544e2 PD |
237 | __get_user((x), __p) : \ |
238 | ((x) = 0, -EFAULT); \ | |
239 | }) | |
240 | ||
5d8544e2 PD |
241 | #define __put_user_asm(insn, x, ptr, err) \ |
242 | do { \ | |
243 | uintptr_t __tmp; \ | |
244 | __typeof__(*(ptr)) __x = x; \ | |
245 | __enable_user_access(); \ | |
246 | __asm__ __volatile__ ( \ | |
247 | "1:\n" \ | |
248 | " " insn " %z3, %2\n" \ | |
249 | "2:\n" \ | |
250 | " .section .fixup,\"ax\"\n" \ | |
251 | " .balign 4\n" \ | |
252 | "3:\n" \ | |
253 | " li %0, %4\n" \ | |
254 | " jump 2b, %1\n" \ | |
255 | " .previous\n" \ | |
256 | " .section __ex_table,\"a\"\n" \ | |
257 | " .balign " RISCV_SZPTR "\n" \ | |
258 | " " RISCV_PTR " 1b, 3b\n" \ | |
259 | " .previous" \ | |
260 | : "+r" (err), "=r" (__tmp), "=m" (*(ptr)) \ | |
261 | : "rJ" (__x), "i" (-EFAULT)); \ | |
262 | __disable_user_access(); \ | |
263 | } while (0) | |
5d8544e2 PD |
264 | |
265 | #ifdef CONFIG_64BIT | |
266 | #define __put_user_8(x, ptr, err) \ | |
267 | __put_user_asm("sd", x, ptr, err) | |
268 | #else /* !CONFIG_64BIT */ | |
5d8544e2 PD |
269 | #define __put_user_8(x, ptr, err) \ |
270 | do { \ | |
271 | u32 __user *__ptr = (u32 __user *)(ptr); \ | |
272 | u64 __x = (__typeof__((x)-(x)))(x); \ | |
273 | uintptr_t __tmp; \ | |
274 | __enable_user_access(); \ | |
275 | __asm__ __volatile__ ( \ | |
276 | "1:\n" \ | |
277 | " sw %z4, %2\n" \ | |
278 | "2:\n" \ | |
279 | " sw %z5, %3\n" \ | |
280 | "3:\n" \ | |
281 | " .section .fixup,\"ax\"\n" \ | |
282 | " .balign 4\n" \ | |
283 | "4:\n" \ | |
284 | " li %0, %6\n" \ | |
dbee9c9c | 285 | " jump 3b, %1\n" \ |
5d8544e2 PD |
286 | " .previous\n" \ |
287 | " .section __ex_table,\"a\"\n" \ | |
288 | " .balign " RISCV_SZPTR "\n" \ | |
289 | " " RISCV_PTR " 1b, 4b\n" \ | |
290 | " " RISCV_PTR " 2b, 4b\n" \ | |
291 | " .previous" \ | |
292 | : "+r" (err), "=r" (__tmp), \ | |
293 | "=m" (__ptr[__LSW]), \ | |
294 | "=m" (__ptr[__MSW]) \ | |
295 | : "rJ" (__x), "rJ" (__x >> 32), "i" (-EFAULT)); \ | |
296 | __disable_user_access(); \ | |
297 | } while (0) | |
5d8544e2 PD |
298 | #endif /* CONFIG_64BIT */ |
299 | ||
300 | ||
301 | /** | |
302 | * __put_user: - Write a simple value into user space, with less checking. | |
303 | * @x: Value to copy to user space. | |
304 | * @ptr: Destination address, in user space. | |
305 | * | |
306 | * Context: User context only. This function may sleep. | |
307 | * | |
308 | * This macro copies a single simple value from kernel space to user | |
309 | * space. It supports simple types like char and int, but not larger | |
310 | * data types like structures or arrays. | |
311 | * | |
312 | * @ptr must have pointer-to-simple-variable type, and @x must be assignable | |
313 | * to the result of dereferencing @ptr. | |
314 | * | |
315 | * Caller must check the pointer with access_ok() before calling this | |
316 | * function. | |
317 | * | |
318 | * Returns zero on success, or -EFAULT on error. | |
319 | */ | |
320 | #define __put_user(x, ptr) \ | |
321 | ({ \ | |
322 | register long __pu_err = 0; \ | |
323 | __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ | |
324 | __chk_user_ptr(__gu_ptr); \ | |
325 | switch (sizeof(*__gu_ptr)) { \ | |
326 | case 1: \ | |
327 | __put_user_asm("sb", (x), __gu_ptr, __pu_err); \ | |
328 | break; \ | |
329 | case 2: \ | |
330 | __put_user_asm("sh", (x), __gu_ptr, __pu_err); \ | |
331 | break; \ | |
332 | case 4: \ | |
333 | __put_user_asm("sw", (x), __gu_ptr, __pu_err); \ | |
334 | break; \ | |
335 | case 8: \ | |
336 | __put_user_8((x), __gu_ptr, __pu_err); \ | |
337 | break; \ | |
338 | default: \ | |
339 | BUILD_BUG(); \ | |
340 | } \ | |
341 | __pu_err; \ | |
342 | }) | |
343 | ||
344 | /** | |
345 | * put_user: - Write a simple value into user space. | |
346 | * @x: Value to copy to user space. | |
347 | * @ptr: Destination address, in user space. | |
348 | * | |
349 | * Context: User context only. This function may sleep. | |
350 | * | |
351 | * This macro copies a single simple value from kernel space to user | |
352 | * space. It supports simple types like char and int, but not larger | |
353 | * data types like structures or arrays. | |
354 | * | |
355 | * @ptr must have pointer-to-simple-variable type, and @x must be assignable | |
356 | * to the result of dereferencing @ptr. | |
357 | * | |
358 | * Returns zero on success, or -EFAULT on error. | |
359 | */ | |
360 | #define put_user(x, ptr) \ | |
361 | ({ \ | |
362 | __typeof__(*(ptr)) __user *__p = (ptr); \ | |
363 | might_fault(); \ | |
96d4f267 | 364 | access_ok(__p, sizeof(*__p)) ? \ |
5d8544e2 PD |
365 | __put_user((x), __p) : \ |
366 | -EFAULT; \ | |
367 | }) | |
368 | ||
369 | ||
86406d51 LVO |
370 | extern unsigned long __must_check __asm_copy_to_user(void __user *to, |
371 | const void *from, unsigned long n); | |
372 | extern unsigned long __must_check __asm_copy_from_user(void *to, | |
5d8544e2 PD |
373 | const void __user *from, unsigned long n); |
374 | ||
375 | static inline unsigned long | |
376 | raw_copy_from_user(void *to, const void __user *from, unsigned long n) | |
377 | { | |
21f70d4a | 378 | return __asm_copy_from_user(to, from, n); |
5d8544e2 PD |
379 | } |
380 | ||
381 | static inline unsigned long | |
382 | raw_copy_to_user(void __user *to, const void *from, unsigned long n) | |
383 | { | |
21f70d4a | 384 | return __asm_copy_to_user(to, from, n); |
5d8544e2 PD |
385 | } |
386 | ||
387 | extern long strncpy_from_user(char *dest, const char __user *src, long count); | |
388 | ||
389 | extern long __must_check strlen_user(const char __user *str); | |
390 | extern long __must_check strnlen_user(const char __user *str, long n); | |
391 | ||
392 | extern | |
393 | unsigned long __must_check __clear_user(void __user *addr, unsigned long n); | |
394 | ||
395 | static inline | |
396 | unsigned long __must_check clear_user(void __user *to, unsigned long n) | |
397 | { | |
398 | might_fault(); | |
96d4f267 | 399 | return access_ok(to, n) ? |
5d8544e2 PD |
400 | __clear_user(to, n) : n; |
401 | } | |
402 | ||
403 | /* | |
404 | * Atomic compare-and-exchange, but with a fixup for userspace faults. Faults | |
405 | * will set "err" to -EFAULT, while successful accesses return the previous | |
406 | * value. | |
407 | */ | |
5d8544e2 PD |
408 | #define __cmpxchg_user(ptr, old, new, err, size, lrb, scb) \ |
409 | ({ \ | |
410 | __typeof__(ptr) __ptr = (ptr); \ | |
411 | __typeof__(*(ptr)) __old = (old); \ | |
412 | __typeof__(*(ptr)) __new = (new); \ | |
413 | __typeof__(*(ptr)) __ret; \ | |
414 | __typeof__(err) __err = 0; \ | |
415 | register unsigned int __rc; \ | |
416 | __enable_user_access(); \ | |
417 | switch (size) { \ | |
418 | case 4: \ | |
419 | __asm__ __volatile__ ( \ | |
420 | "0:\n" \ | |
421 | " lr.w" #scb " %[ret], %[ptr]\n" \ | |
422 | " bne %[ret], %z[old], 1f\n" \ | |
423 | " sc.w" #lrb " %[rc], %z[new], %[ptr]\n" \ | |
424 | " bnez %[rc], 0b\n" \ | |
425 | "1:\n" \ | |
426 | ".section .fixup,\"ax\"\n" \ | |
427 | ".balign 4\n" \ | |
428 | "2:\n" \ | |
429 | " li %[err], %[efault]\n" \ | |
430 | " jump 1b, %[rc]\n" \ | |
431 | ".previous\n" \ | |
432 | ".section __ex_table,\"a\"\n" \ | |
433 | ".balign " RISCV_SZPTR "\n" \ | |
434 | " " RISCV_PTR " 1b, 2b\n" \ | |
435 | ".previous\n" \ | |
436 | : [ret] "=&r" (__ret), \ | |
437 | [rc] "=&r" (__rc), \ | |
438 | [ptr] "+A" (*__ptr), \ | |
439 | [err] "=&r" (__err) \ | |
440 | : [old] "rJ" (__old), \ | |
441 | [new] "rJ" (__new), \ | |
442 | [efault] "i" (-EFAULT)); \ | |
443 | break; \ | |
444 | case 8: \ | |
445 | __asm__ __volatile__ ( \ | |
446 | "0:\n" \ | |
447 | " lr.d" #scb " %[ret], %[ptr]\n" \ | |
448 | " bne %[ret], %z[old], 1f\n" \ | |
449 | " sc.d" #lrb " %[rc], %z[new], %[ptr]\n" \ | |
450 | " bnez %[rc], 0b\n" \ | |
451 | "1:\n" \ | |
452 | ".section .fixup,\"ax\"\n" \ | |
453 | ".balign 4\n" \ | |
454 | "2:\n" \ | |
455 | " li %[err], %[efault]\n" \ | |
456 | " jump 1b, %[rc]\n" \ | |
457 | ".previous\n" \ | |
458 | ".section __ex_table,\"a\"\n" \ | |
459 | ".balign " RISCV_SZPTR "\n" \ | |
460 | " " RISCV_PTR " 1b, 2b\n" \ | |
461 | ".previous\n" \ | |
462 | : [ret] "=&r" (__ret), \ | |
463 | [rc] "=&r" (__rc), \ | |
464 | [ptr] "+A" (*__ptr), \ | |
465 | [err] "=&r" (__err) \ | |
466 | : [old] "rJ" (__old), \ | |
467 | [new] "rJ" (__new), \ | |
468 | [efault] "i" (-EFAULT)); \ | |
469 | break; \ | |
470 | default: \ | |
471 | BUILD_BUG(); \ | |
472 | } \ | |
473 | __disable_user_access(); \ | |
474 | (err) = __err; \ | |
475 | __ret; \ | |
476 | }) | |
5d8544e2 PD |
477 | |
478 | #endif /* _ASM_RISCV_UACCESS_H */ |