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:
parent
9edc34f864
commit
a8346a9865
@ -102,10 +102,11 @@ SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
|
||||
NULL, 1, "Floating point instructions executed in hardware");
|
||||
|
||||
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
|
||||
fpuinit(void)
|
||||
@ -115,22 +116,22 @@ fpuinit(void)
|
||||
u_short control;
|
||||
|
||||
savecrit = intr_disable();
|
||||
PCPU_SET(fpcurthread, 0);
|
||||
stop_emulating();
|
||||
fninit();
|
||||
control = __INITIAL_FPUCW__;
|
||||
fldcw(&control);
|
||||
mxcsr = __INITIAL_MXCSR__;
|
||||
ldmxcsr(mxcsr);
|
||||
fxsave(&fpu_cleanstate);
|
||||
if (fpu_cleanstate.sv_env.en_mxcsr_mask)
|
||||
cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask;
|
||||
else
|
||||
cpu_mxcsr_mask = 0xFFBF;
|
||||
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;
|
||||
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();
|
||||
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);
|
||||
}
|
||||
|
||||
@ -384,8 +385,8 @@ fputrap()
|
||||
|
||||
static int err_count = 0;
|
||||
|
||||
int
|
||||
fpudna()
|
||||
void
|
||||
fpudna(void)
|
||||
{
|
||||
struct pcb *pcb;
|
||||
register_t s;
|
||||
@ -395,7 +396,7 @@ fpudna()
|
||||
printf("fpudna: fpcurthread == curthread %d times\n",
|
||||
++err_count);
|
||||
stop_emulating();
|
||||
return (1);
|
||||
return;
|
||||
}
|
||||
if (PCPU_GET(fpcurthread) != NULL) {
|
||||
printf("fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
|
||||
@ -428,8 +429,6 @@ fpudna()
|
||||
} else
|
||||
fxrstor(&pcb->pcb_save);
|
||||
intr_restore(s);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -457,10 +456,7 @@ fpugetregs(struct thread *td, struct savefpu *addr)
|
||||
register_t s;
|
||||
|
||||
if ((td->td_pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
|
||||
if (fpu_cleanstate_ready)
|
||||
bcopy(&fpu_cleanstate, addr, sizeof(fpu_cleanstate));
|
||||
else
|
||||
bzero(addr, sizeof(*addr));
|
||||
bcopy(&fpu_cleanstate, addr, sizeof(fpu_cleanstate));
|
||||
return (_MC_FPOWNED_NONE);
|
||||
}
|
||||
s = intr_disable();
|
||||
|
@ -416,13 +416,8 @@ trap(struct trapframe *frame)
|
||||
|
||||
case T_DNA:
|
||||
/* transparent fault (due to context switch "late") */
|
||||
if (fpudna())
|
||||
goto userout;
|
||||
printf("pid %d killed due to lack of floating point\n",
|
||||
p->p_pid);
|
||||
i = SIGKILL;
|
||||
ucode = 0;
|
||||
break;
|
||||
fpudna();
|
||||
goto userout;
|
||||
|
||||
case T_FPOPFLT: /* FPU operand fetch fault */
|
||||
ucode = ILL_COPROC;
|
||||
@ -450,11 +445,9 @@ trap(struct trapframe *frame)
|
||||
* XXX this should be fatal unless the kernel has
|
||||
* registered such use.
|
||||
*/
|
||||
if (fpudna()) {
|
||||
printf("fpudna in kernel mode!\n");
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
fpudna();
|
||||
printf("fpudna in kernel mode!\n");
|
||||
goto out;
|
||||
|
||||
case T_STKFLT: /* stack fault */
|
||||
break;
|
||||
|
@ -97,7 +97,7 @@ struct savefpu {
|
||||
#define __INITIAL_MXCSR_MASK__ 0xFFBF
|
||||
|
||||
#ifdef _KERNEL
|
||||
int fpudna(void);
|
||||
void fpudna(void);
|
||||
void fpudrop(void);
|
||||
void fpuexit(struct thread *td);
|
||||
int fpuformat(void);
|
||||
|
Loading…
Reference in New Issue
Block a user