blob: b67a37cab1b07ada69cf5438ee7388b40e67c28c [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
Glauber Costaefea5052008-06-24 16:59:05 -030036 cmp TI_addr_limit(%ebx),%ecx
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 jae bad_put_user
381: movb %al,(%ecx)
Glauber Costaefea5052008-06-24 16:59:05 -030039 xor %eax,%eax
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 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
Glauber Costaefea5052008-06-24 16:59:05 -030045 mov TI_addr_limit(%ebx),%ebx
46 sub $1,%ebx
47 cmp %ebx,%ecx
Linus Torvalds1da177e2005-04-16 15:20:36 -070048 jae bad_put_user
492: movw %ax,(%ecx)
Glauber Costaefea5052008-06-24 16:59:05 -030050 xor %eax,%eax
Linus Torvalds1da177e2005-04-16 15:20:36 -070051 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
Glauber Costaefea5052008-06-24 16:59:05 -030056 mov TI_addr_limit(%ebx),%ebx
57 sub $3,%ebx
58 cmp %ebx,%ecx
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 jae bad_put_user
603: movl %eax,(%ecx)
Glauber Costaefea5052008-06-24 16:59:05 -030061 xor %eax,%eax
Linus Torvalds1da177e2005-04-16 15:20:36 -070062 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
Glauber Costaefea5052008-06-24 16:59:05 -030067 mov TI_addr_limit(%ebx),%ebx
68 sub $7,%ebx
69 cmp %ebx,%ecx
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 jae bad_put_user
714: movl %eax,(%ecx)
725: movl %edx,4(%ecx)
Glauber Costaefea5052008-06-24 16:59:05 -030073 xor %eax,%eax
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 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