diff options
Diffstat (limited to 'arch/x86/lib/usercopy_64.c')
| -rw-r--r-- | arch/x86/lib/usercopy_64.c | 106 | 
1 files changed, 6 insertions, 100 deletions
diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index b7c2849ffb6..c905e89e19f 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c @@ -9,55 +9,6 @@  #include <asm/uaccess.h>  /* - * Copy a null terminated string from userspace. - */ - -#define __do_strncpy_from_user(dst,src,count,res)			   \ -do {									   \ -	long __d0, __d1, __d2;						   \ -	might_fault();							   \ -	__asm__ __volatile__(						   \ -		"	testq %1,%1\n"					   \ -		"	jz 2f\n"					   \ -		"0:	lodsb\n"					   \ -		"	stosb\n"					   \ -		"	testb %%al,%%al\n"				   \ -		"	jz 1f\n"					   \ -		"	decq %1\n"					   \ -		"	jnz 0b\n"					   \ -		"1:	subq %1,%0\n"					   \ -		"2:\n"							   \ -		".section .fixup,\"ax\"\n"				   \ -		"3:	movq %5,%0\n"					   \ -		"	jmp 2b\n"					   \ -		".previous\n"						   \ -		_ASM_EXTABLE(0b,3b)					   \ -		: "=&r"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),	   \ -		  "=&D" (__d2)						   \ -		: "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ -		: "memory");						   \ -} while (0) - -long -__strncpy_from_user(char *dst, const char __user *src, long count) -{ -	long res; -	__do_strncpy_from_user(dst, src, count, res); -	return res; -} -EXPORT_SYMBOL(__strncpy_from_user); - -long -strncpy_from_user(char *dst, const char __user *src, long count) -{ -	long res = -EFAULT; -	if (access_ok(VERIFY_READ, src, 1)) -		return __strncpy_from_user(dst, src, count); -	return res; -} -EXPORT_SYMBOL(strncpy_from_user); - -/*   * Zero Userspace   */ @@ -67,6 +18,7 @@ unsigned long __clear_user(void __user *addr, unsigned long size)  	might_fault();  	/* no memory constraint because it doesn't change any memory gcc knows  	   about */ +	stac();  	asm volatile(  		"	testq  %[size8],%[size8]\n"  		"	jz     4f\n" @@ -89,6 +41,7 @@ unsigned long __clear_user(void __user *addr, unsigned long size)  		: [size8] "=&c"(size), [dst] "=&D" (__d0)  		: [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr),  		  [zero] "r" (0UL), [eight] "r" (8UL)); +	clac();  	return size;  }  EXPORT_SYMBOL(__clear_user); @@ -101,54 +54,6 @@ unsigned long clear_user(void __user *to, unsigned long n)  }  EXPORT_SYMBOL(clear_user); -/* - * Return the size of a string (including the ending 0) - * - * Return 0 on exception, a value greater than N if too long - */ - -long __strnlen_user(const char __user *s, long n) -{ -	long res = 0; -	char c; - -	while (1) { -		if (res>n) -			return n+1; -		if (__get_user(c, s)) -			return 0; -		if (!c) -			return res+1; -		res++; -		s++; -	} -} -EXPORT_SYMBOL(__strnlen_user); - -long strnlen_user(const char __user *s, long n) -{ -	if (!access_ok(VERIFY_READ, s, 1)) -		return 0; -	return __strnlen_user(s, n); -} -EXPORT_SYMBOL(strnlen_user); - -long strlen_user(const char __user *s) -{ -	long res = 0; -	char c; - -	for (;;) { -		if (get_user(c, s)) -			return 0; -		if (!c) -			return res+1; -		res++; -		s++; -	} -} -EXPORT_SYMBOL(strlen_user); -  unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len)  {  	if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) {  @@ -163,21 +68,22 @@ EXPORT_SYMBOL(copy_in_user);   * Since protection fault in copy_from/to_user is not a normal situation,   * it is not necessary to optimize tail handling.   */ -unsigned long +__visible unsigned long  copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest)  {  	char c;  	unsigned zero_len; -	for (; len; --len) { +	for (; len; --len, to++) {  		if (__get_user_nocheck(c, from++, sizeof(char)))  			break; -		if (__put_user_nocheck(c, to++, sizeof(char))) +		if (__put_user_nocheck(c, to, sizeof(char)))  			break;  	}  	for (c = 0, zero_len = len; zerorest && zero_len; --zero_len)  		if (__put_user_nocheck(c, to++, sizeof(char)))  			break; +	clac();  	return len;  }  | 
