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:
parent
8eb48039c9
commit
328d44e227
2 changed files with 8 additions and 17 deletions
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue