From: Nadav Har'El <[email protected]>
Committer: Nadav Har'El <[email protected]>
Branch: master
syscall: skip red zone
The AMD64 ABI allows a function to use 128 bytes beyond the bottom of the
stack without updating the stack pointer - as an optimization known as the
"red zone". If this function calls another function, it is supposed to
update the stack pointer first; But with the SYSCALL instruction, it is not
aware it ends up calling a function.
So our implementation of syscall needs to skip 128 bytes of the stack,
which may be used by the caller's red zone, before making any use of the
stack.
I haven't been able to reproduce a failure without this patch, but I do
believe it is necessary.
Signed-off-by: Nadav Har'El <[email protected]>
Message-Id: <[email protected]>
---
diff --git a/arch/x64/entry.S b/arch/x64/entry.S
--- a/arch/x64/entry.S
+++ b/arch/x64/entry.S
@@ -166,6 +166,10 @@ syscall_entry:
.cfi_startproc simple
# There is no ring transition and rflags are left unchanged.
+ # Skip the "red zone" allowed by the AMD64 ABI (the caller used a
+ # SYSCALL instruction and doesn't know he called a function):
+ subq $128, %rsp
+
# We need to save and restore the caller's %rbp anyway, so let's also
# set it up properly for old-style frame-pointer backtracing to work
# (e.g., backtrace_safe()). Also need to push the return address before
@@ -279,6 +283,8 @@ syscall_entry:
popq %rbp
popq %rcx
+ addq $128, %rsp # undo red-zone skip
+
# jump to rcx where the syscall instruction put rip
# (sysret would leave rxc cloberred so we have nothing to do to restore
it)
jmpq *%rcx
--
You received this message because you are subscribed to the Google Groups "OSv
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.