Implemented TLS for x86_64.
This commit is contained in:
@@ -65,6 +65,7 @@ FUNCTION(long_enter_kernel):
|
||||
// Set data segments.
|
||||
mov $KERNEL_DATA_SEG, %ax
|
||||
mov %ax, %ss
|
||||
xor %ax, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
|
||||
@@ -172,29 +172,6 @@ arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop,
|
||||
}
|
||||
|
||||
|
||||
/*! Initializes the user-space TLS local storage pointer in
|
||||
the thread structure, and the reserved TLS slots.
|
||||
|
||||
Is called from _create_user_thread_kentry().
|
||||
*/
|
||||
status_t
|
||||
arch_thread_init_tls(Thread *thread)
|
||||
{
|
||||
uint32 tls[TLS_USER_THREAD_SLOT + 1];
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
arch_thread_dump_info(void *info)
|
||||
{
|
||||
|
||||
@@ -52,7 +52,8 @@ x86_restart_syscall(iframe* frame)
|
||||
void
|
||||
x86_set_tls_context(Thread* thread)
|
||||
{
|
||||
|
||||
// Set FS segment base address to the TLS segment.
|
||||
x86_write_msr(IA32_MSR_FS_BASE, thread->user_local_storage);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,19 +128,6 @@ arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop,
|
||||
}
|
||||
|
||||
|
||||
/*! Initializes the user-space TLS local storage pointer in
|
||||
the thread structure, and the reserved TLS slots.
|
||||
|
||||
Is called from _create_user_thread_kentry().
|
||||
*/
|
||||
status_t
|
||||
arch_thread_init_tls(Thread* thread)
|
||||
{
|
||||
dprintf("arch_thread_init_tls: TODO\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
arch_thread_dump_info(void* info)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <int.h>
|
||||
#include <team.h>
|
||||
#include <thread.h>
|
||||
#include <tls.h>
|
||||
#include <vm/vm_types.h>
|
||||
#include <vm/VMAddressSpace.h>
|
||||
|
||||
@@ -198,6 +199,29 @@ arch_team_init_team_struct(Team* p, bool kernel)
|
||||
}
|
||||
|
||||
|
||||
/*! Initializes the user-space TLS local storage pointer in
|
||||
the thread structure, and the reserved TLS slots.
|
||||
|
||||
Is called from _create_user_thread_kentry().
|
||||
*/
|
||||
status_t
|
||||
arch_thread_init_tls(Thread* thread)
|
||||
{
|
||||
size_t tls[TLS_USER_THREAD_SLOT + 1];
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
arch_thread_context_switch(Thread* from, Thread* to)
|
||||
{
|
||||
|
||||
@@ -11,8 +11,12 @@
|
||||
thread_id
|
||||
find_thread(const char* name)
|
||||
{
|
||||
// TODO x86_64: x86 is doing some TLS thing here. Should that be done here
|
||||
// too?
|
||||
if (!name) {
|
||||
thread_id thread;
|
||||
__asm__ __volatile__ ("movq %%fs:8, %%rax" : "=a" (thread));
|
||||
return thread;
|
||||
}
|
||||
|
||||
return _kern_find_thread(name);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
*/
|
||||
|
||||
|
||||
// TODO x86_64.
|
||||
// Also want to add inline versions to support/TLS.h.
|
||||
|
||||
|
||||
#ifndef _NO_INLINE_ASM
|
||||
# define _NO_INLINE_ASM 1
|
||||
#endif
|
||||
@@ -19,7 +15,6 @@
|
||||
|
||||
|
||||
static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
|
||||
static void* gSlots[TLS_MAX_KEYS];
|
||||
|
||||
|
||||
int32
|
||||
@@ -34,21 +29,37 @@ tls_allocate(void)
|
||||
|
||||
|
||||
void*
|
||||
tls_get(int32 index)
|
||||
tls_get(int32 _index)
|
||||
{
|
||||
return gSlots[index];
|
||||
int64 index = _index;
|
||||
void* ret;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"movq %%fs:(, %%rdi, 8), %%rax"
|
||||
: "=a" (ret) : "D" (index));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void**
|
||||
tls_address(int32 index)
|
||||
tls_address(int32 _index)
|
||||
{
|
||||
return &gSlots[index];
|
||||
int64 index = _index;
|
||||
void** ret;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"movq %%fs:0, %%rax\n\t"
|
||||
"leaq (%%rax, %%rdi, 8), %%rax\n\t"
|
||||
: "=a" (ret) : "D" (index));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tls_set(int32 index, void* value)
|
||||
tls_set(int32 _index, void* value)
|
||||
{
|
||||
gSlots[index] = value;
|
||||
int64 index = _index;
|
||||
__asm__ __volatile__ (
|
||||
"movq %%rsi, %%fs:(, %%rdi, 8)"
|
||||
: : "D" (index), "S" (value));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user