blob: f58fba109d188a2a19d4d18255df9f1e1b52271f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * __put_user functions.
3 *
4 * (C) Copyright 2005 Linus Torvalds
5 *
6 * These functions have a non-standard call interface
7 * to make them more efficient, especially as they
8 * return an error value in addition to the "real"
9 * return value.
10 */
Jan Beulich00e065e2007-05-02 19:27:05 +020011#include <linux/linkage.h>
12#include <asm/dwarf2.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <asm/thread_info.h>
14
15
16/*
17 * __put_user_X
18 *
19 * Inputs: %eax[:%edx] contains the data
20 * %ecx contains the address
21 *
22 * Outputs: %eax is error code (0 or -EFAULT)
23 *
24 * These functions should not modify any other registers,
25 * as they get called from within inline assembly.
26 */
27
Jan Beulich00e065e2007-05-02 19:27:05 +020028#define ENTER CFI_STARTPROC ; \
29 pushl %ebx ; \
30 CFI_ADJUST_CFA_OFFSET 4 ; \
31 CFI_REL_OFFSET ebx, 0 ; \
32 GET_THREAD_INFO(%ebx)
33#define EXIT popl %ebx ; \
34 CFI_ADJUST_CFA_OFFSET -4 ; \
35 CFI_RESTORE ebx ; \
36 ret ; \
37 CFI_ENDPROC
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
39.text
Jan Beulich00e065e2007-05-02 19:27:05 +020040ENTRY(__put_user_1)
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 ENTER
42 cmpl TI_addr_limit(%ebx),%ecx
43 jae bad_put_user
441: movb %al,(%ecx)
45 xorl %eax,%eax
46 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020047ENDPROC(__put_user_1)
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Jan Beulich00e065e2007-05-02 19:27:05 +020049ENTRY(__put_user_2)
Linus Torvalds1da177e2005-04-16 15:20:36 -070050 ENTER
51 movl TI_addr_limit(%ebx),%ebx
52 subl $1,%ebx
53 cmpl %ebx,%ecx
54 jae bad_put_user
552: movw %ax,(%ecx)
56 xorl %eax,%eax
57 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020058ENDPROC(__put_user_2)
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Jan Beulich00e065e2007-05-02 19:27:05 +020060ENTRY(__put_user_4)
Linus Torvalds1da177e2005-04-16 15:20:36 -070061 ENTER
62 movl TI_addr_limit(%ebx),%ebx
63 subl $3,%ebx
64 cmpl %ebx,%ecx
65 jae bad_put_user
663: movl %eax,(%ecx)
67 xorl %eax,%eax
68 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020069ENDPROC(__put_user_4)
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Jan Beulich00e065e2007-05-02 19:27:05 +020071ENTRY(__put_user_8)
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 ENTER
73 movl TI_addr_limit(%ebx),%ebx
74 subl $7,%ebx
75 cmpl %ebx,%ecx
76 jae bad_put_user
774: movl %eax,(%ecx)
785: movl %edx,4(%ecx)
79 xorl %eax,%eax
80 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020081ENDPROC(__put_user_8)
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
83bad_put_user:
Jan Beulich00e065e2007-05-02 19:27:05 +020084 CFI_STARTPROC simple
85 CFI_DEF_CFA esp, 2*4
86 CFI_OFFSET eip, -1*4
87 CFI_OFFSET ebx, -2*4
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 movl $-14,%eax
89 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020090END(bad_put_user)
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
92.section __ex_table,"a"
93 .long 1b,bad_put_user
94 .long 2b,bad_put_user
95 .long 3b,bad_put_user
96 .long 4b,bad_put_user
97 .long 5b,bad_put_user
98.previous