commit e17a181bfda5a1f72691fc696b826efdef8d2a60
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Sun Nov 29 21:46:55 2020 +0100

    x86: Get default state from the CPU itself
    
    It seems that at least qemu does not like our initial state. We can as
    well just take it from fninit.
    
    * i386/i386/fpu.c (MXCSR_DEFAULT, CWD_DEFAULT): Remove macros.
    (fpu_module_init): Get default state from CPU.
    (fpinit): Do not call fninit.

diff --git a/i386/i386/fpu.c b/i386/i386/fpu.c
index c5401fca..8a971b8e 100644
--- a/i386/i386/fpu.c
+++ b/i386/i386/fpu.c
@@ -77,17 +77,6 @@ struct i386_fpsave_state *fp_default_state;
 struct kmem_cache	ifps_cache;	/* cache for FPU save area */
 static unsigned long	mxcsr_feature_mask = 0xffffffff;	/* Always AND user-provided mxcsr with this security mask */
 
-/* Default FPU configuration */
-#define MXCSR_DEFAULT	0x1f80
-#define CWD_DEFAULT	(FPC_PC_64 |	/* 64bit precision */ \
-			 FPC_RC_RN |	/* round-to-nearest */ \
-			 FPC_ZE |	/* Suppress zero-divide */ \
-			 FPC_OE |	/*  and overflow */ \
-			 FPC_UE |	/*  underflow */ \
-			 FPC_IE |	/* Allow NaNQs and +-INF */ \
-			 FPC_DE |	/* Allow denorms as operands */ \
-			 FPC_PE)	/* No trap for precision loss */ \
-
 #if	NCPUS == 1
 volatile thread_t	fp_thread = THREAD_NULL;
 					/* thread whose state is in FPU */
@@ -265,6 +254,9 @@ fpu_module_init(void)
 	fp_default_state = (struct i386_fpsave_state *) kmem_cache_alloc(&ifps_cache);
 	memset(fp_default_state, 0, fp_xsave_size);
 
+	/* Get default state from CPU.  */
+	clear_ts();
+	fninit();
 	switch (fp_save_kind) {
 	    case FP_XSAVEC:
 	    case FP_XSAVES:
@@ -274,18 +266,13 @@ fpu_module_init(void)
 	    case FP_XSAVE:
 	    case FP_XSAVEOPT:
 	    case FP_FXSAVE:
-		fp_default_state->xfp_save_state.fp_control = CWD_DEFAULT;
-		fp_default_state->xfp_save_state.fp_status = 0;
-		fp_default_state->xfp_save_state.fp_tag = 0xffff;	/* all empty */
-		if (CPU_HAS_FEATURE(CPU_FEATURE_SSE))
-		    fp_default_state->xfp_save_state.fp_mxcsr = MXCSR_DEFAULT;
+		fxsave(&fp_default_state->xfp_save_state);
 		break;
 	    case FP_FNSAVE:
-		fp_default_state->fp_save_state.fp_control = CWD_DEFAULT;
-		fp_default_state->fp_save_state.fp_status = 0;
-		fp_default_state->fp_save_state.fp_tag = 0xffff;	/* all empty */
+		fnsave(&fp_default_state->fp_save_state);
 		break;
 	}
+	set_ts();
 
 	fp_default_state->fp_valid = TRUE;
 }
@@ -591,7 +578,6 @@ static void fpinit(thread_t thread)
 
 ASSERT_IPL(SPL0);
 	clear_ts();
-	fninit();
 	fpu_rstor(fp_default_state);
 
 	control = thread->pcb->init_control;
