svn commit: r191793 - in stable/7/sys: . amd64/amd64 contrib/pf dev/ath/ath_hal dev/cxgb i386/isa

John Baldwin jhb at FreeBSD.org
Mon May 4 19:19:14 UTC 2009


Author: jhb
Date: Mon May  4 19:19:13 2009
New Revision: 191793
URL: http://svn.freebsd.org/changeset/base/191793

Log:
  MFC: More refinements to the x86 FPU support:
  - Rename (fpu|npx)_cleanstate to (fpu|npx)_initialstate to better reflect
    their purpose.
  - Fix a few nits in the earlier changes to prevent local information leakage
    in AMD FPUs.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/amd64/amd64/fpu.c
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/i386/isa/npx.c

Modified: stable/7/sys/amd64/amd64/fpu.c
==============================================================================
--- stable/7/sys/amd64/amd64/fpu.c	Mon May  4 19:06:05 2009	(r191792)
+++ stable/7/sys/amd64/amd64/fpu.c	Mon May  4 19:19:13 2009	(r191793)
@@ -101,7 +101,7 @@ static	void	fpu_clean_state(void);
 SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
     NULL, 1, "Floating point instructions executed in hardware");
 
-static	struct savefpu		fpu_cleanstate;
+static	struct savefpu		fpu_initialstate;
 
 /*
  * Initialize the floating point unit.  On the boot CPU we generate a
@@ -123,13 +123,13 @@ fpuinit(void)
 	mxcsr = __INITIAL_MXCSR__;
 	ldmxcsr(mxcsr);
 	if (PCPU_GET(cpuid) == 0) {
-		fxsave(&fpu_cleanstate);
-		if (fpu_cleanstate.sv_env.en_mxcsr_mask)
-			cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask;
+		fxsave(&fpu_initialstate);
+		if (fpu_initialstate.sv_env.en_mxcsr_mask)
+			cpu_mxcsr_mask = fpu_initialstate.sv_env.en_mxcsr_mask;
 		else
 			cpu_mxcsr_mask = 0xFFBF;
-		bzero(fpu_cleanstate.sv_fp, sizeof(fpu_cleanstate.sv_fp));
-		bzero(fpu_cleanstate.sv_xmm, sizeof(fpu_cleanstate.sv_xmm));
+		bzero(fpu_initialstate.sv_fp, sizeof(fpu_initialstate.sv_fp));
+		bzero(fpu_initialstate.sv_xmm, sizeof(fpu_initialstate.sv_xmm));
 	}
 	start_emulating();
 	intr_restore(savecrit);
@@ -416,10 +416,11 @@ fpudna(void)
 
 	if ((pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
 		/*
-		 * This is the first time this thread has used the FPU,
-		 * explicitly load sanitized registers.
+		 * This is the first time this thread has used the FPU or
+		 * the PCB doesn't contain a clean FPU state.  Explicitly
+		 * load an initial state.
 		 */
-		fxrstor(&fpu_cleanstate);
+		fxrstor(&fpu_initialstate);
 		if (pcb->pcb_initial_fpucw != __INITIAL_FPUCW__)
 			fldcw(&pcb->pcb_initial_fpucw);
 		pcb->pcb_flags |= PCB_FPUINITDONE;
