79f0056002
* The vm86 code or the code running in virtual 8086 mode may clobber the %fs register that we use for the CPU dependent thread local storage (TLS). Previously the vm86 code would simply restore %fs on exit, but this doesn't always work. If the thread got unscheduled while running in virtual 8086 mode and was then rescheduled on a different CPU, the vm86 exit code would restore the %fs register with the TLS value of the old CPU, causing anything using TLS in userland to crash later on. Instead we skip the %fs register restore on exit (as do the other interrupt return functions) and explicitly update the potentially clobbered %fs by calling x86_set_tls_context(). This will repopulate the %fs register with the TLS value for the right CPU. Fixes #8068. * Made the static set_tls_context() into x86_set_tls_context() and made it available to others to faciliate the above. * Sync the vm86 specific interrupt code with the changes from hrev23370, using the iframe pop macro to properly return. Previously what was pushed in int_bottom wasn't poped on return. * Account for the time update macro resetting the in_kernel flag and reset it to 1, as we aren't actually returning to userland. This didn't cause any harm though as only the time tracking is using that flag so far. * Some minor cleanup.
55 lines
1.0 KiB
C
55 lines
1.0 KiB
C
/*
|
|
* Copyright 2002-2011, The Haiku Team. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Copyright 2002, Travis Geiselbrecht. All rights reserved.
|
|
* Distributed under the terms of the NewOS License.
|
|
*/
|
|
#ifndef _KERNEL_ARCH_x86_THREAD_H
|
|
#define _KERNEL_ARCH_x86_THREAD_H
|
|
|
|
|
|
#include <arch/cpu.h>
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct iframe *i386_get_user_iframe(void);
|
|
struct iframe *i386_get_current_iframe(void);
|
|
struct iframe *i386_get_thread_user_iframe(Thread *thread);
|
|
|
|
uint32 x86_next_page_directory(Thread *from, Thread *to);
|
|
|
|
void x86_restart_syscall(struct iframe *frame);
|
|
|
|
void x86_set_tls_context(Thread *thread);
|
|
|
|
// override empty macro
|
|
#undef arch_syscall_64_bit_return_value
|
|
void arch_syscall_64_bit_return_value(void);
|
|
|
|
|
|
static
|
|
inline Thread *
|
|
arch_thread_get_current_thread(void)
|
|
{
|
|
Thread *t;
|
|
read_dr3(t);
|
|
return t;
|
|
}
|
|
|
|
static inline void
|
|
arch_thread_set_current_thread(Thread *t)
|
|
{
|
|
write_dr3(t);
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _KERNEL_ARCH_x86_THREAD_H */
|
|
|