From a3cbaa344931bf034b6476187a605e8112b7d339 Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Tue, 27 Dec 2022 14:04:07 +0100 Subject: [PATCH] Kernel: Move ThreadRegisters into arch-specific directory These are architecture-specific anyway, so they belong in the Arch directory. This commit also adds ThreadRegisters::set_initial_state to factor out the logic in Thread.cpp. --- Kernel/Arch/ThreadRegisters.h | 17 ++++++ Kernel/Arch/aarch64/ThreadRegisters.h | 30 +++++++++++ Kernel/Arch/x86_64/ThreadRegisters.h | 78 +++++++++++++++++++++++++++ Kernel/Syscalls/thread.cpp | 6 ++- Kernel/Thread.cpp | 27 ++-------- Kernel/Thread.h | 50 +---------------- 6 files changed, 133 insertions(+), 75 deletions(-) create mode 100644 Kernel/Arch/ThreadRegisters.h create mode 100644 Kernel/Arch/aarch64/ThreadRegisters.h create mode 100644 Kernel/Arch/x86_64/ThreadRegisters.h diff --git a/Kernel/Arch/ThreadRegisters.h b/Kernel/Arch/ThreadRegisters.h new file mode 100644 index 00000000000..b21b73197a3 --- /dev/null +++ b/Kernel/Arch/ThreadRegisters.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2022, Timon Kruiper + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +#if ARCH(X86_64) +# include +#elif ARCH(AARCH64) +# include +#else +# error "Unknown architecture" +#endif diff --git a/Kernel/Arch/aarch64/ThreadRegisters.h b/Kernel/Arch/aarch64/ThreadRegisters.h new file mode 100644 index 00000000000..540b5886934 --- /dev/null +++ b/Kernel/Arch/aarch64/ThreadRegisters.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Timon Kruiper + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Kernel { + +struct ThreadRegisters { + u64 x[31]; + u64 elr_el1; + u64 sp_el0; + + FlatPtr ip() const { return elr_el1; } + void set_ip(FlatPtr value) { elr_el1 = value; } + + void set_sp(FlatPtr value) { sp_el0 = value; } + + void set_initial_state(bool, Memory::AddressSpace&, FlatPtr kernel_stack_top) + { + set_sp(kernel_stack_top); + } +}; + +} diff --git a/Kernel/Arch/x86_64/ThreadRegisters.h b/Kernel/Arch/x86_64/ThreadRegisters.h new file mode 100644 index 00000000000..921b2eb6107 --- /dev/null +++ b/Kernel/Arch/x86_64/ThreadRegisters.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021, Gunnar Beutner + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Kernel { + +struct ThreadRegisters { + FlatPtr rdi; + FlatPtr rsi; + FlatPtr rbp; + FlatPtr rsp; + FlatPtr rbx; + FlatPtr rdx; + FlatPtr rcx; + FlatPtr rax; + FlatPtr r8; + FlatPtr r9; + FlatPtr r10; + FlatPtr r11; + FlatPtr r12; + FlatPtr r13; + FlatPtr r14; + FlatPtr r15; + FlatPtr rip; + FlatPtr rsp0; + FlatPtr cs; + + 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; } + + FlatPtr cr3; + + FlatPtr ip() const + { + return rip; + } + + FlatPtr sp() const + { + return rsp; + } + + void set_initial_state(bool is_kernel_process, Memory::AddressSpace& space, FlatPtr kernel_stack_top) + { + // Only IF is set when a process boots. + set_flags(0x0202); + + if (is_kernel_process) + cs = GDT_SELECTOR_CODE0; + else + cs = GDT_SELECTOR_CODE3 | 3; + + cr3 = space.page_directory().cr3(); + + if (is_kernel_process) { + set_sp(kernel_stack_top); + set_sp0(kernel_stack_top); + } else { + // Ring 3 processes get a separate stack for ring 0. + // The ring 3 stack will be assigned by exec(). + set_sp0(kernel_stack_top); + } + } +}; + +} diff --git a/Kernel/Syscalls/thread.cpp b/Kernel/Syscalls/thread.cpp index 27f06924dae..e3da9f0a990 100644 --- a/Kernel/Syscalls/thread.cpp +++ b/Kernel/Syscalls/thread.cpp @@ -55,15 +55,17 @@ ErrorOr Process::sys$create_thread(void* (*entry)(void*), Userspaceregs(); regs.set_ip((FlatPtr)entry); - regs.set_flags(0x0202); regs.set_sp(user_sp.value()); + #if ARCH(X86_64) + regs.set_flags(0x0202); + regs.cr3 = address_space().with([](auto& space) { return space->page_directory().cr3(); }); + regs.rdi = params.rdi; regs.rsi = params.rsi; regs.rdx = params.rdx; regs.rcx = params.rcx; #endif - regs.cr3 = address_space().with([](auto& space) { return space->page_directory().cr3(); }); TRY(thread->make_thread_specific_region({})); diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index 2a1ee800023..a9f2b794811 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -77,33 +77,12 @@ Thread::Thread(NonnullLockRefPtr process, NonnullOwnPtr reset_fpu_state(); - // Only IF is set when a process boots. - m_regs.set_flags(0x0202); - -#if ARCH(X86_64) - if (m_process->is_kernel_process()) - m_regs.cs = GDT_SELECTOR_CODE0; - else - m_regs.cs = GDT_SELECTOR_CODE3 | 3; -#elif ARCH(AARCH64) - TODO_AARCH64(); -#else -# error Unknown architecture -#endif - - m_regs.cr3 = m_process->address_space().with([](auto& space) { return space->page_directory().cr3(); }); - m_kernel_stack_base = m_kernel_stack_region->vaddr().get(); m_kernel_stack_top = m_kernel_stack_region->vaddr().offset(default_kernel_stack_size).get() & ~(FlatPtr)0x7u; - if (m_process->is_kernel_process()) { - 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(). - m_regs.set_sp0(m_kernel_stack_top); - } + m_process->address_space().with([&](auto& space) { + m_regs.set_initial_state(m_process->is_kernel_process(), *space, m_kernel_stack_top); + }); // We need to add another reference if we could successfully create // all the resources needed for this thread. The reason for this is that diff --git a/Kernel/Thread.h b/Kernel/Thread.h index e5af91b0c93..ab4f59fa0c3 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -49,55 +50,6 @@ struct ThreadSpecificData { #define THREAD_AFFINITY_DEFAULT 0xffffffff -struct ThreadRegisters { -#if ARCH(X86_64) - FlatPtr rdi; - FlatPtr rsi; - FlatPtr rbp; - FlatPtr rsp; - FlatPtr rbx; - FlatPtr rdx; - FlatPtr rcx; - FlatPtr rax; - FlatPtr r8; - FlatPtr r9; - FlatPtr r10; - FlatPtr r11; - FlatPtr r12; - FlatPtr r13; - FlatPtr r14; - FlatPtr r15; - FlatPtr rip; - FlatPtr rsp0; -#endif - FlatPtr cs; - -#if ARCH(X86_64) - 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 - { -#if ARCH(X86_64) - return rip; -#endif - } - - FlatPtr sp() const - { -#if ARCH(X86_64) - return rsp; -#endif - } -}; - class Thread : public ListedRefCounted , public LockWeakable {