kernel/x86_64: Reset FPU state in x86_64_thread_entry.
Otherwise it won't be reset at all and we will begin with the previous thread's FPU state, both for userland and kernel threads. Also clear the FPU state in x86_return_to_userland, just like in syscall exit. Change-Id: Ie46d0e64a680c860c7fbff8dc57116625724eadd Reviewed-on: https://review.haiku-os.org/c/haiku/+/9092 Tested-by: Commit checker robot <[email protected]> Haiku-Format: Haiku-format Bot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
317307ff46
commit
ea0c6448f2
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
#include <asm_defs.h>
|
#include <asm_defs.h>
|
||||||
|
|
||||||
|
#include <arch/x86/arch_altcodepatch.h>
|
||||||
|
|
||||||
#include "asm_offsets.h"
|
#include "asm_offsets.h"
|
||||||
#include "syscall_numbers.h"
|
#include "syscall_numbers.h"
|
||||||
|
|
||||||
@@ -29,6 +31,17 @@ FUNCTION_END(x86_get_stack_frame)
|
|||||||
|
|
||||||
/* void x86_64_thread_entry(); */
|
/* void x86_64_thread_entry(); */
|
||||||
FUNCTION(x86_64_thread_entry):
|
FUNCTION(x86_64_thread_entry):
|
||||||
|
// Get thread pointer.
|
||||||
|
pop %r12
|
||||||
|
|
||||||
|
// Reset FPU state.
|
||||||
|
movl (gXsaveMask), %eax
|
||||||
|
movl (gXsaveMask+4), %edx
|
||||||
|
leaq THREAD_user_fpu_state(%r12), %rdi
|
||||||
|
CODEPATCH_START
|
||||||
|
fxrstorq (%rdi)
|
||||||
|
CODEPATCH_END(ALTCODEPATCH_TAG_XRSTOR)
|
||||||
|
|
||||||
xorq %rbp, %rbp
|
xorq %rbp, %rbp
|
||||||
|
|
||||||
movq %rsp, %rax
|
movq %rsp, %rax
|
||||||
|
|||||||
@@ -626,9 +626,10 @@ FUNCTION(x86_return_to_userland):
|
|||||||
, THREAD_flags(%r12)
|
, THREAD_flags(%r12)
|
||||||
jnz .Luserland_return_work
|
jnz .Luserland_return_work
|
||||||
|
|
||||||
// update the thread's kernel time and return
|
|
||||||
UPDATE_THREAD_KERNEL_TIME()
|
UPDATE_THREAD_KERNEL_TIME()
|
||||||
|
|
||||||
|
CLEAR_FPU_STATE()
|
||||||
|
|
||||||
// Restore the frame and return.
|
// Restore the frame and return.
|
||||||
RESTORE_IFRAME()
|
RESTORE_IFRAME()
|
||||||
swapgs
|
swapgs
|
||||||
@@ -651,10 +652,10 @@ FUNCTION(x86_return_to_userland):
|
|||||||
movq %rbp, %rdi
|
movq %rbp, %rdi
|
||||||
call x86_init_user_debug_at_kernel_exit
|
call x86_init_user_debug_at_kernel_exit
|
||||||
1:
|
1:
|
||||||
// Restore the saved registers.
|
CLEAR_FPU_STATE()
|
||||||
RESTORE_IFRAME()
|
|
||||||
|
|
||||||
// Restore the previous GS base and return.
|
// Restore the frame and return.
|
||||||
|
RESTORE_IFRAME()
|
||||||
swapgs
|
swapgs
|
||||||
iretq
|
iretq
|
||||||
.Luserland_return_handle_signals:
|
.Luserland_return_handle_signals:
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop,
|
|||||||
|
|
||||||
*--stackTop = uintptr_t(data);
|
*--stackTop = uintptr_t(data);
|
||||||
*--stackTop = uintptr_t(function);
|
*--stackTop = uintptr_t(function);
|
||||||
|
*--stackTop = uintptr_t(thread);
|
||||||
|
|
||||||
// Save the stack position.
|
// Save the stack position.
|
||||||
thread->arch_info.current_stack = stackTop;
|
thread->arch_info.current_stack = stackTop;
|
||||||
|
|||||||
Reference in New Issue
Block a user