Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Jun 2015 00:14:48 +0000 (UTC)
From:      Tycho Nightingale <tychon@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r284174 - head/sys/amd64/vmm/intel
Message-ID:  <201506090014.t590Emmw070900@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tychon
Date: Tue Jun  9 00:14:47 2015
New Revision: 284174
URL: https://svnweb.freebsd.org/changeset/base/284174

Log:
  Support guest writes to the TSC by enabling the "use TSC offsetting"
  execution control and writing the difference between the host TSC and
  the guest TSC into the TSC offset in the VMCS upon encountering a
  write.
  
  Reviewed by:	neel

Modified:
  head/sys/amd64/vmm/intel/vmx.c
  head/sys/amd64/vmm/intel/vmx.h
  head/sys/amd64/vmm/intel/vmx_msr.c

Modified: head/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmx.c	Mon Jun  8 23:37:17 2015	(r284173)
+++ head/sys/amd64/vmm/intel/vmx.c	Tue Jun  9 00:14:47 2015	(r284174)
@@ -856,10 +856,11 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
 	 * VM exit and entry respectively. It is also restored from the
 	 * host VMCS area on a VM exit.
 	 *
-	 * The TSC MSR is exposed read-only. Writes are disallowed as that
-	 * will impact the host TSC.
-	 * XXX Writes would be implemented with a wrmsr trap, and
-	 * then modifying the TSC offset in the VMCS.
+	 * The TSC MSR is exposed read-only. Writes are disallowed as
+	 * that will impact the host TSC.  If the guest does a write
+	 * the "use TSC offsetting" execution control is enabled and the
+	 * difference between the host TSC and the guest TSC is written
+	 * into the TSC offset in the VMCS.
 	 */
 	if (guest_msr_rw(vmx, MSR_GSBASE) ||
 	    guest_msr_rw(vmx, MSR_FSBASE) ||
@@ -1130,6 +1131,22 @@ vmx_clear_nmi_window_exiting(struct vmx 
 	VCPU_CTR0(vmx->vm, vcpu, "Disabling NMI window exiting");
 }
 
+int
+vmx_set_tsc_offset(struct vmx *vmx, int vcpu, uint64_t offset)
+{
+	int error;
+
+	if ((vmx->cap[vcpu].proc_ctls & PROCBASED_TSC_OFFSET) == 0) {
+		vmx->cap[vcpu].proc_ctls |= PROCBASED_TSC_OFFSET;
+		vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls);
+		VCPU_CTR0(vmx->vm, vcpu, "Enabling TSC offsetting");
+	}
+
+	error = vmwrite(VMCS_TSC_OFFSET, offset);
+
+	return (error);
+}
+
 #define	NMI_BLOCKING	(VMCS_INTERRUPTIBILITY_NMI_BLOCKING |		\
 			 VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)
 #define	HWINTR_BLOCKING	(VMCS_INTERRUPTIBILITY_STI_BLOCKING |		\

Modified: head/sys/amd64/vmm/intel/vmx.h
==============================================================================
--- head/sys/amd64/vmm/intel/vmx.h	Mon Jun  8 23:37:17 2015	(r284173)
+++ head/sys/amd64/vmm/intel/vmx.h	Tue Jun  9 00:14:47 2015	(r284174)
@@ -135,6 +135,8 @@ void	vmx_call_isr(uintptr_t entry);
 u_long	vmx_fix_cr0(u_long cr0);
 u_long	vmx_fix_cr4(u_long cr4);
 
+int	vmx_set_tsc_offset(struct vmx *vmx, int vcpu, uint64_t offset);
+
 extern char	vmx_exit_guest[];
 
 #endif

Modified: head/sys/amd64/vmm/intel/vmx_msr.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmx_msr.c	Mon Jun  8 23:37:17 2015	(r284173)
+++ head/sys/amd64/vmm/intel/vmx_msr.c	Tue Jun  9 00:14:47 2015	(r284174)
@@ -474,6 +474,9 @@ vmx_wrmsr(struct vmx *vmx, int vcpuid, u
 		else
 			vm_inject_gp(vmx->vm, vcpuid);
 		break;
+	case MSR_TSC:
+		error = vmx_set_tsc_offset(vmx, vcpuid, val - rdtsc());
+		break;
 	default:
 		error = EINVAL;
 		break;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506090014.t590Emmw070900>