pc64: fix fpu bug
fpurestore() unconditionally changed fpstate to FPinactive when the kernel used the FPU. but in the FPinit case, the registers are not saved by mathemu(), resulting in all zero initialized registers being loaded once userspace uses the FPU so the process would have wrong MXCR value. the index overflow check was wrong with using shifted value.
This commit is contained in:
parent
930efe67e8
commit
66eac7d687
1 changed files with 4 additions and 3 deletions
|
@ -535,7 +535,7 @@ mathemu(Ureg *ureg, void*)
|
||||||
case FPinit:
|
case FPinit:
|
||||||
fpinit();
|
fpinit();
|
||||||
index = up->fpstate >> FPindexs;
|
index = up->fpstate >> FPindexs;
|
||||||
if(index < 0 || index > FPindexm)
|
if(index < 0 || index > (FPindexm>>FPindexs))
|
||||||
panic("fpslot index overflow: %d", index);
|
panic("fpslot index overflow: %d", index);
|
||||||
if(userureg(ureg)){
|
if(userureg(ureg)){
|
||||||
if(index != 0)
|
if(index != 0)
|
||||||
|
@ -684,7 +684,7 @@ procsave(Proc *p)
|
||||||
* emulation fault to activate the FPU.
|
* emulation fault to activate the FPU.
|
||||||
*/
|
*/
|
||||||
fpsave(p->fpsave);
|
fpsave(p->fpsave);
|
||||||
p->fpstate = FPinactive | (p->fpstate & (FPpush|FPnouser|FPkernel|FPindexm));
|
p->fpstate = FPinactive | (p->fpstate & ~FPactive);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,7 +729,8 @@ fpurestore(int ostate)
|
||||||
if((astate & ~(FPnouser|FPkernel|FPindexm)) == FPactive)
|
if((astate & ~(FPnouser|FPkernel|FPindexm)) == FPactive)
|
||||||
_stts();
|
_stts();
|
||||||
up->fpsave = up->fpslot[ostate>>FPindexs];
|
up->fpsave = up->fpslot[ostate>>FPindexs];
|
||||||
ostate = FPinactive | (ostate & (FPillegal|FPpush|FPnouser|FPkernel|FPindexm));
|
if(ostate & FPactive)
|
||||||
|
ostate = FPinactive | (ostate & ~FPactive);
|
||||||
}
|
}
|
||||||
up->fpstate = ostate;
|
up->fpstate = ostate;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue