Fix <math-emu/soft-fp.h> tpyo
[safe/jmp/linux-2.6] / include / asm-mips / uaccess.h
index b41901d..b255117 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef _ASM_UACCESS_H
 #define _ASM_UACCESS_H
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/thread_info.h>
@@ -202,50 +201,49 @@ struct __large_struct { unsigned long buf[100]; };
  * Yuck.  We need two variants, one for 64bit operation and one
  * for 32 bit mode and old iron.
  */
-#ifdef __mips64
-#define __GET_USER_DW(ptr) __get_user_asm("ld", ptr)
-#else
-#define __GET_USER_DW(ptr) __get_user_asm_ll32(ptr)
+#ifdef CONFIG_32BIT
+#define __GET_USER_DW(val, ptr) __get_user_asm_ll32(val, ptr)
+#endif
+#ifdef CONFIG_64BIT
+#define __GET_USER_DW(val, ptr) __get_user_asm(val, "ld", ptr)
 #endif
 
-#define __get_user_nocheck(x,ptr,size)                                 \
-({                                                                     \
-       __typeof(*(ptr)) __gu_val =  (__typeof(*(ptr))) 0;              \
-       long __gu_err = 0;                                              \
-                                                                       \
-       might_sleep();                                                  \
+extern void __get_user_unknown(void);
+
+#define __get_user_common(val, size, ptr)                              \
+do {                                                                   \
        switch (size) {                                                 \
-       case 1: __get_user_asm("lb", ptr); break;                       \
-       case 2: __get_user_asm("lh", ptr); break;                       \
-       case 4: __get_user_asm("lw", ptr); break;                       \
-       case 8: __GET_USER_DW(ptr); break;                              \
+       case 1: __get_user_asm(val, "lb", ptr); break;                  \
+       case 2: __get_user_asm(val, "lh", ptr); break;                  \
+       case 4: __get_user_asm(val, "lw", ptr); break;                  \
+       case 8: __GET_USER_DW(val, ptr); break;                         \
        default: __get_user_unknown(); break;                           \
        }                                                               \
-       (x) = (__typeof__(*(ptr))) __gu_val;                            \
+} while (0)
+
+#define __get_user_nocheck(x,ptr,size)                                 \
+({                                                                     \
+       long __gu_err;                                                  \
+                                                                       \
+       __get_user_common((x), size, ptr);                              \
        __gu_err;                                                       \
 })
 
 #define __get_user_check(x,ptr,size)                                   \
 ({                                                                     \
-       const __typeof__(*(ptr)) __user * __gu_addr = (ptr);            \
-       __typeof__(*(ptr)) __gu_val = 0;                                \
        long __gu_err = -EFAULT;                                        \
+       const __typeof__(*(ptr)) __user * __gu_ptr = (ptr);             \
+                                                                       \
+       if (likely(access_ok(VERIFY_READ,  __gu_ptr, size)))            \
+               __get_user_common((x), size, __gu_ptr);                 \
                                                                        \
-       if (likely(access_ok(VERIFY_READ,  __gu_addr, size))) {         \
-               switch (size) {                                         \
-               case 1: __get_user_asm("lb", __gu_addr); break;         \
-               case 2: __get_user_asm("lh", __gu_addr); break;         \
-               case 4: __get_user_asm("lw", __gu_addr); break;         \
-               case 8: __GET_USER_DW(__gu_addr); break;                \
-               default: __get_user_unknown(); break;                   \
-               }                                                       \
-       }                                                               \
-       (x) = (__typeof__(*(ptr))) __gu_val;                            \
        __gu_err;                                                       \
 })
 
-#define __get_user_asm(insn, addr)                                     \
+#define __get_user_asm(val, insn, addr)                                        \
 {                                                                      \
+       long __gu_tmp;                                                  \
+                                                                       \
        __asm__ __volatile__(                                           \
        "1:     " insn "        %1, %3                          \n"     \
        "2:                                                     \n"     \
@@ -256,19 +254,25 @@ struct __large_struct { unsigned long buf[100]; };
        "       .section __ex_table,\"a\"                       \n"     \
        "       "__UA_ADDR "\t1b, 3b                            \n"     \
        "       .previous                                       \n"     \
-       : "=r" (__gu_err), "=r" (__gu_val)                              \
+       : "=r" (__gu_err), "=r" (__gu_tmp)                              \
        : "0" (0), "o" (__m(addr)), "i" (-EFAULT));                     \
+                                                                       \
+       (val) = (__typeof__(*(addr))) __gu_tmp;                         \
 }
 
 /*
  * Get a long long 64 using 32 bit registers.
  */
-#define __get_user_asm_ll32(addr)                                      \
+#define __get_user_asm_ll32(val, addr)                                 \
 {                                                                      \
+       union {                                                         \
+               unsigned long long      l;                              \
+               __typeof__(*(addr))     t;                              \
+       } __gu_tmp;                                                     \
+                                                                       \
        __asm__ __volatile__(                                           \
        "1:     lw      %1, (%3)                                \n"     \
        "2:     lw      %D1, 4(%3)                              \n"     \
-       "       move    %0, $0                                  \n"     \
        "3:     .section        .fixup,\"ax\"                   \n"     \
        "4:     li      %0, %4                                  \n"     \
        "       move    %1, $0                                  \n"     \
@@ -279,28 +283,28 @@ struct __large_struct { unsigned long buf[100]; };
        "       " __UA_ADDR "   1b, 4b                          \n"     \
        "       " __UA_ADDR "   2b, 4b                          \n"     \
        "       .previous                                       \n"     \
-       : "=r" (__gu_err), "=&r" (__gu_val)                             \
+       : "=r" (__gu_err), "=&r" (__gu_tmp.l)                           \
        : "0" (0), "r" (addr), "i" (-EFAULT));                          \
+                                                                       \
+       (val) = __gu_tmp.t;                                             \
 }
 
-extern void __get_user_unknown(void);
-
 /*
  * Yuck.  We need two variants, one for 64bit operation and one
  * for 32 bit mode and old iron.
  */
-#ifdef __mips64
-#define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr)
-#else
+#ifdef CONFIG_32BIT
 #define __PUT_USER_DW(ptr) __put_user_asm_ll32(ptr)
 #endif
+#ifdef CONFIG_64BIT
+#define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr)
+#endif
 
 #define __put_user_nocheck(x,ptr,size)                                 \
 ({                                                                     \
        __typeof__(*(ptr)) __pu_val;                                    \
        long __pu_err = 0;                                              \
                                                                        \
-       might_sleep();                                                  \
        __pu_val = (x);                                                 \
        switch (size) {                                                 \
        case 1: __put_user_asm("sb", ptr); break;                       \
@@ -431,8 +435,34 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
        __cu_len;                                                       \
 })
 
-#define __copy_to_user_inatomic __copy_to_user
-#define __copy_from_user_inatomic __copy_from_user
+extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
+
+#define __copy_to_user_inatomic(to,from,n)                             \
+({                                                                     \
+       void __user *__cu_to;                                           \
+       const void *__cu_from;                                          \
+       long __cu_len;                                                  \
+                                                                       \
+       __cu_to = (to);                                                 \
+       __cu_from = (from);                                             \
+       __cu_len = (n);                                                 \
+       __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len); \
+       __cu_len;                                                       \
+})
+
+#define __copy_from_user_inatomic(to,from,n)                           \
+({                                                                     \
+       void *__cu_to;                                                  \
+       const void __user *__cu_from;                                   \
+       long __cu_len;                                                  \
+                                                                       \
+       __cu_to = (to);                                                 \
+       __cu_from = (from);                                             \
+       __cu_len = (n);                                                 \
+       __cu_len = __invoke_copy_from_user_inatomic(__cu_to, __cu_from, \
+                                                   __cu_len);          \
+       __cu_len;                                                       \
+})
 
 /*
  * copy_to_user: - Copy a block of data into user space.
@@ -486,8 +516,32 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
        __cu_len_r;                                                     \
 })
 
+#define __invoke_copy_from_user_inatomic(to,from,n)                    \
+({                                                                     \
+       register void *__cu_to_r __asm__ ("$4");                        \
+       register const void __user *__cu_from_r __asm__ ("$5");         \
+       register long __cu_len_r __asm__ ("$6");                        \
+                                                                       \
+       __cu_to_r = (to);                                               \
+       __cu_from_r = (from);                                           \
+       __cu_len_r = (n);                                               \
+       __asm__ __volatile__(                                           \
+       ".set\tnoreorder\n\t"                                           \
+       __MODULE_JAL(__copy_user_inatomic)                              \
+       ".set\tnoat\n\t"                                                \
+       __UA_ADDU "\t$1, %1, %2\n\t"                                    \
+       ".set\tat\n\t"                                                  \
+       ".set\treorder"                                                 \
+       : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)       \
+       :                                                               \
+       : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31",         \
+         "memory");                                                    \
+       __cu_len_r;                                                     \
+})
+
 /*
- * __copy_from_user: - Copy a block of data from user space, with less checking. * @to:   Destination address, in kernel space.
+ * __copy_from_user: - Copy a block of data from user space, with less checking.
+ * @to:   Destination address, in kernel space.
  * @from: Source address, in user space.
  * @n:    Number of bytes to copy.
  *