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
Notes: sideshowbarker 2024-07-18 11:25:26 +09:00
2 changed files with 8 additions and 17 deletions

View file

@ -65,13 +65,14 @@ struct [[gnu::packed]] RegisterState {
#else
FlatPtr rflags;
FlatPtr userspace_rsp;
FlatPtr userspace_ss;
#endif
};
#if ARCH(I386)
# define REGISTER_STATE_SIZE (19 * 4)
#else
# define REGISTER_STATE_SIZE (21 * 8)
# define REGISTER_STATE_SIZE (22 * 8)
#endif
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();
bool return_to_user = (regs.cs & 3) != 0;
// make room for an interrupt frame
if (!return_to_user) {
// userspace_rsp is not popped off by iretq
// unless we're switching back to user mode
stack_top -= sizeof(RegisterState) - 2 * sizeof(FlatPtr);
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);
// For kernel threads we'll push the thread function argument
// 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);
}
stack_top -= sizeof(RegisterState);
// we want to end up 16-byte aligned, %rsp + 8 should be aligned
stack_top -= sizeof(u64);
@ -126,8 +116,8 @@ u32 Processor::init_context(Thread& thread, bool leave_crit)
iretframe.rflags = regs.rflags;
iretframe.rip = regs.rip;
iretframe.cs = regs.cs;
if (return_to_user)
iretframe.userspace_rsp = regs.rsp;
iretframe.userspace_rsp = kernel_stack_top;
iretframe.userspace_ss = 0;
// make space for a trap frame
stack_top -= sizeof(TrapFrame);