1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 21:27:34 +00:00

Kernel: Fix stack for new threads on x86_64

Unlike on x86 iretq always pops rsp and ss.
This commit is contained in:
Gunnar Beutner 2021-06-27 17:22:31 +02:00 committed by Andreas Kling
parent 8eb48039c9
commit 328d44e227
2 changed files with 8 additions and 17 deletions

View file

@ -65,13 +65,14 @@ struct [[gnu::packed]] RegisterState {
#else #else
FlatPtr rflags; FlatPtr rflags;
FlatPtr userspace_rsp; FlatPtr userspace_rsp;
FlatPtr userspace_ss;
#endif #endif
}; };
#if ARCH(I386) #if ARCH(I386)
# define REGISTER_STATE_SIZE (19 * 4) # define REGISTER_STATE_SIZE (19 * 4)
#else #else
# define REGISTER_STATE_SIZE (21 * 8) # define REGISTER_STATE_SIZE (22 * 8)
#endif #endif
static_assert(REGISTER_STATE_SIZE == sizeof(RegisterState)); static_assert(REGISTER_STATE_SIZE == sizeof(RegisterState));

View file

@ -91,21 +91,11 @@ u32 Processor::init_context(Thread& thread, bool leave_crit)
auto& regs = thread.regs(); auto& regs = thread.regs();
bool return_to_user = (regs.cs & 3) != 0; bool return_to_user = (regs.cs & 3) != 0;
// make room for an interrupt frame stack_top -= 2 * sizeof(u64);
if (!return_to_user) { *reinterpret_cast<u64*>(kernel_stack_top - 2 * sizeof(u64)) = regs.rsp;
// userspace_rsp is not popped off by iretq *reinterpret_cast<u64*>(kernel_stack_top - 3 * sizeof(u64)) = FlatPtr(&exit_kernel_thread);
// unless we're switching back to user mode
stack_top -= sizeof(RegisterState) - 2 * sizeof(FlatPtr);
// For kernel threads we'll push the thread function argument stack_top -= sizeof(RegisterState);
// which should be in regs.rsp and exit_kernel_thread as return
// address.
stack_top -= 2 * sizeof(u64);
*reinterpret_cast<u64*>(kernel_stack_top - 2 * sizeof(u64)) = regs.rsp;
*reinterpret_cast<u64*>(kernel_stack_top - 3 * sizeof(u64)) = FlatPtr(&exit_kernel_thread);
} else {
stack_top -= sizeof(RegisterState);
}
// we want to end up 16-byte aligned, %rsp + 8 should be aligned // we want to end up 16-byte aligned, %rsp + 8 should be aligned
stack_top -= sizeof(u64); stack_top -= sizeof(u64);
@ -126,8 +116,8 @@ u32 Processor::init_context(Thread& thread, bool leave_crit)
iretframe.rflags = regs.rflags; iretframe.rflags = regs.rflags;
iretframe.rip = regs.rip; iretframe.rip = regs.rip;
iretframe.cs = regs.cs; iretframe.cs = regs.cs;
if (return_to_user) iretframe.userspace_rsp = kernel_stack_top;
iretframe.userspace_rsp = regs.rsp; iretframe.userspace_ss = 0;
// make space for a trap frame // make space for a trap frame
stack_top -= sizeof(TrapFrame); stack_top -= sizeof(TrapFrame);