1/* 2 * __get_user functions. 3 * 4 * (C) Copyright 1998 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 14/* 15 * __get_user_X 16 * 17 * Inputs: %[r|e]ax contains the address. 18 * 19 * Outputs: %[r|e]ax is error code (0 or -EFAULT) 20 * %[r|e]dx contains zero-extended value 21 * %ecx contains the high half for 32-bit __get_user_8 22 * 23 * 24 * These functions should not modify any other registers, 25 * as they get called from within inline assembly. 26 */ 27 28#include <linux/linkage.h> 29#include <asm/page_types.h> 30#include <asm/errno.h> 31#include <asm/asm-offsets.h> 32#include <asm/thread_info.h> 33#include <asm/asm.h> 34#include <asm/smap.h> 35 36 .text 37ENTRY(__get_user_1) 38 GET_THREAD_INFO(%_ASM_DX) 39 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX 40 jae bad_get_user 41 ASM_STAC 421: movzbl (%_ASM_AX),%edx 43 xor %eax,%eax 44 ASM_CLAC 45 ret 46ENDPROC(__get_user_1) 47 48ENTRY(__get_user_2) 49 add $1,%_ASM_AX 50 jc bad_get_user 51 GET_THREAD_INFO(%_ASM_DX) 52 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX 53 jae bad_get_user 54 ASM_STAC 552: movzwl -1(%_ASM_AX),%edx 56 xor %eax,%eax 57 ASM_CLAC 58 ret 59ENDPROC(__get_user_2) 60 61ENTRY(__get_user_4) 62 add $3,%_ASM_AX 63 jc bad_get_user 64 GET_THREAD_INFO(%_ASM_DX) 65 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX 66 jae bad_get_user 67 ASM_STAC 683: movl -3(%_ASM_AX),%edx 69 xor %eax,%eax 70 ASM_CLAC 71 ret 72ENDPROC(__get_user_4) 73 74ENTRY(__get_user_8) 75#ifdef CONFIG_X86_64 76 add $7,%_ASM_AX 77 jc bad_get_user 78 GET_THREAD_INFO(%_ASM_DX) 79 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX 80 jae bad_get_user 81 ASM_STAC 824: movq -7(%_ASM_AX),%rdx 83 xor %eax,%eax 84 ASM_CLAC 85 ret 86#else 87 add $7,%_ASM_AX 88 jc bad_get_user_8 89 GET_THREAD_INFO(%_ASM_DX) 90 cmp TI_addr_limit(%_ASM_DX),%_ASM_AX 91 jae bad_get_user_8 92 ASM_STAC 934: movl -7(%_ASM_AX),%edx 945: movl -3(%_ASM_AX),%ecx 95 xor %eax,%eax 96 ASM_CLAC 97 ret 98#endif 99ENDPROC(__get_user_8) 100 101 102bad_get_user: 103 xor %edx,%edx 104 mov $(-EFAULT),%_ASM_AX 105 ASM_CLAC 106 ret 107END(bad_get_user) 108 109#ifdef CONFIG_X86_32 110bad_get_user_8: 111 xor %edx,%edx 112 xor %ecx,%ecx 113 mov $(-EFAULT),%_ASM_AX 114 ASM_CLAC 115 ret 116END(bad_get_user_8) 117#endif 118 119 _ASM_EXTABLE(1b,bad_get_user) 120 _ASM_EXTABLE(2b,bad_get_user) 121 _ASM_EXTABLE(3b,bad_get_user) 122#ifdef CONFIG_X86_64 123 _ASM_EXTABLE(4b,bad_get_user) 124#else 125 _ASM_EXTABLE(4b,bad_get_user_8) 126 _ASM_EXTABLE(5b,bad_get_user_8) 127#endif 128