implement TLS for arm64

Use the EL0 Read-Only Software Thread ID Register aka TPIDRRO_EL0
to store TLS pointer.

The EL0 Read-Only Software Thread ID Register is read-only in User mode
and read/write in privileged modes.

Change-Id: Idea7e3d66cd391dbbe3f9395cb37716089a49e13
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5673
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com>
Reviewed-by: David Karoly <karolyd577@gmail.com>
This commit is contained in:
David Karoly 2022-09-17 18:31:35 +02:00
parent 244a9826b8
commit 9a31a30528
3 changed files with 45 additions and 10 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019 Haiku, Inc. All Rights Reserved.
* Copyright 2019-2022 Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <thread.h>
@ -62,16 +62,34 @@ arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop,
status_t
arch_thread_init_tls(Thread *thread)
{
return 0;
uint32 tls[TLS_FIRST_FREE_SLOT];
thread->user_local_storage = thread->user_stack_base
+ thread->user_stack_size;
// initialize default TLS fields
memset(tls, 0, sizeof(tls));
tls[TLS_BASE_ADDRESS_SLOT] = thread->user_local_storage;
tls[TLS_THREAD_ID_SLOT] = thread->id;
tls[TLS_USER_THREAD_SLOT] = (addr_t)thread->user_thread;
return user_memcpy((void *)thread->user_local_storage, tls, sizeof(tls));
}
static void
arm64_set_tls_context(Thread *thread)
{
WRITE_SPECIALREG(tpidrro_el0, thread->user_local_storage);
}
extern "C" void _arch_context_swap(arch_thread *from, arch_thread *to);
void
arch_thread_context_switch(Thread *from, Thread *to)
{
arm64_set_tls_context(to);
_arch_context_swap(&from->arch_info, &to->arch_info);
}
@ -89,6 +107,8 @@ status_t
arch_thread_enter_userspace(Thread *thread, addr_t entry,
void *arg1, void *arg2)
{
arm64_set_tls_context(thread);
addr_t threadExitAddr;
{
addr_t commpageAdr = (addr_t)thread->team->commpage_address;

View File

@ -1,15 +1,19 @@
/*
* Copyright 2019 Haiku, Inc. All Rights Reserved.
* Copyright 2019-2022 Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <OS.h>
#include "syscalls.h"
#include <tls.h>
thread_id
find_thread(const char *name)
{
if (name == NULL)
return (thread_id)(addr_t)tls_get(TLS_THREAD_ID_SLOT);
return _kern_find_thread(name);
}

View File

@ -1,22 +1,33 @@
/*
* Copyright 2019 Haiku, Inc. All Rights Reserved.
* Copyright 2019-2022, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include <runtime_loader/runtime_loader.h>
#include "support/TLS.h"
#include "tls.h"
#include <support/TLS.h>
#include <tls.h>
struct tls_index {
unsigned long ti_module;
unsigned long ti_offset;
};
void* __tls_get_addr(struct tls_index* ti);
static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
void* __tls_get_addr(struct tls_index* ti);
static inline void**
get_tls()
{
void **tls;
asm volatile("MRS %0, tpidrro_el0" : "=r" (tls));
return tls;
}
int32
tls_allocate(void)
@ -32,21 +43,21 @@ tls_allocate(void)
void *
tls_get(int32 index)
{
return NULL;
return get_tls()[index];
}
void **
tls_address(int32 index)
{
return NULL;
return get_tls() + index;
}
void
tls_set(int32 index, void *value)
{
get_tls()[index] = value;
}