1
2
3#include <linux/linkage.h>
4#include <asm/errno.h>
5#include <asm/cpufeatures.h>
6#include <asm/mcsafe_test.h>
7#include <asm/alternative-asm.h>
8#include <asm/export.h>
9
10
11
12
13
14
15
16
17.weak memcpy
18
19
20
21
22
23
24
25
26
27
28
29
30ENTRY(__memcpy)
31ENTRY(memcpy)
32 ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \
33 "jmp memcpy_erms", X86_FEATURE_ERMS
34
35 movq %rdi, %rax
36 movq %rdx, %rcx
37 shrq $3, %rcx
38 andl $7, %edx
39 rep movsq
40 movl %edx, %ecx
41 rep movsb
42 ret
43ENDPROC(memcpy)
44ENDPROC(__memcpy)
45EXPORT_SYMBOL(memcpy)
46EXPORT_SYMBOL(__memcpy)
47
48
49
50
51
52ENTRY(memcpy_erms)
53 movq %rdi, %rax
54 movq %rdx, %rcx
55 rep movsb
56 ret
57ENDPROC(memcpy_erms)
58
59ENTRY(memcpy_orig)
60 movq %rdi, %rax
61
62 cmpq $0x20, %rdx
63 jb .Lhandle_tail
64
65
66
67
68
69 cmp %dil, %sil
70 jl .Lcopy_backward
71 subq $0x20, %rdx
72.Lcopy_forward_loop:
73 subq $0x20, %rdx
74
75
76
77
78 movq 0*8(%rsi), %r8
79 movq 1*8(%rsi), %r9
80 movq 2*8(%rsi), %r10
81 movq 3*8(%rsi), %r11
82 leaq 4*8(%rsi), %rsi
83
84 movq %r8, 0*8(%rdi)
85 movq %r9, 1*8(%rdi)
86 movq %r10, 2*8(%rdi)
87 movq %r11, 3*8(%rdi)
88 leaq 4*8(%rdi), %rdi
89 jae .Lcopy_forward_loop
90 addl $0x20, %edx
91 jmp .Lhandle_tail
92
93.Lcopy_backward:
94
95
96
97 addq %rdx, %rsi
98 addq %rdx, %rdi
99 subq $0x20, %rdx
100
101
102
103
104 .p2align 4
105.Lcopy_backward_loop:
106 subq $0x20, %rdx
107 movq -1*8(%rsi), %r8
108 movq -2*8(%rsi), %r9
109 movq -3*8(%rsi), %r10
110 movq -4*8(%rsi), %r11
111 leaq -4*8(%rsi), %rsi
112 movq %r8, -1*8(%rdi)
113 movq %r9, -2*8(%rdi)
114 movq %r10, -3*8(%rdi)
115 movq %r11, -4*8(%rdi)
116 leaq -4*8(%rdi), %rdi
117 jae .Lcopy_backward_loop
118
119
120
121
122 addl $0x20, %edx
123 subq %rdx, %rsi
124 subq %rdx, %rdi
125.Lhandle_tail:
126 cmpl $16, %edx
127 jb .Lless_16bytes
128
129
130
131
132 movq 0*8(%rsi), %r8
133 movq 1*8(%rsi), %r9
134 movq -2*8(%rsi, %rdx), %r10
135 movq -1*8(%rsi, %rdx), %r11
136 movq %r8, 0*8(%rdi)
137 movq %r9, 1*8(%rdi)
138 movq %r10, -2*8(%rdi, %rdx)
139 movq %r11, -1*8(%rdi, %rdx)
140 retq
141 .p2align 4
142.Lless_16bytes:
143 cmpl $8, %edx
144 jb .Lless_8bytes
145
146
147
148 movq 0*8(%rsi), %r8
149 movq -1*8(%rsi, %rdx), %r9
150 movq %r8, 0*8(%rdi)
151 movq %r9, -1*8(%rdi, %rdx)
152 retq
153 .p2align 4
154.Lless_8bytes:
155 cmpl $4, %edx
156 jb .Lless_3bytes
157
158
159
160
161 movl (%rsi), %ecx
162 movl -4(%rsi, %rdx), %r8d
163 movl %ecx, (%rdi)
164 movl %r8d, -4(%rdi, %rdx)
165 retq
166 .p2align 4
167.Lless_3bytes:
168 subl $1, %edx
169 jb .Lend
170
171
172
173 movzbl (%rsi), %ecx
174 jz .Lstore_1byte
175 movzbq 1(%rsi), %r8
176 movzbq (%rsi, %rdx), %r9
177 movb %r8b, 1(%rdi)
178 movb %r9b, (%rdi, %rdx)
179.Lstore_1byte:
180 movb %cl, (%rdi)
181
182.Lend:
183 retq
184ENDPROC(memcpy_orig)
185
186#ifndef CONFIG_UML
187
188MCSAFE_TEST_CTL
189
190
191
192
193
194
195ENTRY(__memcpy_mcsafe)
196 cmpl $8, %edx
197
198 jb .L_no_whole_words
199
200
201 testl $7, %esi
202
203 jz .L_8byte_aligned
204
205
206 movl %esi, %ecx
207 andl $7, %ecx
208 subl $8, %ecx
209 negl %ecx
210 subl %ecx, %edx
211.L_read_leading_bytes:
212 movb (%rsi), %al
213 MCSAFE_TEST_SRC %rsi 1 .E_leading_bytes
214 MCSAFE_TEST_DST %rdi 1 .E_leading_bytes
215.L_write_leading_bytes:
216 movb %al, (%rdi)
217 incq %rsi
218 incq %rdi
219 decl %ecx
220 jnz .L_read_leading_bytes
221
222.L_8byte_aligned:
223 movl %edx, %ecx
224 andl $7, %edx
225 shrl $3, %ecx
226 jz .L_no_whole_words
227
228.L_read_words:
229 movq (%rsi), %r8
230 MCSAFE_TEST_SRC %rsi 8 .E_read_words
231 MCSAFE_TEST_DST %rdi 8 .E_write_words
232.L_write_words:
233 movq %r8, (%rdi)
234 addq $8, %rsi
235 addq $8, %rdi
236 decl %ecx
237 jnz .L_read_words
238
239
240.L_no_whole_words:
241 andl %edx, %edx
242 jz .L_done_memcpy_trap
243
244
245 movl %edx, %ecx
246.L_read_trailing_bytes:
247 movb (%rsi), %al
248 MCSAFE_TEST_SRC %rsi 1 .E_trailing_bytes
249 MCSAFE_TEST_DST %rdi 1 .E_trailing_bytes
250.L_write_trailing_bytes:
251 movb %al, (%rdi)
252 incq %rsi
253 incq %rdi
254 decl %ecx
255 jnz .L_read_trailing_bytes
256
257
258.L_done_memcpy_trap:
259 xorq %rax, %rax
260 ret
261ENDPROC(__memcpy_mcsafe)
262EXPORT_SYMBOL_GPL(__memcpy_mcsafe)
263
264 .section .fixup, "ax"
265
266
267
268
269
270.E_read_words:
271 shll $3, %ecx
272.E_leading_bytes:
273 addl %edx, %ecx
274.E_trailing_bytes:
275 mov %ecx, %eax
276 ret
277
278
279
280
281
282
283.E_write_words:
284 shll $3, %ecx
285 addl %edx, %ecx
286 movl %ecx, %edx
287 jmp mcsafe_handle_tail
288
289 .previous
290
291 _ASM_EXTABLE_FAULT(.L_read_leading_bytes, .E_leading_bytes)
292 _ASM_EXTABLE_FAULT(.L_read_words, .E_read_words)
293 _ASM_EXTABLE_FAULT(.L_read_trailing_bytes, .E_trailing_bytes)
294 _ASM_EXTABLE(.L_write_leading_bytes, .E_leading_bytes)
295 _ASM_EXTABLE(.L_write_words, .E_write_words)
296 _ASM_EXTABLE(.L_write_trailing_bytes, .E_trailing_bytes)
297#endif
298