mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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:
1 parent
eabcdd0faa
commit
d6397bd0e1
3 files changed
+21
-15
No files matched your search
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
|
||||