From d205814da672985e26db40e9dc3962c6222834a0 Mon Sep 17 00:00:00 2001 From: Daniel Bertalan Date: Sat, 22 Apr 2023 16:29:17 +0200 Subject: [PATCH] Kernel+LibC: Implement `pthread_create` for AArch64 Instead of storing x86_64 register names in `SC_create_thread_params`, let the Kernel figure out how to pass the parameters to `pthread_create_helper`. --- Kernel/API/Syscall.h | 8 ++------ Kernel/Syscalls/thread.cpp | 19 +++++++++++++++---- Userland/Libraries/LibC/pthread.cpp | 15 +++------------ 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index 19b70741975..b2de4d18087 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -370,12 +370,8 @@ struct SC_create_thread_params { unsigned int reported_guard_page_size = 0; // The lie we tell callers unsigned int stack_size = 1 * MiB; // Equal to Thread::default_userspace_stack_size void* stack_location; // nullptr means any, o.w. process virtual address -# if ARCH(X86_64) - FlatPtr rdi; - FlatPtr rsi; - FlatPtr rcx; - FlatPtr rdx; -# endif + void* (*entry)(void*); + void* entry_argument; }; struct SC_realpath_params { diff --git a/Kernel/Syscalls/thread.cpp b/Kernel/Syscalls/thread.cpp index 8e5dfabb38b..1afc29dd787 100644 --- a/Kernel/Syscalls/thread.cpp +++ b/Kernel/Syscalls/thread.cpp @@ -63,10 +63,21 @@ ErrorOr Process::sys$create_thread(void* (*entry)(void*), Userspacepage_directory().cr3(); }); - regs.rdi = params.rdi; - regs.rsi = params.rsi; - regs.rdx = params.rdx; - regs.rcx = params.rcx; + // Set up the argument registers expected by pthread_create_helper. + regs.rdi = (FlatPtr)params.entry; + regs.rsi = (FlatPtr)params.entry_argument; + regs.rdx = (FlatPtr)params.stack_location; + regs.rcx = (FlatPtr)params.stack_size; +#elif ARCH(AARCH64) + regs.ttbr0_el1 = address_space().with([](auto& space) { return space->page_directory().ttbr0(); }); + + // Set up the argument registers expected by pthread_create_helper. + regs.x[0] = (FlatPtr)params.entry; + regs.x[1] = (FlatPtr)params.entry_argument; + regs.x[2] = (FlatPtr)params.stack_location; + regs.x[3] = (FlatPtr)params.stack_size; +#else +# error Unknown architecture #endif TRY(thread->make_thread_specific_region({})); diff --git a/Userland/Libraries/LibC/pthread.cpp b/Userland/Libraries/LibC/pthread.cpp index ab7c5e25f90..6dbce4a45f7 100644 --- a/Userland/Libraries/LibC/pthread.cpp +++ b/Userland/Libraries/LibC/pthread.cpp @@ -90,18 +90,9 @@ static int create_thread(pthread_t* thread, void* (*entry)(void*), void* argumen while (((uintptr_t)stack - 16) % 16 != 0) push_on_stack(nullptr); -#if ARCH(X86_64) - thread_params->rdi = (FlatPtr)entry; - thread_params->rsi = (FlatPtr)argument; - thread_params->rdx = (FlatPtr)thread_params->stack_location; - thread_params->rcx = thread_params->stack_size; -#elif ARCH(AARCH64) - (void)entry; - (void)argument; - TODO_AARCH64(); -#else -# error Unknown architecture -#endif + thread_params->entry = entry; + thread_params->entry_argument = argument; + VERIFY((uintptr_t)stack % 16 == 0); // Push a fake return address