added 1 changeset to branch 'refs/remotes/xyzzy-github/x86_64' old head: 6e2f6d1ace7490a200dcff70c52acf2af59c5bc3 new head: 03add8e7c216a9ba83a2c565cb82962d6cdc53c4 ---------------------------------------------------------------------------- 03add8e: Implemented TLS for x86_64. [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- Commit: 03add8e7c216a9ba83a2c565cb82962d6cdc53c4 Author: Alex Smith <alex@xxxxxxxxxxxxxxxx> Date: Sun Jul 29 10:39:01 2012 UTC ---------------------------------------------------------------------------- 6 files changed, 55 insertions(+), 50 deletions(-) src/system/boot/platform/bios_ia32/long_asm.S | 1 + src/system/kernel/arch/x86/32/thread.cpp | 23 -------------- src/system/kernel/arch/x86/64/thread.cpp | 16 ++-------- src/system/kernel/arch/x86/arch_thread.cpp | 24 +++++++++++++++ src/system/libroot/os/arch/x86_64/thread.cpp | 8 +++-- src/system/libroot/os/arch/x86_64/tls.cpp | 33 ++++++++++++++------- ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/bios_ia32/long_asm.S b/src/system/boot/platform/bios_ia32/long_asm.S index 8c07f39..72b30c2 100644 --- a/src/system/boot/platform/bios_ia32/long_asm.S +++ b/src/system/boot/platform/bios_ia32/long_asm.S @@ -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 diff --git a/src/system/kernel/arch/x86/32/thread.cpp b/src/system/kernel/arch/x86/32/thread.cpp index 4df1685..71b484c 100644 --- a/src/system/kernel/arch/x86/32/thread.cpp +++ b/src/system/kernel/arch/x86/32/thread.cpp @@ -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) { diff --git a/src/system/kernel/arch/x86/64/thread.cpp b/src/system/kernel/arch/x86/64/thread.cpp index 1d0434f..51f4676 100644 --- a/src/system/kernel/arch/x86/64/thread.cpp +++ b/src/system/kernel/arch/x86/64/thread.cpp @@ -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) { diff --git a/src/system/kernel/arch/x86/arch_thread.cpp b/src/system/kernel/arch/x86/arch_thread.cpp index 401f9d4..8b17b1d 100644 --- a/src/system/kernel/arch/x86/arch_thread.cpp +++ b/src/system/kernel/arch/x86/arch_thread.cpp @@ -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) { diff --git a/src/system/libroot/os/arch/x86_64/thread.cpp b/src/system/libroot/os/arch/x86_64/thread.cpp index 7b12f02..10614ba 100644 --- a/src/system/libroot/os/arch/x86_64/thread.cpp +++ b/src/system/libroot/os/arch/x86_64/thread.cpp @@ -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); } diff --git a/src/system/libroot/os/arch/x86_64/tls.cpp b/src/system/libroot/os/arch/x86_64/tls.cpp index c45b7f7..733dc7b 100644 --- a/src/system/libroot/os/arch/x86_64/tls.cpp +++ b/src/system/libroot/os/arch/x86_64/tls.cpp @@ -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)); }