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