diff --git a/Kernel/Arch/x86/RegisterState.h b/Kernel/Arch/x86/RegisterState.h index 299eecf3610..95c6bb47950 100644 --- a/Kernel/Arch/x86/RegisterState.h +++ b/Kernel/Arch/x86/RegisterState.h @@ -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)); diff --git a/Kernel/Arch/x86/x86_64/Processor.cpp b/Kernel/Arch/x86/x86_64/Processor.cpp index f45c95cb4e1..0828506d36e 100644 --- a/Kernel/Arch/x86/x86_64/Processor.cpp +++ b/Kernel/Arch/x86/x86_64/Processor.cpp @@ -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(kernel_stack_top - 2 * sizeof(u64)) = regs.rsp; + *reinterpret_cast(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(kernel_stack_top - 2 * sizeof(u64)) = regs.rsp; - *reinterpret_cast(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);