A few cleanups to the FPU code on amd64:

- fpudna() always returned 1 since amd64 CPUs always have FPUs.  Change
  the function to return void and adjust the calling code in trap() to
  assume the return 1 case is the only case.
- Remove fpu_cleanstate_ready as it is always true when it is tested.
  Also, only initialize fpu_cleanstate when fpuinit() is called on the BSP.

Reviewed by:	bde
This commit is contained in:
John Baldwin 2009-03-05 16:56:16 +00:00
parent 9edc34f864
commit a8346a9865
3 changed files with 22 additions and 33 deletions

View File

@ -102,10 +102,11 @@ SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
NULL, 1, "Floating point instructions executed in hardware"); NULL, 1, "Floating point instructions executed in hardware");
static struct savefpu fpu_cleanstate; static struct savefpu fpu_cleanstate;
static bool_t fpu_cleanstate_ready;
/* /*
* Initialize floating point unit. * Initialize the floating point unit. On the boot CPU we generate a
* clean state that is used to initialize the floating point unit when
* it is first used by a process.
*/ */
void void
fpuinit(void) fpuinit(void)
@ -115,22 +116,22 @@ fpuinit(void)
u_short control; u_short control;
savecrit = intr_disable(); savecrit = intr_disable();
PCPU_SET(fpcurthread, 0);
stop_emulating(); stop_emulating();
fninit(); fninit();
control = __INITIAL_FPUCW__; control = __INITIAL_FPUCW__;
fldcw(&control); fldcw(&control);
mxcsr = __INITIAL_MXCSR__; mxcsr = __INITIAL_MXCSR__;
ldmxcsr(mxcsr); ldmxcsr(mxcsr);
fxsave(&fpu_cleanstate); if (PCPU_GET(cpuid) == 0) {
if (fpu_cleanstate.sv_env.en_mxcsr_mask) fxsave(&fpu_cleanstate);
cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask; if (fpu_cleanstate.sv_env.en_mxcsr_mask)
else cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask;
cpu_mxcsr_mask = 0xFFBF; 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));
}
start_emulating(); start_emulating();
bzero(fpu_cleanstate.sv_fp, sizeof(fpu_cleanstate.sv_fp));
bzero(fpu_cleanstate.sv_xmm, sizeof(fpu_cleanstate.sv_xmm));
fpu_cleanstate_ready = 1;
intr_restore(savecrit); intr_restore(savecrit);
} }
@ -384,8 +385,8 @@ fputrap()
static int err_count = 0; static int err_count = 0;
int void
fpudna() fpudna(void)
{ {
struct pcb *pcb; struct pcb *pcb;
register_t s; register_t s;
@ -395,7 +396,7 @@ fpudna()
printf("fpudna: fpcurthread == curthread %d times\n", printf("fpudna: fpcurthread == curthread %d times\n",
++err_count); ++err_count);
stop_emulating(); stop_emulating();
return (1); return;
} }
if (PCPU_GET(fpcurthread) != NULL) { if (PCPU_GET(fpcurthread) != NULL) {
printf("fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n", printf("fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
@ -428,8 +429,6 @@ fpudna()
} else } else
fxrstor(&pcb->pcb_save); fxrstor(&pcb->pcb_save);
intr_restore(s); intr_restore(s);
return (1);
} }
/* /*
@ -457,10 +456,7 @@ fpugetregs(struct thread *td, struct savefpu *addr)
register_t s; register_t s;
if ((td->td_pcb->pcb_flags & PCB_FPUINITDONE) == 0) { if ((td->td_pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
if (fpu_cleanstate_ready) bcopy(&fpu_cleanstate, addr, sizeof(fpu_cleanstate));
bcopy(&fpu_cleanstate, addr, sizeof(fpu_cleanstate));
else
bzero(addr, sizeof(*addr));
return (_MC_FPOWNED_NONE); return (_MC_FPOWNED_NONE);
} }
s = intr_disable(); s = intr_disable();

View File

@ -416,13 +416,8 @@ trap(struct trapframe *frame)
case T_DNA: case T_DNA:
/* transparent fault (due to context switch "late") */ /* transparent fault (due to context switch "late") */
if (fpudna()) fpudna();
goto userout; goto userout;
printf("pid %d killed due to lack of floating point\n",
p->p_pid);
i = SIGKILL;
ucode = 0;
break;
case T_FPOPFLT: /* FPU operand fetch fault */ case T_FPOPFLT: /* FPU operand fetch fault */
ucode = ILL_COPROC; ucode = ILL_COPROC;
@ -450,11 +445,9 @@ trap(struct trapframe *frame)
* XXX this should be fatal unless the kernel has * XXX this should be fatal unless the kernel has
* registered such use. * registered such use.
*/ */
if (fpudna()) { fpudna();
printf("fpudna in kernel mode!\n"); printf("fpudna in kernel mode!\n");
goto out; goto out;
}
break;
case T_STKFLT: /* stack fault */ case T_STKFLT: /* stack fault */
break; break;

View File

@ -97,7 +97,7 @@ struct savefpu {
#define __INITIAL_MXCSR_MASK__ 0xFFBF #define __INITIAL_MXCSR_MASK__ 0xFFBF
#ifdef _KERNEL #ifdef _KERNEL
int fpudna(void); void fpudna(void);
void fpudrop(void); void fpudrop(void);
void fpuexit(struct thread *td); void fpuexit(struct thread *td);
int fpuformat(void); int fpuformat(void);