Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/lib/getuser.S
26439 views
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 <linux/objtool.h>
32
#include <asm/page_types.h>
33
#include <asm/errno.h>
34
#include <asm/asm-offsets.h>
35
#include <asm/thread_info.h>
36
#include <asm/asm.h>
37
#include <asm/smap.h>
38
#include <asm/runtime-const.h>
39
40
#define ASM_BARRIER_NOSPEC ALTERNATIVE "", "lfence", X86_FEATURE_LFENCE_RDTSC
41
42
.macro check_range size:req
43
.if IS_ENABLED(CONFIG_X86_64)
44
RUNTIME_CONST_PTR USER_PTR_MAX, rdx
45
cmp %rdx, %rax
46
cmova %rdx, %rax
47
.else
48
cmp $TASK_SIZE_MAX-\size+1, %eax
49
jae .Lbad_get_user
50
sbb %edx, %edx /* array_index_mask_nospec() */
51
and %edx, %eax
52
.endif
53
.endm
54
55
.macro UACCESS op src dst
56
1: \op \src,\dst
57
_ASM_EXTABLE_UA(1b, __get_user_handle_exception)
58
.endm
59
60
61
.text
62
SYM_FUNC_START(__get_user_1)
63
ANNOTATE_NOENDBR
64
check_range size=1
65
ASM_STAC
66
UACCESS movzbl (%_ASM_AX),%edx
67
xor %eax,%eax
68
ASM_CLAC
69
RET
70
SYM_FUNC_END(__get_user_1)
71
EXPORT_SYMBOL(__get_user_1)
72
73
SYM_FUNC_START(__get_user_2)
74
ANNOTATE_NOENDBR
75
check_range size=2
76
ASM_STAC
77
UACCESS movzwl (%_ASM_AX),%edx
78
xor %eax,%eax
79
ASM_CLAC
80
RET
81
SYM_FUNC_END(__get_user_2)
82
EXPORT_SYMBOL(__get_user_2)
83
84
SYM_FUNC_START(__get_user_4)
85
ANNOTATE_NOENDBR
86
check_range size=4
87
ASM_STAC
88
UACCESS movl (%_ASM_AX),%edx
89
xor %eax,%eax
90
ASM_CLAC
91
RET
92
SYM_FUNC_END(__get_user_4)
93
EXPORT_SYMBOL(__get_user_4)
94
95
SYM_FUNC_START(__get_user_8)
96
ANNOTATE_NOENDBR
97
#ifndef CONFIG_X86_64
98
xor %ecx,%ecx
99
#endif
100
check_range size=8
101
ASM_STAC
102
#ifdef CONFIG_X86_64
103
UACCESS movq (%_ASM_AX),%rdx
104
#else
105
UACCESS movl (%_ASM_AX),%edx
106
UACCESS movl 4(%_ASM_AX),%ecx
107
#endif
108
xor %eax,%eax
109
ASM_CLAC
110
RET
111
SYM_FUNC_END(__get_user_8)
112
EXPORT_SYMBOL(__get_user_8)
113
114
/* .. and the same for __get_user, just without the range checks */
115
SYM_FUNC_START(__get_user_nocheck_1)
116
ANNOTATE_NOENDBR
117
ASM_STAC
118
ASM_BARRIER_NOSPEC
119
UACCESS movzbl (%_ASM_AX),%edx
120
xor %eax,%eax
121
ASM_CLAC
122
RET
123
SYM_FUNC_END(__get_user_nocheck_1)
124
EXPORT_SYMBOL(__get_user_nocheck_1)
125
126
SYM_FUNC_START(__get_user_nocheck_2)
127
ANNOTATE_NOENDBR
128
ASM_STAC
129
ASM_BARRIER_NOSPEC
130
UACCESS movzwl (%_ASM_AX),%edx
131
xor %eax,%eax
132
ASM_CLAC
133
RET
134
SYM_FUNC_END(__get_user_nocheck_2)
135
EXPORT_SYMBOL(__get_user_nocheck_2)
136
137
SYM_FUNC_START(__get_user_nocheck_4)
138
ANNOTATE_NOENDBR
139
ASM_STAC
140
ASM_BARRIER_NOSPEC
141
UACCESS movl (%_ASM_AX),%edx
142
xor %eax,%eax
143
ASM_CLAC
144
RET
145
SYM_FUNC_END(__get_user_nocheck_4)
146
EXPORT_SYMBOL(__get_user_nocheck_4)
147
148
SYM_FUNC_START(__get_user_nocheck_8)
149
ANNOTATE_NOENDBR
150
ASM_STAC
151
ASM_BARRIER_NOSPEC
152
#ifdef CONFIG_X86_64
153
UACCESS movq (%_ASM_AX),%rdx
154
#else
155
xor %ecx,%ecx
156
UACCESS movl (%_ASM_AX),%edx
157
UACCESS movl 4(%_ASM_AX),%ecx
158
#endif
159
xor %eax,%eax
160
ASM_CLAC
161
RET
162
SYM_FUNC_END(__get_user_nocheck_8)
163
EXPORT_SYMBOL(__get_user_nocheck_8)
164
165
166
SYM_CODE_START_LOCAL(__get_user_handle_exception)
167
ASM_CLAC
168
.Lbad_get_user:
169
xor %edx,%edx
170
mov $(-EFAULT),%_ASM_AX
171
RET
172
SYM_CODE_END(__get_user_handle_exception)
173
174