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

[xen staging] x86: re-work memset()



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

    x86: re-work memset()
    
    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.
    
    For RET to be usable in an alternative's replacement code, extend the
    CALL/JMP patching to cover the case of "JMP __x86_return_thunk" coming
    last in replacement code.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Jason Andryuk <jason.andryuk@xxxxxxx>
---
 xen/arch/x86/Makefile      |  1 +
 xen/arch/x86/alternative.c |  6 ++++++
 xen/arch/x86/memset.S      | 30 ++++++++++++++++++++++++++++++
 xen/arch/x86/string.c      | 13 -------------
 4 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 96d63219e7..8a9d021223 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 += memset.o
 obj-y += mm.o x86_64/mm.o
 obj-$(CONFIG_VM_EVENT) += monitor.o
 obj-y += mpparse.o
diff --git a/xen/arch/x86/alternative.c b/xen/arch/x86/alternative.c
index e1c34dafec..9f844241bc 100644
--- a/xen/arch/x86/alternative.c
+++ b/xen/arch/x86/alternative.c
@@ -351,6 +351,12 @@ static int init_or_livepatch _apply_alternatives(struct 
alt_instr *start,
         /* 0xe8/0xe9 are relative branches; fix the offset. */
         if ( a->repl_len >= 5 && (*buf & 0xfe) == 0xe8 )
             *(int32_t *)(buf + 1) += repl - orig;
+        else if ( IS_ENABLED(CONFIG_RETURN_THUNK) &&
+                  a->repl_len > 5 && buf[a->repl_len - 5] == 0xe9 &&
+                  ((long)repl + a->repl_len +
+                   *(int32_t *)(buf + a->repl_len - 4) ==
+                   (long)__x86_return_thunk) )
+            *(int32_t *)(buf + a->repl_len - 4) += repl - orig;
 
         a->priv = 1;
 
diff --git a/xen/arch/x86/memset.S b/xen/arch/x86/memset.S
new file mode 100644
index 0000000000..81ec6f6ba2
--- /dev/null
+++ b/xen/arch/x86/memset.S
@@ -0,0 +1,30 @@
+#include <asm/asm_defns.h>
+
+.macro memset
+        and     $7, %edx
+        shr     $3, %rcx
+        movzbl  %sil, %esi
+        mov     $0x0101010101010101, %rax
+        imul    %rsi, %rax
+        mov     %rdi, %r8
+        rep stosq
+        or      %edx, %ecx
+        jz      0f
+        rep stosb
+0:
+        mov     %r8, %rax
+        RET
+.endm
+
+.macro memset_erms
+        mov     %esi, %eax
+        mov     %rdi, %r8
+        rep stosb
+        mov     %r8, %rax
+        RET
+.endm
+
+FUNC(memset)
+        mov     %rdx, %rcx
+        ALTERNATIVE memset, memset_erms, X86_FEATURE_ERMS
+END(memset)
diff --git a/xen/arch/x86/string.c b/xen/arch/x86/string.c
index bda24b14ac..5b52981260 100644
--- a/xen/arch/x86/string.c
+++ b/xen/arch/x86/string.c
@@ -22,19 +22,6 @@ void *(memcpy)(void *dest, const void *src, size_t n)
     return dest;
 }
 
-void *(memset)(void *s, int c, size_t n)
-{
-    long d0, d1;
-
-    asm volatile (
-        "rep stosb"
-        : "=&c" (d0), "=&D" (d1)
-        : "a" (c), "1" (s), "0" (n)
-        : "memory");
-
-    return s;
-}
-
 void *(memmove)(void *dest, const void *src, size_t n)
 {
     long d0, d1, d2;
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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