mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-22 17:31:58 -05:00
Kernel/x86: Use iretq instead of sysretq for sys$sigreturn
Using sysretq clobbers rcx and r11 as this instruction loads the rip and
rflags from those registers. This is fine for normal syscalls.
Signal dispatching works like this:
The kernel makes userspace jump to the signal trampoline when a signal
is dispatched. That trampoline then executes the sigreturn syscall after
calling the signal handler to continue executing the code before the
signal was dispatched.
Since e71c320154
the sigreturn syscall is done via the syscall
instruction (and int 0x82 support was removed in the next commit),
which causes the kernel to currently use sysretq to return to userspace.
But signals can happen at any time, not just during syscalls, so the
sigreturn syscall shouldn't clobber the contents of those registers when
returning to userspace.
This commit is contained in:
parent
b806c52bd3
commit
d9c098f103
1 changed files with 8 additions and 1 deletions
|
@ -52,12 +52,19 @@ extern "C" NO_SANITIZE_COVERAGE [[gnu::naked]] void syscall_entry()
|
|||
" pushq %%rsi \n"
|
||||
" pushq %%rdi \n"
|
||||
|
||||
" movq %%rax, %%rbx \n" // Move the syscall function to a callee-saved register.
|
||||
|
||||
" pushq %%rsp \n" // TrapFrame::regs
|
||||
" subq $" __STRINGIFY(TRAP_FRAME_SIZE - 8) ", %%rsp \n"
|
||||
" movq %%rsp, %%rdi \n"
|
||||
" call enter_trap_no_irq \n"
|
||||
" movq %%rsp, %%rdi \n"
|
||||
" call syscall_handler \n"
|
||||
|
||||
// We have to use iretq for sys$sigreturn, as signals would otherwise clobber rcx and r11 when using sysretq.
|
||||
" cmpq %[sc_sigreturn], %%rbx \n"
|
||||
" je common_trap_exit \n"
|
||||
|
||||
" movq %%rsp, %%rdi \n"
|
||||
" call exit_trap \n"
|
||||
" addq $" __STRINGIFY(TRAP_FRAME_SIZE) ", %%rsp \n" // Pop TrapFrame
|
||||
|
@ -88,6 +95,6 @@ extern "C" NO_SANITIZE_COVERAGE [[gnu::naked]] void syscall_entry()
|
|||
" cli \n"
|
||||
" popq %%rsp \n"
|
||||
" sysretq \n"
|
||||
:: [user_stack] "i"(Kernel::Processor::user_stack_offset()), [kernel_stack] "i"(Kernel::Processor::kernel_stack_offset()));
|
||||
:: [user_stack] "i"(Kernel::Processor::user_stack_offset()), [kernel_stack] "i"(Kernel::Processor::kernel_stack_offset()), [sc_sigreturn] "i"(SC_sigreturn));
|
||||
// clang-format on
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue