1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 12:27:35 +00:00

Kernel: Add x86_64 support for fork()

This commit is contained in:
Gunnar Beutner 2021-06-29 02:56:07 +02:00 committed by Andreas Kling
parent 811f9d562d
commit df9e73de25
4 changed files with 42 additions and 35 deletions

View file

@ -39,6 +39,7 @@ Atomic<u32> 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();
}
}

View file

@ -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());

View file

@ -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());