diff options
Diffstat (limited to 'arch/x86/lib')
| -rw-r--r-- | arch/x86/lib/copy_user_64.S | 7 | ||||
| -rw-r--r-- | arch/x86/lib/copy_user_nocache_64.S | 3 | ||||
| -rw-r--r-- | arch/x86/lib/getuser.S | 10 | ||||
| -rw-r--r-- | arch/x86/lib/putuser.S | 8 | ||||
| -rw-r--r-- | arch/x86/lib/usercopy_32.c | 13 | ||||
| -rw-r--r-- | arch/x86/lib/usercopy_64.c | 3 | 
6 files changed, 42 insertions, 2 deletions
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index 5b2995f4557..a30ca15be21 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S @@ -17,6 +17,7 @@  #include <asm/cpufeature.h>  #include <asm/alternative-asm.h>  #include <asm/asm.h> +#include <asm/smap.h>  /*   * By placing feature2 after feature1 in altinstructions section, we logically @@ -130,6 +131,7 @@ ENDPROC(bad_from_user)   */  ENTRY(copy_user_generic_unrolled)  	CFI_STARTPROC +	ASM_STAC  	cmpl $8,%edx  	jb 20f		/* less then 8 bytes, go to byte copy loop */  	ALIGN_DESTINATION @@ -177,6 +179,7 @@ ENTRY(copy_user_generic_unrolled)  	decl %ecx  	jnz 21b  23:	xor %eax,%eax +	ASM_CLAC  	ret  	.section .fixup,"ax" @@ -232,6 +235,7 @@ ENDPROC(copy_user_generic_unrolled)   */  ENTRY(copy_user_generic_string)  	CFI_STARTPROC +	ASM_STAC  	andl %edx,%edx  	jz 4f  	cmpl $8,%edx @@ -246,6 +250,7 @@ ENTRY(copy_user_generic_string)  3:	rep  	movsb  4:	xorl %eax,%eax +	ASM_CLAC  	ret  	.section .fixup,"ax" @@ -273,12 +278,14 @@ ENDPROC(copy_user_generic_string)   */  ENTRY(copy_user_enhanced_fast_string)  	CFI_STARTPROC +	ASM_STAC  	andl %edx,%edx  	jz 2f  	movl %edx,%ecx  1:	rep  	movsb  2:	xorl %eax,%eax +	ASM_CLAC  	ret  	.section .fixup,"ax" diff --git a/arch/x86/lib/copy_user_nocache_64.S b/arch/x86/lib/copy_user_nocache_64.S index cacddc7163e..6a4f43c2d9e 100644 --- a/arch/x86/lib/copy_user_nocache_64.S +++ b/arch/x86/lib/copy_user_nocache_64.S @@ -15,6 +15,7 @@  #include <asm/asm-offsets.h>  #include <asm/thread_info.h>  #include <asm/asm.h> +#include <asm/smap.h>  	.macro ALIGN_DESTINATION  #ifdef FIX_ALIGNMENT @@ -48,6 +49,7 @@   */  ENTRY(__copy_user_nocache)  	CFI_STARTPROC +	ASM_STAC  	cmpl $8,%edx  	jb 20f		/* less then 8 bytes, go to byte copy loop */  	ALIGN_DESTINATION @@ -95,6 +97,7 @@ ENTRY(__copy_user_nocache)  	decl %ecx  	jnz 21b  23:	xorl %eax,%eax +	ASM_CLAC  	sfence  	ret diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S index b33b1fb1e6d..156b9c80467 100644 --- a/arch/x86/lib/getuser.S +++ b/arch/x86/lib/getuser.S @@ -33,6 +33,7 @@  #include <asm/asm-offsets.h>  #include <asm/thread_info.h>  #include <asm/asm.h> +#include <asm/smap.h>  	.text  ENTRY(__get_user_1) @@ -40,8 +41,10 @@ ENTRY(__get_user_1)  	GET_THREAD_INFO(%_ASM_DX)  	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX  	jae bad_get_user +	ASM_STAC  1:	movzb (%_ASM_AX),%edx  	xor %eax,%eax +	ASM_CLAC  	ret  	CFI_ENDPROC  ENDPROC(__get_user_1) @@ -53,8 +56,10 @@ ENTRY(__get_user_2)  	GET_THREAD_INFO(%_ASM_DX)  	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX  	jae bad_get_user +	ASM_STAC  2:	movzwl -1(%_ASM_AX),%edx  	xor %eax,%eax +	ASM_CLAC  	ret  	CFI_ENDPROC  ENDPROC(__get_user_2) @@ -66,8 +71,10 @@ ENTRY(__get_user_4)  	GET_THREAD_INFO(%_ASM_DX)  	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX  	jae bad_get_user +	ASM_STAC  3:	mov -3(%_ASM_AX),%edx  	xor %eax,%eax +	ASM_CLAC  	ret  	CFI_ENDPROC  ENDPROC(__get_user_4) @@ -80,8 +87,10 @@ ENTRY(__get_user_8)  	GET_THREAD_INFO(%_ASM_DX)  	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX  	jae	bad_get_user +	ASM_STAC  4:	movq -7(%_ASM_AX),%_ASM_DX  	xor %eax,%eax +	ASM_CLAC  	ret  	CFI_ENDPROC  ENDPROC(__get_user_8) @@ -91,6 +100,7 @@ bad_get_user:  	CFI_STARTPROC  	xor %edx,%edx  	mov $(-EFAULT),%_ASM_AX +	ASM_CLAC  	ret  	CFI_ENDPROC  END(bad_get_user) diff --git a/arch/x86/lib/putuser.S b/arch/x86/lib/putuser.S index 7f951c8f76c..fc6ba17a7ee 100644 --- a/arch/x86/lib/putuser.S +++ b/arch/x86/lib/putuser.S @@ -15,6 +15,7 @@  #include <asm/thread_info.h>  #include <asm/errno.h>  #include <asm/asm.h> +#include <asm/smap.h>  /* @@ -31,7 +32,8 @@  #define ENTER	CFI_STARTPROC ; \  		GET_THREAD_INFO(%_ASM_BX) -#define EXIT	ret ; \ +#define EXIT	ASM_CLAC ;	\ +		ret ;		\  		CFI_ENDPROC  .text @@ -39,6 +41,7 @@ ENTRY(__put_user_1)  	ENTER  	cmp TI_addr_limit(%_ASM_BX),%_ASM_CX  	jae bad_put_user +	ASM_STAC  1:	movb %al,(%_ASM_CX)  	xor %eax,%eax  	EXIT @@ -50,6 +53,7 @@ ENTRY(__put_user_2)  	sub $1,%_ASM_BX  	cmp %_ASM_BX,%_ASM_CX  	jae bad_put_user +	ASM_STAC  2:	movw %ax,(%_ASM_CX)  	xor %eax,%eax  	EXIT @@ -61,6 +65,7 @@ ENTRY(__put_user_4)  	sub $3,%_ASM_BX  	cmp %_ASM_BX,%_ASM_CX  	jae bad_put_user +	ASM_STAC  3:	movl %eax,(%_ASM_CX)  	xor %eax,%eax  	EXIT @@ -72,6 +77,7 @@ ENTRY(__put_user_8)  	sub $7,%_ASM_BX  	cmp %_ASM_BX,%_ASM_CX  	jae bad_put_user +	ASM_STAC  4:	mov %_ASM_AX,(%_ASM_CX)  #ifdef CONFIG_X86_32  5:	movl %edx,4(%_ASM_CX) diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c index 1781b2f950e..98f6d6b68f5 100644 --- a/arch/x86/lib/usercopy_32.c +++ b/arch/x86/lib/usercopy_32.c @@ -42,10 +42,11 @@ do {									\  	int __d0;							\  	might_fault();							\  	__asm__ __volatile__(						\ +		ASM_STAC "\n"						\  		"0:	rep; stosl\n"					\  		"	movl %2,%0\n"					\  		"1:	rep; stosb\n"					\ -		"2:\n"							\ +		"2: " ASM_CLAC "\n"					\  		".section .fixup,\"ax\"\n"				\  		"3:	lea 0(%2,%0,4),%0\n"				\  		"	jmp 2b\n"					\ @@ -626,10 +627,12 @@ survive:  		return n;  	}  #endif +	stac();  	if (movsl_is_ok(to, from, n))  		__copy_user(to, from, n);  	else  		n = __copy_user_intel(to, from, n); +	clac();  	return n;  }  EXPORT_SYMBOL(__copy_to_user_ll); @@ -637,10 +640,12 @@ EXPORT_SYMBOL(__copy_to_user_ll);  unsigned long __copy_from_user_ll(void *to, const void __user *from,  					unsigned long n)  { +	stac();  	if (movsl_is_ok(to, from, n))  		__copy_user_zeroing(to, from, n);  	else  		n = __copy_user_zeroing_intel(to, from, n); +	clac();  	return n;  }  EXPORT_SYMBOL(__copy_from_user_ll); @@ -648,11 +653,13 @@ EXPORT_SYMBOL(__copy_from_user_ll);  unsigned long __copy_from_user_ll_nozero(void *to, const void __user *from,  					 unsigned long n)  { +	stac();  	if (movsl_is_ok(to, from, n))  		__copy_user(to, from, n);  	else  		n = __copy_user_intel((void __user *)to,  				      (const void *)from, n); +	clac();  	return n;  }  EXPORT_SYMBOL(__copy_from_user_ll_nozero); @@ -660,6 +667,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nozero);  unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from,  					unsigned long n)  { +	stac();  #ifdef CONFIG_X86_INTEL_USERCOPY  	if (n > 64 && cpu_has_xmm2)  		n = __copy_user_zeroing_intel_nocache(to, from, n); @@ -668,6 +676,7 @@ unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from,  #else  	__copy_user_zeroing(to, from, n);  #endif +	clac();  	return n;  }  EXPORT_SYMBOL(__copy_from_user_ll_nocache); @@ -675,6 +684,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nocache);  unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from,  					unsigned long n)  { +	stac();  #ifdef CONFIG_X86_INTEL_USERCOPY  	if (n > 64 && cpu_has_xmm2)  		n = __copy_user_intel_nocache(to, from, n); @@ -683,6 +693,7 @@ unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *fr  #else  	__copy_user(to, from, n);  #endif +	clac();  	return n;  }  EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero); diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index e5b130bc2d0..05928aae911 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c @@ -18,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" @@ -40,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); @@ -82,5 +84,6 @@ copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest)  	for (c = 0, zero_len = len; zerorest && zero_len; --zero_len)  		if (__put_user_nocheck(c, to++, sizeof(char)))  			break; +	clac();  	return len;  }  |