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 Add MSR_TSC.



details:   https://anonhg.NetBSD.org/src/rev/2cf3759d9ea7
branches:  trunk
changeset: 840339:2cf3759d9ea7
user:      maxv <maxv%NetBSD.org@localhost>
date:      Wed Apr 03 17:32:58 2019 +0000

description:
Add MSR_TSC.

diffstat:

 sys/dev/nvmm/x86/nvmm_x86.c     |   5 +++--
 sys/dev/nvmm/x86/nvmm_x86.h     |   5 +++--
 sys/dev/nvmm/x86/nvmm_x86_svm.c |  31 +++++++++++++++++++------------
 sys/dev/nvmm/x86/nvmm_x86_vmx.c |  31 ++++++++++++++++++++-----------
 4 files changed, 45 insertions(+), 27 deletions(-)

diffs (269 lines):

diff -r 25a298648f5d -r 2cf3759d9ea7 sys/dev/nvmm/x86/nvmm_x86.c
--- a/sys/dev/nvmm/x86/nvmm_x86.c       Wed Apr 03 16:30:28 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86.c       Wed Apr 03 17:32:58 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86.c,v 1.3 2019/03/03 07:01:09 maxv Exp $        */
+/*     $NetBSD: nvmm_x86.c,v 1.4 2019/04/03 17:32:58 maxv Exp $        */
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.3 2019/03/03 07:01:09 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.4 2019/04/03 17:32:58 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -210,6 +210,7 @@
                    PATENTRY(2, PAT_UCMINUS) | PATENTRY(3, PAT_UC) |
                    PATENTRY(4, PAT_WB) | PATENTRY(5, PAT_WT) |
                    PATENTRY(6, PAT_UCMINUS) | PATENTRY(7, PAT_UC),
+               [NVMM_X64_MSR_TSC] = 0,
        },
 
        .misc = {
diff -r 25a298648f5d -r 2cf3759d9ea7 sys/dev/nvmm/x86/nvmm_x86.h
--- a/sys/dev/nvmm/x86/nvmm_x86.h       Wed Apr 03 16:30:28 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86.h       Wed Apr 03 17:32:58 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86.h,v 1.8 2019/03/03 07:01:09 maxv Exp $        */
+/*     $NetBSD: nvmm_x86.h,v 1.9 2019/04/03 17:32:58 maxv Exp $        */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -95,7 +95,8 @@
 #define NVMM_X64_MSR_SYSENTER_ESP      7
 #define NVMM_X64_MSR_SYSENTER_EIP      8
 #define NVMM_X64_MSR_PAT               9
-#define NVMM_X64_NMSR                  10
+#define NVMM_X64_MSR_TSC               10
+#define NVMM_X64_NMSR                  11
 
 /* Misc. */
 #define NVMM_X64_MISC_INT_SHADOW       0
diff -r 25a298648f5d -r 2cf3759d9ea7 sys/dev/nvmm/x86/nvmm_x86_svm.c
--- a/sys/dev/nvmm/x86/nvmm_x86_svm.c   Wed Apr 03 16:30:28 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_svm.c   Wed Apr 03 17:32:58 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_svm.c,v 1.35 2019/03/21 20:21:41 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_svm.c,v 1.36 2019/04/03 17:32:58 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.35 2019/03/21 20:21:41 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.36 2019/04/03 17:32:58 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -505,6 +505,7 @@
        /* General */
        bool shared_asid;
        bool gtlb_want_flush;
+       bool gtsc_want_update;
        uint64_t vcpu_htlb_gen;
 
        /* VMCB */
@@ -538,7 +539,7 @@
        uint64_t gxcr0;
        uint64_t gprs[NVMM_X64_NGPR];
        uint64_t drs[NVMM_X64_NDR];
-       uint64_t tsc_offset;
+       uint64_t gtsc;
        struct xsave_header gfpu __aligned(64);
 };
 
