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);

Reply via email to