1 /* 2 * __put_user functions. 3 * 4 * (C) Copyright 2005 Linus Torvalds 5 * (C) Copyright 2005 Andi Kleen 6 * (C) Copyright 2008 Glauber Costa 7 * 8 * These functions have a non-standard call interface 9 * to make them more efficient, especially as they 10 * return an error value in addition to the "real" 11 * return value. 12 */ 13 #include <linux/linkage.h> 14 #include <asm/dwarf2.h> 15 #include <asm/thread_info.h> 16 #include <asm/errno.h> 17 #include <asm/asm.h> 18 19 20 /* 21 * __put_user_X 22 * 23 * Inputs: %eax[:%edx] contains the data 24 * %ecx contains the address 25 * 26 * Outputs: %eax is error code (0 or -EFAULT) 27 * 28 * These functions should not modify any other registers, 29 * as they get called from within inline assembly. 30 */ 31 32 #define ENTER CFI_STARTPROC ; \ 33 GET_THREAD_INFO(%_ASM_BX) 34 #define EXIT ret ; \ 35 CFI_ENDPROC 36 37 .text 38 ENTRY(__put_user_1) 39 ENTER 40 cmp TI_addr_limit(%_ASM_BX),%_ASM_CX 41 jae bad_put_user 42 1: movb %al,(%_ASM_CX) 43 xor %eax,%eax 44 EXIT 45 ENDPROC(__put_user_1) 46 47 ENTRY(__put_user_2) 48 ENTER 49 mov TI_addr_limit(%_ASM_BX),%_ASM_BX 50 sub $1,%_ASM_BX 51 cmp %_ASM_BX,%_ASM_CX 52 jae bad_put_user 53 2: movw %ax,(%_ASM_CX) 54 xor %eax,%eax 55 EXIT 56 ENDPROC(__put_user_2) 57 58 ENTRY(__put_user_4) 59 ENTER 60 mov TI_addr_limit(%_ASM_BX),%_ASM_BX 61 sub $3,%_ASM_BX 62 cmp %_ASM_BX,%_ASM_CX 63 jae bad_put_user 64 3: movl %eax,(%_ASM_CX) 65 xor %eax,%eax 66 EXIT 67 ENDPROC(__put_user_4) 68 69 ENTRY(__put_user_8) 70 ENTER 71 mov TI_addr_limit(%_ASM_BX),%_ASM_BX 72 sub $7,%_ASM_BX 73 cmp %_ASM_BX,%_ASM_CX 74 jae bad_put_user 75 4: mov %_ASM_AX,(%_ASM_CX) 76 #ifdef CONFIG_X86_32 77 5: movl %edx,4(%_ASM_CX) 78 #endif 79 xor %eax,%eax 80 EXIT 81 ENDPROC(__put_user_8) 82 83 bad_put_user: 84 CFI_STARTPROC 85 movl $-EFAULT,%eax 86 EXIT 87 END(bad_put_user) 88 89 .section __ex_table,"a" 90 _ASM_PTR 1b,bad_put_user 91 _ASM_PTR 2b,bad_put_user 92 _ASM_PTR 3b,bad_put_user 93 _ASM_PTR 4b,bad_put_user 94 #ifdef CONFIG_X86_32 95 _ASM_PTR 5b,bad_put_user 96 #endif 97 .previous 98