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 <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
345265c3d6
commit
c7360f4b02
@@ -9,6 +9,10 @@
|
|||||||
#include <arch_thread_types.h>
|
#include <arch_thread_types.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern uint16 gFPUControlDefault;
|
||||||
|
extern uint32 gFPUMXCSRDefault;
|
||||||
|
|
||||||
|
|
||||||
static inline uint64_t
|
static inline uint64_t
|
||||||
x86_read_msr(uint32_t msr)
|
x86_read_msr(uint32_t msr)
|
||||||
{
|
{
|
||||||
@@ -28,10 +32,6 @@ x86_write_msr(uint32_t msr, uint64_t value)
|
|||||||
static inline void
|
static inline void
|
||||||
x86_context_switch(arch_thread* oldState, arch_thread* newState)
|
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(
|
asm volatile(
|
||||||
"pushq %%rbp;"
|
"pushq %%rbp;"
|
||||||
"movq $1f, %c[rip](%0);"
|
"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",
|
"r14", "r15", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5",
|
||||||
"xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13",
|
"xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13",
|
||||||
"xmm14", "xmm15", "memory");
|
"xmm14", "xmm15", "memory");
|
||||||
// so that x87 FPU floating-point instructions can be executed
|
asm volatile("ldmxcsr %0" : : "m" (gFPUMXCSRDefault));
|
||||||
asm volatile("emms");
|
asm volatile("fldcw %0" : : "m" (gFPUControlDefault));
|
||||||
asm volatile("ldmxcsr %0" : : "m" (sseControl));
|
|
||||||
asm volatile("fldcw %0" : : "m" (fpuControl));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ extern "C" void x86_64_thread_entry();
|
|||||||
|
|
||||||
// Initial thread saved state.
|
// Initial thread saved state.
|
||||||
static arch_thread sInitialState _ALIGNED(64);
|
static arch_thread sInitialState _ALIGNED(64);
|
||||||
|
uint16 gFPUControlDefault;
|
||||||
|
uint32 gFPUMXCSRDefault;
|
||||||
extern uint64 gFPUSaveLength;
|
extern uint64 gFPUSaveLength;
|
||||||
extern bool gHasXsave;
|
extern bool gHasXsave;
|
||||||
extern bool gHasXsavec;
|
extern bool gHasXsavec;
|
||||||
@@ -201,6 +203,8 @@ arch_thread_init(kernel_args* args)
|
|||||||
"fxsaveq %0"
|
"fxsaveq %0"
|
||||||
:: "m" (sInitialState.fpu_state));
|
:: "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);
|
register_generic_syscall(THREAD_SYSCALLS, arch_thread_control, 1, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -161,9 +161,6 @@ x86_unexpected_exception(iframe* frame)
|
|||||||
// TODO: Determine the correct cause via the FPU status
|
// TODO: Determine the correct cause via the FPU status
|
||||||
// register!
|
// register!
|
||||||
signalAddress = frame->ip;
|
signalAddress = frame->ip;
|
||||||
// clear any pending exceptions, otherwise loading a new control word
|
|
||||||
// could raise exceptions.
|
|
||||||
asm volatile("fnclex");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 17: // Alignment Check Exception (#AC)
|
case 17: // Alignment Check Exception (#AC)
|
||||||
|
|||||||
Reference in New Issue
Block a user