1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright (C) 2012 Regents of the University of California
5 * This file was copied from include/asm-generic/uaccess.h
8 #ifndef _ASM_RISCV_UACCESS_H
9 #define _ASM_RISCV_UACCESS_H
11 #include <asm/asm-extable.h>
12 #include <asm/pgtable.h> /* for TASK_SIZE */
15 * User space memory access functions
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>
24 #include <asm-generic/access_ok.h>
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")
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
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.
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()"
53 #define __get_user_asm(insn, x, ptr, err) \
56 __asm__ __volatile__ ( \
58 " " insn " %1, %2\n" \
60 _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1) \
61 : "+r" (err), "=&r" (__x) \
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) \
72 u32 __user *__ptr = (u32 __user *)(ptr); \
74 __asm__ __volatile__ ( \
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])); \
86 (x) = (__typeof__(x))((__typeof__((x)-(x)))( \
87 (((u64)__hi << 32) | __lo))); \
89 #endif /* CONFIG_64BIT */
91 #define __get_user_nocheck(x, __gu_ptr, __gu_err) \
93 switch (sizeof(*__gu_ptr)) { \
95 __get_user_asm("lb", (x), __gu_ptr, __gu_err); \
98 __get_user_asm("lh", (x), __gu_ptr, __gu_err); \
101 __get_user_asm("lw", (x), __gu_ptr, __gu_err); \
104 __get_user_8((x), __gu_ptr, __gu_err); \
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.
116 * Context: User context only. This function may sleep.
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.
122 * @ptr must have pointer-to-simple-variable type, and the result of
123 * dereferencing @ptr must be assignable to @x without a cast.
125 * Caller must check the pointer with access_ok() before calling this
128 * Returns zero on success, or -EFAULT on error.
129 * On error, the variable @x is set to zero.
131 #define __get_user(x, ptr) \
133 const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
136 __chk_user_ptr(__gu_ptr); \
138 __enable_user_access(); \
139 __get_user_nocheck(x, __gu_ptr, __gu_err); \
140 __disable_user_access(); \
146 * get_user: - Get a simple variable from user space.
147 * @x: Variable to store result.
148 * @ptr: Source address, in user space.
150 * Context: User context only. This function may sleep.
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.
156 * @ptr must have pointer-to-simple-variable type, and the result of
157 * dereferencing @ptr must be assignable to @x without a cast.
159 * Returns zero on success, or -EFAULT on error.
160 * On error, the variable @x is set to zero.
162 #define get_user(x, ptr) \
164 const __typeof__(*(ptr)) __user *__p = (ptr); \
166 access_ok(__p, sizeof(*__p)) ? \
167 __get_user((x), __p) : \
168 ((x) = (__force __typeof__(x))0, -EFAULT); \
171 #define __put_user_asm(insn, x, ptr, err) \
173 __typeof__(*(ptr)) __x = x; \
174 __asm__ __volatile__ ( \
176 " " insn " %z2, %1\n" \
178 _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0) \
179 : "+r" (err), "=m" (*(ptr)) \
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) \
189 u32 __user *__ptr = (u32 __user *)(ptr); \
190 u64 __x = (__typeof__((x)-(x)))(x); \
191 __asm__ __volatile__ ( \
197 _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0) \
198 _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0) \
200 "=m" (__ptr[__LSW]), \
201 "=m" (__ptr[__MSW]) \
202 : "rJ" (__x), "rJ" (__x >> 32)); \
204 #endif /* CONFIG_64BIT */
206 #define __put_user_nocheck(x, __gu_ptr, __pu_err) \
208 switch (sizeof(*__gu_ptr)) { \
210 __put_user_asm("sb", (x), __gu_ptr, __pu_err); \
213 __put_user_asm("sh", (x), __gu_ptr, __pu_err); \
216 __put_user_asm("sw", (x), __gu_ptr, __pu_err); \
219 __put_user_8((x), __gu_ptr, __pu_err); \
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.
231 * Context: User context only. This function may sleep.
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.
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).
242 * Caller must check the pointer with access_ok() before calling this
245 * Returns zero on success, or -EFAULT on error.
247 #define __put_user(x, ptr) \
249 __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
250 __typeof__(*__gu_ptr) __val = (x); \
253 __chk_user_ptr(__gu_ptr); \
255 __enable_user_access(); \
256 __put_user_nocheck(__val, __gu_ptr, __pu_err); \
257 __disable_user_access(); \
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.
267 * Context: User context only. This function may sleep.
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.
273 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
274 * to the result of dereferencing @ptr.
276 * Returns zero on success, or -EFAULT on error.
278 #define put_user(x, ptr) \
280 __typeof__(*(ptr)) __user *__p = (ptr); \
282 access_ok(__p, sizeof(*__p)) ? \
283 __put_user((x), __p) : \
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
);
293 static inline unsigned long
294 raw_copy_from_user(void *to
, const void __user
*from
, unsigned long n
)
296 return __asm_copy_from_user(to
, from
, n
);
299 static inline unsigned long
300 raw_copy_to_user(void __user
*to
, const void *from
, unsigned long n
)
302 return __asm_copy_to_user(to
, from
, n
);
305 extern long strncpy_from_user(char *dest
, const char __user
*src
, long count
);
307 extern long __must_check
strnlen_user(const char __user
*str
, long n
);
310 unsigned long __must_check
__clear_user(void __user
*addr
, unsigned long n
);
313 unsigned long __must_check
clear_user(void __user
*to
, unsigned long n
)
316 return access_ok(to
, n
) ?
317 __clear_user(to
, n
) : n
;
320 #define __get_kernel_nofault(dst, src, type, err_label) \
324 __get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \
325 if (unlikely(__kr_err)) \
329 #define __put_kernel_nofault(dst, src, type, err_label) \
333 __put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err); \
334 if (unlikely(__kr_err)) \
338 #else /* CONFIG_MMU */
339 #include <asm-generic/uaccess.h>
340 #endif /* CONFIG_MMU */
341 #endif /* _ASM_RISCV_UACCESS_H */