diff options
author | Andreas Kling <kling@serenityos.org> | 2021-08-19 21:53:53 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-19 23:22:02 +0200 |
commit | 961f727448019047433ac1b045f8075f269ba9f7 (patch) | |
tree | 25f3972636525b96df35941cb72fc7a03e6f78e5 /Kernel | |
parent | 3f5a42b3dd05e56794e5a1394c6e008c15b3f58e (diff) | |
download | serenity-961f727448019047433ac1b045f8075f269ba9f7.zip |
Kernel: Consolidate a bunch of i386/x86_64 code paths
Add some arch-specific getters and setters that allow us to merge blocks
that were previously specific to either ARCH(I386) or ARCH(X86_64).
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Arch/x86/RegisterState.h | 68 | ||||
-rw-r--r-- | Kernel/Arch/x86/common/SafeMem.cpp | 18 | ||||
-rw-r--r-- | Kernel/Process.cpp | 12 | ||||
-rw-r--r-- | Kernel/Syscalls/thread.cpp | 12 | ||||
-rw-r--r-- | Kernel/Thread.cpp | 59 | ||||
-rw-r--r-- | Kernel/Thread.h | 12 |
6 files changed, 64 insertions, 117 deletions
diff --git a/Kernel/Arch/x86/RegisterState.h b/Kernel/Arch/x86/RegisterState.h index 21e9fe13cd..cefd54209b 100644 --- a/Kernel/Arch/x86/RegisterState.h +++ b/Kernel/Arch/x86/RegisterState.h @@ -68,41 +68,35 @@ struct [[gnu::packed]] RegisterState { FlatPtr userspace_ss; #endif +#if ARCH(I386) FlatPtr userspace_sp() const { -#if ARCH(I386) return userspace_esp; -#else - return userspace_rsp; -#endif } - - FlatPtr ip() const - { -#if ARCH(I386) - return eip; -#else - return rip; -#endif - } - - FlatPtr bp() const + void set_userspace_sp(FlatPtr value) { userspace_esp = value; } + FlatPtr ip() const { return eip; } + void set_ip(FlatPtr value) { eip = value; } + void set_dx(FlatPtr value) { edx = value; } + FlatPtr bp() const { return ebp; } + void set_bp(FlatPtr value) { ebp = value; } + FlatPtr flags() const { return eflags; } + void set_flags(FlatPtr value) { eflags = value; } + void set_return_reg(FlatPtr value) { eax = value; } +#elif ARCH(X86_64) + FlatPtr userspace_sp() const { -#if ARCH(I386) - return ebp; -#else - return rbp; -#endif + return userspace_rsp; } - - FlatPtr flags() const - { -#if ARCH(I386) - return eflags; -#else - return rflags; + void set_userspace_sp(FlatPtr value) { userspace_rsp = value; } + FlatPtr ip() const { return rip; } + void set_ip(FlatPtr value) { rip = value; } + void set_dx(FlatPtr value) { rdx = value; } + FlatPtr bp() const { return rbp; } + void set_bp(FlatPtr value) { rbp = value; } + FlatPtr flags() const { return rflags; } + void set_flags(FlatPtr value) { rflags = value; } + void set_return_reg(FlatPtr value) { rax = value; } #endif - } void capture_syscall_params(FlatPtr& function, FlatPtr& arg1, FlatPtr& arg2, FlatPtr& arg3, FlatPtr& arg4) const { @@ -120,24 +114,6 @@ struct [[gnu::packed]] RegisterState { arg4 = rsi; #endif } - - void set_ip_reg(FlatPtr value) - { -#if ARCH(I386) - eip = value; -#else - rip = value; -#endif - } - - void set_return_reg(FlatPtr value) - { -#if ARCH(I386) - eax = value; -#else - rax = value; -#endif - } }; #if ARCH(I386) diff --git a/Kernel/Arch/x86/common/SafeMem.cpp b/Kernel/Arch/x86/common/SafeMem.cpp index 9fb7208ad3..36824714f8 100644 --- a/Kernel/Arch/x86/common/SafeMem.cpp +++ b/Kernel/Arch/x86/common/SafeMem.cpp @@ -299,13 +299,8 @@ bool handle_safe_access_fault(RegisterState& regs, FlatPtr fault_address) else return false; -#if ARCH(I386) - regs.eip = ip; - regs.edx = fault_address; -#else - regs.rip = ip; - regs.rdx = fault_address; -#endif + regs.set_ip(ip); + regs.set_dx(fault_address); return true; } if (ip >= (FlatPtr)&start_of_safemem_atomic_text && ip < (FlatPtr)&end_of_safemem_atomic_text) { @@ -325,13 +320,8 @@ bool handle_safe_access_fault(RegisterState& regs, FlatPtr fault_address) else return false; -#if ARCH(I386) - regs.eip = ip; - regs.edx = 1; -#else - regs.rip = ip; - regs.rdx = 1; -#endif + regs.set_ip(ip); + regs.set_dx(1); return true; } return false; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index f197cb4f92..61143fd994 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -195,11 +195,10 @@ RefPtr<Process> Process::create_kernel_process(RefPtr<Thread>& first_thread, Str auto process = Process::create(first_thread, move(name), (uid_t)0, (gid_t)0, ProcessID(0), true); if (!first_thread || !process) return {}; + first_thread->regs().set_ip((FlatPtr)entry); #if ARCH(I386) - first_thread->regs().eip = (FlatPtr)entry; first_thread->regs().esp = FlatPtr(entry_data); // entry function argument is expected to be in regs.esp #else - first_thread->regs().rip = (FlatPtr)entry; first_thread->regs().rdi = FlatPtr(entry_data); // entry function argument is expected to be in regs.rdi #endif @@ -769,13 +768,8 @@ RefPtr<Thread> Process::create_kernel_thread(void (*entry)(void*), void* entry_d thread->detach(); auto& regs = thread->regs(); -#if ARCH(I386) - regs.eip = (FlatPtr)entry; - regs.esp = FlatPtr(entry_data); // entry function argument is expected to be in regs.rsp -#else - regs.rip = (FlatPtr)entry; - regs.rsp = FlatPtr(entry_data); // entry function argument is expected to be in regs.rsp -#endif + regs.set_ip((FlatPtr)entry); + regs.set_sp((FlatPtr)entry_data); // entry function argument is expected to be in the SP register ScopedSpinLock lock(g_scheduler_lock); thread->set_state(Thread::State::Runnable); diff --git a/Kernel/Syscalls/thread.cpp b/Kernel/Syscalls/thread.cpp index e3c3ff9e07..ec4b567f03 100644 --- a/Kernel/Syscalls/thread.cpp +++ b/Kernel/Syscalls/thread.cpp @@ -60,14 +60,10 @@ KResultOr<FlatPtr> Process::sys$create_thread(void* (*entry)(void*), Userspace<c thread->detach(); auto& regs = thread->regs(); -#if ARCH(I386) - regs.eip = (FlatPtr)entry; - regs.eflags = 0x0202; - regs.esp = user_sp.value(); -#else - regs.rip = (FlatPtr)entry; - regs.rflags = 0x0202; - regs.rsp = user_sp.value(); + regs.set_ip((FlatPtr)entry); + regs.set_flags(0x0202); + regs.set_sp(user_sp.value()); +#if ARCH(X86_64) regs.rdi = params.rdi; regs.rsi = params.rsi; regs.rdx = params.rdx; diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index 06954a485a..2408dfac5c 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -86,10 +86,10 @@ Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Memory::Region> ker reset_fpu_state(); -#if ARCH(I386) // Only IF is set when a process boots. - m_regs.eflags = 0x0202; + m_regs.set_flags(0x0202); +#if ARCH(I386) if (m_process->is_kernel_process()) { m_regs.cs = GDT_SELECTOR_CODE0; m_regs.ds = GDT_SELECTOR_DATA0; @@ -106,9 +106,6 @@ Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Memory::Region> ker m_regs.gs = GDT_SELECTOR_TLS | 3; } #else - // Only IF is set when a process boots. - m_regs.rflags = 0x0202; - if (m_process->is_kernel_process()) m_regs.cs = GDT_SELECTOR_CODE0; else @@ -121,20 +118,15 @@ Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Memory::Region> ker m_kernel_stack_top = m_kernel_stack_region->vaddr().offset(default_kernel_stack_size).get() & ~(FlatPtr)0x7u; if (m_process->is_kernel_process()) { -#if ARCH(I386) - m_regs.esp = m_regs.esp0 = m_kernel_stack_top; -#else - m_regs.rsp = m_regs.rsp0 = m_kernel_stack_top; -#endif + m_regs.set_sp(m_kernel_stack_top); + m_regs.set_sp0(m_kernel_stack_top); } else { // Ring 3 processes get a separate stack for ring 0. // The ring 3 stack will be assigned by exec(). #if ARCH(I386) m_regs.ss0 = GDT_SELECTOR_DATA0; - m_regs.esp0 = m_kernel_stack_top; -#else - m_regs.rsp0 = m_kernel_stack_top; #endif + m_regs.set_sp0(m_kernel_stack_top); } // We need to add another reference if we could successfully create @@ -938,21 +930,12 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal) m_have_any_unmasked_pending_signals.store(m_pending_signals & ~m_signal_mask, AK::memory_order_release); auto setup_stack = [&](RegisterState& state) { -#if ARCH(I386) - FlatPtr stack = state.userspace_esp; - FlatPtr old_esp = stack; - FlatPtr ret_eip = state.eip; - FlatPtr ret_eflags = state.eflags; - - dbgln_if(SIGNAL_DEBUG, "Setting up user stack to return to EIP {:p}, ESP {:p}", ret_eip, old_esp); -#elif ARCH(X86_64) - FlatPtr stack = state.userspace_rsp; - FlatPtr old_rsp = stack; - FlatPtr ret_rip = state.rip; - FlatPtr ret_rflags = state.rflags; - - dbgln_if(SIGNAL_DEBUG, "Setting up user stack to return to RIP {:p}, RSP {:p}", ret_rip, old_rsp); -#endif + FlatPtr stack = state.userspace_sp(); + FlatPtr old_sp = stack; + FlatPtr ret_ip = state.ip(); + FlatPtr ret_flags = state.flags(); + + dbgln_if(SIGNAL_DEBUG, "Setting up user stack to return to IP {:p}, SP {:p}", ret_ip, old_sp); #if ARCH(I386) // Align the stack to 16 bytes. @@ -963,14 +946,14 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal) FlatPtr stack_alignment = (stack - 8) % 16; stack -= stack_alignment; - push_value_on_user_stack(stack, ret_eflags); + push_value_on_user_stack(stack, ret_flags); - push_value_on_user_stack(stack, ret_eip); + push_value_on_user_stack(stack, ret_ip); push_value_on_user_stack(stack, state.eax); push_value_on_user_stack(stack, state.ecx); push_value_on_user_stack(stack, state.edx); push_value_on_user_stack(stack, state.ebx); - push_value_on_user_stack(stack, old_esp); + push_value_on_user_stack(stack, old_sp); push_value_on_user_stack(stack, state.ebp); push_value_on_user_stack(stack, state.esi); push_value_on_user_stack(stack, state.edi); @@ -984,9 +967,9 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal) FlatPtr stack_alignment = stack % 16; stack -= 128 + stack_alignment; - push_value_on_user_stack(stack, ret_rflags); + push_value_on_user_stack(stack, ret_flags); - push_value_on_user_stack(stack, ret_rip); + push_value_on_user_stack(stack, ret_ip); push_value_on_user_stack(stack, state.r15); push_value_on_user_stack(stack, state.r14); push_value_on_user_stack(stack, state.r13); @@ -999,7 +982,7 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal) push_value_on_user_stack(stack, state.rcx); push_value_on_user_stack(stack, state.rdx); push_value_on_user_stack(stack, state.rbx); - push_value_on_user_stack(stack, old_rsp); + push_value_on_user_stack(stack, old_sp); push_value_on_user_stack(stack, state.rbp); push_value_on_user_stack(stack, state.rsi); push_value_on_user_stack(stack, state.rdi); @@ -1014,11 +997,7 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal) // We write back the adjusted stack value into the register state. // We have to do this because we can't just pass around a reference to a packed field, as it's UB. -#if ARCH(I386) - state.userspace_esp = stack; -#else - state.userspace_rsp = stack; -#endif + state.set_userspace_sp(stack); VERIFY((stack % 16) == 0); }; @@ -1030,7 +1009,7 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal) auto& regs = get_register_dump_from_stack(); setup_stack(regs); auto signal_trampoline_addr = process.signal_trampoline().get(); - regs.set_ip_reg(signal_trampoline_addr); + regs.set_ip(signal_trampoline_addr); dbgln_if(SIGNAL_DEBUG, "Thread in state '{}' has been primed with signal handler {:#04x}:{:p} to deliver {}", state_string(), m_regs.cs, m_regs.ip(), signal); diff --git a/Kernel/Thread.h b/Kernel/Thread.h index c78c13b6d0..602058b4da 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -105,11 +105,23 @@ struct ThreadRegisters { FlatPtr rsp0; #endif FlatPtr cs; + #if ARCH(I386) FlatPtr eflags; + FlatPtr flags() const { return eflags; } + void set_flags(FlatPtr value) { eflags = value; } + void set_sp(FlatPtr value) { esp = value; } + void set_sp0(FlatPtr value) { esp0 = value; } + void set_ip(FlatPtr value) { eip = value; } #else FlatPtr rflags; + FlatPtr flags() const { return rflags; } + void set_flags(FlatPtr value) { rflags = value; } + void set_sp(FlatPtr value) { rsp = value; } + void set_sp0(FlatPtr value) { rsp0 = value; } + void set_ip(FlatPtr value) { rip = value; } #endif + FlatPtr cr3; FlatPtr ip() const |