GNU Linux-libre 5.19-rc6-gnu
[releases.git] / arch / riscv / include / asm / uaccess.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2012 Regents of the University of California
4  *
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 #include <asm/asm-extable.h>
12 #include <asm/pgtable.h>                /* for TASK_SIZE */
13
14 /*
15  * User space memory access functions
16  */
17 #ifdef CONFIG_MMU
18 #include <linux/errno.h>
19 #include <linux/compiler.h>
20 #include <linux/thread_info.h>
21 #include <asm/byteorder.h>
22 #include <asm/extable.h>
23 #include <asm/asm.h>
24 #include <asm-generic/access_ok.h>
25
26 #define __enable_user_access()                                                  \
27         __asm__ __volatile__ ("csrs sstatus, %0" : : "r" (SR_SUM) : "memory")
28 #define __disable_user_access()                                                 \
29         __asm__ __volatile__ ("csrc sstatus, %0" : : "r" (SR_SUM) : "memory")
30
31 /*
32  * The exception table consists of pairs of addresses: the first is the
33  * address of an instruction that is allowed to fault, and the second is
34  * the address at which the program should continue.  No registers are
35  * modified, so it is entirely up to the continuation code to figure out
36  * what to do.
37  *
38  * All the routines below use bits of fixup code that are out of line
39  * with the main instruction path.  This means when everything is well,
40  * we don't even have to jump over them.  Further, they do not intrude
41  * on our cache or tlb entries.
42  */
43
44 #define __LSW   0
45 #define __MSW   1
46
47 /*
48  * The "__xxx" versions of the user access functions do not verify the address
49  * space - it must have been done previously with a separate "access_ok()"
50  * call.
51  */
52
53 #define __get_user_asm(insn, x, ptr, err)                       \
54 do {                                                            \
55         __typeof__(x) __x;                                      \
56         __asm__ __volatile__ (                                  \
57                 "1:\n"                                          \
58                 "       " insn " %1, %2\n"                      \
59                 "2:\n"                                          \
60                 _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1)   \
61                 : "+r" (err), "=&r" (__x)                       \
62                 : "m" (*(ptr)));                                \
63         (x) = __x;                                              \
64 } while (0)
65
66 #ifdef CONFIG_64BIT
67 #define __get_user_8(x, ptr, err) \
68         __get_user_asm("ld", x, ptr, err)
69 #else /* !CONFIG_64BIT */
70 #define __get_user_8(x, ptr, err)                               \
71 do {                                                            \
72         u32 __user *__ptr = (u32 __user *)(ptr);                \
73         u32 __lo, __hi;                                         \
74         __asm__ __volatile__ (                                  \
75                 "1:\n"                                          \
76                 "       lw %1, %3\n"                            \
77                 "2:\n"                                          \
78                 "       lw %2, %4\n"                            \
79                 "3:\n"                                          \
80                 _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 3b, %0, %1)   \
81                 _ASM_EXTABLE_UACCESS_ERR_ZERO(2b, 3b, %0, %1)   \
82                 : "+r" (err), "=&r" (__lo), "=r" (__hi)         \
83                 : "m" (__ptr[__LSW]), "m" (__ptr[__MSW]));      \
84         if (err)                                                \
85                 __hi = 0;                                       \
86         (x) = (__typeof__(x))((__typeof__((x)-(x)))(            \
87                 (((u64)__hi << 32) | __lo)));                   \
88 } while (0)
89 #endif /* CONFIG_64BIT */
90
91 #define __get_user_nocheck(x, __gu_ptr, __gu_err)               \
92 do {                                                            \
93         switch (sizeof(*__gu_ptr)) {                            \
94         case 1:                                                 \
95                 __get_user_asm("lb", (x), __gu_ptr, __gu_err);  \
96                 break;                                          \
97         case 2:                                                 \
98                 __get_user_asm("lh", (x), __gu_ptr, __gu_err);  \
99                 break;                                          \
100         case 4:                                                 \
101                 __get_user_asm("lw", (x), __gu_ptr, __gu_err);  \
102                 break;                                          \
103         case 8:                                                 \
104                 __get_user_8((x), __gu_ptr, __gu_err);  \
105                 break;                                          \
106         default:                                                \
107                 BUILD_BUG();                                    \
108         }                                                       \
109 } while (0)
110
111 /**
112  * __get_user: - Get a simple variable from user space, with less checking.
113  * @x:   Variable to store result.
114  * @ptr: Source address, in user space.
115  *
116  * Context: User context only.  This function may sleep.
117  *
118  * This macro copies a single simple variable from user space to kernel
119  * space.  It supports simple types like char and int, but not larger
120  * data types like structures or arrays.
121  *
122  * @ptr must have pointer-to-simple-variable type, and the result of
123  * dereferencing @ptr must be assignable to @x without a cast.
124  *
125  * Caller must check the pointer with access_ok() before calling this
126  * function.
127  *
128  * Returns zero on success, or -EFAULT on error.
129  * On error, the variable @x is set to zero.
130  */
131 #define __get_user(x, ptr)                                      \
132 ({                                                              \
133         const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);      \
134         long __gu_err = 0;                                      \
135                                                                 \
136         __chk_user_ptr(__gu_ptr);                               \
137                                                                 \
138         __enable_user_access();                                 \
139         __get_user_nocheck(x, __gu_ptr, __gu_err);              \
140         __disable_user_access();                                \
141                                                                 \
142         __gu_err;                                               \
143 })
144
145 /**
146  * get_user: - Get a simple variable from user space.
147  * @x:   Variable to store result.
148  * @ptr: Source address, in user space.
149  *
150  * Context: User context only.  This function may sleep.
151  *
152  * This macro copies a single simple variable from user space to kernel
153  * space.  It supports simple types like char and int, but not larger
154  * data types like structures or arrays.
155  *
156  * @ptr must have pointer-to-simple-variable type, and the result of
157  * dereferencing @ptr must be assignable to @x without a cast.
158  *
159  * Returns zero on success, or -EFAULT on error.
160  * On error, the variable @x is set to zero.
161  */
162 #define get_user(x, ptr)                                        \
163 ({                                                              \
164         const __typeof__(*(ptr)) __user *__p = (ptr);           \
165         might_fault();                                          \
166         access_ok(__p, sizeof(*__p)) ?          \
167                 __get_user((x), __p) :                          \
168                 ((x) = 0, -EFAULT);                             \
169 })
170
171 #define __put_user_asm(insn, x, ptr, err)                       \
172 do {                                                            \
173         __typeof__(*(ptr)) __x = x;                             \
174         __asm__ __volatile__ (                                  \
175                 "1:\n"                                          \
176                 "       " insn " %z2, %1\n"                     \
177                 "2:\n"                                          \
178                 _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0)            \
179                 : "+r" (err), "=m" (*(ptr))                     \
180                 : "rJ" (__x));                                  \
181 } while (0)
182
183 #ifdef CONFIG_64BIT
184 #define __put_user_8(x, ptr, err) \
185         __put_user_asm("sd", x, ptr, err)
186 #else /* !CONFIG_64BIT */
187 #define __put_user_8(x, ptr, err)                               \
188 do {                                                            \
189         u32 __user *__ptr = (u32 __user *)(ptr);                \
190         u64 __x = (__typeof__((x)-(x)))(x);                     \
191         __asm__ __volatile__ (                                  \
192                 "1:\n"                                          \
193                 "       sw %z3, %1\n"                           \
194                 "2:\n"                                          \
195                 "       sw %z4, %2\n"                           \
196                 "3:\n"                                          \
197                 _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0)            \
198                 _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0)            \
199                 : "+r" (err),                                   \
200                         "=m" (__ptr[__LSW]),                    \
201                         "=m" (__ptr[__MSW])                     \
202                 : "rJ" (__x), "rJ" (__x >> 32));                \
203 } while (0)
204 #endif /* CONFIG_64BIT */
205
206 #define __put_user_nocheck(x, __gu_ptr, __pu_err)                                       \
207 do {                                                            \
208         switch (sizeof(*__gu_ptr)) {                            \
209         case 1:                                                 \
210                 __put_user_asm("sb", (x), __gu_ptr, __pu_err);  \
211                 break;                                          \
212         case 2:                                                 \
213                 __put_user_asm("sh", (x), __gu_ptr, __pu_err);  \
214                 break;                                          \
215         case 4:                                                 \
216                 __put_user_asm("sw", (x), __gu_ptr, __pu_err);  \
217                 break;                                          \
218         case 8:                                                 \
219                 __put_user_8((x), __gu_ptr, __pu_err);  \
220                 break;                                          \
221         default:                                                \
222                 BUILD_BUG();                                    \
223         }                                                       \
224 } while (0)
225
226 /**
227  * __put_user: - Write a simple value into user space, with less checking.
228  * @x:   Value to copy to user space.
229  * @ptr: Destination address, in user space.
230  *
231  * Context: User context only.  This function may sleep.
232  *
233  * This macro copies a single simple value from kernel space to user
234  * space.  It supports simple types like char and int, but not larger
235  * data types like structures or arrays.
236  *
237  * @ptr must have pointer-to-simple-variable type, and @x must be assignable
238  * to the result of dereferencing @ptr. The value of @x is copied to avoid
239  * re-ordering where @x is evaluated inside the block that enables user-space
240  * access (thus bypassing user space protection if @x is a function).
241  *
242  * Caller must check the pointer with access_ok() before calling this
243  * function.
244  *
245  * Returns zero on success, or -EFAULT on error.
246  */
247 #define __put_user(x, ptr)                                      \
248 ({                                                              \
249         __typeof__(*(ptr)) __user *__gu_ptr = (ptr);            \
250         __typeof__(*__gu_ptr) __val = (x);                      \
251         long __pu_err = 0;                                      \
252                                                                 \
253         __chk_user_ptr(__gu_ptr);                               \
254                                                                 \
255         __enable_user_access();                                 \
256         __put_user_nocheck(__val, __gu_ptr, __pu_err);          \
257         __disable_user_access();                                \
258                                                                 \
259         __pu_err;                                               \
260 })
261
262 /**
263  * put_user: - Write a simple value into user space.
264  * @x:   Value to copy to user space.
265  * @ptr: Destination address, in user space.
266  *
267  * Context: User context only.  This function may sleep.
268  *
269  * This macro copies a single simple value from kernel space to user
270  * space.  It supports simple types like char and int, but not larger
271  * data types like structures or arrays.
272  *
273  * @ptr must have pointer-to-simple-variable type, and @x must be assignable
274  * to the result of dereferencing @ptr.
275  *
276  * Returns zero on success, or -EFAULT on error.
277  */
278 #define put_user(x, ptr)                                        \
279 ({                                                              \
280         __typeof__(*(ptr)) __user *__p = (ptr);                 \
281         might_fault();                                          \
282         access_ok(__p, sizeof(*__p)) ?          \
283                 __put_user((x), __p) :                          \
284                 -EFAULT;                                        \
285 })
286
287
288 unsigned long __must_check __asm_copy_to_user(void __user *to,
289         const void *from, unsigned long n);
290 unsigned long __must_check __asm_copy_from_user(void *to,
291         const void __user *from, unsigned long n);
292
293 static inline unsigned long
294 raw_copy_from_user(void *to, const void __user *from, unsigned long n)
295 {
296         return __asm_copy_from_user(to, from, n);
297 }
298
299 static inline unsigned long
300 raw_copy_to_user(void __user *to, const void *from, unsigned long n)
301 {
302         return __asm_copy_to_user(to, from, n);
303 }
304
305 extern long strncpy_from_user(char *dest, const char __user *src, long count);
306
307 extern long __must_check strnlen_user(const char __user *str, long n);
308
309 extern
310 unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
311
312 static inline
313 unsigned long __must_check clear_user(void __user *to, unsigned long n)
314 {
315         might_fault();
316         return access_ok(to, n) ?
317                 __clear_user(to, n) : n;
318 }
319
320 #define __get_kernel_nofault(dst, src, type, err_label)                 \
321 do {                                                                    \
322         long __kr_err;                                                  \
323                                                                         \
324         __get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err);  \
325         if (unlikely(__kr_err))                                         \
326                 goto err_label;                                         \
327 } while (0)
328
329 #define __put_kernel_nofault(dst, src, type, err_label)                 \
330 do {                                                                    \
331         long __kr_err;                                                  \
332                                                                         \
333         __put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err);  \
334         if (unlikely(__kr_err))                                         \
335                 goto err_label;                                         \
336 } while (0)
337
338 #else /* CONFIG_MMU */
339 #include <asm-generic/uaccess.h>
340 #endif /* CONFIG_MMU */
341 #endif /* _ASM_RISCV_UACCESS_H */