drm/rockchip: vop2: Fix the windows switch between different layers
[drm/drm-misc.git] / arch / mips / include / asm / uaccess.h
blobc0cede273c7c04a86313741ac9af0c1cfd4dac66
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
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.
11 #ifndef _ASM_UACCESS_H
12 #define _ASM_UACCESS_H
14 #include <linux/kernel.h>
15 #include <linux/string.h>
16 #include <asm/asm-eva.h>
17 #include <asm/extable.h>
19 #ifdef CONFIG_32BIT
21 #define __UA_LIMIT 0x80000000UL
22 #define TASK_SIZE_MAX KSEG0
24 #define __UA_ADDR ".word"
25 #define __UA_LA "la"
26 #define __UA_ADDU "addu"
27 #define __UA_t0 "$8"
28 #define __UA_t1 "$9"
30 #endif /* CONFIG_32BIT */
32 #ifdef CONFIG_64BIT
34 extern u64 __ua_limit;
36 #define __UA_LIMIT __ua_limit
37 #define TASK_SIZE_MAX XKSSEG
39 #define __UA_ADDR ".dword"
40 #define __UA_LA "dla"
41 #define __UA_ADDU "daddu"
42 #define __UA_t0 "$12"
43 #define __UA_t1 "$13"
45 #endif /* CONFIG_64BIT */
47 #include <asm-generic/access_ok.h>
50 * put_user: - Write a simple value into user space.
51 * @x: Value to copy to user space.
52 * @ptr: Destination address, in user space.
54 * Context: User context only. This function may sleep if pagefaults are
55 * enabled.
57 * This macro copies a single simple value from kernel space to user
58 * space. It supports simple types like char and int, but not larger
59 * data types like structures or arrays.
61 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
62 * to the result of dereferencing @ptr.
64 * Returns zero on success, or -EFAULT on error.
66 #define put_user(x, ptr) \
67 ({ \
68 __typeof__(*(ptr)) __user *__p = (ptr); \
70 might_fault(); \
71 access_ok(__p, sizeof(*__p)) ? __put_user((x), __p) : -EFAULT; \
75 * get_user: - Get a simple variable from user space.
76 * @x: Variable to store result.
77 * @ptr: Source address, in user space.
79 * Context: User context only. This function may sleep if pagefaults are
80 * enabled.
82 * This macro copies a single simple variable from user space to kernel
83 * space. It supports simple types like char and int, but not larger
84 * data types like structures or arrays.
86 * @ptr must have pointer-to-simple-variable type, and the result of
87 * dereferencing @ptr must be assignable to @x without a cast.
89 * Returns zero on success, or -EFAULT on error.
90 * On error, the variable @x is set to zero.
92 #define get_user(x, ptr) \
93 ({ \
94 const __typeof__(*(ptr)) __user *__p = (ptr); \
96 might_fault(); \
97 access_ok(__p, sizeof(*__p)) ? __get_user((x), __p) : \
98 ((x) = 0, -EFAULT); \
102 * __put_user: - Write a simple value into user space, with less checking.
103 * @x: Value to copy to user space.
104 * @ptr: Destination address, in user space.
106 * Context: User context only. This function may sleep if pagefaults are
107 * enabled.
109 * This macro copies a single simple value from kernel space to user
110 * space. It supports simple types like char and int, but not larger
111 * data types like structures or arrays.
113 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
114 * to the result of dereferencing @ptr.
116 * Caller must check the pointer with access_ok() before calling this
117 * function.
119 * Returns zero on success, or -EFAULT on error.
121 #define __put_user(x, ptr) \
122 ({ \
123 __typeof__(*(ptr)) __user *__pu_ptr = (ptr); \
124 __typeof__(*(ptr)) __pu_val = (x); \
125 int __pu_err = 0; \
127 __chk_user_ptr(__pu_ptr); \
128 switch (sizeof(*__pu_ptr)) { \
129 case 1: \
130 __put_data_asm(user_sb, __pu_ptr); \
131 break; \
132 case 2: \
133 __put_data_asm(user_sh, __pu_ptr); \
134 break; \
135 case 4: \
136 __put_data_asm(user_sw, __pu_ptr); \
137 break; \
138 case 8: \
139 __PUT_DW(user_sd, __pu_ptr); \
140 break; \
141 default: \
142 BUILD_BUG(); \
145 __pu_err; \
149 * __get_user: - Get a simple variable from user space, with less checking.
150 * @x: Variable to store result.
151 * @ptr: Source address, in user space.
153 * Context: User context only. This function may sleep if pagefaults are
154 * enabled.
156 * This macro copies a single simple variable from user space to kernel
157 * space. It supports simple types like char and int, but not larger
158 * data types like structures or arrays.
160 * @ptr must have pointer-to-simple-variable type, and the result of
161 * dereferencing @ptr must be assignable to @x without a cast.
163 * Caller must check the pointer with access_ok() before calling this
164 * function.
166 * Returns zero on success, or -EFAULT on error.
167 * On error, the variable @x is set to zero.
169 #define __get_user(x, ptr) \
170 ({ \
171 const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
172 int __gu_err = 0; \
174 __chk_user_ptr(__gu_ptr); \
175 switch (sizeof(*__gu_ptr)) { \
176 case 1: \
177 __get_data_asm((x), user_lb, __gu_ptr); \
178 break; \
179 case 2: \
180 __get_data_asm((x), user_lh, __gu_ptr); \
181 break; \
182 case 4: \
183 __get_data_asm((x), user_lw, __gu_ptr); \
184 break; \
185 case 8: \
186 __GET_DW((x), user_ld, __gu_ptr); \
187 break; \
188 default: \
189 BUILD_BUG(); \
192 __gu_err; \
195 struct __large_struct { unsigned long buf[100]; };
196 #define __m(x) (*(struct __large_struct __user *)(x))
198 #ifdef CONFIG_32BIT
199 #define __GET_DW(val, insn, ptr) __get_data_asm_ll32(val, insn, ptr)
200 #endif
201 #ifdef CONFIG_64BIT
202 #define __GET_DW(val, insn, ptr) __get_data_asm(val, insn, ptr)
203 #endif
205 #define __get_data_asm(val, insn, addr) \
207 long __gu_tmp; \
209 __asm__ __volatile__( \
210 "1: "insn("%1", "%3")" \n" \
211 "2: \n" \
212 " .insn \n" \
213 " .section .fixup,\"ax\" \n" \
214 "3: li %0, %4 \n" \
215 " move %1, $0 \n" \
216 " j 2b \n" \
217 " .previous \n" \
218 " .section __ex_table,\"a\" \n" \
219 " "__UA_ADDR "\t1b, 3b \n" \
220 " .previous \n" \
221 : "=r" (__gu_err), "=r" (__gu_tmp) \
222 : "0" (0), "o" (__m(addr)), "i" (-EFAULT)); \
224 (val) = (__typeof__(*(addr))) __gu_tmp; \
228 * Get a long long 64 using 32 bit registers.
230 #define __get_data_asm_ll32(val, insn, addr) \
232 union { \
233 unsigned long long l; \
234 __typeof__(*(addr)) t; \
235 } __gu_tmp; \
237 __asm__ __volatile__( \
238 "1: " insn("%1", "(%3)")" \n" \
239 "2: " insn("%D1", "4(%3)")" \n" \
240 "3: \n" \
241 " .insn \n" \
242 " .section .fixup,\"ax\" \n" \
243 "4: li %0, %4 \n" \
244 " move %1, $0 \n" \
245 " move %D1, $0 \n" \
246 " j 3b \n" \
247 " .previous \n" \
248 " .section __ex_table,\"a\" \n" \
249 " " __UA_ADDR " 1b, 4b \n" \
250 " " __UA_ADDR " 2b, 4b \n" \
251 " .previous \n" \
252 : "=r" (__gu_err), "=&r" (__gu_tmp.l) \
253 : "0" (0), "r" (addr), "i" (-EFAULT)); \
255 (val) = __gu_tmp.t; \
258 #define __get_kernel_nofault(dst, src, type, err_label) \
259 do { \
260 int __gu_err; \
262 switch (sizeof(type)) { \
263 case 1: \
264 __get_data_asm(*(type *)(dst), kernel_lb, \
265 (__force type *)(src)); \
266 break; \
267 case 2: \
268 __get_data_asm(*(type *)(dst), kernel_lh, \
269 (__force type *)(src)); \
270 break; \
271 case 4: \
272 __get_data_asm(*(type *)(dst), kernel_lw, \
273 (__force type *)(src)); \
274 break; \
275 case 8: \
276 __GET_DW(*(type *)(dst), kernel_ld, \
277 (__force type *)(src)); \
278 break; \
279 default: \
280 BUILD_BUG(); \
281 break; \
283 if (unlikely(__gu_err)) \
284 goto err_label; \
285 } while (0)
288 * Yuck. We need two variants, one for 64bit operation and one
289 * for 32 bit mode and old iron.
291 #ifdef CONFIG_32BIT
292 #define __PUT_DW(insn, ptr) __put_data_asm_ll32(insn, ptr)
293 #endif
294 #ifdef CONFIG_64BIT
295 #define __PUT_DW(insn, ptr) __put_data_asm(insn, ptr)
296 #endif
298 #define __put_data_asm(insn, ptr) \
300 __asm__ __volatile__( \
301 "1: "insn("%z2", "%3")" # __put_data_asm \n" \
302 "2: \n" \
303 " .insn \n" \
304 " .section .fixup,\"ax\" \n" \
305 "3: li %0, %4 \n" \
306 " j 2b \n" \
307 " .previous \n" \
308 " .section __ex_table,\"a\" \n" \
309 " " __UA_ADDR " 1b, 3b \n" \
310 " .previous \n" \
311 : "=r" (__pu_err) \
312 : "0" (0), "Jr" (__pu_val), "o" (__m(ptr)), \
313 "i" (-EFAULT)); \
316 #define __put_data_asm_ll32(insn, ptr) \
318 __asm__ __volatile__( \
319 "1: "insn("%2", "(%3)")" # __put_data_asm_ll32 \n" \
320 "2: "insn("%D2", "4(%3)")" \n" \
321 "3: \n" \
322 " .insn \n" \
323 " .section .fixup,\"ax\" \n" \
324 "4: li %0, %4 \n" \
325 " j 3b \n" \
326 " .previous \n" \
327 " .section __ex_table,\"a\" \n" \
328 " " __UA_ADDR " 1b, 4b \n" \
329 " " __UA_ADDR " 2b, 4b \n" \
330 " .previous" \
331 : "=r" (__pu_err) \
332 : "0" (0), "r" (__pu_val), "r" (ptr), \
333 "i" (-EFAULT)); \
336 #define __put_kernel_nofault(dst, src, type, err_label) \
337 do { \
338 type __pu_val; \
339 int __pu_err = 0; \
341 __pu_val = *(__force type *)(src); \
342 switch (sizeof(type)) { \
343 case 1: \
344 __put_data_asm(kernel_sb, (type *)(dst)); \
345 break; \
346 case 2: \
347 __put_data_asm(kernel_sh, (type *)(dst)); \
348 break; \
349 case 4: \
350 __put_data_asm(kernel_sw, (type *)(dst)) \
351 break; \
352 case 8: \
353 __PUT_DW(kernel_sd, (type *)(dst)); \
354 break; \
355 default: \
356 BUILD_BUG(); \
357 break; \
359 if (unlikely(__pu_err)) \
360 goto err_label; \
361 } while (0)
365 * We're generating jump to subroutines which will be outside the range of
366 * jump instructions
368 #ifdef MODULE
369 #define __MODULE_JAL(destination) \
370 ".set\tnoat\n\t" \
371 __UA_LA "\t$1, " #destination "\n\t" \
372 "jalr\t$1\n\t" \
373 ".set\tat\n\t"
374 #else
375 #define __MODULE_JAL(destination) \
376 "jal\t" #destination "\n\t"
377 #endif
379 #if defined(CONFIG_CPU_DADDI_WORKAROUNDS) || (defined(CONFIG_EVA) && \
380 defined(CONFIG_CPU_HAS_PREFETCH))
381 #define DADDI_SCRATCH "$3"
382 #else
383 #define DADDI_SCRATCH "$0"
384 #endif
386 extern size_t __raw_copy_from_user(void *__to, const void *__from, size_t __n);
387 extern size_t __raw_copy_to_user(void *__to, const void *__from, size_t __n);
389 static inline unsigned long
390 raw_copy_from_user(void *to, const void __user *from, unsigned long n)
392 register void *__cu_to_r __asm__("$4");
393 register const void __user *__cu_from_r __asm__("$5");
394 register long __cu_len_r __asm__("$6");
396 __cu_to_r = to;
397 __cu_from_r = from;
398 __cu_len_r = n;
400 __asm__ __volatile__(
401 ".set\tnoreorder\n\t"
402 __MODULE_JAL(__raw_copy_from_user)
403 ".set\tnoat\n\t"
404 __UA_ADDU "\t$1, %1, %2\n\t"
405 ".set\tat\n\t"
406 ".set\treorder"
407 : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)
409 : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",
410 DADDI_SCRATCH, "memory");
412 return __cu_len_r;
415 static inline unsigned long
416 raw_copy_to_user(void __user *to, const void *from, unsigned long n)
418 register void __user *__cu_to_r __asm__("$4");
419 register const void *__cu_from_r __asm__("$5");
420 register long __cu_len_r __asm__("$6");
422 __cu_to_r = (to);
423 __cu_from_r = (from);
424 __cu_len_r = (n);
426 __asm__ __volatile__(
427 __MODULE_JAL(__raw_copy_to_user)
428 : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)
430 : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",
431 DADDI_SCRATCH, "memory");
433 return __cu_len_r;
436 #define INLINE_COPY_FROM_USER
437 #define INLINE_COPY_TO_USER
439 extern __kernel_size_t __bzero(void __user *addr, __kernel_size_t size);
442 * __clear_user: - Zero a block of memory in user space, with less checking.
443 * @to: Destination address, in user space.
444 * @n: Number of bytes to zero.
446 * Zero a block of memory in user space. Caller must check
447 * the specified block with access_ok() before calling this function.
449 * Returns number of bytes that could not be cleared.
450 * On success, this will be zero.
452 static inline __kernel_size_t
453 __clear_user(void __user *addr, __kernel_size_t size)
455 __kernel_size_t res;
457 #ifdef CONFIG_CPU_MICROMIPS
458 /* micromips memset / bzero also clobbers t7 & t8 */
459 #define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$15", "$24", "$31"
460 #else
461 #define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"
462 #endif /* CONFIG_CPU_MICROMIPS */
464 might_fault();
465 __asm__ __volatile__(
466 "move\t$4, %1\n\t"
467 "move\t$5, $0\n\t"
468 "move\t$6, %2\n\t"
469 __MODULE_JAL(__bzero)
470 "move\t%0, $6"
471 : "=r" (res)
472 : "r" (addr), "r" (size)
473 : bzero_clobbers);
475 return res;
478 #define clear_user(addr,n) \
479 ({ \
480 void __user * __cl_addr = (addr); \
481 unsigned long __cl_size = (n); \
482 if (__cl_size && access_ok(__cl_addr, __cl_size)) \
483 __cl_size = __clear_user(__cl_addr, __cl_size); \
484 __cl_size; \
487 extern long __strncpy_from_user_asm(char *__to, const char __user *__from, long __len);
490 * strncpy_from_user: - Copy a NUL terminated string from userspace.
491 * @dst: Destination address, in kernel space. This buffer must be at
492 * least @count bytes long.
493 * @src: Source address, in user space.
494 * @count: Maximum number of bytes to copy, including the trailing NUL.
496 * Copies a NUL-terminated string from userspace to kernel space.
498 * On success, returns the length of the string (not including the trailing
499 * NUL).
501 * If access to userspace fails, returns -EFAULT (some data may have been
502 * copied).
504 * If @count is smaller than the length of the string, copies @count bytes
505 * and returns @count.
507 static inline long
508 strncpy_from_user(char *__to, const char __user *__from, long __len)
510 long res;
512 if (!access_ok(__from, __len))
513 return -EFAULT;
515 might_fault();
516 __asm__ __volatile__(
517 "move\t$4, %1\n\t"
518 "move\t$5, %2\n\t"
519 "move\t$6, %3\n\t"
520 __MODULE_JAL(__strncpy_from_user_asm)
521 "move\t%0, $2"
522 : "=r" (res)
523 : "r" (__to), "r" (__from), "r" (__len)
524 : "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
526 return res;
529 extern long __strnlen_user_asm(const char __user *s, long n);
532 * strnlen_user: - Get the size of a string in user space.
533 * @str: The string to measure.
535 * Context: User context only. This function may sleep if pagefaults are
536 * enabled.
538 * Get the size of a NUL-terminated string in user space.
540 * Returns the size of the string INCLUDING the terminating NUL.
541 * On exception, returns 0.
542 * If the string is too long, returns a value greater than @n.
544 static inline long strnlen_user(const char __user *s, long n)
546 long res;
548 if (!access_ok(s, 1))
549 return 0;
551 might_fault();
552 __asm__ __volatile__(
553 "move\t$4, %1\n\t"
554 "move\t$5, %2\n\t"
555 __MODULE_JAL(__strnlen_user_asm)
556 "move\t%0, $2"
557 : "=r" (res)
558 : "r" (s), "r" (n)
559 : "$2", "$4", "$5", __UA_t0, "$31");
561 return res;
564 #endif /* _ASM_UACCESS_H */