summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2018-05-21 19:23:54 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2018-05-21 19:23:54 +0200
commit66eac7d687219c71a9e3482f80b62de8b3693423 (patch)
tree698433b1c0b5a09eed78fb58b80a51b8378806d1
parent930efe67e81635e632f1e6f93e1c56499c79a55f (diff)
downloadplan9front-66eac7d687219c71a9e3482f80b62de8b3693423.tar.xz
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.
-rw-r--r--sys/src/9/pc64/main.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c
index 175f809bc..7e1b8449a 100644
--- a/sys/src/9/pc64/main.c
+++ b/sys/src/9/pc64/main.c
@@ -535,7 +535,7 @@ mathemu(Ureg *ureg, void*)
case FPinit:
fpinit();
index = up->fpstate >> FPindexs;
- if(index < 0 || index > FPindexm)
+ if(index < 0 || index > (FPindexm>>FPindexs))
panic("fpslot index overflow: %d", index);
if(userureg(ureg)){
if(index != 0)
@@ -684,7 +684,7 @@ procsave(Proc *p)
* emulation fault to activate the FPU.
*/
fpsave(p->fpsave);
- p->fpstate = FPinactive | (p->fpstate & (FPpush|FPnouser|FPkernel|FPindexm));
+ p->fpstate = FPinactive | (p->fpstate & ~FPactive);
break;
}
@@ -729,7 +729,8 @@ fpurestore(int ostate)
if((astate & ~(FPnouser|FPkernel|FPindexm)) == FPactive)
_stts();
up->fpsave = up->fpslot[ostate>>FPindexs];
- ostate = FPinactive | (ostate & (FPillegal|FPpush|FPnouser|FPkernel|FPindexm));
+ if(ostate & FPactive)
+ ostate = FPinactive | (ostate & ~FPactive);
}
up->fpstate = ostate;
}