diff options
-rw-r--r-- | arch/metag/include/asm/uaccess.h | 9 | ||||
-rw-r--r-- | arch/metag/lib/usercopy.c | 24 |
2 files changed, 31 insertions, 2 deletions
diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h index 07238b39638c..469a2f1393d3 100644 --- a/arch/metag/include/asm/uaccess.h +++ b/arch/metag/include/asm/uaccess.h | |||
@@ -138,7 +138,8 @@ extern long __get_user_bad(void); | |||
138 | 138 | ||
139 | #define __get_user_nocheck(x, ptr, size) \ | 139 | #define __get_user_nocheck(x, ptr, size) \ |
140 | ({ \ | 140 | ({ \ |
141 | long __gu_err, __gu_val; \ | 141 | long __gu_err; \ |
142 | long long __gu_val; \ | ||
142 | __get_user_size(__gu_val, (ptr), (size), __gu_err); \ | 143 | __get_user_size(__gu_val, (ptr), (size), __gu_err); \ |
143 | (x) = (__force __typeof__(*(ptr)))__gu_val; \ | 144 | (x) = (__force __typeof__(*(ptr)))__gu_val; \ |
144 | __gu_err; \ | 145 | __gu_err; \ |
@@ -146,7 +147,8 @@ extern long __get_user_bad(void); | |||
146 | 147 | ||
147 | #define __get_user_check(x, ptr, size) \ | 148 | #define __get_user_check(x, ptr, size) \ |
148 | ({ \ | 149 | ({ \ |
149 | long __gu_err = -EFAULT, __gu_val = 0; \ | 150 | long __gu_err = -EFAULT; \ |
151 | long long __gu_val = 0; \ | ||
150 | const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ | 152 | const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ |
151 | if (access_ok(VERIFY_READ, __gu_addr, size)) \ | 153 | if (access_ok(VERIFY_READ, __gu_addr, size)) \ |
152 | __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ | 154 | __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ |
@@ -157,6 +159,7 @@ extern long __get_user_bad(void); | |||
157 | extern unsigned char __get_user_asm_b(const void __user *addr, long *err); | 159 | extern unsigned char __get_user_asm_b(const void __user *addr, long *err); |
158 | extern unsigned short __get_user_asm_w(const void __user *addr, long *err); | 160 | extern unsigned short __get_user_asm_w(const void __user *addr, long *err); |
159 | extern unsigned int __get_user_asm_d(const void __user *addr, long *err); | 161 | extern unsigned int __get_user_asm_d(const void __user *addr, long *err); |
162 | extern unsigned long long __get_user_asm_l(const void __user *addr, long *err); | ||
160 | 163 | ||
161 | #define __get_user_size(x, ptr, size, retval) \ | 164 | #define __get_user_size(x, ptr, size, retval) \ |
162 | do { \ | 165 | do { \ |
@@ -168,6 +171,8 @@ do { \ | |||
168 | x = __get_user_asm_w(ptr, &retval); break; \ | 171 | x = __get_user_asm_w(ptr, &retval); break; \ |
169 | case 4: \ | 172 | case 4: \ |
170 | x = __get_user_asm_d(ptr, &retval); break; \ | 173 | x = __get_user_asm_d(ptr, &retval); break; \ |
174 | case 8: \ | ||
175 | x = __get_user_asm_l(ptr, &retval); break; \ | ||
171 | default: \ | 176 | default: \ |
172 | (x) = __get_user_bad(); \ | 177 | (x) = __get_user_bad(); \ |
173 | } \ | 178 | } \ |
diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c index ceb4590fbca5..45e7b79eca19 100644 --- a/arch/metag/lib/usercopy.c +++ b/arch/metag/lib/usercopy.c | |||
@@ -1044,6 +1044,30 @@ unsigned int __get_user_asm_d(const void __user *addr, long *err) | |||
1044 | } | 1044 | } |
1045 | EXPORT_SYMBOL(__get_user_asm_d); | 1045 | EXPORT_SYMBOL(__get_user_asm_d); |
1046 | 1046 | ||
1047 | unsigned long long __get_user_asm_l(const void __user *addr, long *err) | ||
1048 | { | ||
1049 | register unsigned long long x asm ("D0Re0") = 0; | ||
1050 | asm volatile ( | ||
1051 | " GETL %0,%t0,[%2]\n" | ||
1052 | "1:\n" | ||
1053 | " GETL %0,%t0,[%2]\n" | ||
1054 | "2:\n" | ||
1055 | " .section .fixup,\"ax\"\n" | ||
1056 | "3: MOV D0FrT,%3\n" | ||
1057 | " SETD [%1],D0FrT\n" | ||
1058 | " MOVT D0FrT,#HI(2b)\n" | ||
1059 | " JUMP D0FrT,#LO(2b)\n" | ||
1060 | " .previous\n" | ||
1061 | " .section __ex_table,\"a\"\n" | ||
1062 | " .long 1b,3b\n" | ||
1063 | " .previous\n" | ||
1064 | : "=r" (x) | ||
1065 | : "r" (err), "r" (addr), "P" (-EFAULT) | ||
1066 | : "D0FrT"); | ||
1067 | return x; | ||
1068 | } | ||
1069 | EXPORT_SYMBOL(__get_user_asm_l); | ||
1070 | |||
1047 | long __put_user_asm_b(unsigned int x, void __user *addr) | 1071 | long __put_user_asm_b(unsigned int x, void __user *addr) |
1048 | { | 1072 | { |
1049 | register unsigned int err asm ("D0Re0") = 0; | 1073 | register unsigned int err asm ("D0Re0") = 0; |