diff --git a/headers/private/kernel/arch/x86/32/descriptors.h b/headers/private/kernel/arch/x86/32/descriptors.h index 3bdc8c3310..5308ce0547 100644 --- a/headers/private/kernel/arch/x86/32/descriptors.h +++ b/headers/private/kernel/arch/x86/32/descriptors.h @@ -38,6 +38,8 @@ #define USER_CODE_SELECTOR ((USER_CODE_SEGMENT << 3) | DPL_USER) #define USER_DATA_SELECTOR ((USER_DATA_SEGMENT << 3) | DPL_USER) +#define KERNEL_TLS_SELECTOR ((KERNEL_TLS_SEGMENT << 3) | DPL_KERNEL) + #ifndef _ASSEMBLER // this file can also be included from assembler as well diff --git a/headers/private/kernel/arch/x86/arch_thread.h b/headers/private/kernel/arch/x86/arch_thread.h index 0769195543..b7e1493c15 100644 --- a/headers/private/kernel/arch/x86/arch_thread.h +++ b/headers/private/kernel/arch/x86/arch_thread.h @@ -30,9 +30,6 @@ void x86_restart_syscall(struct iframe* frame); void x86_set_tls_context(Thread* thread); -#ifdef __x86_64__ - - static inline Thread* arch_thread_get_current_thread(void) { @@ -42,6 +39,9 @@ arch_thread_get_current_thread(void) } +#ifdef __x86_64__ + + static inline void arch_thread_set_current_thread(Thread* t) { @@ -59,18 +59,10 @@ arch_thread_set_current_thread(Thread* t) void arch_syscall_64_bit_return_value(void); -static inline Thread* -arch_thread_get_current_thread(void) -{ - Thread* t = (Thread*)x86_read_dr3(); - return t; -} - - static inline void arch_thread_set_current_thread(Thread* t) { - x86_write_dr3(t); + asm volatile("mov %0, %%gs:0" : : "r" (t)); } @@ -82,3 +74,4 @@ arch_thread_set_current_thread(Thread* t) #endif #endif /* _KERNEL_ARCH_x86_THREAD_H */ + diff --git a/src/system/kernel/arch/x86/32/interrupts.S b/src/system/kernel/arch/x86/32/interrupts.S index 917ca79cf9..d42f66ed34 100644 --- a/src/system/kernel/arch/x86/32/interrupts.S +++ b/src/system/kernel/arch/x86/32/interrupts.S @@ -159,7 +159,7 @@ \ /* restore pointers and clear fault handler */ \ movl %edx, %esi; /* syscall info pointer */ \ - movl %dr3, %edi; /* thread pointer */ \ + movl %gs:0, %edi; /* thread pointer */ \ movl $0, THREAD_fault_handler(%edi) #if SYSCALL_TRACING @@ -509,6 +509,9 @@ FUNCTION_END(trap14_double_fault) STATIC_FUNCTION(int_bottom): PUSH_IFRAME_BOTTOM(IFRAME_TYPE_OTHER) + movl $KERNEL_TLS_SELECTOR, %edx + movw %dx, %gs + movl %esp, %ebp // frame pointer is the iframe // Set the RF (resume flag) in EFLAGS. This prevents an instruction @@ -524,7 +527,7 @@ STATIC_FUNCTION(int_bottom): // so that we have to do it in the instruction before, thus opening a // window for an interrupt while still being in the kernel, but having set // up everything for userland already. - movl %dr3, %edi // thread pointer + movl %gs:0, %edi // thread pointer cmpb $0, THREAD_in_kernel(%edi) je int_bottom_user @@ -546,7 +549,7 @@ STATIC_FUNCTION(int_bottom_user): movl %eax,%es // disable breakpoints, if installed - movl %dr3, %edi // thread pointer + movl %gs:0, %edi // thread pointer cli // disable interrupts STOP_USER_DEBUGGING() @@ -600,6 +603,9 @@ FUNCTION_END(trap99) STATIC_FUNCTION(handle_syscall): + movl $KERNEL_TLS_SELECTOR, %edx + movw %dx, %gs + // save %eax, the number of the syscall movl %eax, %esi @@ -610,7 +616,7 @@ STATIC_FUNCTION(handle_syscall): lea 4(%esp), %ebp // skipping the return address, the stack // frame pointer is the iframe - movl %dr3, %edi // thread pointer + movl %gs:0, %edi // thread pointer // disable breakpoints, if installed cli // disable interrupts @@ -745,7 +751,7 @@ FUNCTION_END(handle_syscall) STATIC_FUNCTION(bad_syscall_params): // clear the fault handler and exit normally - movl %dr3, %edi + movl %gs:0, %edi movl $0, THREAD_fault_handler(%edi) jmp kernel_exit_work FUNCTION_END(bad_syscall_params) @@ -756,7 +762,11 @@ FUNCTION_END(handle_syscall) */ FUNCTION(x86_sysenter): // get the thread - movl %dr3, %edx + push %gs + movl $KERNEL_TLS_SELECTOR, %edx + movw %dx, %gs + movl %gs:0, %edx + pop %gs // push the iframe pushl $USER_DATA_SELECTOR // user_ss @@ -816,7 +826,7 @@ FUNCTION(x86_return_to_userland): movl %ebp, %esp // check, if any kernel exit work has to be done - movl %dr3, %edi + movl %gs:0, %edi testl $(THREAD_FLAGS_DEBUGGER_INSTALLED | THREAD_FLAGS_SIGNALS_PENDING \ | THREAD_FLAGS_DEBUG_THREAD | THREAD_FLAGS_BREAKPOINTS_DEFINED) \ , THREAD_flags(%edi)