blob: 5b2a926f0e2811d3a127b35d3ac2e720321f93a9 [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 ; \
Jan Beulich00e065e2007-05-02 19:27:05 +020029 GET_THREAD_INFO(%ebx)
Glauber Costa268cf042008-06-24 12:40:55 -030030#define EXIT ret ; \
Jan Beulich00e065e2007-05-02 19:27:05 +020031 CFI_ENDPROC
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
33.text
Jan Beulich00e065e2007-05-02 19:27:05 +020034ENTRY(__put_user_1)
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 ENTER
36 cmpl TI_addr_limit(%ebx),%ecx
37 jae bad_put_user
381: movb %al,(%ecx)
39 xorl %eax,%eax
40 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020041ENDPROC(__put_user_1)
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Jan Beulich00e065e2007-05-02 19:27:05 +020043ENTRY(__put_user_2)
Linus Torvalds1da177e2005-04-16 15:20:36 -070044 ENTER
45 movl TI_addr_limit(%ebx),%ebx
46 subl $1,%ebx
47 cmpl %ebx,%ecx
48 jae bad_put_user
492: movw %ax,(%ecx)
50 xorl %eax,%eax
51 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020052ENDPROC(__put_user_2)
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Jan Beulich00e065e2007-05-02 19:27:05 +020054ENTRY(__put_user_4)
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 ENTER
56 movl TI_addr_limit(%ebx),%ebx
57 subl $3,%ebx
58 cmpl %ebx,%ecx
59 jae bad_put_user
603: movl %eax,(%ecx)
61 xorl %eax,%eax
62 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020063ENDPROC(__put_user_4)
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
Jan Beulich00e065e2007-05-02 19:27:05 +020065ENTRY(__put_user_8)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 ENTER
67 movl TI_addr_limit(%ebx),%ebx
68 subl $7,%ebx
69 cmpl %ebx,%ecx
70 jae bad_put_user
714: movl %eax,(%ecx)
725: movl %edx,4(%ecx)
73 xorl %eax,%eax
74 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020075ENDPROC(__put_user_8)
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
77bad_put_user:
Glauber Costa268cf042008-06-24 12:40:55 -030078 CFI_STARTPROC
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 movl $-14,%eax
80 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020081END(bad_put_user)
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
83.section __ex_table,"a"
84 .long 1b,bad_put_user
85 .long 2b,bad_put_user
86 .long 3b,bad_put_user
87 .long 4b,bad_put_user
88 .long 5b,bad_put_user
89.previous