@@ -453,7 +454,7 @@ fpugetregs(struct thread *td, struct sav
 	register_t s;
 
 	if ((td->td_pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
-		bcopy(&fpu_cleanstate, addr, sizeof(fpu_cleanstate));
+		bcopy(&fpu_initialstate, addr, sizeof(fpu_initialstate));
 		addr->sv_env.en_cw = td->td_pcb->pcb_initial_fpucw;
 		return (_MC_FPOWNED_NONE);
 	}
@@ -479,7 +480,6 @@ fpusetregs(struct thread *td, struct sav
 
 	s = intr_disable();
 	if (td == PCPU_GET(fpcurthread)) {
-		fpu_clean_state();
 		fxrstor(addr);
 		intr_restore(s);
 	} else {
@@ -498,10 +498,10 @@ fpusetregs(struct thread *td, struct sav
  * In order to avoid leaking this information across processes, we clean
  * these values by performing a dummy load before executing fxrstor().
  */
-static	double	dummy_variable = 0.0;
 static void
 fpu_clean_state(void)
 {
+	static float dummy_variable = 0.0;
 	u_short status;
 
 	/*

Modified: stable/7/sys/i386/isa/npx.c
==============================================================================
--- stable/7/sys/i386/isa/npx.c	Mon May  4 19:06:05 2009	(r191792)
+++ stable/7/sys/i386/isa/npx.c	Mon May  4 19:19:13 2009	(r191793)
@@ -172,7 +172,7 @@ SYSCTL_INT(_hw, HW_FLOATINGPT, floatingp
 static	volatile u_int		npx_intrs_while_probing;
 static	volatile u_int		npx_traps_while_probing;
 
-static	union savefpu		npx_cleanstate;
+static	union savefpu		npx_initialstate;
 static	bool_t			npx_ex16;
 static	bool_t			npx_exists;
 static	bool_t			npx_irq13;
@@ -414,24 +414,24 @@ npx_attach(dev)
 
 	s = intr_disable();
 	stop_emulating();
-	fpusave(&npx_cleanstate);
+	fpusave(&npx_initialstate);
 	start_emulating();
 #ifdef CPU_ENABLE_SSE
 	if (cpu_fxsr) {
-		if (npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask)
+		if (npx_initialstate.sv_xmm.sv_env.en_mxcsr_mask)
 			cpu_mxcsr_mask = 
-			    npx_cleanstate.sv_xmm.sv_env.en_mxcsr_mask;
+			    npx_initialstate.sv_xmm.sv_env.en_mxcsr_mask;
 		else
 			cpu_mxcsr_mask = 0xFFBF;
-		bzero(npx_cleanstate.sv_xmm.sv_fp,
-		    sizeof(npx_cleanstate.sv_xmm.sv_fp));
-		bzero(npx_cleanstate.sv_xmm.sv_xmm,
-		    sizeof(npx_cleanstate.sv_xmm.sv_xmm));
+		bzero(npx_initialstate.sv_xmm.sv_fp,
+		    sizeof(npx_initialstate.sv_xmm.sv_fp));
+		bzero(npx_initialstate.sv_xmm.sv_xmm,
+		    sizeof(npx_initialstate.sv_xmm.sv_xmm));
 		/* XXX might need even more zeroing. */
 	} else
 #endif
-		bzero(npx_cleanstate.sv_87.sv_ac,
-		    sizeof(npx_cleanstate.sv_87.sv_ac));
+		bzero(npx_initialstate.sv_87.sv_ac,
+		    sizeof(npx_initialstate.sv_87.sv_ac));
 	intr_restore(s);
 #ifdef I586_CPU_XXX
 	if (cpu_class == CPUCLASS_586 && npx_ex16 &&
@@ -785,13 +785,18 @@ npxdna(void)
 	PCPU_SET(fpcurthread, curthread);
 	pcb = PCPU_GET(curpcb);
 
+#ifdef CPU_ENABLE_SSE
+	if (cpu_fxsr)
+		fpu_clean_state();
+#endif
+
 	if ((pcb->pcb_flags & PCB_NPXINITDONE) == 0) {
 		/*
 		 * This is the first time this thread has used the FPU or
 		 * the PCB doesn't contain a clean FPU state.  Explicitly
-		 * load sanitized registers.
+		 * load an initial state.
 		 */
-		fpurstor(&npx_cleanstate);
+		fpurstor(&npx_initialstate);
 		if (pcb->pcb_initial_npxcw != __INITIAL_NPXCW__)
 			fldcw(&pcb->pcb_initial_npxcw);
 		pcb->pcb_flags |= PCB_NPXINITDONE;
@@ -891,7 +896,7 @@ npxgetregs(td, addr)
 		return (_MC_FPOWNED_NONE);
 
 	if ((td->td_pcb->pcb_flags & PCB_NPXINITDONE) == 0) {
-		bcopy(&npx_cleanstate, addr, sizeof(npx_cleanstate));
+		bcopy(&npx_initialstate, addr, sizeof(npx_initialstate));
 		SET_FPU_CW(addr, td->td_pcb->pcb_initial_npxcw);
 		return (_MC_FPOWNED_NONE);
 	}
@@ -967,10 +972,10 @@ fpusave(addr)
  * In order to avoid leaking this information across processes, we clean
  * these values by performing a dummy load before executing fxrstor().
  */
-static	double	dummy_variable = 0.0;
 static void
 fpu_clean_state(void)
 {
+	static float dummy_variable = 0.0;
 	u_short status;
 
 	/*
@@ -996,10 +1001,9 @@ fpurstor(addr)
 {
 
 #ifdef CPU_ENABLE_SSE
-	if (cpu_fxsr) {
-		fpu_clean_state();
+	if (cpu_fxsr)
 		fxrstor(addr);
-	} else
+	else
 #endif
 		frstor(addr);
 }


More information about the svn-src-all mailing list