From 883858e60b1d12c73e6e26190babc3bd4b486078 Mon Sep 17 00:00:00 2001 From: David Karoly Date: Thu, 24 Feb 2022 20:58:19 +0100 Subject: [PATCH] implement TLS for arm Use the User Read-only Thread ID Register aka TPIDRURO to store TLS pointer. The User Read-only Thread ID Register is read-only in User mode, and read/write in privileged modes. see: ARMv7 Architecture Reference Manual, section B3.12.46 CP15 c13 Software Thread ID registers Change-Id: I7bff2fd66f41d7bf1a8a247151bcd02b32733c1b Reviewed-on: https://review.haiku-os.org/c/haiku/+/4994 Tested-by: Commit checker robot Reviewed-by: Fredrik Holmqvist --- src/system/kernel/arch/arm/arch_thread.cpp | 13 +++++- src/system/libroot/os/arch/arm/tls.c | 51 +++++++++++++++------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/system/kernel/arch/arm/arch_thread.cpp b/src/system/kernel/arch/arm/arch_thread.cpp index e364e5e6a4..4670fc1434 100644 --- a/src/system/kernel/arch/arm/arch_thread.cpp +++ b/src/system/kernel/arch/arm/arch_thread.cpp @@ -118,7 +118,7 @@ arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop, status_t arch_thread_init_tls(Thread *thread) { - uint32 tls[TLS_USER_THREAD_SLOT + 1]; + uint32 tls[TLS_FIRST_FREE_SLOT]; thread->user_local_storage = thread->user_stack_base + thread->user_stack_size; @@ -149,9 +149,20 @@ arm_swap_pgdir(uint32_t pageDirectoryAddress) } +void +arm_set_tls_context(Thread *thread) +{ + // Set TPIDRURO to point to TLS base + asm volatile("MCR p15, 0, %0, c13, c0, 3" + : : "r" (thread->user_local_storage)); +} + + void arch_thread_context_switch(Thread *from, Thread *to) { + arm_set_tls_context(to); + VMAddressSpace *oldAddressSpace = from->team->address_space; VMTranslationMap *oldTranslationMap = oldAddressSpace->TranslationMap(); phys_addr_t oldPageDirectoryAddress = diff --git a/src/system/libroot/os/arch/arm/tls.c b/src/system/libroot/os/arch/arm/tls.c index 79c0a5a632..1286a28b61 100644 --- a/src/system/libroot/os/arch/arm/tls.c +++ b/src/system/libroot/os/arch/arm/tls.c @@ -1,23 +1,37 @@ -/* -** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the MIT License. -*/ +/* + * Copyright 2019-2022, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ -// ToDo: this is a dummy implementation - I've not yet gained enough knowledge -// to decide how this should be done, so it's just broken now (okay for single -// threaded apps, though). - -// we don't want to have the inline assembly included here #ifndef _NO_INLINE_ASM # define _NO_INLINE_ASM 1 #endif -#include "support/TLS.h" -#include "tls.h" +#include + +#include +#include + + +struct tls_index { + unsigned long ti_module; + unsigned long ti_offset; +}; static int32 gNextSlot = TLS_FIRST_FREE_SLOT; -static void *gSlots[TLS_MAX_KEYS]; + + +static inline void** +get_tls() +{ + void **tls; + asm volatile("MRC p15, 0, %0, c13, c0, 3" : "=r" (tls)); + return tls; +} int32 @@ -34,20 +48,27 @@ tls_allocate(void) void * tls_get(int32 index) { - return gSlots[index]; + return get_tls()[index]; } void ** tls_address(int32 index) { - return &gSlots[index]; + return get_tls() + index; } void tls_set(int32 index, void *value) { - gSlots[index] = value; + get_tls()[index] = value; +} + + +void * +__tls_get_addr(struct tls_index *ti) +{ + return __gRuntimeLoader->get_tls_address(ti->ti_module, ti->ti_offset); }