Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/nvmm/x86 Fix omission: if we receive a guest trap on...



details:   https://anonhg.NetBSD.org/src/rev/a2b5953e6588
branches:  trunk
changeset: 449091:a2b5953e6588
user:      maxv <maxv%NetBSD.org@localhost>
date:      Fri Feb 22 12:24:34 2019 +0000

description:
Fix omission: if we receive a guest trap on CR0, and if the original
instruction would have resulted in Long Mode being enabled, we need to
manually enable Long Mode ourselves. We were already doing that correctly
in setstate, but not in the CR0 trap handler.

Problem initially reported by Aymeric Vincent; ArchLinux wouldn't boot,
now it does and works correctly.

While here, add CR0_ET in the CR0 mask, for the associated shadow to
be taken into account. Normally this shadow bit shouldn't be necessary,
but for now I keep it regardless.

diffstat:

 sys/dev/nvmm/x86/nvmm_x86_vmx.c |  26 +++++++++++++++++++++++---
 1 files changed, 23 insertions(+), 3 deletions(-)

diffs (61 lines):

diff -r 28ed891fc434 -r a2b5953e6588 sys/dev/nvmm/x86/nvmm_x86_vmx.c
--- a/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Fri Feb 22 09:01:32 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Fri Feb 22 12:24:34 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_vmx.c,v 1.10 2019/02/21 13:25:44 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_vmx.c,v 1.11 2019/02/22 12:24:34 maxv Exp $   */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.10 2019/02/21 13:25:44 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.11 2019/02/22 12:24:34 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1154,6 +1154,7 @@
 {
        struct vmx_cpudata *cpudata = vcpu->cpudata;
        uint64_t type, gpr, cr0;
+       uint64_t efer, ctls1;
 
        type = __SHIFTOUT(qual, VMX_QUAL_CR_TYPE);
        if (type != CR_TYPE_WRITE) {
@@ -1176,6 +1177,25 @@
                return -1;
        }
 
+       /*
+        * XXX Handle 32bit PAE paging, need to set PDPTEs, fetched manually
+        * from CR3.
+        */
+
+       if (cr0 & CR0_PG) {
+               vmx_vmread(VMCS_ENTRY_CTLS, &ctls1);
+               vmx_vmread(VMCS_GUEST_IA32_EFER, &efer);
+               if (efer & EFER_LME) {
+                       ctls1 |= ENTRY_CTLS_LONG_MODE;
+                       efer |= EFER_LMA;
+               } else {
+                       ctls1 &= ~ENTRY_CTLS_LONG_MODE;
+                       efer &= ~EFER_LMA;
+               }
+               vmx_vmwrite(VMCS_GUEST_IA32_EFER, efer);
+               vmx_vmwrite(VMCS_ENTRY_CTLS, ctls1);
+       }
+
        vmx_vmwrite(VMCS_GUEST_CR0, cr0);
        vmx_inkernel_advance();
        return 0;
@@ -2043,7 +2063,7 @@
        vmx_vmwrite(VMCS_EXIT_MSR_STORE_COUNT, VMX_MSRLIST_EXIT_NMSR);
 
        /* Force CR0_NW and CR0_CD to zero, CR0_ET to one. */
-       vmx_vmwrite(VMCS_CR0_MASK, CR0_NW|CR0_CD);
+       vmx_vmwrite(VMCS_CR0_MASK, CR0_NW|CR0_CD|CR0_ET);
        vmx_vmwrite(VMCS_CR0_SHADOW, CR0_ET);
 
        /* Force CR4_VMXE to zero. */



Home | Main Index | Thread Index | Old Index