Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/lib/putuser.S
26424 views
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/export.h>
15
#include <linux/linkage.h>
16
#include <linux/objtool.h>
17
#include <asm/thread_info.h>
18
#include <asm/errno.h>
19
#include <asm/asm.h>
20
#include <asm/smap.h>
21
22
/*
23
* __put_user_X
24
*
25
* Inputs: %eax[:%edx] contains the data
26
* %ecx contains the address
27
*
28
* Outputs: %ecx is error code (0 or -EFAULT)
29
*
30
* Clobbers: %ebx needed for task pointer
31
*
32
* These functions should not modify any other registers,
33
* as they get called from within inline assembly.
34
*/
35
36
.macro check_range size:req
37
.if IS_ENABLED(CONFIG_X86_64)
38
mov %rcx, %rbx
39
sar $63, %rbx
40
or %rbx, %rcx
41
.else
42
cmp $TASK_SIZE_MAX-\size+1, %ecx
43
jae .Lbad_put_user
44
.endif
45
.endm
46
47
.text
48
SYM_FUNC_START(__put_user_1)
49
ANNOTATE_NOENDBR
50
check_range size=1
51
ASM_STAC
52
1: movb %al,(%_ASM_CX)
53
xor %ecx,%ecx
54
ASM_CLAC
55
RET
56
SYM_FUNC_END(__put_user_1)
57
EXPORT_SYMBOL(__put_user_1)
58
59
SYM_FUNC_START(__put_user_nocheck_1)
60
ANNOTATE_NOENDBR
61
ASM_STAC
62
2: movb %al,(%_ASM_CX)
63
xor %ecx,%ecx
64
ASM_CLAC
65
RET
66
SYM_FUNC_END(__put_user_nocheck_1)
67
EXPORT_SYMBOL(__put_user_nocheck_1)
68
69
SYM_FUNC_START(__put_user_2)
70
ANNOTATE_NOENDBR
71
check_range size=2
72
ASM_STAC
73
3: movw %ax,(%_ASM_CX)
74
xor %ecx,%ecx
75
ASM_CLAC
76
RET
77
SYM_FUNC_END(__put_user_2)
78
EXPORT_SYMBOL(__put_user_2)
79
80
SYM_FUNC_START(__put_user_nocheck_2)
81
ANNOTATE_NOENDBR
82
ASM_STAC
83
4: movw %ax,(%_ASM_CX)
84
xor %ecx,%ecx
85
ASM_CLAC
86
RET
87
SYM_FUNC_END(__put_user_nocheck_2)
88
EXPORT_SYMBOL(__put_user_nocheck_2)
89
90
SYM_FUNC_START(__put_user_4)
91
ANNOTATE_NOENDBR
92
check_range size=4
93
ASM_STAC
94
5: movl %eax,(%_ASM_CX)
95
xor %ecx,%ecx
96
ASM_CLAC
97
RET
98
SYM_FUNC_END(__put_user_4)
99
EXPORT_SYMBOL(__put_user_4)
100
101
SYM_FUNC_START(__put_user_nocheck_4)
102
ANNOTATE_NOENDBR
103
ASM_STAC
104
6: movl %eax,(%_ASM_CX)
105
xor %ecx,%ecx
106
ASM_CLAC
107
RET
108
SYM_FUNC_END(__put_user_nocheck_4)
109
EXPORT_SYMBOL(__put_user_nocheck_4)
110
111
SYM_FUNC_START(__put_user_8)
112
ANNOTATE_NOENDBR
113
check_range size=8
114
ASM_STAC
115
7: mov %_ASM_AX,(%_ASM_CX)
116
#ifdef CONFIG_X86_32
117
8: movl %edx,4(%_ASM_CX)
118
#endif
119
xor %ecx,%ecx
120
ASM_CLAC
121
RET
122
SYM_FUNC_END(__put_user_8)
123
EXPORT_SYMBOL(__put_user_8)
124
125
SYM_FUNC_START(__put_user_nocheck_8)
126
ANNOTATE_NOENDBR
127
ASM_STAC
128
9: mov %_ASM_AX,(%_ASM_CX)
129
#ifdef CONFIG_X86_32
130
10: movl %edx,4(%_ASM_CX)
131
#endif
132
xor %ecx,%ecx
133
ASM_CLAC
134
RET
135
SYM_FUNC_END(__put_user_nocheck_8)
136
EXPORT_SYMBOL(__put_user_nocheck_8)
137
138
SYM_CODE_START_LOCAL(__put_user_handle_exception)
139
ASM_CLAC
140
.Lbad_put_user:
141
movl $-EFAULT,%ecx
142
RET
143
SYM_CODE_END(__put_user_handle_exception)
144
145
_ASM_EXTABLE_UA(1b, __put_user_handle_exception)
146
_ASM_EXTABLE_UA(2b, __put_user_handle_exception)
147
_ASM_EXTABLE_UA(3b, __put_user_handle_exception)
148
_ASM_EXTABLE_UA(4b, __put_user_handle_exception)
149
_ASM_EXTABLE_UA(5b, __put_user_handle_exception)
150
_ASM_EXTABLE_UA(6b, __put_user_handle_exception)
151
_ASM_EXTABLE_UA(7b, __put_user_handle_exception)
152
_ASM_EXTABLE_UA(9b, __put_user_handle_exception)
153
#ifdef CONFIG_X86_32
154
_ASM_EXTABLE_UA(8b, __put_user_handle_exception)
155
_ASM_EXTABLE_UA(10b, __put_user_handle_exception)
156
#endif
157
158