From df9e73de25637c88413b045bf21cd0fec7f72a68 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 29 Jun 2021 02:56:07 +0200 Subject: Kernel: Add x86_64 support for fork() --- Kernel/Arch/x86/common/Processor.cpp | 17 +++++++++++++++++ Kernel/Arch/x86/i386/Processor.cpp | 16 ---------------- Kernel/Arch/x86/x86_64/Processor.cpp | 19 ++----------------- 3 files changed, 19 insertions(+), 33 deletions(-) (limited to 'Kernel/Arch') diff --git a/Kernel/Arch/x86/common/Processor.cpp b/Kernel/Arch/x86/common/Processor.cpp index cbff6fcdb7..60947f8734 100644 --- a/Kernel/Arch/x86/common/Processor.cpp +++ b/Kernel/Arch/x86/common/Processor.cpp @@ -39,6 +39,7 @@ Atomic Processor::s_idle_cpu_mask { 0 }; extern "C" void thread_context_first_enter(void); extern "C" void exit_kernel_thread(void); +extern "C" void do_assume_context(Thread* thread, u32 flags); // The compiler can't see the calls to these functions inside assembly. // Declare them, to avoid dead code warnings. @@ -1233,4 +1234,20 @@ extern "C" FlatPtr do_init_context(Thread* thread, u32 flags) #endif return Processor::current().init_context(*thread, true); } + +void Processor::assume_context(Thread& thread, FlatPtr flags) +{ + dbgln_if(CONTEXT_SWITCH_DEBUG, "Assume context for thread {} {}", VirtualAddress(&thread), thread); + + VERIFY_INTERRUPTS_DISABLED(); + Scheduler::prepare_after_exec(); + // in_critical() should be 2 here. The critical section in Process::exec + // and then the scheduler lock + VERIFY(Processor::current().in_critical() == 2); + + do_assume_context(&thread, flags); + + VERIFY_NOT_REACHED(); +} + } diff --git a/Kernel/Arch/x86/i386/Processor.cpp b/Kernel/Arch/x86/i386/Processor.cpp index af5d14d93d..801d928bd2 100644 --- a/Kernel/Arch/x86/i386/Processor.cpp +++ b/Kernel/Arch/x86/i386/Processor.cpp @@ -17,7 +17,6 @@ namespace Kernel { #define ENTER_THREAD_CONTEXT_ARGS_SIZE (2 * 4) // to_thread, from_thread extern "C" void thread_context_first_enter(void); -extern "C" void do_assume_context(Thread* thread, u32 flags); extern "C" void exit_kernel_thread(void); // clang-format off @@ -236,21 +235,6 @@ void Processor::switch_context(Thread*& from_thread, Thread*& to_thread) Processor::current().restore_in_critical(to_thread->saved_critical()); } -void Processor::assume_context(Thread& thread, FlatPtr flags) -{ - dbgln_if(CONTEXT_SWITCH_DEBUG, "Assume context for thread {} {}", VirtualAddress(&thread), thread); - - VERIFY_INTERRUPTS_DISABLED(); - Scheduler::prepare_after_exec(); - // in_critical() should be 2 here. The critical section in Process::exec - // and then the scheduler lock - VERIFY(Processor::current().in_critical() == 2); - - do_assume_context(&thread, flags); - - VERIFY_NOT_REACHED(); -} - UNMAP_AFTER_INIT void Processor::initialize_context_switching(Thread& initial_thread) { VERIFY(initial_thread.process().is_kernel_process()); diff --git a/Kernel/Arch/x86/x86_64/Processor.cpp b/Kernel/Arch/x86/x86_64/Processor.cpp index ccf46873b3..acb409b8b8 100644 --- a/Kernel/Arch/x86/x86_64/Processor.cpp +++ b/Kernel/Arch/x86/x86_64/Processor.cpp @@ -16,7 +16,6 @@ namespace Kernel { extern "C" void thread_context_first_enter(void); -extern "C" void do_assume_context(Thread* thread, u32 flags); extern "C" void exit_kernel_thread(void); // clang-format off @@ -50,6 +49,8 @@ asm( " movq %rax, %rsp \n" // move stack pointer to what Processor::init_context set up for us " movq %r12, %rdi \n" // to_thread " movq %r12, %rsi \n" // from_thread +" pushq %r12 \n" // to_thread (for thread_context_first_enter) +" pushq %r12 \n" // from_thread (for thread_context_first_enter) " movabs $thread_context_first_enter, %r12 \n" // should be same as regs.rip " pushq %r12 \n" " jmp enter_thread_context \n" @@ -238,22 +239,6 @@ void Processor::switch_context(Thread*& from_thread, Thread*& to_thread) Processor::current().restore_in_critical(to_thread->saved_critical()); } -void Processor::assume_context(Thread& thread, FlatPtr flags) -{ - dbgln_if(CONTEXT_SWITCH_DEBUG, "Assume context for thread {} {}", VirtualAddress(&thread), thread); - - VERIFY_INTERRUPTS_DISABLED(); - Scheduler::prepare_after_exec(); - // in_critical() should be 2 here. The critical section in Process::exec - // and then the scheduler lock - VERIFY(Processor::current().in_critical() == 2); - - (void)flags; - TODO(); - - VERIFY_NOT_REACHED(); -} - UNMAP_AFTER_INIT void Processor::initialize_context_switching(Thread& initial_thread) { VERIFY(initial_thread.process().is_kernel_process()); -- cgit v1.2.3