Commit d3ba2e92 authored by James Hogan's avatar James Hogan
Browse files

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: default avatarJames Hogan <james.hogan@imgtec.com>
Cc: linux-metag@vger.kernel.org
parent fc1b759a
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -138,7 +138,8 @@ extern long __get_user_bad(void);

#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);	\
	(x) = (__force __typeof__(*(ptr)))__gu_val;             \
	__gu_err;                                               \
@@ -146,7 +147,8 @@ extern long __get_user_bad(void);

#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);		\
	if (access_ok(VERIFY_READ, __gu_addr, size))			\
		__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 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 long long __get_user_asm_l(const void __user *addr, long *err);

#define __get_user_size(x, ptr, size, retval)			\
do {                                                            \
@@ -168,6 +171,8 @@ do { \
		x = __get_user_asm_w(ptr, &retval); break;	\
	case 4:							\
		x = __get_user_asm_d(ptr, &retval); break;	\
	case 8:							\
		x = __get_user_asm_l(ptr, &retval); break;	\
	default:						\
		(x) = __get_user_bad();				\
	}                                                       \
+24 −0
Original line number Diff line number Diff line
@@ -1044,6 +1044,30 @@ unsigned int __get_user_asm_d(const void __user *addr, long *err)
}
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)
{
	register unsigned int err asm ("D0Re0") = 0;