@@ -1000,10 +1001,8 @@
                        goto handled;
                }
                if (exit->u.msr.msr == MSR_TSC) {
-                       cpudata->tsc_offset = exit->u.msr.val - cpu_counter();
-                       vmcb->ctrl.tsc_offset = cpudata->tsc_offset +
-                           curcpu()->ci_data.cpu_cc_skew;
-                       svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
+                       cpudata->gtsc = exit->u.msr.val;
+                       cpudata->gtsc_want_update = true;
                        goto handled;
                }
                for (i = 0; i < __arraycount(msr_ignore_list); i++) {
@@ -1268,9 +1267,8 @@
        svm_htlb_catchup(vcpu, hcpu);
 
        if (vcpu->hcpu_last != hcpu) {
-               vmcb->ctrl.tsc_offset = cpudata->tsc_offset +
-                   curcpu()->ci_data.cpu_cc_skew;
                svm_vmcb_cache_flush_all(vmcb);
+               cpudata->gtsc_want_update = true;
        }
 
        svm_vcpu_guest_dbregs_enter(vcpu);
@@ -1283,6 +1281,11 @@
                        vmcb->ctrl.tlb_ctrl = 0;
                }
 
+               if (__predict_false(cpudata->gtsc_want_update)) {
+                       vmcb->ctrl.tsc_offset = cpudata->gtsc - rdtsc();
+                       svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
+               }
+
                s = splhigh();
                machgen = svm_htlb_flush(machdata, cpudata);
                svm_vcpu_guest_fpu_enter(vcpu);
@@ -1295,6 +1298,7 @@
 
                if (vmcb->ctrl.exitcode != VMCB_EXITCODE_INVALID) {
                        cpudata->gtlb_want_flush = false;
+                       cpudata->gtsc_want_update = false;
                        vcpu->hcpu_last = hcpu;
                }
 
@@ -1376,6 +1380,8 @@
                }
        }
 
+       cpudata->gtsc = rdtsc() + vmcb->ctrl.tsc_offset;
+
        svm_vcpu_guest_misc_leave(vcpu);
        svm_vcpu_guest_dbregs_leave(vcpu);
 
@@ -1644,6 +1650,9 @@
                vmcb->state.sysenter_eip =
                    state->msrs[NVMM_X64_MSR_SYSENTER_EIP];
                vmcb->state.g_pat = state->msrs[NVMM_X64_MSR_PAT];
+
+               cpudata->gtsc = state->msrs[NVMM_X64_MSR_TSC];
+               cpudata->gtsc_want_update = true;
        }
 
        if (flags & NVMM_X64_STATE_MISC) {
@@ -1759,6 +1768,7 @@
                state->msrs[NVMM_X64_MSR_SYSENTER_EIP] =
                    vmcb->state.sysenter_eip;
                state->msrs[NVMM_X64_MSR_PAT] = vmcb->state.g_pat;
+               state->msrs[NVMM_X64_MSR_TSC] = cpudata->gtsc;
 
                /* Hide SVME. */
                state->msrs[NVMM_X64_MSR_EFER] &= ~EFER_SVME;
@@ -1943,9 +1953,6 @@
        cpudata->gfpu.xsh_xstate_bv = svm_xcr0_mask;
        cpudata->gfpu.xsh_xcomp_bv = 0;
 
-       /* Set guest TSC to zero, more or less. */
-       cpudata->tsc_offset = -cpu_counter();
-
        /* These MSRs are static. */
        cpudata->star = rdmsr(MSR_STAR);
        cpudata->lstar = rdmsr(MSR_LSTAR);
diff -r 25a298648f5d -r 2cf3759d9ea7 sys/dev/nvmm/x86/nvmm_x86_vmx.c
--- a/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Wed Apr 03 16:30:28 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Wed Apr 03 17:32:58 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_vmx.c,v 1.20 2019/03/21 20:21:41 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_vmx.c,v 1.21 2019/04/03 17:32:58 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.20 2019/03/21 20:21:41 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.21 2019/04/03 17:32:58 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -642,6 +642,7 @@
        /* General */
        uint64_t asid;
        bool gtlb_want_flush;
+       bool gtsc_want_update;
        uint64_t vcpu_htlb_gen;
        kcpuset_t *htlb_want_flush;
 
@@ -679,7 +680,7 @@
        uint64_t gxcr0;
        uint64_t gprs[NVMM_X64_NGPR];
        uint64_t drs[NVMM_X64_NDR];
-       uint64_t tsc_offset;
+       uint64_t gtsc;
        struct xsave_header gfpu __aligned(64);
 };
 
