| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /* | 
					
						
							|  |  |  |  * __put_user functions. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * (C) Copyright 2005 Linus Torvalds | 
					
						
							| 
									
										
										
										
											2008-06-24 17:40:14 -03:00
										 |  |  |  * (C) Copyright 2005 Andi Kleen | 
					
						
							|  |  |  |  * (C) Copyright 2008 Glauber Costa | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  * These functions have a non-standard call interface | 
					
						
							|  |  |  |  * to make them more efficient, especially as they | 
					
						
							|  |  |  |  * return an error value in addition to the "real" | 
					
						
							|  |  |  |  * return value. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | #include <linux/linkage.h> | 
					
						
							|  |  |  | #include <asm/dwarf2.h> | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #include <asm/thread_info.h> | 
					
						
							| 
									
										
										
										
											2008-06-24 17:40:14 -03:00
										 |  |  | #include <asm/errno.h> | 
					
						
							| 
									
										
										
										
											2008-06-24 17:36:31 -03:00
										 |  |  | #include <asm/asm.h> | 
					
						
							| 
									
										
										
										
											2012-09-21 12:43:12 -07:00
										 |  |  | #include <asm/smap.h> | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * __put_user_X | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Inputs:	%eax[:%edx] contains the data | 
					
						
							|  |  |  |  *		%ecx contains the address | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Outputs:	%eax is error code (0 or -EFAULT) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * These functions should not modify any other registers, | 
					
						
							|  |  |  |  * as they get called from within inline assembly. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | #define ENTER	CFI_STARTPROC ; \
 | 
					
						
							| 
									
										
										
										
											2008-06-24 17:36:31 -03:00
										 |  |  | 		GET_THREAD_INFO(%_ASM_BX) | 
					
						
							| 
									
										
										
										
											2012-09-21 12:43:12 -07:00
										 |  |  | #define EXIT	ASM_CLAC ;	\
 | 
					
						
							|  |  |  | 		ret ;		\
 | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | 		CFI_ENDPROC | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | .text | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | ENTRY(__put_user_1) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	ENTER | 
					
						
							| 
									
										
										
										
											2008-06-24 17:36:31 -03:00
										 |  |  | 	cmp TI_addr_limit(%_ASM_BX),%_ASM_CX | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	jae bad_put_user | 
					
						
							| 
									
										
										
										
											2012-09-21 12:43:12 -07:00
										 |  |  | 	ASM_STAC | 
					
						
							| 
									
										
										
										
											2008-06-24 17:36:31 -03:00
										 |  |  | 1:	movb %al,(%_ASM_CX) | 
					
						
							| 
									
										
										
										
											2008-06-24 16:59:05 -03:00
										 |  |  | 	xor %eax,%eax | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	EXIT | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | ENDPROC(__put_user_1) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | ENTRY(__put_user_2) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	ENTER | 
					
						
							| 
									
										
										
										
											2008-06-24 17:36:31 -03:00
										 |  |  | 	mov TI_addr_limit(%_ASM_BX),%_ASM_BX | 
					
						
							|  |  |  | 	sub $1,%_ASM_BX | 
					
						
							|  |  |  | 	cmp %_ASM_BX,%_ASM_CX | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	jae bad_put_user | 
					
						
							| 
									
										
										
										
											2012-09-21 12:43:12 -07:00
										 |  |  | 	ASM_STAC | 
					
						
							| 
									
										
										
										
											2008-06-24 17:36:31 -03:00
										 |  |  | 2:	movw %ax,(%_ASM_CX) | 
					
						
							| 
									
										
										
										
											2008-06-24 16:59:05 -03:00
										 |  |  | 	xor %eax,%eax | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	EXIT | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | ENDPROC(__put_user_2) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | ENTRY(__put_user_4) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	ENTER | 
					
						
							| 
									
										
										
										
											2008-06-24 17:36:31 -03:00
										 |  |  | 	mov TI_addr_limit(%_ASM_BX),%_ASM_BX | 
					
						
							|  |  |  | 	sub $3,%_ASM_BX | 
					
						
							|  |  |  | 	cmp %_ASM_BX,%_ASM_CX | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	jae bad_put_user | 
					
						
							| 
									
										
										
										
											2012-09-21 12:43:12 -07:00
										 |  |  | 	ASM_STAC | 
					
						
							| 
									
										
										
										
											2008-06-24 17:36:31 -03:00
										 |  |  | 3:	movl %eax,(%_ASM_CX) | 
					
						
							| 
									
										
										
										
											2008-06-24 16:59:05 -03:00
										 |  |  | 	xor %eax,%eax | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	EXIT | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | ENDPROC(__put_user_4) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | ENTRY(__put_user_8) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	ENTER | 
					
						
							| 
									
										
										
										
											2008-06-24 17:36:31 -03:00
										 |  |  | 	mov TI_addr_limit(%_ASM_BX),%_ASM_BX | 
					
						
							|  |  |  | 	sub $7,%_ASM_BX | 
					
						
							|  |  |  | 	cmp %_ASM_BX,%_ASM_CX | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	jae bad_put_user | 
					
						
							| 
									
										
										
										
											2012-09-21 12:43:12 -07:00
										 |  |  | 	ASM_STAC | 
					
						
							| 
									
										
										
										
											2008-06-24 17:40:14 -03:00
										 |  |  | 4:	mov %_ASM_AX,(%_ASM_CX) | 
					
						
							|  |  |  | #ifdef CONFIG_X86_32 | 
					
						
							| 
									
										
										
										
											2008-06-24 17:36:31 -03:00
										 |  |  | 5:	movl %edx,4(%_ASM_CX) | 
					
						
							| 
									
										
										
										
											2008-06-24 17:40:14 -03:00
										 |  |  | #endif | 
					
						
							| 
									
										
										
										
											2008-06-24 16:59:05 -03:00
										 |  |  | 	xor %eax,%eax | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	EXIT | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | ENDPROC(__put_user_8) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | bad_put_user: | 
					
						
							| 
									
										
										
										
											2008-06-24 12:40:55 -03:00
										 |  |  | 	CFI_STARTPROC | 
					
						
							| 
									
										
										
										
											2008-06-24 17:40:14 -03:00
										 |  |  | 	movl $-EFAULT,%eax | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	EXIT | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:05 +02:00
										 |  |  | END(bad_put_user) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-20 12:19:52 -07:00
										 |  |  | 	_ASM_EXTABLE(1b,bad_put_user) | 
					
						
							|  |  |  | 	_ASM_EXTABLE(2b,bad_put_user) | 
					
						
							|  |  |  | 	_ASM_EXTABLE(3b,bad_put_user) | 
					
						
							|  |  |  | 	_ASM_EXTABLE(4b,bad_put_user) | 
					
						
							| 
									
										
										
										
											2008-06-24 17:40:14 -03:00
										 |  |  | #ifdef CONFIG_X86_32 | 
					
						
							| 
									
										
										
										
											2012-04-20 12:19:52 -07:00
										 |  |  | 	_ASM_EXTABLE(5b,bad_put_user) | 
					
						
							| 
									
										
										
										
											2008-06-24 17:40:14 -03:00
										 |  |  | #endif |