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 Optimize: cache the guest state entirely in...



details:   https://anonhg.NetBSD.org/src/rev/ec1c1907fc9c
branches:  trunk
changeset: 447309:ec1c1907fc9c
user:      maxv <maxv%NetBSD.org@localhost>
date:      Mon Jan 07 14:08:02 2019 +0000

description:
Optimize: cache the guest state entirely in the VMCB-cache, flush it on a
state-by-state basis when needed.

diffstat:

 sys/dev/nvmm/x86/nvmm_x86_svm.c |  87 +++++++++++++++++++++++++++++++---------
 1 files changed, 66 insertions(+), 21 deletions(-)

diffs (154 lines):

diff -r 28d97e9cd852 -r ec1c1907fc9c sys/dev/nvmm/x86/nvmm_x86_svm.c
--- a/sys/dev/nvmm/x86/nvmm_x86_svm.c   Mon Jan 07 13:47:33 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_svm.c   Mon Jan 07 14:08:02 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_svm.c,v 1.11 2019/01/06 18:32:54 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_svm.c,v 1.12 2019/01/07 14:08:02 maxv Exp $   */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.11 2019/01/06 18:32:54 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.12 2019/01/07 14:08:02 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -314,7 +314,6 @@
 
        uint64_t intr;
 #define VMCB_CTRL_INTR_SHADOW          __BIT(0)
-#define VMCB_CTRL_GUEST_INTR_MASK      __BIT(1)
 
        uint64_t exitcode;
        uint64_t exitinfo1;
@@ -538,6 +537,61 @@
        struct xsave_header gfpu __aligned(16);
 };
 
+static void
+svm_vmcb_cache_default(struct vmcb *vmcb)
+{
+       vmcb->ctrl.vmcb_clean =
+           VMCB_CTRL_VMCB_CLEAN_I |
+           VMCB_CTRL_VMCB_CLEAN_IOPM |
+           VMCB_CTRL_VMCB_CLEAN_ASID |
+           VMCB_CTRL_VMCB_CLEAN_TPR |
+           VMCB_CTRL_VMCB_CLEAN_NP |
+           VMCB_CTRL_VMCB_CLEAN_CR |
+           VMCB_CTRL_VMCB_CLEAN_DR |
+           VMCB_CTRL_VMCB_CLEAN_DT |
+           VMCB_CTRL_VMCB_CLEAN_SEG |
+           VMCB_CTRL_VMCB_CLEAN_CR2 |
+           VMCB_CTRL_VMCB_CLEAN_LBR |
+           VMCB_CTRL_VMCB_CLEAN_AVIC;
+}
+
+static void
+svm_vmcb_cache_update(struct vmcb *vmcb, uint64_t flags)
+{
+       if (flags & NVMM_X64_STATE_SEGS) {
+               vmcb->ctrl.vmcb_clean &=
+                   ~(VMCB_CTRL_VMCB_CLEAN_SEG | VMCB_CTRL_VMCB_CLEAN_DT);
+       }
+       if (flags & NVMM_X64_STATE_CRS) {
+               vmcb->ctrl.vmcb_clean &=
+                   ~(VMCB_CTRL_VMCB_CLEAN_CR | VMCB_CTRL_VMCB_CLEAN_CR2);
+       }
+       if (flags & NVMM_X64_STATE_DRS) {
+               vmcb->ctrl.vmcb_clean &= ~VMCB_CTRL_VMCB_CLEAN_DR;
+       }
+       if (flags & NVMM_X64_STATE_MSRS) {
+               /* CR for EFER, NP for PAT. */
+               vmcb->ctrl.vmcb_clean &=
+                   ~(VMCB_CTRL_VMCB_CLEAN_CR | VMCB_CTRL_VMCB_CLEAN_NP);
+       }
+       if (flags & NVMM_X64_STATE_MISC) {
+               /* SEG for CPL. */
+               vmcb->ctrl.vmcb_clean &= ~VMCB_CTRL_VMCB_CLEAN_SEG;
+       }
+}
+
+static inline void
+svm_vmcb_cache_flush(struct vmcb *vmcb, uint64_t flags)
+{
+       vmcb->ctrl.vmcb_clean &= ~flags;
+}
+
+static inline void
+svm_vmcb_cache_flush_all(struct vmcb *vmcb)
+{
+       vmcb->ctrl.vmcb_clean = 0;
+}
+
 #define SVM_EVENT_TYPE_HW_INT  0
 #define SVM_EVENT_TYPE_NMI     2
 #define SVM_EVENT_TYPE_EXC     3
@@ -555,8 +609,11 @@
        } else {
                vmcb->ctrl.intercept_misc1 |= VMCB_CTRL_INTERCEPT_VINTR;
                vmcb->ctrl.v |= (VMCB_CTRL_V_IRQ | VMCB_CTRL_V_IGN_TPR);
+               svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_TPR);
                cpudata->int_window_exit = true;
        }
+
+       svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
 }
 
 static void
@@ -571,8 +628,11 @@
        } else {
                vmcb->ctrl.intercept_misc1 &= ~VMCB_CTRL_INTERCEPT_VINTR;
                vmcb->ctrl.v &= ~(VMCB_CTRL_V_IRQ | VMCB_CTRL_V_IGN_TPR);
+               svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_TPR);
                cpudata->int_window_exit = false;
        }
+
+       svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
 }
 
 static inline int
@@ -1031,23 +1091,6 @@
 }
 
 static void
-svm_vmcb_cache_default(struct vmcb *vmcb)
-{
-       vmcb->ctrl.vmcb_clean =
-           VMCB_CTRL_VMCB_CLEAN_I |
-           VMCB_CTRL_VMCB_CLEAN_IOPM |
-           VMCB_CTRL_VMCB_CLEAN_ASID |
-           VMCB_CTRL_VMCB_CLEAN_LBR |
-           VMCB_CTRL_VMCB_CLEAN_AVIC;
-}
-
-static void
-svm_vmcb_cache_flush(struct vmcb *vmcb)
-{
-       vmcb->ctrl.vmcb_clean = 0;
-}
-
-static void
 svm_vcpu_guest_fpu_enter(struct nvmm_cpu *vcpu)
 {
        struct svm_cpudata *cpudata = vcpu->cpudata;
@@ -1164,7 +1207,7 @@
        if (vcpu->hcpu_last != hcpu) {
                vmcb->ctrl.tsc_offset = cpudata->tsc_offset +
                    curcpu()->ci_data.cpu_cc_skew;
-               svm_vmcb_cache_flush(vmcb);
+               svm_vmcb_cache_flush_all(vmcb);
        }
 
        svm_vcpu_guest_dbregs_enter(vcpu);
@@ -1821,6 +1864,8 @@
                fpustate->fx_mxcsr_mask &= x86_fpu_mxcsr_mask;
                fpustate->fx_mxcsr &= fpustate->fx_mxcsr_mask;
        }
+
+       svm_vmcb_cache_update(vmcb, flags);
 }
 
 static void



Home | Main Index | Thread Index | Old Index