@@ -1493,9 +1494,8 @@
                break;
        case NVMM_EXIT_MSR_WRMSR:
                if (exit->u.msr.msr == MSR_TSC) {
-                       cpudata->tsc_offset = exit->u.msr.val - cpu_counter();
-                       vmx_vmwrite(VMCS_TSC_OFFSET, cpudata->tsc_offset +
-                           curcpu()->ci_data.cpu_cc_skew);
+                       cpudata->gtsc = exit->u.msr.val;
+                       cpudata->gtsc_want_update = true;
                        goto handled;
                }
                if (exit->u.msr.msr == MSR_CR_PAT) {
@@ -1793,8 +1793,7 @@
                vmx_vmwrite(VMCS_HOST_TR_BASE, (uint64_t)ci->ci_tss);
                vmx_vmwrite(VMCS_HOST_GDTR_BASE, (uint64_t)ci->ci_gdt);
                vmx_vmwrite(VMCS_HOST_GS_BASE, rdmsr(MSR_GSBASE));
-               vmx_vmwrite(VMCS_TSC_OFFSET, cpudata->tsc_offset +
-                   curcpu()->ci_data.cpu_cc_skew);
+               cpudata->gtsc_want_update = true;
                vcpu->hcpu_last = hcpu;
        }
 
@@ -1809,6 +1808,11 @@
                        cpudata->gtlb_want_flush = false;
                }
 
+               if (__predict_false(cpudata->gtsc_want_update)) {
+                       vmx_vmwrite(VMCS_TSC_OFFSET, cpudata->gtsc - rdtsc());
+                       cpudata->gtsc_want_update = false;
+               }
+
                s = splhigh();
                machgen = vmx_htlb_flush(machdata, cpudata);
                vmx_vcpu_guest_fpu_enter(vcpu);
@@ -1920,6 +1924,9 @@
 
        cpudata->vmcs_launched = launched;
 
+       vmx_vmread(VMCS_TSC_OFFSET, &cpudata->gtsc);
+       cpudata->gtsc += rdtsc();
+
        vmx_vcpu_guest_misc_leave(vcpu);
        vmx_vcpu_guest_dbregs_leave(vcpu);
 
@@ -2200,6 +2207,9 @@
                vmx_vmwrite(VMCS_GUEST_IA32_SYSENTER_EIP,
                    state->msrs[NVMM_X64_MSR_SYSENTER_EIP]);
 
+               cpudata->gtsc = state->msrs[NVMM_X64_MSR_TSC];
+               cpudata->gtsc_want_update = true;
+
                /* ENTRY_CTLS_LONG_MODE must match EFER_LMA. */
                vmx_vmread(VMCS_ENTRY_CTLS, &ctls1);
                if (state->msrs[NVMM_X64_MSR_EFER] & EFER_LMA) {
@@ -2321,6 +2331,8 @@
                    &state->msrs[NVMM_X64_MSR_SYSENTER_ESP]);
                vmx_vmread(VMCS_GUEST_IA32_SYSENTER_EIP,
                    &state->msrs[NVMM_X64_MSR_SYSENTER_EIP]);
+
+               state->msrs[NVMM_X64_MSR_TSC] = cpudata->gtsc;
        }
 
        if (flags & NVMM_X64_STATE_MISC) {
@@ -2501,9 +2513,6 @@
        cpudata->gfpu.xsh_xstate_bv = vmx_xcr0_mask;
        cpudata->gfpu.xsh_xcomp_bv = 0;
 
-       /* Set guest TSC to zero, more or less. */
-       cpudata->tsc_offset = -cpu_counter();
-
        /* These MSRs are static. */
        cpudata->star = rdmsr(MSR_STAR);
        cpudata->cstar = rdmsr(MSR_CSTAR);



Home | Main Index | Thread Index | Old Index