Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
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 | */ | |
00e065ea JB |
11 | #include <linux/linkage.h> |
12 | #include <asm/dwarf2.h> | |
1da177e4 | 13 | #include <asm/thread_info.h> |
2528de43 | 14 | #include <asm/asm.h> |
1da177e4 LT |
15 | |
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 | ||
00e065ea | 29 | #define ENTER CFI_STARTPROC ; \ |
2528de43 | 30 | GET_THREAD_INFO(%_ASM_BX) |
268cf048 | 31 | #define EXIT ret ; \ |
00e065ea | 32 | CFI_ENDPROC |
1da177e4 LT |
33 | |
34 | .text | |
00e065ea | 35 | ENTRY(__put_user_1) |
1da177e4 | 36 | ENTER |
2528de43 | 37 | cmp TI_addr_limit(%_ASM_BX),%_ASM_CX |
1da177e4 | 38 | jae bad_put_user |
2528de43 | 39 | 1: movb %al,(%_ASM_CX) |
efea505d | 40 | xor %eax,%eax |
1da177e4 | 41 | EXIT |
00e065ea | 42 | ENDPROC(__put_user_1) |
1da177e4 | 43 | |
00e065ea | 44 | ENTRY(__put_user_2) |
1da177e4 | 45 | ENTER |
2528de43 GC |
46 | mov TI_addr_limit(%_ASM_BX),%_ASM_BX |
47 | sub $1,%_ASM_BX | |
48 | cmp %_ASM_BX,%_ASM_CX | |
1da177e4 | 49 | jae bad_put_user |
2528de43 | 50 | 2: movw %ax,(%_ASM_CX) |
efea505d | 51 | xor %eax,%eax |
1da177e4 | 52 | EXIT |
00e065ea | 53 | ENDPROC(__put_user_2) |
1da177e4 | 54 | |
00e065ea | 55 | ENTRY(__put_user_4) |
1da177e4 | 56 | ENTER |
2528de43 GC |
57 | mov TI_addr_limit(%_ASM_BX),%_ASM_BX |
58 | sub $3,%_ASM_BX | |
59 | cmp %_ASM_BX,%_ASM_CX | |
1da177e4 | 60 | jae bad_put_user |
2528de43 | 61 | 3: movl %eax,(%_ASM_CX) |
efea505d | 62 | xor %eax,%eax |
1da177e4 | 63 | EXIT |
00e065ea | 64 | ENDPROC(__put_user_4) |
1da177e4 | 65 | |
00e065ea | 66 | ENTRY(__put_user_8) |
1da177e4 | 67 | ENTER |
2528de43 GC |
68 | mov TI_addr_limit(%_ASM_BX),%_ASM_BX |
69 | sub $7,%_ASM_BX | |
70 | cmp %_ASM_BX,%_ASM_CX | |
1da177e4 | 71 | jae bad_put_user |
2528de43 GC |
72 | 4: movl %_ASM_AX,(%_ASM_CX) |
73 | 5: movl %edx,4(%_ASM_CX) | |
efea505d | 74 | xor %eax,%eax |
1da177e4 | 75 | EXIT |
00e065ea | 76 | ENDPROC(__put_user_8) |
1da177e4 LT |
77 | |
78 | bad_put_user: | |
268cf048 | 79 | CFI_STARTPROC |
1da177e4 LT |
80 | movl $-14,%eax |
81 | EXIT | |
00e065ea | 82 | END(bad_put_user) |
1da177e4 LT |
83 | |
84 | .section __ex_table,"a" | |
2528de43 GC |
85 | _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 | |
1da177e4 | 90 | .previous |