metag/usercopy: Add 64-bit get_user support
Metag already supports 64-bit put_user, so add support for 64-bit get_user too so that the test_user_copy module can test both. Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: linux-metag@vger.kernel.org
This commit is contained in:
parent
fc1b759ae4
commit
d3ba2e922d
|
@ -138,7 +138,8 @@ extern long __get_user_bad(void);
|
||||||
|
|
||||||
#define __get_user_nocheck(x, ptr, size) \
|
#define __get_user_nocheck(x, ptr, size) \
|
||||||
({ \
|
({ \
|
||||||
long __gu_err, __gu_val; \
|
long __gu_err; \
|
||||||
|
long long __gu_val; \
|
||||||
__get_user_size(__gu_val, (ptr), (size), __gu_err); \
|
__get_user_size(__gu_val, (ptr), (size), __gu_err); \
|
||||||
(x) = (__force __typeof__(*(ptr)))__gu_val; \
|
(x) = (__force __typeof__(*(ptr)))__gu_val; \
|
||||||
__gu_err; \
|
__gu_err; \
|
||||||
|
@ -146,7 +147,8 @@ extern long __get_user_bad(void);
|
||||||
|
|
||||||
#define __get_user_check(x, ptr, size) \
|
#define __get_user_check(x, ptr, size) \
|
||||||
({ \
|
({ \
|
||||||
long __gu_err = -EFAULT, __gu_val = 0; \
|
long __gu_err = -EFAULT; \
|
||||||
|
long long __gu_val = 0; \
|
||||||
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
|
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
|
||||||
if (access_ok(VERIFY_READ, __gu_addr, size)) \
|
if (access_ok(VERIFY_READ, __gu_addr, size)) \
|
||||||
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
|
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
|
||||||
|
@ -157,6 +159,7 @@ extern long __get_user_bad(void);
|
||||||
extern unsigned char __get_user_asm_b(const void __user *addr, long *err);
|
extern unsigned char __get_user_asm_b(const void __user *addr, long *err);
|
||||||
extern unsigned short __get_user_asm_w(const void __user *addr, long *err);
|
extern unsigned short __get_user_asm_w(const void __user *addr, long *err);
|
||||||
extern unsigned int __get_user_asm_d(const void __user *addr, long *err);
|
extern unsigned int __get_user_asm_d(const void __user *addr, long *err);
|
||||||
|
extern unsigned long long __get_user_asm_l(const void __user *addr, long *err);
|
||||||
|
|
||||||
#define __get_user_size(x, ptr, size, retval) \
|
#define __get_user_size(x, ptr, size, retval) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -168,6 +171,8 @@ do { \
|
||||||
x = __get_user_asm_w(ptr, &retval); break; \
|
x = __get_user_asm_w(ptr, &retval); break; \
|
||||||
case 4: \
|
case 4: \
|
||||||
x = __get_user_asm_d(ptr, &retval); break; \
|
x = __get_user_asm_d(ptr, &retval); break; \
|
||||||
|
case 8: \
|
||||||
|
x = __get_user_asm_l(ptr, &retval); break; \
|
||||||
default: \
|
default: \
|
||||||
(x) = __get_user_bad(); \
|
(x) = __get_user_bad(); \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -1044,6 +1044,30 @@ unsigned int __get_user_asm_d(const void __user *addr, long *err)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__get_user_asm_d);
|
EXPORT_SYMBOL(__get_user_asm_d);
|
||||||
|
|
||||||
|
unsigned long long __get_user_asm_l(const void __user *addr, long *err)
|
||||||
|
{
|
||||||
|
register unsigned long long x asm ("D0Re0") = 0;
|
||||||
|
asm volatile (
|
||||||
|
" GETL %0,%t0,[%2]\n"
|
||||||
|
"1:\n"
|
||||||
|
" GETL %0,%t0,[%2]\n"
|
||||||
|
"2:\n"
|
||||||
|
" .section .fixup,\"ax\"\n"
|
||||||
|
"3: MOV D0FrT,%3\n"
|
||||||
|
" SETD [%1],D0FrT\n"
|
||||||
|
" MOVT D0FrT,#HI(2b)\n"
|
||||||
|
" JUMP D0FrT,#LO(2b)\n"
|
||||||
|
" .previous\n"
|
||||||
|
" .section __ex_table,\"a\"\n"
|
||||||
|
" .long 1b,3b\n"
|
||||||
|
" .previous\n"
|
||||||
|
: "=r" (x)
|
||||||
|
: "r" (err), "r" (addr), "P" (-EFAULT)
|
||||||
|
: "D0FrT");
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__get_user_asm_l);
|
||||||
|
|
||||||
long __put_user_asm_b(unsigned int x, void __user *addr)
|
long __put_user_asm_b(unsigned int x, void __user *addr)
|
||||||
{
|
{
|
||||||
register unsigned int err asm ("D0Re0") = 0;
|
register unsigned int err asm ("D0Re0") = 0;
|
||||||
|
|
Loading…
Reference in New Issue