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