[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] x86: re-work memcpy()



commit d6397bd0e11cbbaa750a794a7476f2b0739f372a
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Jul 23 15:18:50 2025 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Jul 23 15:18:50 2025 +0200

    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@xxxxxxxx>
    Reviewed-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
    Reviewed-by: Jason Andryuk <jason.andryuk@xxxxxxx>
---
 xen/arch/x86/Makefile |  1 +
 xen/arch/x86/memcpy.S | 20 ++++++++++++++++++++
 xen/arch/x86/string.c | 15 ---------------
 3 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 8a9d021223..e32200f5e3 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -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
diff --git a/xen/arch/x86/memcpy.S b/xen/arch/x86/memcpy.S
new file mode 100644
index 0000000000..aaee012126
--- /dev/null
+++ b/xen/arch/x86/memcpy.S
@@ -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)
diff --git a/xen/arch/x86/string.c b/xen/arch/x86/string.c
index 5b52981260..61c4aae6b4 100644
--- a/xen/arch/x86/string.c
+++ b/xen/arch/x86/string.c
@@ -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;
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.