ref: 753f64a8777aac7341193ba6f17efca677509827
parent: f4880742fd204d538168c8bae11ba2935b2b13d6
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Nov 13 19:16:21 EST 2017
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.
--- a/sys/src/9/pc64/main.c
+++ b/sys/src/9/pc64/main.c
@@ -712,20 +712,25 @@
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));
}