ladybird/Kernel/Arch/ProcessorFunctions.include
Sönke Holz 243d7003a2 Kernel+LibC+LibELF: Move TLS handling to userspace
This removes the allocate_tls syscall and adds an archctl option to set
the fs_base for the current thread on x86-64, since you can't set that
register from userspace. enter_thread_context loads the fs_base for the
next thread on each context switch.
This also moves tpidr_el0 (the thread pointer register on AArch64) to
the register state, so it gets properly saved/restored on context
switches.

The userspace TLS allocation code is kept pretty similar to the original
kernel TLS code, aside from a couple of style changes.

We also have to add a new argument "tls_pointer" to
SC_create_thread_params, as we otherwise can't prevent race conditions
between setting the thread pointer register and signal handling code
that might be triggered before the thread pointer was set, which could
use TLS.
2024-04-19 16:46:47 -06:00

35 lines
1.9 KiB
Text

/*
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <Kernel/Arch/Processor.h>
// This header instantiates all functions of ProcessorBase that are architecture-specific.
namespace Kernel {
template bool ProcessorBase<Processor>::is_smp_enabled();
template void ProcessorBase<Processor>::idle_begin() const;
template void ProcessorBase<Processor>::idle_end() const;
template void ProcessorBase<Processor>::smp_enable();
template void ProcessorBase<Processor>::flush_tlb_local(VirtualAddress vaddr, size_t page_count);
template void ProcessorBase<Processor>::flush_entire_tlb_local();
template void ProcessorBase<Processor>::flush_tlb(Memory::PageDirectory const*, VirtualAddress, size_t);
template void ProcessorBase<Processor>::early_initialize(u32 cpu);
template void ProcessorBase<Processor>::initialize(u32 cpu);
template void ProcessorBase<Processor>::halt();
template void ProcessorBase<Processor>::exit_trap(TrapFrame& trap);
template u32 ProcessorBase<Processor>::clear_critical();
template bool ProcessorBase<Processor>::are_interrupts_enabled();
template void ProcessorBase<Processor>::wait_for_interrupt() const;
template Processor& ProcessorBase<Processor>::by_id(u32 id);
template StringView ProcessorBase<Processor>::platform_string();
template void ProcessorBase<Processor>::initialize_context_switching(Thread& initial_thread);
template void ProcessorBase<Processor>::switch_context(Thread*& from_thread, Thread*& to_thread);
template void ProcessorBase<Processor>::assume_context(Thread& thread, InterruptsState new_interrupts_state);
template FlatPtr ProcessorBase<Processor>::init_context(Thread& thread, bool leave_crit);
template ErrorOr<Vector<FlatPtr, 32>> ProcessorBase<Processor>::capture_stack_trace(Thread& thread, size_t max_frames);
template u32 ProcessorBase<Processor>::smp_wake_n_idle_processors(u32 wake_count);
}