• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * __put_user functions.
3  *
4  * (C) Copyright 2005 Linus Torvalds
5  * (C) Copyright 2005 Andi Kleen
6  * (C) Copyright 2008 Glauber Costa
7  *
8  * These functions have a non-standard call interface
9  * to make them more efficient, especially as they
10  * return an error value in addition to the "real"
11  * return value.
12  */
13 #include <linux/linkage.h>
14 #include <asm/dwarf2.h>
15 #include <asm/thread_info.h>
16 #include <asm/errno.h>
17 #include <asm/asm.h>
18 
19 
20 /*
21  * __put_user_X
22  *
23  * Inputs:	%eax[:%edx] contains the data
24  *		%ecx contains the address
25  *
26  * Outputs:	%eax is error code (0 or -EFAULT)
27  *
28  * These functions should not modify any other registers,
29  * as they get called from within inline assembly.
30  */
31 
32 #define ENTER	CFI_STARTPROC ; \
33 		GET_THREAD_INFO(%_ASM_BX)
34 #define EXIT	ret ; \
35 		CFI_ENDPROC
36 
37 .text
38 ENTRY(__put_user_1)
39 	ENTER
40 	cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
41 	jae bad_put_user
42 1:	movb %al,(%_ASM_CX)
43 	xor %eax,%eax
44 	EXIT
45 ENDPROC(__put_user_1)
46 
47 ENTRY(__put_user_2)
48 	ENTER
49 	mov TI_addr_limit(%_ASM_BX),%_ASM_BX
50 	sub $1,%_ASM_BX
51 	cmp %_ASM_BX,%_ASM_CX
52 	jae bad_put_user
53 2:	movw %ax,(%_ASM_CX)
54 	xor %eax,%eax
55 	EXIT
56 ENDPROC(__put_user_2)
57 
58 ENTRY(__put_user_4)
59 	ENTER
60 	mov TI_addr_limit(%_ASM_BX),%_ASM_BX
61 	sub $3,%_ASM_BX
62 	cmp %_ASM_BX,%_ASM_CX
63 	jae bad_put_user
64 3:	movl %eax,(%_ASM_CX)
65 	xor %eax,%eax
66 	EXIT
67 ENDPROC(__put_user_4)
68 
69 ENTRY(__put_user_8)
70 	ENTER
71 	mov TI_addr_limit(%_ASM_BX),%_ASM_BX
72 	sub $7,%_ASM_BX
73 	cmp %_ASM_BX,%_ASM_CX
74 	jae bad_put_user
75 4:	mov %_ASM_AX,(%_ASM_CX)
76 #ifdef CONFIG_X86_32
77 5:	movl %edx,4(%_ASM_CX)
78 #endif
79 	xor %eax,%eax
80 	EXIT
81 ENDPROC(__put_user_8)
82 
83 bad_put_user:
84 	CFI_STARTPROC
85 	movl $-EFAULT,%eax
86 	EXIT
87 END(bad_put_user)
88 
89 .section __ex_table,"a"
90 	_ASM_PTR 1b,bad_put_user
91 	_ASM_PTR 2b,bad_put_user
92 	_ASM_PTR 3b,bad_put_user
93 	_ASM_PTR 4b,bad_put_user
94 #ifdef CONFIG_X86_32
95 	_ASM_PTR 5b,bad_put_user
96 #endif
97 .previous
98