Index: /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 46803)
+++ /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 46804)
@@ -193,4 +193,6 @@
      *  contributary exception or a page-fault. */
     bool            fVectoringPF;
+    /** Whether the TSC offset mode needs to be updated. */
+    bool            fUpdateTscOffsetting;
 } SVMTRANSIENT, *PSVMTRANSIENT;
 /** @}  */
@@ -1894,5 +1896,6 @@
 
 /**
- * Sets up the usage of TSC offsetting for the VCPU.
+ * Updates the use of TSC offsetting mode for the CPU and adjusts the necessary
+ * intercepts.
  *
  * @param   pVCpu       Pointer to the VMCPU.
@@ -1900,5 +1903,5 @@
  * @remarks No-long-jump zone!!!
  */
-static void hmR0SvmSetupTscOffsetting(PVMCPU pVCpu)
+static void hmR0SvmUpdateTscOffsetting(PVMCPU pVCpu)
 {
     PSVMVMCB pVmcb = (PSVMVMCB)pVCpu->hm.s.svm.pvVmcb;
@@ -2584,4 +2587,12 @@
     }
 
+    /* Setup TSC offsetting. */
+    if (   pSvmTransient->fUpdateTscOffsetting
+        || HMR0GetCurrentCpu()->idCpu != pVCpu->hm.s.idLastCpu)
+    {
+        pSvmTransient->fUpdateTscOffsetting = false;
+        hmR0SvmUpdateTscOffsetting(pVCpu);
+    }
+
     /* Flush the appropriate tagged-TLB entries. */
     ASMAtomicWriteBool(&pVCpu->hm.s.fCheckedTLBFlush, true);    /* Used for TLB-shootdowns, set this across the world switch. */
@@ -2662,13 +2673,12 @@
     pVmcb->ctrl.u64VmcbCleanBits = HMSVM_VMCB_CLEAN_ALL;        /* Mark the VMCB-state cache as unmodified by VMM. */
 
-    /* Restore host's TSC_AUX if required. */
     if (!(pVmcb->ctrl.u32InterceptCtrl1 & SVM_CTRL1_INTERCEPT_RDTSC))
     {
+        /* Restore host's TSC_AUX if required. */
         if (pVM->hm.s.cpuid.u32AMDFeatureEDX & X86_CPUID_EXT_FEATURE_EDX_RDTSCP)
             ASMWrMsr(MSR_K8_TSC_AUX, pVCpu->hm.s.u64HostTscAux);
 
         /** @todo Find a way to fix hardcoding a guestimate.  */
-        TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() +
-                             pVmcb->ctrl.u64TSCOffset - 0x400);
+        TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVmcb->ctrl.u64TSCOffset - 0x400);
     }
 
@@ -2728,4 +2738,5 @@
 
     SVMTRANSIENT SvmTransient;
+    SvmTransient.fUpdateTscOffsetting = true;
     uint32_t cLoops = 0;
     PSVMVMCB pVmcb  = (PSVMVMCB)pVCpu->hm.s.svm.pvVmcb;
@@ -3490,5 +3501,8 @@
     int rc = EMInterpretRdtsc(pVM, pVCpu, CPUMCTX2CORE(pCtx));
     if (RT_LIKELY(rc == VINF_SUCCESS))
+    {
         pCtx->rip += 2;     /* Hardcoded opcode, AMD-V doesn't give us this information. */
+        pSvmTransient->fUpdateTscOffsetting = true;
+    }
     else
     {
@@ -3509,5 +3523,8 @@
     int rc = EMInterpretRdtscp(pVCpu->CTX_SUFF(pVM), pVCpu, pCtx);
     if (RT_LIKELY(rc == VINF_SUCCESS))
+    {
         pCtx->rip += 3;     /* Hardcoded opcode, AMD-V doesn't give us this information. */
+        pSvmTransient->fUpdateTscOffsetting = true;
+    }
     else
     {
@@ -3744,4 +3761,6 @@
         if (pCtx->ecx == MSR_K6_EFER)
             pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_SVM_GUEST_EFER_MSR;
+        else if (pCtx->ecx == MSR_IA32_TSC)
+            pSvmTransient->fUpdateTscOffsetting = true;
     }
     else
