@@ -184,11 +184,11 @@ ENDPROC(memcpy_orig)
184
184
185
185
#ifndef CONFIG_UML
186
186
/*
187
- * memcpy_mcsafe_unrolled - memory copy with machine check exception handling
187
+ * __memcpy_mcsafe - memory copy with machine check exception handling
188
188
* Note that we only catch machine checks when reading the source addresses.
189
189
* Writes to target are posted and don't generate machine checks.
190
190
*/
191
- ENTRY(memcpy_mcsafe_unrolled )
191
+ ENTRY(__memcpy_mcsafe )
192
192
cmpl $8 , %edx
193
193
/* Less than 8 bytes? Go to byte copy loop */
194
194
jb .L_no_whole_words
@@ -204,58 +204,29 @@ ENTRY(memcpy_mcsafe_unrolled)
204
204
subl $8 , %ecx
205
205
negl %ecx
206
206
subl %ecx , %edx
207
- .L_copy_leading_bytes :
207
+ .L_read_leading_bytes :
208
208
movb (%rsi ), %al
209
+ .L_write_leading_bytes:
209
210
movb %al , (%rdi )
210
211
incq %rsi
211
212
incq %rdi
212
213
decl %ecx
213
- jnz .L_copy_leading_bytes
214
+ jnz .L_read_leading_bytes
214
215
215
216
.L_8byte_aligned:
216
- /* Figure out how many whole cache lines (64-bytes) to copy */
217
- movl %edx , %ecx
218
- andl $63 , %edx
219
- shrl $6 , %ecx
220
- jz .L_no_whole_cache_lines
221
-
222
- /* Loop copying whole cache lines */
223
- .L_cache_w0: movq (%rsi ), %r8
224
- .L_cache_w1: movq 1*8 (%rsi ), %r9
225
- .L_cache_w2: movq 2*8 (%rsi ), %r10
226
- .L_cache_w3: movq 3*8 (%rsi ), %r11
227
- movq %r8 , (%rdi )
228
- movq %r9 , 1*8 (%rdi )
229
- movq %r10 , 2*8 (%rdi )
230
- movq %r11 , 3*8 (%rdi )
231
- .L_cache_w4: movq 4*8 (%rsi ), %r8
232
- .L_cache_w5: movq 5*8 (%rsi ), %r9
233
- .L_cache_w6: movq 6*8 (%rsi ), %r10
234
- .L_cache_w7: movq 7*8 (%rsi ), %r11
235
- movq %r8 , 4*8 (%rdi )
236
- movq %r9 , 5*8 (%rdi )
237
- movq %r10 , 6*8 (%rdi )
238
- movq %r11 , 7*8 (%rdi )
239
- leaq 64 (%rsi ), %rsi
240
- leaq 64 (%rdi ), %rdi
241
- decl %ecx
242
- jnz .L_cache_w0
243
-
244
- /* Are there any trailing 8-byte words? */
245
- .L_no_whole_cache_lines:
246
217
movl %edx , %ecx
247
218
andl $7 , %edx
248
219
shrl $3 , %ecx
249
220
jz .L_no_whole_words
250
221
251
- /* Copy trailing words */
252
- .L_copy_trailing_words:
222
+ .L_read_words:
253
223
movq (%rsi ), %r8
254
- mov %r8 , (%rdi )
255
- leaq 8 (%rsi ), %rsi
256
- leaq 8 (%rdi ), %rdi
224
+ .L_write_words:
225
+ movq %r8 , (%rdi )
226
+ addq $8 , %rsi
227
+ addq $8 , %rdi
257
228
decl %ecx
258
- jnz .L_copy_trailing_words
229
+ jnz .L_read_words
259
230
260
231
/* Any trailing bytes? */
261
232
.L_no_whole_words:
@@ -264,38 +235,53 @@ ENTRY(memcpy_mcsafe_unrolled)
264
235
265
236
/* Copy trailing bytes */
266
237
movl %edx , %ecx
267
- .L_copy_trailing_bytes :
238
+ .L_read_trailing_bytes :
268
239
movb (%rsi ), %al
240
+ .L_write_trailing_bytes:
269
241
movb %al , (%rdi )
270
242
incq %rsi
271
243
incq %rdi
272
244
decl %ecx
273
- jnz .L_copy_trailing_bytes
245
+ jnz .L_read_trailing_bytes
274
246
275
247
/* Copy successful. Return zero */
276
248
.L_done_memcpy_trap:
277
249
xorq %rax , %rax
278
250
ret
279
- ENDPROC(memcpy_mcsafe_unrolled )
280
- EXPORT_SYMBOL_GPL(memcpy_mcsafe_unrolled )
251
+ ENDPROC(__memcpy_mcsafe )
252
+ EXPORT_SYMBOL_GPL(__memcpy_mcsafe )
281
253
282
254
.section .fixup, "ax"
283
- /* Return -EFAULT for any failure */
284
- .L_memcpy_mcsafe_fail:
285
- mov $-EFAULT, %rax
255
+ /*
256
+ * Return number of bytes not copied for any failure. Note that
257
+ * there is no "tail" handling since the source buffer is 8-byte
258
+ * aligned and poison is cacheline aligned.
259
+ */
260
+ .E_read_words:
261
+ shll $3 , %ecx
262
+ .E_leading_bytes:
263
+ addl %edx , %ecx
264
+ .E_trailing_bytes:
265
+ mov %ecx , %eax
286
266
ret
287
267
268
+ /*
269
+ * For write fault handling, given the destination is unaligned,
270
+ * we handle faults on multi-byte writes with a byte-by-byte
271
+ * copy up to the write-protected page.
272
+ */
273
+ .E_write_words:
274
+ shll $3 , %ecx
275
+ addl %edx , %ecx
276
+ movl %ecx , %edx
277
+ jmp mcsafe_handle_tail
278
+
288
279
.previous
289
280
290
- _ASM_EXTABLE_FAULT(.L_copy_leading_bytes, .L_memcpy_mcsafe_fail)
291
- _ASM_EXTABLE_FAULT(.L_cache_w0, .L_memcpy_mcsafe_fail)
292
- _ASM_EXTABLE_FAULT(.L_cache_w1, .L_memcpy_mcsafe_fail)
293
- _ASM_EXTABLE_FAULT(.L_cache_w2, .L_memcpy_mcsafe_fail)
294
- _ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail)
295
- _ASM_EXTABLE_FAULT(.L_cache_w4, .L_memcpy_mcsafe_fail)
296
- _ASM_EXTABLE_FAULT(.L_cache_w5, .L_memcpy_mcsafe_fail)
297
- _ASM_EXTABLE_FAULT(.L_cache_w6, .L_memcpy_mcsafe_fail)
298
- _ASM_EXTABLE_FAULT(.L_cache_w7, .L_memcpy_mcsafe_fail)
299
- _ASM_EXTABLE_FAULT(.L_copy_trailing_words, .L_memcpy_mcsafe_fail)
300
- _ASM_EXTABLE_FAULT(.L_copy_trailing_bytes, .L_memcpy_mcsafe_fail)
281
+ _ASM_EXTABLE_FAULT(.L_read_leading_bytes, .E_leading_bytes)
282
+ _ASM_EXTABLE_FAULT(.L_read_words, .E_read_words)
283
+ _ASM_EXTABLE_FAULT(.L_read_trailing_bytes, .E_trailing_bytes)
284
+ _ASM_EXTABLE(.L_write_leading_bytes, .E_leading_bytes)
285
+ _ASM_EXTABLE(.L_write_words, .E_write_words)
286
+ _ASM_EXTABLE(.L_write_trailing_bytes, .E_trailing_bytes)
301
287
#endif
0 commit comments