From 20eafb4cc46e512327593baeeb1e2c9581b2bb07 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Thu, 3 Aug 2023 18:09:48 +0300 Subject: [PATCH] Kernel: align userspace stacks I was getting #GP on sse instructions --- kernel/arch/x86_64/Signal.S | 10 +++++++++- kernel/kernel/Thread.cpp | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/kernel/arch/x86_64/Signal.S b/kernel/arch/x86_64/Signal.S index 2b82cb5118..0e24f639be 100644 --- a/kernel/arch/x86_64/Signal.S +++ b/kernel/arch/x86_64/Signal.S @@ -2,6 +2,11 @@ #include +// stack contains +// return address +// signal number +// signal handler + .global signal_trampoline signal_trampoline: pushq %rax @@ -20,6 +25,8 @@ signal_trampoline: pushq %r14 pushq %r15 + // This is 16 byte aligned + movq 128(%rsp), %rdi movq 120(%rsp), %rax call *%rax @@ -46,4 +53,5 @@ signal_trampoline: addq $16, %rsp - ret + // return over red-zone + ret $128 diff --git a/kernel/kernel/Thread.cpp b/kernel/kernel/Thread.cpp index c6a30f478c..800c113494 100644 --- a/kernel/kernel/Thread.cpp +++ b/kernel/kernel/Thread.cpp @@ -83,6 +83,7 @@ namespace Kernel thread->m_rip = (uintptr_t)entry; // Initialize stack for returning + write_to_stack(thread->m_rsp, nullptr); // alignment write_to_stack(thread->m_rsp, thread); write_to_stack(thread->m_rsp, &Thread::on_exit); write_to_stack(thread->m_rsp, data); @@ -179,6 +180,7 @@ namespace Kernel { // FIXME: don't use PageTableScope PageTableScope _(process().page_table()); + write_to_stack(m_rsp, nullptr); // alignment write_to_stack(m_rsp, this); write_to_stack(m_rsp, &Thread::on_exit); write_to_stack(m_rsp, nullptr); @@ -206,6 +208,7 @@ namespace Kernel { // FIXME: don't use PageTableScope PageTableScope _(process().page_table()); + write_to_stack(m_rsp, nullptr); // alignment write_to_stack(m_rsp, this); write_to_stack(m_rsp, &Thread::on_exit); write_to_stack(m_rsp, m_process); @@ -275,6 +278,7 @@ namespace Kernel // FIXME: signal trampoline should take a hash etc // to only allow marking signals done from it m_handling_signal = signal; + return_rsp += 128; // skip possible red-zone write_to_stack(return_rsp, return_rip); write_to_stack(return_rsp, signal); write_to_stack(return_rsp, signal_handler);