From c7360f4b02123700e1dbf54bda1e3c9956d53014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Mon, 13 Nov 2023 20:54:17 +0100 Subject: [PATCH] kernel/x86_64: on context switch, load defaults in fpu control and mxcsr after a0131eaae2884fdced27158c3d34732d1656aca9 mxcsr was possibly also incorrect. fpu control and mxcsr will be restored with fxrstor/xrstor. no need to clear pending exceptions on #MF fix #18656 (and #18624 after reverting). Change-Id: I7dd5e2e4610747c5b82abd6c67e302d264b4be92 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7104 Tested-by: Commit checker robot Reviewed-by: waddlesplash --- headers/private/kernel/arch/x86/64/cpu.h | 14 ++++++-------- src/system/kernel/arch/x86/64/thread.cpp | 4 ++++ src/system/kernel/arch/x86/arch_int.cpp | 3 --- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/headers/private/kernel/arch/x86/64/cpu.h b/headers/private/kernel/arch/x86/64/cpu.h index e6c15951c6..d69ebcae39 100644 --- a/headers/private/kernel/arch/x86/64/cpu.h +++ b/headers/private/kernel/arch/x86/64/cpu.h @@ -9,6 +9,10 @@ #include +extern uint16 gFPUControlDefault; +extern uint32 gFPUMXCSRDefault; + + static inline uint64_t x86_read_msr(uint32_t msr) { @@ -28,10 +32,6 @@ x86_write_msr(uint32_t msr, uint64_t value) static inline void x86_context_switch(arch_thread* oldState, arch_thread* newState) { - uint16_t fpuControl; - asm volatile("fnstcw %0" : "=m" (fpuControl)); - uint32_t sseControl; - asm volatile("stmxcsr %0" : "=m" (sseControl)); asm volatile( "pushq %%rbp;" "movq $1f, %c[rip](%0);" @@ -48,10 +48,8 @@ x86_context_switch(arch_thread* oldState, arch_thread* newState) "r14", "r15", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", "memory"); - // so that x87 FPU floating-point instructions can be executed - asm volatile("emms"); - asm volatile("ldmxcsr %0" : : "m" (sseControl)); - asm volatile("fldcw %0" : : "m" (fpuControl)); + asm volatile("ldmxcsr %0" : : "m" (gFPUMXCSRDefault)); + asm volatile("fldcw %0" : : "m" (gFPUControlDefault)); } diff --git a/src/system/kernel/arch/x86/64/thread.cpp b/src/system/kernel/arch/x86/64/thread.cpp index 7a35c88427..51f76d2717 100644 --- a/src/system/kernel/arch/x86/64/thread.cpp +++ b/src/system/kernel/arch/x86/64/thread.cpp @@ -71,6 +71,8 @@ extern "C" void x86_64_thread_entry(); // Initial thread saved state. static arch_thread sInitialState _ALIGNED(64); +uint16 gFPUControlDefault; +uint32 gFPUMXCSRDefault; extern uint64 gFPUSaveLength; extern bool gHasXsave; extern bool gHasXsavec; @@ -201,6 +203,8 @@ arch_thread_init(kernel_args* args) "fxsaveq %0" :: "m" (sInitialState.fpu_state)); } + gFPUControlDefault = ((savefpu*)&sInitialState.fpu_state)->fp_fxsave.control; + gFPUMXCSRDefault = ((savefpu*)&sInitialState.fpu_state)->fp_fxsave.mxcsr; register_generic_syscall(THREAD_SYSCALLS, arch_thread_control, 1, 0); diff --git a/src/system/kernel/arch/x86/arch_int.cpp b/src/system/kernel/arch/x86/arch_int.cpp index 05eff26306..9281a5e71a 100644 --- a/src/system/kernel/arch/x86/arch_int.cpp +++ b/src/system/kernel/arch/x86/arch_int.cpp @@ -161,9 +161,6 @@ x86_unexpected_exception(iframe* frame) // TODO: Determine the correct cause via the FPU status // register! signalAddress = frame->ip; - // clear any pending exceptions, otherwise loading a new control word - // could raise exceptions. - asm volatile("fnclex"); break; case 17: // Alignment Check Exception (#AC)