Module Name: src Committed By: maxv Date: Wed Apr 3 17:32:58 UTC 2019
Modified Files: src/sys/dev/nvmm/x86: nvmm_x86.c nvmm_x86.h nvmm_x86_svm.c nvmm_x86_vmx.c Log Message: Add MSR_TSC. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/dev/nvmm/x86/nvmm_x86.c cvs rdiff -u -r1.8 -r1.9 src/sys/dev/nvmm/x86/nvmm_x86.h cvs rdiff -u -r1.35 -r1.36 src/sys/dev/nvmm/x86/nvmm_x86_svm.c cvs rdiff -u -r1.20 -r1.21 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/nvmm/x86/nvmm_x86.c diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.3 src/sys/dev/nvmm/x86/nvmm_x86.c:1.4 --- src/sys/dev/nvmm/x86/nvmm_x86.c:1.3 Sun Mar 3 07:01:09 2019 +++ src/sys/dev/nvmm/x86/nvmm_x86.c Wed Apr 3 17:32:58 2019 @@ -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 @@ const struct nvmm_x64_state nvmm_x86_res 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 = { Index: src/sys/dev/nvmm/x86/nvmm_x86.h diff -u src/sys/dev/nvmm/x86/nvmm_x86.h:1.8 src/sys/dev/nvmm/x86/nvmm_x86.h:1.9 --- src/sys/dev/nvmm/x86/nvmm_x86.h:1.8 Sun Mar 3 07:01:09 2019 +++ src/sys/dev/nvmm/x86/nvmm_x86.h Wed Apr 3 17:32:58 2019 @@ -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 Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.35 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.36 --- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.35 Thu Mar 21 20:21:41 2019 +++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c Wed Apr 3 17:32:58 2019 @@ -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 @@ struct svm_cpudata { /* General */ bool shared_asid; bool gtlb_want_flush; + bool gtsc_want_update; uint64_t vcpu_htlb_gen; /* VMCB */ @@ -538,7 +539,7 @@ struct svm_cpudata { 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 @@ svm_inkernel_handle_msr(struct nvmm_mach 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_vcpu_run(struct nvmm_machine *mach, 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 @@ svm_vcpu_run(struct nvmm_machine *mach, 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 @@ svm_vcpu_run(struct nvmm_machine *mach, 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 @@ svm_vcpu_run(struct nvmm_machine *mach, } } + cpudata->gtsc = rdtsc() + vmcb->ctrl.tsc_offset; + svm_vcpu_guest_misc_leave(vcpu); svm_vcpu_guest_dbregs_leave(vcpu); @@ -1644,6 +1650,9 @@ svm_vcpu_setstate(struct nvmm_cpu *vcpu, 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 @@ svm_vcpu_getstate(struct nvmm_cpu *vcpu, 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 @@ svm_vcpu_init(struct nvmm_machine *mach, 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); Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.20 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.21 --- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.20 Thu Mar 21 20:21:41 2019 +++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c Wed Apr 3 17:32:58 2019 @@ -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 @@ struct vmx_cpudata { /* 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 @@ struct vmx_cpudata { 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 @@ vmx_inkernel_handle_msr(struct nvmm_mach 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_vcpu_run(struct nvmm_machine *mach, 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 @@ vmx_vcpu_run(struct nvmm_machine *mach, 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 @@ vmx_vcpu_run(struct nvmm_machine *mach, 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_vcpu_setstate(struct nvmm_cpu *vcpu, 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 @@ vmx_vcpu_getstate(struct nvmm_cpu *vcpu, &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 @@ vmx_vcpu_init(struct nvmm_machine *mach, 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);