Source-Changes-HG archive

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

[src/trunk]: src/sys Improvements in NVMM



details:   https://anonhg.NetBSD.org/src/rev/f298b73a497a
branches:  trunk
changeset: 447654:f298b73a497a
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sun Jan 20 16:55:21 2019 +0000

description:
Improvements in NVMM

 * Handle the FPU differently, limit the states via the given mask rather
   than via XCR0. Align to 64 bytes. Provide an initial gXCR0, to be sure
   that XCR0_X87 is set. Reset XSTATE_BV when the state is modified by
   the virtualizer, to force a reload from memory.

 * Hide RDTSCP.

 * Zero-extend RBX/RCX/RDX when handling the NVMM CPUID signature.

 * Take ECX and not RCX on MSR instructions.

diffstat:

 sys/arch/x86/include/fpu.h      |   6 ++--
 sys/arch/x86/x86/fpu.c          |  18 +++++++-------
 sys/dev/nvmm/x86/nvmm_x86_svm.c |  52 +++++++++++++++++++++++-----------------
 3 files changed, 42 insertions(+), 34 deletions(-)

diffs (239 lines):

diff -r 26325216090a -r f298b73a497a sys/arch/x86/include/fpu.h
--- a/sys/arch/x86/include/fpu.h        Sun Jan 20 16:02:32 2019 +0000
+++ b/sys/arch/x86/include/fpu.h        Sun Jan 20 16:55:21 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu.h,v 1.13 2018/10/05 18:51:52 maxv Exp $    */
+/*     $NetBSD: fpu.h,v 1.14 2019/01/20 16:55:21 maxv Exp $    */
 
 #ifndef        _X86_FPU_H_
 #define        _X86_FPU_H_
@@ -14,8 +14,8 @@
 void fpuinit(struct cpu_info *);
 void fpuinit_mxcsr_mask(void);
 
-void fpu_area_save(void *);
-void fpu_area_restore(void *);
+void fpu_area_save(void *, uint64_t);
+void fpu_area_restore(void *, uint64_t);
 
 void fpusave_lwp(struct lwp *, bool);
 void fpusave_cpu(bool);
diff -r 26325216090a -r f298b73a497a sys/arch/x86/x86/fpu.c
--- a/sys/arch/x86/x86/fpu.c    Sun Jan 20 16:02:32 2019 +0000
+++ b/sys/arch/x86/x86/fpu.c    Sun Jan 20 16:55:21 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu.c,v 1.48 2018/10/05 18:51:52 maxv Exp $    */
+/*     $NetBSD: fpu.c,v 1.49 2019/01/20 16:55:21 maxv Exp $    */
 
 /*
  * Copyright (c) 2008 The NetBSD Foundation, Inc.  All
@@ -96,7 +96,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.48 2018/10/05 18:51:52 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.49 2019/01/20 16:55:21 maxv Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -209,7 +209,7 @@
 }
 
 void
-fpu_area_save(void *area)
+fpu_area_save(void *area, uint64_t xsave_features)
 {
        clts();
 
@@ -221,16 +221,16 @@
                fxsave(area);
                break;
        case FPU_SAVE_XSAVE:
-               xsave(area, x86_xsave_features);
+               xsave(area, xsave_features);
                break;
        case FPU_SAVE_XSAVEOPT:
-               xsaveopt(area, x86_xsave_features);
+               xsaveopt(area, xsave_features);
                break;
        }
 }
 
 void
-fpu_area_restore(void *area)
+fpu_area_restore(void *area, uint64_t xsave_features)
 {
        clts();
 
@@ -247,7 +247,7 @@
        case FPU_SAVE_XSAVEOPT:
                if (cpu_vendor == CPUVENDOR_AMD)
                        fpu_clear_amd();
-               xrstor(area, x86_xsave_features);
+               xrstor(area, xsave_features);
                break;
        }
 }
@@ -262,7 +262,7 @@
        KASSERT(pcb->pcb_fpcpu == NULL);
        ci->ci_fpcurlwp = l;
        pcb->pcb_fpcpu = ci;
-       fpu_area_restore(&pcb->pcb_savefpu);
+       fpu_area_restore(&pcb->pcb_savefpu, x86_xsave_features);
 }
 
 void
@@ -532,7 +532,7 @@
        pcb = lwp_getpcb(l);
 
        if (save) {
-               fpu_area_save(&pcb->pcb_savefpu);
+               fpu_area_save(&pcb->pcb_savefpu, x86_xsave_features);
        }
 
        stts();
diff -r 26325216090a -r f298b73a497a sys/dev/nvmm/x86/nvmm_x86_svm.c
--- a/sys/dev/nvmm/x86/nvmm_x86_svm.c   Sun Jan 20 16:02:32 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_svm.c   Sun Jan 20 16:55:21 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_svm.c,v 1.15 2019/01/13 10:07:50 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_svm.c,v 1.16 2019/01/20 16:55:21 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.15 2019/01/13 10:07:50 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.16 2019/01/20 16:55:21 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -524,7 +524,7 @@
        uint64_t fsbase;
        uint64_t kernelgsbase;
        bool ts_set;
-       struct xsave_header hfpu __aligned(16);
+       struct xsave_header hfpu __aligned(64);
 
        /* Event state */
        bool int_window_exit;
