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