shithub: riscv

Download patch

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));
 	}