@@ -535,7 +535,7 @@
        uint64_t gprs[NVMM_X64_NGPR];
        uint64_t drs[NVMM_X64_NDR];
        uint64_t tsc_offset;
-       struct xsave_header gfpu __aligned(16);
+       struct xsave_header gfpu __aligned(64);
 };
 
 static void
@@ -779,12 +779,16 @@
                cpudata->gprs[NVMM_X64_GPR_RDX] = svm_xcr0_mask >> 32;
                break;
        case 0x40000000:
+               cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
+               cpudata->gprs[NVMM_X64_GPR_RCX] = 0;
+               cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
                memcpy(&cpudata->gprs[NVMM_X64_GPR_RBX], "___ ", 4);
                memcpy(&cpudata->gprs[NVMM_X64_GPR_RCX], "NVMM", 4);
                memcpy(&cpudata->gprs[NVMM_X64_GPR_RDX], " ___", 4);
                break;
-       case 0x80000001: /* No SVM in ECX. The rest is tunable. */
+       case 0x80000001: /* No SVM, no RDTSCP. The rest is tunable. */
                cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID_SVM;
+               cpudata->gprs[NVMM_X64_GPR_RDX] &= ~CPUID_RDTSCP;
                break;
        default:
                break;
@@ -1007,7 +1011,7 @@
                exit->u.msr.type = NVMM_EXIT_MSR_WRMSR;
        }
 
-       exit->u.msr.msr = cpudata->gprs[NVMM_X64_GPR_RCX];
+       exit->u.msr.msr = (cpudata->gprs[NVMM_X64_GPR_RCX] & 0xFFFFFFFF);
 
        if (info == 1) {
                uint64_t rdx, rax;
@@ -1092,15 +1096,15 @@
 {
        struct svm_cpudata *cpudata = vcpu->cpudata;
 
-       if (x86_xsave_features != 0) {
+       cpudata->ts_set = (rcr0() & CR0_TS) != 0;
+
+       fpu_area_save(&cpudata->hfpu, svm_xcr0_mask);
+       fpu_area_restore(&cpudata->gfpu, svm_xcr0_mask);
+
+       if (svm_xcr0_mask != 0) {
                cpudata->hxcr0 = rdxcr(0);
                wrxcr(0, cpudata->gxcr0);
        }
-
-       cpudata->ts_set = (rcr0() & CR0_TS) != 0;
-
-       fpu_area_save(&cpudata->hfpu);
-       fpu_area_restore(&cpudata->gfpu);
 }
 
 static void
@@ -1108,17 +1112,17 @@
 {
        struct svm_cpudata *cpudata = vcpu->cpudata;
 
-       fpu_area_save(&cpudata->gfpu);
-       fpu_area_restore(&cpudata->hfpu);
+       if (svm_xcr0_mask != 0) {
+               cpudata->gxcr0 = rdxcr(0);
+               wrxcr(0, cpudata->hxcr0);
+       }
+
+       fpu_area_save(&cpudata->gfpu, svm_xcr0_mask);
+       fpu_area_restore(&cpudata->hfpu, svm_xcr0_mask);
 
        if (cpudata->ts_set) {
                stts();
        }
-
-       if (x86_xsave_features != 0) {
-               cpudata->gxcr0 = rdxcr(0);
-               wrxcr(0, cpudata->hxcr0);
-       }
 }
 
 static void
@@ -1580,6 +1584,7 @@
 
        /* Must always be set. */
        vmcb->state.efer = EFER_SVME;
+       cpudata->gxcr0 = XCR0_X87;
 
        /* Init XSAVE header. */
        cpudata->gfpu.xsh_xstate_bv = svm_xcr0_mask;
@@ -1779,13 +1784,11 @@
                vmcb->ctrl.v |= __SHIFTIN(state->crs[NVMM_X64_CR_CR8],
                    VMCB_CTRL_V_TPR);
 
-               /* Clear unsupported XCR0 bits, set mandatory X87 bit. */
                if (svm_xcr0_mask != 0) {
+                       /* Clear illegal XCR0 bits, set mandatory X87 bit. */
                        cpudata->gxcr0 = state->crs[NVMM_X64_CR_XCR0];
                        cpudata->gxcr0 &= svm_xcr0_mask;
                        cpudata->gxcr0 |= XCR0_X87;
-               } else {
-                       cpudata->gxcr0 = 0;
                }
        }
 
@@ -1846,6 +1849,11 @@
                fpustate = (struct fxsave *)cpudata->gfpu.xsh_fxsave;
                fpustate->fx_mxcsr_mask &= x86_fpu_mxcsr_mask;
                fpustate->fx_mxcsr &= fpustate->fx_mxcsr_mask;
+
+               if (svm_xcr0_mask != 0) {
+                       /* Reset XSTATE_BV, to force a reload. */
+                       cpudata->gfpu.xsh_xstate_bv = svm_xcr0_mask;
+               }
        }
 
        svm_vmcb_cache_update(vmcb, flags);



Home | Main Index | Thread Index | Old Index