xref: /linux/arch/loongarch/include/asm/uaccess.h (revision c6fbb759)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4  *
5  * Derived from MIPS:
6  * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03, 04 by Ralf Baechle
7  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8  * Copyright (C) 2007  Maciej W. Rozycki
9  * Copyright (C) 2014, Imagination Technologies Ltd.
10  */
11 #ifndef _ASM_UACCESS_H
12 #define _ASM_UACCESS_H
13 
14 #include <linux/kernel.h>
15 #include <linux/string.h>
16 #include <linux/extable.h>
17 #include <asm/pgtable.h>
18 #include <asm-generic/extable.h>
19 #include <asm-generic/access_ok.h>
20 
21 extern u64 __ua_limit;
22 
23 #define __UA_ADDR	".dword"
24 #define __UA_LA		"la.abs"
25 #define __UA_LIMIT	__ua_limit
26 
27 /*
28  * get_user: - Get a simple variable from user space.
29  * @x:	 Variable to store result.
30  * @ptr: Source address, in user space.
31  *
32  * Context: User context only. This function may sleep if pagefaults are
33  *          enabled.
34  *
35  * This macro copies a single simple variable from user space to kernel
36  * space.  It supports simple types like char and int, but not larger
37  * data types like structures or arrays.
38  *
39  * @ptr must have pointer-to-simple-variable type, and the result of
40  * dereferencing @ptr must be assignable to @x without a cast.
41  *
42  * Returns zero on success, or -EFAULT on error.
43  * On error, the variable @x is set to zero.
44  */
45 #define get_user(x, ptr) \
46 ({									\
47 	const __typeof__(*(ptr)) __user *__p = (ptr);			\
48 									\
49 	might_fault();							\
50 	access_ok(__p, sizeof(*__p)) ? __get_user((x), __p) :		\
51 				       ((x) = 0, -EFAULT);		\
52 })
53 
54 /*
55  * put_user: - Write a simple value into user space.
56  * @x:	 Value to copy to user space.
57  * @ptr: Destination address, in user space.
58  *
59  * Context: User context only. This function may sleep if pagefaults are
60  *          enabled.
61  *
62  * This macro copies a single simple value from kernel space to user
63  * space.  It supports simple types like char and int, but not larger
64  * data types like structures or arrays.
65  *
66  * @ptr must have pointer-to-simple-variable type, and @x must be assignable
67  * to the result of dereferencing @ptr.
68  *
69  * Returns zero on success, or -EFAULT on error.
70  */
71 #define put_user(x, ptr) \
72 ({									\
73 	__typeof__(*(ptr)) __user *__p = (ptr);				\
74 									\
75 	might_fault();							\
76 	access_ok(__p, sizeof(*__p)) ? __put_user((x), __p) : -EFAULT;	\
77 })
78 
79 /*
80  * __get_user: - Get a simple variable from user space, with less checking.
81  * @x:	 Variable to store result.
82  * @ptr: Source address, in user space.
83  *
84  * Context: User context only. This function may sleep if pagefaults are
85  *          enabled.
86  *
87  * This macro copies a single simple variable from user space to kernel
88  * space.  It supports simple types like char and int, but not larger
89  * data types like structures or arrays.
90  *
91  * @ptr must have pointer-to-simple-variable type, and the result of
92  * dereferencing @ptr must be assignable to @x without a cast.
93  *
94  * Caller must check the pointer with access_ok() before calling this
95  * function.
96  *
97  * Returns zero on success, or -EFAULT on error.
98  * On error, the variable @x is set to zero.
99  */
100 #define __get_user(x, ptr) \
101 ({									\
102 	int __gu_err = 0;						\
103 									\
104 	__chk_user_ptr(ptr);						\
105 	__get_user_common((x), sizeof(*(ptr)), ptr);			\
106 	__gu_err;							\
107 })
108 
109 /*
110  * __put_user: - Write a simple value into user space, with less checking.
111  * @x:	 Value to copy to user space.
112  * @ptr: Destination address, in user space.
113  *
114  * Context: User context only. This function may sleep if pagefaults are
115  *          enabled.
116  *
117  * This macro copies a single simple value from kernel space to user
118  * space.  It supports simple types like char and int, but not larger
119  * data types like structures or arrays.
120  *
121  * @ptr must have pointer-to-simple-variable type, and @x must be assignable
122  * to the result of dereferencing @ptr.
123  *
124  * Caller must check the pointer with access_ok() before calling this
125  * function.
126  *
127  * Returns zero on success, or -EFAULT on error.
128  */
129 #define __put_user(x, ptr) \
130 ({									\
131 	int __pu_err = 0;						\
132 	__typeof__(*(ptr)) __pu_val;					\
133 									\
134 	__pu_val = (x);							\
135 	__chk_user_ptr(ptr);						\
136 	__put_user_common(ptr, sizeof(*(ptr)));				\
137 	__pu_err;							\
138 })
139 
140 struct __large_struct { unsigned long buf[100]; };
141 #define __m(x) (*(struct __large_struct __user *)(x))
142 
143 #define __get_user_common(val, size, ptr)				\
144 do {									\
145 	switch (size) {							\
146 	case 1: __get_data_asm(val, "ld.b", ptr); break;		\
147 	case 2: __get_data_asm(val, "ld.h", ptr); break;		\
148 	case 4: __get_data_asm(val, "ld.w", ptr); break;		\
149 	case 8: __get_data_asm(val, "ld.d", ptr); break;		\
150 	default: BUILD_BUG(); break;					\
151 	}								\
152 } while (0)
153 
154 #define __get_kernel_common(val, size, ptr) __get_user_common(val, size, ptr)
155 
156 #define __get_data_asm(val, insn, ptr)					\
157 {									\
158 	long __gu_tmp;							\
159 									\
160 	__asm__ __volatile__(						\
161 	"1:	" insn "	%1, %2				\n"	\
162 	"2:							\n"	\
163 	"	.section .fixup,\"ax\"				\n"	\
164 	"3:	li.w	%0, %3					\n"	\
165 	"	move	%1, $zero				\n"	\
166 	"	b	2b					\n"	\
167 	"	.previous					\n"	\
168 	"	.section __ex_table,\"a\"			\n"	\
169 	"	"__UA_ADDR "\t1b, 3b				\n"	\
170 	"	.previous					\n"	\
171 	: "+r" (__gu_err), "=r" (__gu_tmp)				\
172 	: "m" (__m(ptr)), "i" (-EFAULT));				\
173 									\
174 	(val) = (__typeof__(*(ptr))) __gu_tmp;				\
175 }
176 
177 #define __put_user_common(ptr, size)					\
178 do {									\
179 	switch (size) {							\
180 	case 1: __put_data_asm("st.b", ptr); break;			\
181 	case 2: __put_data_asm("st.h", ptr); break;			\
182 	case 4: __put_data_asm("st.w", ptr); break;			\
183 	case 8: __put_data_asm("st.d", ptr); break;			\
184 	default: BUILD_BUG(); break;					\
185 	}								\
186 } while (0)
187 
188 #define __put_kernel_common(ptr, size) __put_user_common(ptr, size)
189 
190 #define __put_data_asm(insn, ptr)					\
191 {									\
192 	__asm__ __volatile__(						\
193 	"1:	" insn "	%z2, %1		# __put_user_asm\n"	\
194 	"2:							\n"	\
195 	"	.section	.fixup,\"ax\"			\n"	\
196 	"3:	li.w	%0, %3					\n"	\
197 	"	b	2b					\n"	\
198 	"	.previous					\n"	\
199 	"	.section	__ex_table,\"a\"		\n"	\
200 	"	" __UA_ADDR "	1b, 3b				\n"	\
201 	"	.previous					\n"	\
202 	: "+r" (__pu_err), "=m" (__m(ptr))				\
203 	: "Jr" (__pu_val), "i" (-EFAULT));				\
204 }
205 
206 #define __get_kernel_nofault(dst, src, type, err_label)			\
207 do {									\
208 	int __gu_err = 0;						\
209 									\
210 	__get_kernel_common(*((type *)(dst)), sizeof(type),		\
211 			    (__force type *)(src));			\
212 	if (unlikely(__gu_err))						\
213 		goto err_label;						\
214 } while (0)
215 
216 #define __put_kernel_nofault(dst, src, type, err_label)			\
217 do {									\
218 	type __pu_val;							\
219 	int __pu_err = 0;						\
220 									\
221 	__pu_val = *(__force type *)(src);				\
222 	__put_kernel_common(((type *)(dst)), sizeof(type));		\
223 	if (unlikely(__pu_err))						\
224 		goto err_label;						\
225 } while (0)
226 
227 extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);
228 
229 static inline unsigned long __must_check
230 raw_copy_from_user(void *to, const void __user *from, unsigned long n)
231 {
232 	return __copy_user(to, (__force const void *)from, n);
233 }
234 
235 static inline unsigned long __must_check
236 raw_copy_to_user(void __user *to, const void *from, unsigned long n)
237 {
238 	return __copy_user((__force void *)to, from, n);
239 }
240 
241 #define INLINE_COPY_FROM_USER
242 #define INLINE_COPY_TO_USER
243 
244 /*
245  * __clear_user: - Zero a block of memory in user space, with less checking.
246  * @addr: Destination address, in user space.
247  * @size: Number of bytes to zero.
248  *
249  * Zero a block of memory in user space.  Caller must check
250  * the specified block with access_ok() before calling this function.
251  *
252  * Returns number of bytes that could not be cleared.
253  * On success, this will be zero.
254  */
255 extern unsigned long __clear_user(void __user *addr, __kernel_size_t size);
256 
257 #define clear_user(addr, n)						\
258 ({									\
259 	void __user *__cl_addr = (addr);				\
260 	unsigned long __cl_size = (n);					\
261 	if (__cl_size && access_ok(__cl_addr, __cl_size))		\
262 		__cl_size = __clear_user(__cl_addr, __cl_size);		\
263 	__cl_size;							\
264 })
265 
266 extern long strncpy_from_user(char *to, const char __user *from, long n);
267 extern long strnlen_user(const char __user *str, long n);
268 
269 #endif /* _ASM_UACCESS_H */
270