summaryrefslogtreecommitdiffstats
path: root/sys/amd64/vmm/intel/vmx.c
diff options
context:
space:
mode:
authortychon <tychon@FreeBSD.org>2015-06-09 00:14:47 +0000
committertychon <tychon@FreeBSD.org>2015-06-09 00:14:47 +0000
commit3259f3f35f305b53c284808724fe23d22697f8cb (patch)
treed4779e32e860798d2ddf42e82c0d3f98007246e2 /sys/amd64/vmm/intel/vmx.c
parent81fc71b09027deb3faed44719f7c83b71aee7062 (diff)
downloadFreeBSD-src-3259f3f35f305b53c284808724fe23d22697f8cb.zip
FreeBSD-src-3259f3f35f305b53c284808724fe23d22697f8cb.tar.gz
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
Diffstat (limited to 'sys/amd64/vmm/intel/vmx.c')
-rw-r--r--sys/amd64/vmm/intel/vmx.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index 7ee50d4..f590586 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -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 *vmx, int vcpu)
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 | \
OpenPOWER on IntegriCloud