Module Name:    src
Committed By:   maxv
Date:           Fri Feb 15 13:17:05 UTC 2019

Modified Files:
        src/sys/dev/nvmm/x86: nvmm_x86_svm.c nvmm_x86_vmx.c

Log Message:
Initialize the guest TSC to zero at VCPU creation time, and handle guest
writes to MSR_TSC at run time.

This is imprecise, because the hardware does not provide a way to preserve
the TSC during #VMEXITs, but that's fine enough.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sys/dev/nvmm/x86/nvmm_x86_svm.c
cvs rdiff -u -r1.3 -r1.4 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_svm.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.23 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.24
--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.23	Thu Feb 14 14:30:20 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c	Fri Feb 15 13:17:05 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_svm.c,v 1.23 2019/02/14 14:30:20 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_svm.c,v 1.24 2019/02/15 13:17:05 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.23 2019/02/14 14:30:20 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.24 2019/02/15 13:17:05 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm
 #include <x86/specialreg.h>
 #include <x86/pmap.h>
 #include <x86/dbregs.h>
+#include <x86/cpu_counter.h>
 #include <machine/cpuvar.h>
 
 #include <dev/nvmm/nvmm.h>
@@ -965,7 +966,14 @@ svm_inkernel_handle_msr(struct nvmm_mach
 				cpudata->tlb_want_flush = true;
 			}
 			vmcb->state.efer = exit->u.msr.val | EFER_SVME;
-			vmcb->ctrl.vmcb_clean &= ~VMCB_CTRL_VMCB_CLEAN_CR;
+			svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_CR);
+			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);
 			goto handled;
 		}
 		for (i = 0; i < __arraycount(msr_ignore_list); i++) {
@@ -1582,8 +1590,8 @@ svm_vcpu_init(struct nvmm_machine *mach,
 	cpudata->gfpu.xsh_xstate_bv = svm_xcr0_mask;
 	cpudata->gfpu.xsh_xcomp_bv = 0;
 
-	/* Bluntly hide the host TSC. */
-	cpudata->tsc_offset = rdtsc();
+	/* Set guest TSC to zero, more or less. */
+	cpudata->tsc_offset = -cpu_counter();
 
 	/* These MSRs are static. */
 	cpudata->star = rdmsr(MSR_STAR);

Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.3 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.4
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.3	Thu Feb 14 14:30:20 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c	Fri Feb 15 13:17:05 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmm_x86_vmx.c,v 1.3 2019/02/14 14:30:20 maxv Exp $	*/
+/*	$NetBSD: nvmm_x86_vmx.c,v 1.4 2019/02/15 13:17:05 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.3 2019/02/14 14:30:20 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.4 2019/02/15 13:17:05 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx
 #include <x86/specialreg.h>
 #include <x86/pmap.h>
 #include <x86/dbregs.h>
+#include <x86/cpu_counter.h>
 #include <machine/cpuvar.h>
 
 #include <dev/nvmm/nvmm.h>
@@ -1370,6 +1371,12 @@ 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);
+			goto handled;
+		}
 		if (exit->u.msr.msr == MSR_CR_PAT) {
 			vmx_vmwrite(VMCS_GUEST_IA32_PAT, exit->u.msr.val);
 			goto handled;
@@ -2009,8 +2016,8 @@ vmx_vcpu_init(struct nvmm_machine *mach,
 	cpudata->gfpu.xsh_xstate_bv = vmx_xcr0_mask;
 	cpudata->gfpu.xsh_xcomp_bv = 0;
 
-	/* Bluntly hide the host TSC. */
-	cpudata->tsc_offset = rdtsc();
+	/* Set guest TSC to zero, more or less. */
+	cpudata->tsc_offset = -cpu_counter();
 
 	/* These MSRs are static. */
 	cpudata->star = rdmsr(MSR_STAR);

Reply via email to