Implemented TLS for x86_64.

This commit is contained in:
Alex Smith
2012-07-29 11:39:01 +01:00
parent 6e2f6d1ace
commit 03add8e7c2
6 changed files with 55 additions and 50 deletions
@@ -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
-23
View File
@@ -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)
{
+2 -14
View File
@@ -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)
{
+6 -2
View File
@@ -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);
}
+22 -11
View File
@@ -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));
}