git: 9front

Download patch

ref: 78844aeaf21c1144b1f92165d6384d407152057f
parent: a8c3484a6a0fd50f9dbb853eb457e21ebd91ea74
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon May 21 15:23:54 EDT 2018

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.

--- a/sys/src/9/pc64/main.c
+++ b/sys/src/9/pc64/main.c
@@ -535,7 +535,7 @@
 	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 @@
 		 * 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 @@
 		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;
 }
--