blob: e7eda34feb343c786c4f7332d2976a2fa90d1c85 [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>
Glauber Costa2528de42008-06-24 17:36:31 -030014#include <asm/asm.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015
16
17/*
18 * __put_user_X
19 *
20 * Inputs: %eax[:%edx] contains the data
21 * %ecx contains the address
22 *
23 * Outputs: %eax is error code (0 or -EFAULT)
24 *
25 * These functions should not modify any other registers,
26 * as they get called from within inline assembly.
27 */
28
Jan Beulich00e065e2007-05-02 19:27:05 +020029#define ENTER CFI_STARTPROC ; \
Glauber Costa2528de42008-06-24 17:36:31 -030030 GET_THREAD_INFO(%_ASM_BX)
Glauber Costa268cf042008-06-24 12:40:55 -030031#define EXIT ret ; \
Jan Beulich00e065e2007-05-02 19:27:05 +020032 CFI_ENDPROC
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
34.text
Jan Beulich00e065e2007-05-02 19:27:05 +020035ENTRY(__put_user_1)
Linus Torvalds1da177e2005-04-16 15:20:36 -070036 ENTER
Glauber Costa2528de42008-06-24 17:36:31 -030037 cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
Linus Torvalds1da177e2005-04-16 15:20:36 -070038 jae bad_put_user
Glauber Costa2528de42008-06-24 17:36:31 -0300391: movb %al,(%_ASM_CX)
Glauber Costaefea5052008-06-24 16:59:05 -030040 xor %eax,%eax
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020042ENDPROC(__put_user_1)
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Jan Beulich00e065e2007-05-02 19:27:05 +020044ENTRY(__put_user_2)
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 ENTER
Glauber Costa2528de42008-06-24 17:36:31 -030046 mov TI_addr_limit(%_ASM_BX),%_ASM_BX
47 sub $1,%_ASM_BX
48 cmp %_ASM_BX,%_ASM_CX
Linus Torvalds1da177e2005-04-16 15:20:36 -070049 jae bad_put_user
Glauber Costa2528de42008-06-24 17:36:31 -0300502: movw %ax,(%_ASM_CX)
Glauber Costaefea5052008-06-24 16:59:05 -030051 xor %eax,%eax
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020053ENDPROC(__put_user_2)
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Jan Beulich00e065e2007-05-02 19:27:05 +020055ENTRY(__put_user_4)
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 ENTER
Glauber Costa2528de42008-06-24 17:36:31 -030057 mov TI_addr_limit(%_ASM_BX),%_ASM_BX
58 sub $3,%_ASM_BX
59 cmp %_ASM_BX,%_ASM_CX
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 jae bad_put_user
Glauber Costa2528de42008-06-24 17:36:31 -0300613: movl %eax,(%_ASM_CX)
Glauber Costaefea5052008-06-24 16:59:05 -030062 xor %eax,%eax
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020064ENDPROC(__put_user_4)
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
Jan Beulich00e065e2007-05-02 19:27:05 +020066ENTRY(__put_user_8)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067 ENTER
Glauber Costa2528de42008-06-24 17:36:31 -030068 mov TI_addr_limit(%_ASM_BX),%_ASM_BX
69 sub $7,%_ASM_BX
70 cmp %_ASM_BX,%_ASM_CX
Linus Torvalds1da177e2005-04-16 15:20:36 -070071 jae bad_put_user
Glauber Costa2528de42008-06-24 17:36:31 -0300724: movl %_ASM_AX,(%_ASM_CX)
735: movl %edx,4(%_ASM_CX)
Glauber Costaefea5052008-06-24 16:59:05 -030074 xor %eax,%eax
Linus Torvalds1da177e2005-04-16 15:20:36 -070075 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020076ENDPROC(__put_user_8)
Linus Torvalds1da177e2005-04-16 15:20:36 -070077
78bad_put_user:
Glauber Costa268cf042008-06-24 12:40:55 -030079 CFI_STARTPROC
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 movl $-14,%eax
81 EXIT
Jan Beulich00e065e2007-05-02 19:27:05 +020082END(bad_put_user)
Linus Torvalds1da177e2005-04-16 15:20:36 -070083
84.section __ex_table,"a"
Glauber Costa2528de42008-06-24 17:36:31 -030085 _ASM_PTR 1b,bad_put_user
86 _ASM_PTR 2b,bad_put_user
87 _ASM_PTR 3b,bad_put_user
88 _ASM_PTR 4b,bad_put_user
89 _ASM_PTR 5b,bad_put_user
Linus Torvalds1da177e2005-04-16 15:20:36 -070090.previous