1
2
3
4
5
6
7
8
9#include <linux/linkage.h>
10#include <asm/dwarf2.h>
11#include <asm/current.h>
12#include <asm/asm-offsets.h>
13#include <asm/thread_info.h>
14#include <asm/cpufeature.h>
15#include <asm/alternative-asm.h>
16#include <asm/asm.h>
17#include <asm/smap.h>
18
19 .macro ALIGN_DESTINATION
20
21 movl %edi,%ecx
22 andl $7,%ecx
23 jz 102f
24 subl $8,%ecx
25 negl %ecx
26 subl %ecx,%edx
27100: movb (%rsi),%al
28101: movb %al,(%rdi)
29 incq %rsi
30 incq %rdi
31 decl %ecx
32 jnz 100b
33102:
34 .section .fixup,"ax"
35103: addl %ecx,%edx
36 jmp copy_user_handle_tail
37 .previous
38
39 _ASM_EXTABLE(100b,103b)
40 _ASM_EXTABLE(101b,103b)
41 .endm
42
43
44ENTRY(_copy_to_user)
45 CFI_STARTPROC
46 GET_THREAD_INFO(%rax)
47 movq %rdi,%rcx
48 addq %rdx,%rcx
49 jc bad_to_user
50 cmpq TI_addr_limit(%rax),%rcx
51 ja bad_to_user
52 ALTERNATIVE_2 "jmp copy_user_generic_unrolled", \
53 "jmp copy_user_generic_string", \
54 X86_FEATURE_REP_GOOD, \
55 "jmp copy_user_enhanced_fast_string", \
56 X86_FEATURE_ERMS
57 CFI_ENDPROC
58ENDPROC(_copy_to_user)
59
60
61ENTRY(_copy_from_user)
62 CFI_STARTPROC
63 GET_THREAD_INFO(%rax)
64 movq %rsi,%rcx
65 addq %rdx,%rcx
66 jc bad_from_user
67 cmpq TI_addr_limit(%rax),%rcx
68 ja bad_from_user
69 ALTERNATIVE_2 "jmp copy_user_generic_unrolled", \
70 "jmp copy_user_generic_string", \
71 X86_FEATURE_REP_GOOD, \
72 "jmp copy_user_enhanced_fast_string", \
73 X86_FEATURE_ERMS
74 CFI_ENDPROC
75ENDPROC(_copy_from_user)
76
77 .section .fixup,"ax"
78
79ENTRY(bad_from_user)
80bad_from_user:
81 CFI_STARTPROC
82 movl %edx,%ecx
83 xorl %eax,%eax
84 rep
85 stosb
86bad_to_user:
87 movl %edx,%eax
88 ret
89 CFI_ENDPROC
90ENDPROC(bad_from_user)
91 .previous
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106ENTRY(copy_user_generic_unrolled)
107 CFI_STARTPROC
108 ASM_STAC
109 cmpl $8,%edx
110 jb 20f
111 ALIGN_DESTINATION
112 movl %edx,%ecx
113 andl $63,%edx
114 shrl $6,%ecx
115 jz 17f
1161: movq (%rsi),%r8
1172: movq 1*8(%rsi),%r9
1183: movq 2*8(%rsi),%r10
1194: movq 3*8(%rsi),%r11
1205: movq %r8,(%rdi)
1216: movq %r9,1*8(%rdi)
1227: movq %r10,2*8(%rdi)
1238: movq %r11,3*8(%rdi)
1249: movq 4*8(%rsi),%r8
12510: movq 5*8(%rsi),%r9
12611: movq 6*8(%rsi),%r10
12712: movq 7*8(%rsi),%r11
12813: movq %r8,4*8(%rdi)
12914: movq %r9,5*8(%rdi)
13015: movq %r10,6*8(%rdi)
13116: movq %r11,7*8(%rdi)
132 leaq 64(%rsi),%rsi
133 leaq 64(%rdi),%rdi
134 decl %ecx
135 jnz 1b
13617: movl %edx,%ecx
137 andl $7,%edx
138 shrl $3,%ecx
139 jz 20f
14018: movq (%rsi),%r8
14119: movq %r8,(%rdi)
142 leaq 8(%rsi),%rsi
143 leaq 8(%rdi),%rdi
144 decl %ecx
145 jnz 18b
14620: andl %edx,%edx
147 jz 23f
148 movl %edx,%ecx
14921: movb (%rsi),%al
15022: movb %al,(%rdi)
151 incq %rsi
152 incq %rdi
153 decl %ecx
154 jnz 21b
15523: xor %eax,%eax
156 ASM_CLAC
157 ret
158
159 .section .fixup,"ax"
16030: shll $6,%ecx
161 addl %ecx,%edx
162 jmp 60f
16340: leal (%rdx,%rcx,8),%edx
164 jmp 60f
16550: movl %ecx,%edx
16660: jmp copy_user_handle_tail
167 .previous
168
169 _ASM_EXTABLE(1b,30b)
170 _ASM_EXTABLE(2b,30b)
171 _ASM_EXTABLE(3b,30b)
172 _ASM_EXTABLE(4b,30b)
173 _ASM_EXTABLE(5b,30b)
174 _ASM_EXTABLE(6b,30b)
175 _ASM_EXTABLE(7b,30b)
176 _ASM_EXTABLE(8b,30b)
177 _ASM_EXTABLE(9b,30b)
178 _ASM_EXTABLE(10b,30b)
179 _ASM_EXTABLE(11b,30b)
180 _ASM_EXTABLE(12b,30b)
181 _ASM_EXTABLE(13b,30b)
182 _ASM_EXTABLE(14b,30b)
183 _ASM_EXTABLE(15b,30b)
184 _ASM_EXTABLE(16b,30b)
185 _ASM_EXTABLE(18b,40b)
186 _ASM_EXTABLE(19b,40b)
187 _ASM_EXTABLE(21b,50b)
188 _ASM_EXTABLE(22b,50b)
189 CFI_ENDPROC
190ENDPROC(copy_user_generic_unrolled)
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210ENTRY(copy_user_generic_string)
211 CFI_STARTPROC
212 ASM_STAC
213 cmpl $8,%edx
214 jb 2f
215 ALIGN_DESTINATION
216 movl %edx,%ecx
217 shrl $3,%ecx
218 andl $7,%edx
2191: rep
220 movsq
2212: movl %edx,%ecx
2223: rep
223 movsb
224 xorl %eax,%eax
225 ASM_CLAC
226 ret
227
228 .section .fixup,"ax"
22911: leal (%rdx,%rcx,8),%ecx
23012: movl %ecx,%edx
231 jmp copy_user_handle_tail
232 .previous
233
234 _ASM_EXTABLE(1b,11b)
235 _ASM_EXTABLE(3b,12b)
236 CFI_ENDPROC
237ENDPROC(copy_user_generic_string)
238
239
240
241
242
243
244
245
246
247
248
249
250
251ENTRY(copy_user_enhanced_fast_string)
252 CFI_STARTPROC
253 ASM_STAC
254 movl %edx,%ecx
2551: rep
256 movsb
257 xorl %eax,%eax
258 ASM_CLAC
259 ret
260
261 .section .fixup,"ax"
26212: movl %ecx,%edx
263 jmp copy_user_handle_tail
264 .previous
265
266 _ASM_EXTABLE(1b,12b)
267 CFI_ENDPROC
268ENDPROC(copy_user_enhanced_fast_string)
269