shithub: riscv

Download patch

ref: 217222e75a112845a0345875b0404afa1c6a58b0
parent: 1647696236f2d10e70cd8a0fc2a04fabfa5f63a6
author: cinap_lenrek <[email protected]>
date: Sat Jul 8 13:51:52 EDT 2023

devvmx: reset kernel fpu state before loading vmx fpu state

--- a/sys/src/9/pc/devvmx.c
+++ b/sys/src/9/pc/devvmx.c
@@ -491,7 +491,7 @@
 static int
 xcr0write(Vmx *vmx, char *s)
 {
-	vmx->xcr0 = parseval(s) & 7;
+	vmx->xcr0 = (parseval(s) | 1) & m->xcr0;
 	return 0;
 }
 
@@ -936,6 +936,7 @@
 {
 	vlong msr;
 	u32int x;
+	int s;
 	
 	memset(&vmx->ureg, 0, sizeof(vmx->ureg));
 	vmx->launched = 0;
@@ -1055,8 +1056,15 @@
 	vmcswrite(GUEST_RFLAGS, 2);
 	
 	vmx->onentry = FLUSHVPID | FLUSHEPT;
+
+	s = splhi();
+#ifdef KFPSTATE
+	fpukexit(nil, nil);
+#endif
 	fpinit();
-	vmx->xcr0 = m->xcr0 & 1; /* x87 alone */
+	fpsave(&vmx->fp);
+	vmx->xcr0 = m->xcr0;
+	splx(s);
 
 	memset(vmx->msrbits, -1, 4096);
 	vmxtrapmsr(vmx, Efer, 0);
@@ -1669,9 +1677,11 @@
 			}
 			if((vmx->dr[7] & ~0xd400) != 0)
 				putdr01236(vmx->dr);
-
+#ifdef KFPSTATE
+			fpukexit(nil, nil);
+#endif
 			fprestore(&vmx->fp);
-			if(m->xcr0 != 0 && vmx->xcr0 != m->xcr0)
+			if(vmx->xcr0 != m->xcr0)
 				putxcr0(vmx->xcr0);
 			if(vmx->cr2 != getcr2())
 				putcr2(vmx->cr2);
@@ -1688,10 +1698,9 @@
 			cycles(&end);
 			useend = vmx->procbctls & PROCB_TSCOFFSET;
 			vmx->cr2 = getcr2();
-			if(m->xcr0 != 0 && vmx->xcr0 != m->xcr0)
+			if(vmx->xcr0 != m->xcr0)
 				putxcr0(m->xcr0);
 			fpsave(&vmx->fp);
-
 			splx(x);
 			if(rc < 0)
 				error("vmlaunch failed");
--- a/sys/src/9/pc64/fns.h
+++ b/sys/src/9/pc64/fns.h
@@ -36,9 +36,9 @@
 int	ecread(uchar addr);
 int	ecwrite(uchar addr, uchar val);
 #define	evenaddr(x)				/* x86 doesn't care */
-void	fpinit(void);
 void	(*fprestore)(FPsave*);
 void	(*fpsave)(FPsave*);
+void	fpinit(void);
 FPsave*	fpukenter(Ureg*);
 void	fpukexit(Ureg*, FPsave*);
 void	fpuprocfork(Proc*);