diff options
| author | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-05-21 19:23:54 +0200 |
|---|---|---|
| committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-05-21 19:23:54 +0200 |
| commit | 66eac7d687219c71a9e3482f80b62de8b3693423 (patch) | |
| tree | 698433b1c0b5a09eed78fb58b80a51b8378806d1 | |
| parent | 930efe67e81635e632f1e6f93e1c56499c79a55f (diff) | |
| download | plan9front-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.c | 7 |
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; } |
