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
raw_copy_from_user(void * to,const void __user * from,unsigned long n)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
raw_copy_to_user(void __user * to,const void * from,unsigned long n)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
clear_user(void __user * to,unsigned long n)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 */
342