x86: re-work memcpy()

Move the function to its own assembly file. Having it in C just for the
entire body to be an asm() isn't really helpful. Then have two flavors:
A "basic" version using qword steps for the bulk of the operation, and an
ERMS version for modern hardware, to be substituted in via alternatives
patching.

Alternatives patching, however, requires an extra precaution: It uses
memcpy() itself, and hence the function may patch itself. Luckily the
patched-in code only replaces the prolog of the original function. Make
sure this remains this way.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
This commit is contained in:
Jan Beulich committed 2025-07-23 15:18:50 +02:00
1 parent eabcdd0faa
commit d6397bd0e1
3 files changed
+21 -15

No files matched your search

+1
View File
@@ -47,6 +47,7 @@ obj-$(CONFIG_RETURN_THUNK) += indirect-thunk.o
obj-$(CONFIG_PV) += ioport_emulate.o
obj-y += irq.o
obj-$(CONFIG_KEXEC) += machine_kexec.o
obj-y += memcpy.o
obj-y += memset.o
obj-y += mm.o x86_64/mm.o
obj-$(CONFIG_VM_EVENT) += monitor.o
+20
View File
@@ -0,0 +1,20 @@
#include <asm/asm_defns.h>
FUNC(memcpy)
mov %rdx, %rcx
mov %rdi, %rax
/*
* We need to be careful here: memcpy() is involved in alternatives
* patching, so the code doing the actual copying (i.e. past setting
* up registers) may not be subject to patching (unless further
* precautions were taken).
*/
ALTERNATIVE "and $7, %edx; shr $3, %rcx", \
STR(rep movsb; RET), X86_FEATURE_ERMS
rep movsq
or %edx, %ecx
jz 1f
rep movsb
1:
RET
END(memcpy)
-15
View File
@@ -7,21 +7,6 @@
#include <xen/lib.h>
void *(memcpy)(void *dest, const void *src, size_t n)
{
long d0, d1, d2;
asm volatile (
" rep ; movs"__OS" ; "
" mov %k4,%k3 ; "
" rep ; movsb "
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n/BYTES_PER_LONG), "r" (n%BYTES_PER_LONG), "1" (dest), "2" (src)
: "memory" );
return dest;
}
void *(memmove)(void *dest, const void *src, size_t n)
{
long d0, d1, d2;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.