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