diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-11-14 00:16:21 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-11-14 00:16:21 +0100 |
commit | 753f64a8777aac7341193ba6f17efca677509827 (patch) | |
tree | a89157a57edbf133bb446afda0b653714e65bf6a /sys/src/9/pc64/main.c | |
parent | f4880742fd204d538168c8bae11ba2935b2b13d6 (diff) |
pc64: fix mistake fpurestore() mistake
cannot just reenable the fpu in FPactive case as we might have
been procsaved() an rescheduled on another cpu. what was i thinking...
thanks qu7uux for reproducing the problem.
Diffstat (limited to 'sys/src/9/pc64/main.c')
-rw-r--r-- | sys/src/9/pc64/main.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c index e56ad9197..458ff0c16 100644 --- a/sys/src/9/pc64/main.c +++ b/sys/src/9/pc64/main.c @@ -712,20 +712,25 @@ int fpusave(void) { int ostate = up->fpstate; - if((up->fpstate & ~(FPnouser|FPkernel|FPindexm)) == FPactive) + if((ostate & ~(FPnouser|FPkernel|FPindexm)) == FPactive) _stts(); - up->fpstate = FPpush | (up->fpstate & ~FPillegal); + up->fpstate = FPpush | (ostate & ~FPillegal); return ostate; } void fpurestore(int ostate) { - if((up->fpstate & ~(FPnouser|FPkernel|FPindexm)) == FPactive) + int astate = up->fpstate; + if((astate & ~(FPnouser|FPkernel|FPindexm)) == FPactive) _stts(); - if((ostate & FPindexm) == (up->fpstate & FPindexm)){ - if((ostate & ~(FPnouser|FPkernel|FPindexm)) == FPactive) + if((astate & FPindexm) == (ostate & FPindexm)){ + if((ostate & ~(FPnouser|FPkernel|FPindexm)) == FPactive){ + if((astate & ~(FPpush|FPnouser|FPkernel|FPindexm)) != FPactive) + goto saved; _clts(); + } } else { + saved: up->fpsave = up->fpslot[ostate>>FPindexs]; ostate = FPinactive | (ostate & (FPillegal|FPpush|FPnouser|FPkernel|FPindexm)); } |