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/extable.h>
19 #include <asm/asm-extable.h>
20 #include <asm-generic/access_ok.h>
21
22 #define __LSW 0
23 #define __MSW 1
24
25 extern u64 __ua_limit;
26
27 #ifdef CONFIG_64BIT
28 #define __UA_LIMIT __ua_limit
29 #else
30 #define __UA_LIMIT 0x80000000UL
31 #endif
32
33 /*
34 * get_user: - Get a simple variable from user space.
35 * @x: Variable to store result.
36 * @ptr: Source address, in user space.
37 *
38 * Context: User context only. This function may sleep if pagefaults are
39 * enabled.
40 *
41 * This macro copies a single simple variable from user space to kernel
42 * space. It supports simple types like char and int, but not larger
43 * data types like structures or arrays.
44 *
45 * @ptr must have pointer-to-simple-variable type, and the result of
46 * dereferencing @ptr must be assignable to @x without a cast.
47 *
48 * Returns zero on success, or -EFAULT on error.
49 * On error, the variable @x is set to zero.
50 */
51 #define get_user(x, ptr) \
52 ({ \
53 const __typeof__(*(ptr)) __user *__p = (ptr); \
54 \
55 might_fault(); \
56 access_ok(__p, sizeof(*__p)) ? __get_user((x), __p) : \
57 ((x) = 0, -EFAULT); \
58 })
59
60 /*
61 * put_user: - Write a simple value into user space.
62 * @x: Value to copy to user space.
63 * @ptr: Destination address, in user space.
64 *
65 * Context: User context only. This function may sleep if pagefaults are
66 * enabled.
67 *
68 * This macro copies a single simple value from kernel space to user
69 * space. It supports simple types like char and int, but not larger
70 * data types like structures or arrays.
71 *
72 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
73 * to the result of dereferencing @ptr.
74 *
75 * Returns zero on success, or -EFAULT on error.
76 */
77 #define put_user(x, ptr) \
78 ({ \
79 __typeof__(*(ptr)) __user *__p = (ptr); \
80 \
81 might_fault(); \
82 access_ok(__p, sizeof(*__p)) ? __put_user((x), __p) : -EFAULT; \
83 })
84
85 /*
86 * __get_user: - Get a simple variable from user space, with less checking.
87 * @x: Variable to store result.
88 * @ptr: Source address, in user space.
89 *
90 * Context: User context only. This function may sleep if pagefaults are
91 * enabled.
92 *
93 * This macro copies a single simple variable from user space to kernel
94 * space. It supports simple types like char and int, but not larger
95 * data types like structures or arrays.
96 *
97 * @ptr must have pointer-to-simple-variable type, and the result of
98 * dereferencing @ptr must be assignable to @x without a cast.
99 *
100 * Caller must check the pointer with access_ok() before calling this
101 * function.
102 *
103 * Returns zero on success, or -EFAULT on error.
104 * On error, the variable @x is set to zero.
105 */
106 #define __get_user(x, ptr) \
107 ({ \
108 int __gu_err = 0; \
109 \
110 __chk_user_ptr(ptr); \
111 __get_user_common((x), sizeof(*(ptr)), ptr); \
112 __gu_err; \
113 })
114
115 /*
116 * __put_user: - Write a simple value into user space, with less checking.
117 * @x: Value to copy to user space.
118 * @ptr: Destination address, in user space.
119 *
120 * Context: User context only. This function may sleep if pagefaults are
121 * enabled.
122 *
123 * This macro copies a single simple value from kernel space to user
124 * space. It supports simple types like char and int, but not larger
125 * data types like structures or arrays.
126 *
127 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
128 * to the result of dereferencing @ptr.
129 *
130 * Caller must check the pointer with access_ok() before calling this
131 * function.
132 *
133 * Returns zero on success, or -EFAULT on error.
134 */
135
136 #define __put_user(x, ptr) \
137 ({ \
138 int __pu_err = 0; \
139 __typeof__(*(ptr)) __pu_val; \
140 \
141 __pu_val = (x); \
142 __chk_user_ptr(ptr); \
143 __put_user_common(ptr, sizeof(*(ptr))); \
144 __pu_err; \
145 })
146
147 struct __large_struct { unsigned long buf[100]; };
148 #define __m(x) (*(struct __large_struct __user *)(x))
149
150 #define __get_user_common(val, size, ptr) \
151 do { \
152 switch (size) { \
153 case 1: __get_data_asm(val, "ld.b", ptr); break; \
154 case 2: __get_data_asm(val, "ld.h", ptr); break; \
155 case 4: __get_data_asm(val, "ld.w", ptr); break; \
156 case 8: __get_data_asm_8(val, ptr); break; \
157 default: BUILD_BUG(); break; \
158 } \
159 } while (0)
160
161 #define __get_kernel_common(val, size, ptr) __get_user_common(val, size, ptr)
162
163 #define __get_data_asm(val, insn, ptr) \
164 { \
165 long __gu_tmp; \
166 \
167 __asm__ __volatile__( \
168 "1: " insn " %1, %2 \n" \
169 "2: \n" \
170 _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1) \
171 : "+r" (__gu_err), "=r" (__gu_tmp) \
172 : "m" (__m(ptr))); \
173 \
174 (val) = (__typeof__(*(ptr))) __gu_tmp; \
175 }
176
177 #ifdef CONFIG_64BIT
178 #define __get_data_asm_8(val, ptr) \
179 __get_data_asm(val, "ld.d", ptr)
180 #else /* !CONFIG_64BIT */
181 #define __get_data_asm_8(val, ptr) \
182 { \
183 u32 __lo, __hi; \
184 u32 __user *__ptr = (u32 __user *)(ptr); \
185 \
186 __asm__ __volatile__ ( \
187 "1:\n" \
188 " ld.w %1, %3 \n" \
189 "2:\n" \
190 " ld.w %2, %4 \n" \
191 "3:\n" \
192 _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 3b, %0, %1) \
193 _ASM_EXTABLE_UACCESS_ERR_ZERO(2b, 3b, %0, %1) \
194 : "+r" (__gu_err), "=&r" (__lo), "=r" (__hi) \
195 : "m" (__ptr[__LSW]), "m" (__ptr[__MSW])); \
196 if (__gu_err) \
197 __hi = 0; \
198 (val) = (__typeof__(val))((__typeof__((val)-(val))) \
199 ((((u64)__hi << 32) | __lo))); \
200 }
201 #endif /* CONFIG_64BIT */
202
203 #define __put_user_common(ptr, size) \
204 do { \
205 switch (size) { \
206 case 1: __put_data_asm("st.b", ptr); break; \
207 case 2: __put_data_asm("st.h", ptr); break; \
208 case 4: __put_data_asm("st.w", ptr); break; \
209 case 8: __put_data_asm_8(ptr); break; \
210 default: BUILD_BUG(); break; \
211 } \
212 } while (0)
213
214 #define __put_kernel_common(ptr, size) __put_user_common(ptr, size)
215
216 #define __put_data_asm(insn, ptr) \
217 { \
218 __asm__ __volatile__( \
219 "1: " insn " %z2, %1 # __put_user_asm\n" \
220 "2: \n" \
221 _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0) \
222 : "+r" (__pu_err), "=m" (__m(ptr)) \
223 : "Jr" (__pu_val)); \
224 }
225
226 #ifdef CONFIG_64BIT
227 #define __put_data_asm_8(ptr) \
228 __put_data_asm("st.d", ptr)
229 #else /* !CONFIG_64BIT */
230 #define __put_data_asm_8(ptr) \
231 { \
232 u32 __user *__ptr = (u32 __user *)(ptr); \
233 u64 __x = (__typeof__((__pu_val)-(__pu_val)))(__pu_val); \
234 \
235 __asm__ __volatile__ ( \
236 "1:\n" \
237 " st.w %z3, %1 \n" \
238 "2:\n" \
239 " st.w %z4, %2 \n" \
240 "3:\n" \
241 _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0) \
242 _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0) \
243 : "+r" (__pu_err), \
244 "=m" (__ptr[__LSW]), \
245 "=m" (__ptr[__MSW]) \
246 : "rJ" (__x), "rJ" (__x >> 32)); \
247 }
248 #endif /* CONFIG_64BIT */
249
250 #define __get_kernel_nofault(dst, src, type, err_label) \
251 do { \
252 int __gu_err = 0; \
253 \
254 __get_kernel_common(*((type *)(dst)), sizeof(type), \
255 (__force type *)(src)); \
256 if (unlikely(__gu_err)) \
257 goto err_label; \
258 } while (0)
259
260 #define __put_kernel_nofault(dst, src, type, err_label) \
261 do { \
262 type __pu_val; \
263 int __pu_err = 0; \
264 \
265 __pu_val = *(__force type *)(src); \
266 __put_kernel_common(((type *)(dst)), sizeof(type)); \
267 if (unlikely(__pu_err)) \
268 goto err_label; \
269 } while (0)
270
271 extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);
272
273 static inline unsigned long __must_check
raw_copy_from_user(void * to,const void __user * from,unsigned long n)274 raw_copy_from_user(void *to, const void __user *from, unsigned long n)
275 {
276 return __copy_user(to, (__force const void *)from, n);
277 }
278
279 static inline unsigned long __must_check
raw_copy_to_user(void __user * to,const void * from,unsigned long n)280 raw_copy_to_user(void __user *to, const void *from, unsigned long n)
281 {
282 return __copy_user((__force void *)to, from, n);
283 }
284
285 #define INLINE_COPY_FROM_USER
286 #define INLINE_COPY_TO_USER
287
288 /*
289 * __clear_user: - Zero a block of memory in user space, with less checking.
290 * @addr: Destination address, in user space.
291 * @size: Number of bytes to zero.
292 *
293 * Zero a block of memory in user space. Caller must check
294 * the specified block with access_ok() before calling this function.
295 *
296 * Returns number of bytes that could not be cleared.
297 * On success, this will be zero.
298 */
299 extern unsigned long __clear_user(void __user *addr, __kernel_size_t size);
300
301 #define clear_user(addr, n) \
302 ({ \
303 void __user *__cl_addr = (addr); \
304 unsigned long __cl_size = (n); \
305 if (__cl_size && access_ok(__cl_addr, __cl_size)) \
306 __cl_size = __clear_user(__cl_addr, __cl_size); \
307 __cl_size; \
308 })
309
310 extern long strncpy_from_user(char *to, const char __user *from, long n);
311 extern long strnlen_user(const char __user *str, long n);
312
313 #endif /* _ASM_UACCESS_H */
314