~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/lib/getuser.S

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  * __get_user functions.
  4  *
  5  * (C) Copyright 1998 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 
 15 /*
 16  * __get_user_X
 17  *
 18  * Inputs:      %[r|e]ax contains the address.
 19  *
 20  * Outputs:     %[r|e]ax is error code (0 or -EFAULT)
 21  *              %[r|e]dx contains zero-extended value
 22  *              %ecx contains the high half for 32-bit __get_user_8
 23  *
 24  *
 25  * These functions should not modify any other registers,
 26  * as they get called from within inline assembly.
 27  */
 28 
 29 #include <linux/export.h>
 30 #include <linux/linkage.h>
 31 #include <asm/page_types.h>
 32 #include <asm/errno.h>
 33 #include <asm/asm-offsets.h>
 34 #include <asm/thread_info.h>
 35 #include <asm/asm.h>
 36 #include <asm/smap.h>
 37 
 38 #define ASM_BARRIER_NOSPEC ALTERNATIVE "", "lfence", X86_FEATURE_LFENCE_RDTSC
 39 
 40 .macro check_range size:req
 41 .if IS_ENABLED(CONFIG_X86_64)
 42         mov %rax, %rdx
 43         sar $63, %rdx
 44         or %rdx, %rax
 45 .else
 46         cmp $TASK_SIZE_MAX-\size+1, %eax
 47         jae .Lbad_get_user
 48         sbb %edx, %edx          /* array_index_mask_nospec() */
 49         and %edx, %eax
 50 .endif
 51 .endm
 52 
 53 .macro UACCESS op src dst
 54 1:      \op \src,\dst
 55         _ASM_EXTABLE_UA(1b, __get_user_handle_exception)
 56 .endm
 57 
 58 
 59         .text
 60 SYM_FUNC_START(__get_user_1)
 61         check_range size=1
 62         ASM_STAC
 63         UACCESS movzbl (%_ASM_AX),%edx
 64         xor %eax,%eax
 65         ASM_CLAC
 66         RET
 67 SYM_FUNC_END(__get_user_1)
 68 EXPORT_SYMBOL(__get_user_1)
 69 
 70 SYM_FUNC_START(__get_user_2)
 71         check_range size=2
 72         ASM_STAC
 73         UACCESS movzwl (%_ASM_AX),%edx
 74         xor %eax,%eax
 75         ASM_CLAC
 76         RET
 77 SYM_FUNC_END(__get_user_2)
 78 EXPORT_SYMBOL(__get_user_2)
 79 
 80 SYM_FUNC_START(__get_user_4)
 81         check_range size=4
 82         ASM_STAC
 83         UACCESS movl (%_ASM_AX),%edx
 84         xor %eax,%eax
 85         ASM_CLAC
 86         RET
 87 SYM_FUNC_END(__get_user_4)
 88 EXPORT_SYMBOL(__get_user_4)
 89 
 90 SYM_FUNC_START(__get_user_8)
 91 #ifndef CONFIG_X86_64
 92         xor %ecx,%ecx
 93 #endif
 94         check_range size=8
 95         ASM_STAC
 96 #ifdef CONFIG_X86_64
 97         UACCESS movq (%_ASM_AX),%rdx
 98 #else
 99         UACCESS movl (%_ASM_AX),%edx
100         UACCESS movl 4(%_ASM_AX),%ecx
101 #endif
102         xor %eax,%eax
103         ASM_CLAC
104         RET
105 SYM_FUNC_END(__get_user_8)
106 EXPORT_SYMBOL(__get_user_8)
107 
108 /* .. and the same for __get_user, just without the range checks */
109 SYM_FUNC_START(__get_user_nocheck_1)
110         ASM_STAC
111         ASM_BARRIER_NOSPEC
112         UACCESS movzbl (%_ASM_AX),%edx
113         xor %eax,%eax
114         ASM_CLAC
115         RET
116 SYM_FUNC_END(__get_user_nocheck_1)
117 EXPORT_SYMBOL(__get_user_nocheck_1)
118 
119 SYM_FUNC_START(__get_user_nocheck_2)
120         ASM_STAC
121         ASM_BARRIER_NOSPEC
122         UACCESS movzwl (%_ASM_AX),%edx
123         xor %eax,%eax
124         ASM_CLAC
125         RET
126 SYM_FUNC_END(__get_user_nocheck_2)
127 EXPORT_SYMBOL(__get_user_nocheck_2)
128 
129 SYM_FUNC_START(__get_user_nocheck_4)
130         ASM_STAC
131         ASM_BARRIER_NOSPEC
132         UACCESS movl (%_ASM_AX),%edx
133         xor %eax,%eax
134         ASM_CLAC
135         RET
136 SYM_FUNC_END(__get_user_nocheck_4)
137 EXPORT_SYMBOL(__get_user_nocheck_4)
138 
139 SYM_FUNC_START(__get_user_nocheck_8)
140         ASM_STAC
141         ASM_BARRIER_NOSPEC
142 #ifdef CONFIG_X86_64
143         UACCESS movq (%_ASM_AX),%rdx
144 #else
145         xor %ecx,%ecx
146         UACCESS movl (%_ASM_AX),%edx
147         UACCESS movl 4(%_ASM_AX),%ecx
148 #endif
149         xor %eax,%eax
150         ASM_CLAC
151         RET
152 SYM_FUNC_END(__get_user_nocheck_8)
153 EXPORT_SYMBOL(__get_user_nocheck_8)
154 
155 
156 SYM_CODE_START_LOCAL(__get_user_handle_exception)
157         ASM_CLAC
158 .Lbad_get_user:
159         xor %edx,%edx
160         mov $(-EFAULT),%_ASM_AX
161         RET
162 SYM_CODE_END(__get_user_handle_exception)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php