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. // Set data segments.
mov $KERNEL_DATA_SEG, %ax mov $KERNEL_DATA_SEG, %ax
mov %ax, %ss mov %ax, %ss
xor %ax, %ax
mov %ax, %ds mov %ax, %ds
mov %ax, %es mov %ax, %es
mov %ax, %fs 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 void
arch_thread_dump_info(void *info) arch_thread_dump_info(void *info)
{ {
+2 -14
View File
@@ -52,7 +52,8 @@ x86_restart_syscall(iframe* frame)
void void
x86_set_tls_context(Thread* thread) 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 void
arch_thread_dump_info(void* info) arch_thread_dump_info(void* info)
{ {
@@ -18,6 +18,7 @@
#include <int.h> #include <int.h>
#include <team.h> #include <team.h>
#include <thread.h> #include <thread.h>
#include <tls.h>
#include <vm/vm_types.h> #include <vm/vm_types.h>
#include <vm/VMAddressSpace.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 void
arch_thread_context_switch(Thread* from, Thread* to) arch_thread_context_switch(Thread* from, Thread* to)
{ {
+6 -2
View File
@@ -11,8 +11,12 @@
thread_id thread_id
find_thread(const char* name) find_thread(const char* name)
{ {
// TODO x86_64: x86 is doing some TLS thing here. Should that be done here if (!name) {
// too? thread_id thread;
__asm__ __volatile__ ("movq %%fs:8, %%rax" : "=a" (thread));
return thread;
}
return _kern_find_thread(name); 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 #ifndef _NO_INLINE_ASM
# define _NO_INLINE_ASM 1 # define _NO_INLINE_ASM 1
#endif #endif
@@ -19,7 +15,6 @@
static int32 gNextSlot = TLS_FIRST_FREE_SLOT; static int32 gNextSlot = TLS_FIRST_FREE_SLOT;
static void* gSlots[TLS_MAX_KEYS];
int32 int32
@@ -34,21 +29,37 @@ tls_allocate(void)
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** 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 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));
} }