Index: /trunk/include/VBox/tm.h
===================================================================
--- /trunk/include/VBox/tm.h	(revision 19031)
+++ /trunk/include/VBox/tm.h	(revision 19032)
@@ -73,8 +73,8 @@
 
 
-VMMDECL(void)     TMNotifyStartOfExecution(PVM pVM);
-VMMDECL(void)     TMNotifyEndOfExecution(PVM pVM);
-VMMDECL(void)     TMNotifyStartOfHalt(PVM pVM);
-VMMDECL(void)     TMNotifyEndOfHalt(PVM pVM);
+VMMDECL(void)     TMNotifyStartOfExecution(PVMCPU pVCpu);
+VMMDECL(void)     TMNotifyEndOfExecution(PVMCPU pVCpu);
+VMMDECL(void)     TMNotifyStartOfHalt(PVMCPU pVCpu);
+VMMDECL(void)     TMNotifyEndOfHalt(PVMCPU pVCpu);
 
 
@@ -113,9 +113,9 @@
  * @{
  */
-VMMDECL(int)      TMCpuTickResume(PVM pVM);
-VMMDECL(int)      TMCpuTickPause(PVM pVM);
-VMMDECL(uint64_t) TMCpuTickGet(PVM pVM);
-VMMDECL(bool)     TMCpuTickCanUseRealTSC(PVM pVM, uint64_t *poffRealTSC);
-VMMDECL(int)      TMCpuTickSet(PVM pVM, uint64_t u64Tick);
+VMMDECL(int)      TMCpuTickResume(PVMCPU pVCpu);
+VMMDECL(int)      TMCpuTickPause(PVMCPU pVCpu);
+VMMDECL(uint64_t) TMCpuTickGet(PVMCPU pVCpu);
+VMMDECL(bool)     TMCpuTickCanUseRealTSC(PVMCPU pVCpu, uint64_t *poffRealTSC);
+VMMDECL(int)      TMCpuTickSet(PVMCPU pVCpu, uint64_t u64Tick);
 VMMDECL(uint64_t) TMCpuTicksPerSecond(PVM pVM);
 /** @} */
Index: /trunk/src/VBox/VMM/EM.cpp
===================================================================
--- /trunk/src/VBox/VMM/EM.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/EM.cpp	(revision 19032)
@@ -3509,5 +3509,5 @@
         rc = TMVirtualResume(pVM);
         Assert(rc == VINF_SUCCESS);
-        rc = TMCpuTickResume(pVM);
+        rc = TMCpuTickResume(pVCpu);
         Assert(rc == VINF_SUCCESS);
 
@@ -3646,5 +3646,5 @@
                     Log2(("EMR3ExecuteVM: returns VINF_EM_OFF (%d -> %d)\n", pVCpu->em.s.enmState, EMSTATE_TERMINATING));
                     TMVirtualPause(pVM);
-                    TMCpuTickPause(pVM);
+                    TMCpuTickPause(pVCpu);
                     VMMR3Unlock(pVM);
                     STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
@@ -3658,5 +3658,5 @@
                     Log(("EMR3ExecuteVM returns VINF_EM_TERMINATE (%d -> %d)\n", pVCpu->em.s.enmState, EMSTATE_TERMINATING));
                     TMVirtualPause(pVM);
-                    TMCpuTickPause(pVM);
+                    TMCpuTickPause(pVCpu);
                     STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
                     return rc;
@@ -3670,5 +3670,5 @@
                     pVCpu->em.s.enmState = EMSTATE_SUSPENDED;
                     TMVirtualPause(pVM);
-                    TMCpuTickPause(pVM);
+                    TMCpuTickPause(pVCpu);
                     VMMR3Unlock(pVM);
                     STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
@@ -3806,5 +3806,5 @@
                 case EMSTATE_SUSPENDED:
                     TMVirtualPause(pVM);
-                    TMCpuTickPause(pVM);
+                    TMCpuTickPause(pVCpu);
                     VMMR3Unlock(pVM);
                     STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
@@ -3817,8 +3817,8 @@
                 case EMSTATE_DEBUG_GUEST_RAW:
                     TMVirtualPause(pVM);
-                    TMCpuTickPause(pVM);
+                    TMCpuTickPause(pVCpu);
                     rc = emR3Debug(pVM, pVCpu, rc);
                     TMVirtualResume(pVM);
-                    TMCpuTickResume(pVM);
+                    TMCpuTickResume(pVCpu);
                     Log2(("EMR3ExecuteVM: enmr3Debug -> %Rrc (state %d)\n", rc, pVCpu->em.s.enmState));
                     break;
@@ -3830,5 +3830,5 @@
                 {
                     TMVirtualPause(pVM);
-                    TMCpuTickPause(pVM);
+                    TMCpuTickPause(pVCpu);
                     STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
 
@@ -3845,5 +3845,5 @@
                     STAM_REL_PROFILE_ADV_START(&pVCpu->em.s.StatTotal, x);
                     TMVirtualResume(pVM);
-                    TMCpuTickResume(pVM);
+                    TMCpuTickResume(pVCpu);
                     break;
                 }
@@ -3855,5 +3855,5 @@
                 {
                     TMVirtualPause(pVM);
-                    TMCpuTickPause(pVM);
+                    TMCpuTickPause(pVCpu);
                     VMMR3FatalDump(pVM, pVCpu, rc);
                     emR3Debug(pVM, pVCpu, rc);
@@ -3872,5 +3872,5 @@
                     pVCpu->em.s.enmState = EMSTATE_GURU_MEDITATION;
                     TMVirtualPause(pVM);
-                    TMCpuTickPause(pVM);
+                    TMCpuTickPause(pVCpu);
                     VMMR3Unlock(pVM);
                     STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
@@ -3886,5 +3886,5 @@
         LogFlow(("EMR3ExecuteVM: returns %Rrc (longjmp / fatal error)\n", rc));
         TMVirtualPause(pVM);
-        TMCpuTickPause(pVM);
+        TMCpuTickPause(pVCpu);
         VMMR3FatalDump(pVM, pVCpu, rc);
         emR3Debug(pVM, pVCpu, rc);
Index: /trunk/src/VBox/VMM/TM.cpp
===================================================================
--- /trunk/src/VBox/VMM/TM.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/TM.cpp	(revision 19032)
@@ -91,5 +91,5 @@
  * Each clock has its own scheduling facility, or timer queue if you like.
  * There are a few factors which makes it a bit complex.  First, there is the
- * usual R0 vs R3 vs. RC thing.  Then there is multiple threads, and then there
+ * usual R0 vs R3 vs. RC thing.  Then there are multiple threads, and then there
  * is the timer thread that periodically checks whether any timers has expired
  * without EMT noticing.  On the API level, all but the create and save APIs
@@ -98,5 +98,5 @@
  * The design is using a doubly linked list of active timers which is ordered
  * by expire date.  This list is only modified by the EMT thread.  Updates to
- * the list are batched in a singly linked list, which is then process by the
+ * the list are batched in a singly linked list, which is then processed by the
  * EMT thread at the first opportunity (immediately, next time EMT modifies a
  * timer on that clock, or next timer timeout).  Both lists are offset based and
@@ -310,5 +310,9 @@
     {
         if (!pVM->tm.s.fTSCUseRealTSC)
-            pVM->tm.s.fMaybeUseOffsettedHostTSC = tmR3HasFixedTSC(pVM);
+        {
+            /* @todo simple case for guest SMP; always emulate RDTSC */
+            if (pVM->cCPUs == 1)
+                pVM->tm.s.fMaybeUseOffsettedHostTSC = tmR3HasFixedTSC(pVM);
+        }
         else
             pVM->tm.s.fMaybeUseOffsettedHostTSC = true;
@@ -346,5 +350,5 @@
     /** @cfgm{TM/TSCTiedToExecution, bool, false}
      * Whether the TSC should be tied to execution. This will exclude most of the
-     * virtualization overhead, but will by default include the time spend in the
+     * virtualization overhead, but will by default include the time spent in the
      * halt state (see TM/TSCNotTiedToHalt). This setting will override all other
      * TSC settings except for TSCTicksPerSecond and TSCNotTiedToHalt, which should
@@ -984,8 +988,16 @@
 static DECLCALLBACK(int) tmR3Save(PVM pVM, PSSMHANDLE pSSM)
 {
+    unsigned i;
+
     LogFlow(("tmR3Save:\n"));
-    Assert(!pVM->tm.s.fTSCTicking);
+#ifdef VBOX_STRICT
+    for (i=0;i<pVM->cCPUs;i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+        Assert(!pVCpu->tm.s.fTSCTicking);
+    }
     Assert(!pVM->tm.s.fVirtualTicking);
     Assert(!pVM->tm.s.fVirtualSyncTicking);
+#endif
 
     /*
@@ -1006,6 +1018,11 @@
     SSMR3PutU64(pSSM, TMCLOCK_FREQ_REAL);
 
-    /* the cpu tick clock. */
-    SSMR3PutU64(pSSM, TMCpuTickGet(pVM));
+    for (i=0;i<pVM->cCPUs;i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+
+        /* the cpu tick clock. */
+        SSMR3PutU64(pSSM, TMCpuTickGet(pVCpu));
+    }
     return SSMR3PutU64(pSSM, pVM->tm.s.cTSCTicksPerSecond);
 }
@@ -1022,8 +1039,16 @@
 static DECLCALLBACK(int) tmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version)
 {
+    unsigned i;
     LogFlow(("tmR3Load:\n"));
-    Assert(!pVM->tm.s.fTSCTicking);
+
+#ifdef VBOX_STRICT
+    for (i=0;i<pVM->cCPUs;i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+        Assert(!pVCpu->tm.s.fTSCTicking);
+    }
     Assert(!pVM->tm.s.fVirtualTicking);
     Assert(!pVM->tm.s.fVirtualSyncTicking);
+#endif
 
     /*
@@ -1081,13 +1106,21 @@
 
     /* the cpu tick clock. */
-    pVM->tm.s.fTSCTicking = false;
-    SSMR3GetU64(pSSM, &pVM->tm.s.u64TSC);
+    for (i=0;i<pVM->cCPUs;i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+
+        pVCpu->tm.s.fTSCTicking = false;
+        SSMR3GetU64(pSSM, &pVCpu->tm.s.u64TSC);
+
+        if (pVM->tm.s.fTSCUseRealTSC)
+            pVCpu->tm.s.u64TSCOffset = 0; /** @todo TSC restore stuff and HWACC. */
+    }
+
     rc = SSMR3GetU64(pSSM, &u64Hz);
     if (RT_FAILURE(rc))
         return rc;
-    if (pVM->tm.s.fTSCUseRealTSC)
-        pVM->tm.s.u64TSCOffset = 0; /** @todo TSC restore stuff and HWACC. */
-    else
+    if (!pVM->tm.s.fTSCUseRealTSC)
         pVM->tm.s.cTSCTicksPerSecond = u64Hz;
+
     LogRel(("TM: cTSCTicksPerSecond=%#RX64 (%RU64) fTSCVirtualized=%RTbool fTSCUseRealTSC=%RTbool (state load)\n",
             pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.fTSCVirtualized, pVM->tm.s.fTSCUseRealTSC));
@@ -1360,5 +1393,5 @@
         case TMCLOCK_VIRTUAL_SYNC:  return TMVirtualSyncGet(pVM);
         case TMCLOCK_REAL:          return TMRealGet(pVM);
-        case TMCLOCK_TSC:           return TMCpuTickGet(pVM);
+        case TMCLOCK_TSC:           return TMCpuTickGet(&pVM->aCpus[0] /* just take VCPU 0 */);
         default:
             AssertMsgFailed(("enmClock=%d\n", enmClock));
@@ -2083,26 +2116,31 @@
      * Read the times first to avoid more than necessary time variation.
      */
-    const uint64_t u64TSC = TMCpuTickGet(pVM);
     const uint64_t u64Virtual = TMVirtualGet(pVM);
     const uint64_t u64VirtualSync = TMVirtualSyncGet(pVM);
     const uint64_t u64Real = TMRealGet(pVM);
 
-    /*
-     * TSC
-     */
-    pHlp->pfnPrintf(pHlp,
-                    "Cpu Tick: %18RU64 (%#016RX64) %RU64Hz %s%s",
-                    u64TSC, u64TSC, TMCpuTicksPerSecond(pVM),
-                    pVM->tm.s.fTSCTicking ? "ticking" : "paused",
-                    pVM->tm.s.fTSCVirtualized ? " - virtualized" : "");
-    if (pVM->tm.s.fTSCUseRealTSC)
-    {
-        pHlp->pfnPrintf(pHlp, " - real tsc");
-        if (pVM->tm.s.u64TSCOffset)
-            pHlp->pfnPrintf(pHlp, "\n          offset %RU64", pVM->tm.s.u64TSCOffset);
-    }
-    else
-        pHlp->pfnPrintf(pHlp, " - virtual clock");
-    pHlp->pfnPrintf(pHlp, "\n");
+    for (unsigned i=0;i<pVM->cCPUs;i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+
+        uint64_t u64TSC = TMCpuTickGet(pVCpu);
+        /*
+         * TSC
+         */
+        pHlp->pfnPrintf(pHlp,
+                        "Cpu Tick: %18RU64 (%#016RX64) %RU64Hz %s%s",
+                        u64TSC, u64TSC, TMCpuTicksPerSecond(pVM),
+                        pVCpu->tm.s.fTSCTicking ? "ticking" : "paused",
+                        pVM->tm.s.fTSCVirtualized ? " - virtualized" : "");
+        if (pVM->tm.s.fTSCUseRealTSC)
+        {
+            pHlp->pfnPrintf(pHlp, " - real tsc");
+            if (pVCpu->tm.s.u64TSCOffset)
+                pHlp->pfnPrintf(pHlp, "\n          offset %RU64", pVCpu->tm.s.u64TSCOffset);
+        }
+        else
+            pHlp->pfnPrintf(pHlp, " - virtual clock");
+        pHlp->pfnPrintf(pHlp, "\n");
+    }
 
     /*
Index: /trunk/src/VBox/VMM/TMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/TMInternal.h	(revision 19031)
+++ /trunk/src/VBox/VMM/TMInternal.h	(revision 19032)
@@ -287,6 +287,4 @@
     RTUINT                      offVM;
 
-    /** CPU timestamp ticking enabled indicator (bool). (RDTSC) */
-    bool                        fTSCTicking;
     /** Set if we fully virtualize the TSC, i.e. intercept all rdtsc instructions.
      * Config variable: TSCVirtualized (bool) */
@@ -307,9 +305,4 @@
     bool                        fTSCNotTiedToHalt;
     bool                        afAlignment0[6]; /**< alignment padding */
-    /** The offset between the host TSC and the Guest TSC.
-     * Only valid if fTicking is set and and fTSCUseRealTSC is clear. */
-    uint64_t                    u64TSCOffset;
-    /** The guest TSC when fTicking is cleared. */
-    uint64_t                    u64TSC;
     /** The number of CPU clock ticks per second (TMCLOCK_TSC).
      * Config variable: TSCTicksPerSecond (64-bit unsigned int)
@@ -508,4 +501,16 @@
      * See TMCPU2VM(). */
     RTUINT                      offVMCPU;
+
+    /** CPU timestamp ticking enabled indicator (bool). (RDTSC) */
+    bool                        fTSCTicking;
+    bool                        afAlignment0[3]; /**< alignment padding */
+
+    /** The offset between the host TSC and the Guest TSC.
+     * Only valid if fTicking is set and and fTSCUseRealTSC is clear. */
+    uint64_t                    u64TSCOffset;
+
+    /** The guest TSC when fTicking is cleared. */
+    uint64_t                    u64TSC;
+
 } TMCPU;
 /** Pointer to TM VMCPU instance data. */
@@ -518,6 +523,6 @@
 #endif
 
-int                     tmCpuTickPause(PVM pVM);
-int                     tmCpuTickResume(PVM pVM);
+int                     tmCpuTickPause(PVM pVM, PVMCPU pVCpu);
+int                     tmCpuTickResume(PVM pVM, PVMCPU pVCpu);
 
 DECLEXPORT(void)        tmVirtualNanoTSBad(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS);
Index: /trunk/src/VBox/VMM/VMEmt.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMEmt.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/VMEmt.cpp	(revision 19032)
@@ -985,4 +985,6 @@
 VMMR3DECL(int) VMR3WaitHalted(PVM pVM, bool fIgnoreInterrupts)
 {
+    PVMCPU pVCpu = VMMGetCpu(pVM);  /* @todo SMP: get rid of this */
+
     LogFlow(("VMR3WaitHalted: fIgnoreInterrupts=%d\n", fIgnoreInterrupts));
 
@@ -1004,5 +1006,5 @@
      */
     VMMR3YieldSuspend(pVM);
-    TMNotifyStartOfHalt(pVM);
+    TMNotifyStartOfHalt(pVCpu);
 
     /*
@@ -1037,5 +1039,5 @@
      * Notify TM and resume the yielder
      */
-    TMNotifyEndOfHalt(pVM);
+    TMNotifyEndOfHalt(pVCpu);
     VMMR3YieldResume(pVM);
 
Index: /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 19032)
@@ -740,5 +740,5 @@
     {
         case MSR_IA32_TSC:
-            u64 = TMCpuTickGet(pVCpu->CTX_SUFF(pVM));
+            u64 = TMCpuTickGet(pVCpu);
             break;
 
Index: /trunk/src/VBox/VMM/VMMAll/EMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/EMAll.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/VMMAll/EMAll.cpp	(revision 19032)
@@ -2555,5 +2555,5 @@
         return VERR_EM_INTERPRETER; /* genuine #GP */
 
-    uint64_t uTicks = TMCpuTickGet(pVM);
+    uint64_t uTicks = TMCpuTickGet(pVCpu);
 
     /* Same behaviour in 32 & 64 bits mode */
@@ -2586,5 +2586,5 @@
         return VERR_EM_INTERPRETER; /* genuine #GP */
 
-    uint64_t uTicks = TMCpuTickGet(pVM);
+    uint64_t uTicks = TMCpuTickGet(pVCpu);
 
     /* Same behaviour in 32 & 64 bits mode */
@@ -2799,5 +2799,5 @@
     {
     case MSR_IA32_TSC:
-        val = TMCpuTickGet(pVM);
+        val = TMCpuTickGet(pVCpu);
         break;
 
Index: /trunk/src/VBox/VMM/VMMAll/TMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 19032)
@@ -53,10 +53,12 @@
  * clocks that only ticks when we're executing guest code.
  *
- * @param   pVM         Pointer to the shared VM structure.
- */
-VMMDECL(void) TMNotifyStartOfExecution(PVM pVM)
-{
+ * @param   pVCpu       The VMCPU to operate on.
+ */
+VMMDECL(void) TMNotifyStartOfExecution(PVMCPU pVCpu)
+{
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
+
     if (pVM->tm.s.fTSCTiedToExecution)
-        tmCpuTickResume(pVM);
+        tmCpuTickResume(pVM, pVCpu);
 }
 
@@ -70,10 +72,12 @@
  * clocks that only ticks when we're executing guest code.
  *
- * @param   pVM         Pointer to the shared VM structure.
- */
-VMMDECL(void) TMNotifyEndOfExecution(PVM pVM)
-{
+ * @param   pVCpu       The VMCPU to operate on.
+ */
+VMMDECL(void) TMNotifyEndOfExecution(PVMCPU pVCpu)
+{
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
+
     if (pVM->tm.s.fTSCTiedToExecution)
-        tmCpuTickPause(pVM);
+        tmCpuTickPause(pVM, pVCpu);
 }
 
@@ -87,11 +91,13 @@
  * clocks that only ticks when we're halted.
  *
- * @param   pVM         Pointer to the shared VM structure.
- */
-VMMDECL(void) TMNotifyStartOfHalt(PVM pVM)
-{
+ * @param   pVCpu       The VMCPU to operate on.
+ */
+VMMDECL(void) TMNotifyStartOfHalt(PVMCPU pVCpu)
+{
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
+
     if (    pVM->tm.s.fTSCTiedToExecution
         &&  !pVM->tm.s.fTSCNotTiedToHalt)
-        tmCpuTickResume(pVM);
+        tmCpuTickResume(pVM, pVCpu);
 }
 
@@ -105,11 +111,13 @@
  * clocks that only ticks when we're halted.
  *
- * @param   pVM         Pointer to the shared VM structure.
- */
-VMMDECL(void) TMNotifyEndOfHalt(PVM pVM)
-{
+ * @param   pVCpu       The VMCPU to operate on.
+ */
+VMMDECL(void) TMNotifyEndOfHalt(PVMCPU pVCpu)
+{
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
+
     if (    pVM->tm.s.fTSCTiedToExecution
         &&  !pVM->tm.s.fTSCNotTiedToHalt)
-        tmCpuTickPause(pVM);
+        tmCpuTickPause(pVM, pVCpu);
 }
 
@@ -659,5 +667,7 @@
 VMMDECL(int) TMTimerSetMillies(PTMTIMER pTimer, uint32_t cMilliesToNext)
 {
-    PVM pVM = pTimer->CTX_SUFF(pVM);
+    PVM    pVM   = pTimer->CTX_SUFF(pVM);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
+
     switch (pTimer->enmClock)
     {
@@ -670,5 +680,5 @@
             return TMTimerSet(pTimer, cMilliesToNext + TMRealGet(pVM));
         case TMCLOCK_TSC:
-            return TMTimerSet(pTimer, cMilliesToNext * pVM->tm.s.cTSCTicksPerSecond / 1000 + TMCpuTickGet(pVM));
+            return TMTimerSet(pTimer, cMilliesToNext * pVM->tm.s.cTSCTicksPerSecond / 1000 + TMCpuTickGet(pVCpu));
 
         default:
@@ -688,5 +698,7 @@
 VMMDECL(int) TMTimerSetMicro(PTMTIMER pTimer, uint64_t cMicrosToNext)
 {
-    PVM pVM = pTimer->CTX_SUFF(pVM);
+    PVM    pVM   = pTimer->CTX_SUFF(pVM);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
+
     switch (pTimer->enmClock)
     {
@@ -704,5 +716,5 @@
 
         case TMCLOCK_TSC:
-            return TMTimerSet(pTimer, TMTimerFromMicro(pTimer, cMicrosToNext) + TMCpuTickGet(pVM));
+            return TMTimerSet(pTimer, TMTimerFromMicro(pTimer, cMicrosToNext) + TMCpuTickGet(pVCpu));
 
         default:
@@ -722,5 +734,7 @@
 VMMDECL(int) TMTimerSetNano(PTMTIMER pTimer, uint64_t cNanosToNext)
 {
-    PVM pVM = pTimer->CTX_SUFF(pVM);
+    PVM    pVM   = pTimer->CTX_SUFF(pVM);
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
+
     switch (pTimer->enmClock)
     {
@@ -738,5 +752,5 @@
 
         case TMCLOCK_TSC:
-            return TMTimerSet(pTimer, TMTimerFromNano(pTimer, cNanosToNext) + TMCpuTickGet(pVM));
+            return TMTimerSet(pTimer, TMTimerFromNano(pTimer, cNanosToNext) + TMCpuTickGet(pVCpu));
 
         default:
@@ -847,5 +861,6 @@
 {
     uint64_t u64;
-    PVM pVM = pTimer->CTX_SUFF(pVM);
+    PVM      pVM   = pTimer->CTX_SUFF(pVM);
+
     switch (pTimer->enmClock)
     {
@@ -860,7 +875,9 @@
             break;
         case TMCLOCK_TSC:
-            u64 = TMCpuTickGet(pVM);
+        {
+            PVMCPU pVCpu = &pVM->aCpus[0];  /* just take the first VCPU */
+            u64 = TMCpuTickGet(pVCpu);
             break;
-
+        }
         default:
             AssertMsgFailed(("Invalid enmClock=%d\n", pTimer->enmClock));
Index: /trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp	(revision 19032)
@@ -54,18 +54,19 @@
  * @returns VBox status code.
  * @param   pVM         The VM to operate on.
+ * @param   pVCpu       The VMCPU to operate on.
  * @internal
  */
-int tmCpuTickResume(PVM pVM)
-{
-    if (!pVM->tm.s.fTSCTicking)
-    {
-        pVM->tm.s.fTSCTicking = true;
+int tmCpuTickResume(PVM pVM, PVMCPU pVCpu)
+{
+    if (!pVCpu->tm.s.fTSCTicking)
+    {
+        pVCpu->tm.s.fTSCTicking = true;
         if (pVM->tm.s.fTSCVirtualized)
         {
             if (pVM->tm.s.fTSCUseRealTSC)
-                pVM->tm.s.u64TSCOffset = ASMReadTSC() - pVM->tm.s.u64TSC;
+                pVCpu->tm.s.u64TSCOffset = ASMReadTSC() - pVCpu->tm.s.u64TSC;
             else
-                pVM->tm.s.u64TSCOffset = tmCpuTickGetRawVirtual(pVM, false /* don't check for pending timers */)
-                                       - pVM->tm.s.u64TSC;
+                pVCpu->tm.s.u64TSCOffset = tmCpuTickGetRawVirtual(pVM, false /* don't check for pending timers */)
+                                         - pVCpu->tm.s.u64TSC;
         }
         return VINF_SUCCESS;
@@ -80,11 +81,13 @@
  *
  * @returns VBox status code.
- * @param   pVM         The VM to operate on.
+ * @param   pVCpu       The VMCPU to operate on.
  * @todo replace this with TMNotifyResume
  */
-VMMDECL(int) TMCpuTickResume(PVM pVM)
-{
+VMMDECL(int) TMCpuTickResume(PVMCPU pVCpu)
+{
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
+
     if (!pVM->tm.s.fTSCTiedToExecution)
-        return tmCpuTickResume(pVM);
+        return tmCpuTickResume(pVM, pVCpu);
     /* ignored */
     return VINF_SUCCESS;
@@ -97,12 +100,13 @@
  * @returns VBox status code.
  * @param   pVM         The VM to operate on.
+ * @param   pVCpu       The VMCPU to operate on.
  * @internal
  */
-int tmCpuTickPause(PVM pVM)
-{
-    if (pVM->tm.s.fTSCTicking)
-    {
-        pVM->tm.s.u64TSC = TMCpuTickGet(pVM);
-        pVM->tm.s.fTSCTicking = false;
+int tmCpuTickPause(PVM pVM, PVMCPU pVCpu)
+{
+    if (pVCpu->tm.s.fTSCTicking)
+    {
+        pVCpu->tm.s.u64TSC = TMCpuTickGet(pVCpu);
+        pVCpu->tm.s.fTSCTicking = false;
         return VINF_SUCCESS;
     }
@@ -116,11 +120,13 @@
  *
  * @returns VBox status code.
- * @param   pVM         The VM to operate on.
+ * @param   pVCpu       The VMCPU to operate on.
  * @todo replace this with TMNotifySuspend
  */
-VMMDECL(int) TMCpuTickPause(PVM pVM)
-{
+VMMDECL(int) TMCpuTickPause(PVMCPU pVCpu)
+{
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
+
     if (!pVM->tm.s.fTSCTiedToExecution)
-        return tmCpuTickPause(pVM);
+        return tmCpuTickPause(pVM, pVCpu);
     /* ignored */
     return VINF_SUCCESS;
@@ -132,11 +138,13 @@
  *
  * @returns true/false accordingly.
- * @param   pVM             The VM handle.
+ * @param   pVCpu       The VMCPU to operate on.
  * @param   poffRealTSC     The offset against the TSC of the current CPU.
  *                          Can be NULL.
  * @thread EMT.
  */
-VMMDECL(bool) TMCpuTickCanUseRealTSC(PVM pVM, uint64_t *poffRealTSC)
-{
+VMMDECL(bool) TMCpuTickCanUseRealTSC(PVMCPU pVCpu, uint64_t *poffRealTSC)
+{
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
+
     /*
      * We require:
@@ -149,5 +157,5 @@
      */
     if (    pVM->tm.s.fMaybeUseOffsettedHostTSC
-        &&  RT_LIKELY(pVM->tm.s.fTSCTicking)
+        &&  RT_LIKELY(pVCpu->tm.s.fTSCTicking)
         &&  (   pVM->tm.s.fTSCUseRealTSC
              || (   !pVM->tm.s.fVirtualSyncCatchUp
@@ -164,5 +172,5 @@
             {
                 uint64_t u64Now = tmCpuTickGetRawVirtual(pVM, false /* don't check for pending timers */)
-                                - pVM->tm.s.u64TSCOffset;
+                                - pVCpu->tm.s.u64TSCOffset;
                 /** @todo When we start collecting statistics on how much time we spend executing
                  * guest code before exiting, we should check this against the next virtual sync
@@ -176,5 +184,5 @@
             /* The source is the real TSC. */
             if (pVM->tm.s.fTSCVirtualized)
-                *poffRealTSC = pVM->tm.s.u64TSCOffset;
+                *poffRealTSC = pVCpu->tm.s.u64TSCOffset;
             else
                 *poffRealTSC = 0;
@@ -188,5 +196,5 @@
     if (!pVM->tm.s.fMaybeUseOffsettedHostTSC)
        STAM_COUNTER_INC(&pVM->tm.s.StatTSCNotFixed);
-    else if (!pVM->tm.s.fTSCTicking)
+    else if (!pVCpu->tm.s.fTSCTicking)
        STAM_COUNTER_INC(&pVM->tm.s.StatTSCNotTicking);
     else if (!pVM->tm.s.fTSCUseRealTSC)
@@ -217,10 +225,12 @@
  *
  * @returns Gets the CPU tsc.
- * @param   pVM         The VM to operate on.
- */
-VMMDECL(uint64_t) TMCpuTickGet(PVM pVM)
-{
+ * @param   pVCpu       The VMCPU to operate on.
+ */
+VMMDECL(uint64_t) TMCpuTickGet(PVMCPU pVCpu)
+{
+    PVM      pVM = pVCpu->CTX_SUFF(pVM);
     uint64_t u64;
-    if (RT_LIKELY(pVM->tm.s.fTSCTicking))
+
+    if (RT_LIKELY(pVCpu->tm.s.fTSCTicking))
     {
         if (pVM->tm.s.fTSCVirtualized)
@@ -230,5 +240,5 @@
             else
                 u64 = tmCpuTickGetRawVirtual(pVM, true /* check for pending timers */);
-            u64 -= pVM->tm.s.u64TSCOffset;
+            u64 -= pVCpu->tm.s.u64TSCOffset;
         }
         else
@@ -236,5 +246,5 @@
     }
     else
-        u64 = pVM->tm.s.u64TSC;
+        u64 = pVCpu->tm.s.u64TSC;
     return u64;
 }
@@ -245,11 +255,11 @@
  *
  * @returns VBox status code.
- * @param   pVM         The VM to operate on.
+ * @param   pVCpu       The VMCPU to operate on.
  * @param   u64Tick     The new timestamp value.
  */
-VMMDECL(int) TMCpuTickSet(PVM pVM, uint64_t u64Tick)
-{
-    Assert(!pVM->tm.s.fTSCTicking);
-    pVM->tm.s.u64TSC = u64Tick;
+VMMDECL(int) TMCpuTickSet(PVMCPU pVCpu, uint64_t u64Tick)
+{
+    Assert(!pVCpu->tm.s.fTSCTicking);
+    pVCpu->tm.s.u64TSC = u64Tick;
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp	(revision 19032)
@@ -32,4 +32,5 @@
 #include "TMInternal.h"
 #include <VBox/vm.h>
+#include <VBox/vmm.h>
 #include <VBox/err.h>
 #include <VBox/log.h>
@@ -682,4 +683,6 @@
 static DECLCALLBACK(int) tmVirtualSetWarpDrive(PVM pVM, uint32_t u32Percent)
 {
+    PVMCPU pVCpu = VMMGetCpu(pVM);
+
     /*
      * Validate it.
@@ -698,5 +701,5 @@
         int rc = TMVirtualPause(pVM);
         AssertRCReturn(rc, rc);
-        rc = TMCpuTickPause(pVM);
+        rc = TMCpuTickPause(pVCpu);
         AssertRCReturn(rc, rc);
     }
@@ -711,5 +714,5 @@
         int rc = TMVirtualResume(pVM);
         AssertRCReturn(rc, rc);
-        rc = TMCpuTickResume(pVM);
+        rc = TMCpuTickResume(pVCpu);
         AssertRCReturn(rc, rc);
     }
Index: /trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp	(revision 19032)
@@ -798,5 +798,5 @@
         return trpmGCExitTrap(pVM, VINF_EM_RAW_EMULATE_INSTR, pRegFrame); /* will trap (optimize later). */
 
-    uint64_t uTicks = TMCpuTickGet(pVM);
+    uint64_t uTicks = TMCpuTickGet(pVCpu);
     pRegFrame->eax = uTicks;
     pRegFrame->edx = uTicks >> 32;
Index: /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 19032)
@@ -792,5 +792,5 @@
 
     /* TSC offset. */
-    if (TMCpuTickCanUseRealTSC(pVM, &pVMCB->ctrl.u64TSCOffset))
+    if (TMCpuTickCanUseRealTSC(pVCpu, &pVMCB->ctrl.u64TSCOffset))
     {
         pVMCB->ctrl.u32InterceptCtrl1 &= ~SVM_CTRL1_INTERCEPT_RDTSC;
@@ -1053,7 +1053,7 @@
     Assert(idCpuCheck == RTMpCpuId());
 #endif
-    TMNotifyStartOfExecution(pVM);
+    TMNotifyStartOfExecution(pVCpu);
     pVCpu->hwaccm.s.svm.pfnVMRun(pVM->hwaccm.s.svm.pVMCBHostPhys, pVCpu->hwaccm.s.svm.pVMCBPhys, pCtx, pVM, pVCpu);
-    TMNotifyEndOfExecution(pVM);
+    TMNotifyEndOfExecution(pVCpu);
     STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatInGC, x);
 
Index: /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 19032)
@@ -1600,5 +1600,5 @@
     uint64_t u64TSCOffset;
 
-    if (TMCpuTickCanUseRealTSC(pVM, &u64TSCOffset))
+    if (TMCpuTickCanUseRealTSC(pVCpu, &u64TSCOffset))
     {
         /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT takes precedence over TSC_OFFSET */
@@ -2192,7 +2192,7 @@
 #endif
 
-    TMNotifyStartOfExecution(pVM);
+    TMNotifyStartOfExecution(pVCpu);
     rc = pVCpu->hwaccm.s.vmx.pfnStartVM(pVCpu->hwaccm.s.fResumeVM, pCtx, &pVCpu->hwaccm.s.vmx.VMCSCache, pVM, pVCpu);
-    TMNotifyEndOfExecution(pVM);
+    TMNotifyEndOfExecution(pVCpu);
 
     AssertMsg(!pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries, ("pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries=%d\n", pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries));
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 19032)
@@ -568,8 +568,8 @@
                 }
 
-                TMNotifyStartOfExecution(pVM);
+                TMNotifyStartOfExecution(pVCpu);
                 rc = pVM->vmm.s.pfnHostToGuestR0(pVM);
                 pVM->vmm.s.iLastGZRc = rc;
-                TMNotifyEndOfExecution(pVM);
+                TMNotifyEndOfExecution(pVCpu);
 
                 /* Re-enable VT-x if previously turned off. */
Index: /trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp	(revision 19031)
+++ /trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp	(revision 19032)
@@ -761,9 +761,9 @@
     //GEN_CHECK_OFF(TM, pvGIPR0);
     GEN_CHECK_OFF(TM, pvGIPRC);
-    GEN_CHECK_OFF(TM, fTSCTicking);
+    GEN_CHECK_OFF(TMCPU, fTSCTicking);
     GEN_CHECK_OFF(TM, fTSCUseRealTSC);
     GEN_CHECK_OFF(TM, fTSCTiedToExecution);
-    GEN_CHECK_OFF(TM, u64TSCOffset);
-    GEN_CHECK_OFF(TM, u64TSC);
+    GEN_CHECK_OFF(TMCPU, u64TSCOffset);
+    GEN_CHECK_OFF(TMCPU, u64TSC);
     GEN_CHECK_OFF(TM, cTSCTicksPerSecond);
     GEN_CHECK_OFF(TM, fVirtualTicking);
Index: /trunk/src/recompiler_new/VBoxREMWrapper.cpp
===================================================================
--- /trunk/src/recompiler_new/VBoxREMWrapper.cpp	(revision 19031)
+++ /trunk/src/recompiler_new/VBoxREMWrapper.cpp	(revision 19032)
@@ -1161,9 +1161,9 @@
     { "STAMR3Register",                         (void *)(uintptr_t)&STAMR3Register,                 &g_aArgsSTAMR3Register[0],                  RT_ELEMENTS(g_aArgsSTAMR3Register),                    REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
     { "STAMR3Deregister",                       (void *)(uintptr_t)&STAMR3Deregister,               &g_aArgsSTAMR3Deregister[0],                RT_ELEMENTS(g_aArgsSTAMR3Deregister),                  REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
-    { "TMCpuTickGet",                           (void *)(uintptr_t)&TMCpuTickGet,                   &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(uint64_t),   NULL },
-    { "TMCpuTickPause",                         (void *)(uintptr_t)&TMCpuTickPause,                 &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
-    { "TMCpuTickResume",                        (void *)(uintptr_t)&TMCpuTickResume,                &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
-    { "TMNotifyEndOfExecution",                 (void *)(uintptr_t)&TMNotifyEndOfExecution,         &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
-    { "TMNotifyStartOfExecution",               (void *)(uintptr_t)&TMNotifyStartOfExecution,       &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
+    { "TMCpuTickGet",                           (void *)(uintptr_t)&TMCpuTickGet,                   &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_INT,    sizeof(uint64_t),   NULL },
+    { "TMCpuTickPause",                         (void *)(uintptr_t)&TMCpuTickPause,                 &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
+    { "TMCpuTickResume",                        (void *)(uintptr_t)&TMCpuTickResume,                &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
+    { "TMNotifyEndOfExecution",                 (void *)(uintptr_t)&TMNotifyEndOfExecution,         &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
+    { "TMNotifyStartOfExecution",               (void *)(uintptr_t)&TMNotifyStartOfExecution,       &g_aArgsVMCPU[0],                           RT_ELEMENTS(g_aArgsVMCPU),                             REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
     { "TMTimerPoll",                            (void *)(uintptr_t)&TMTimerPoll,                    &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_INT,    sizeof(uint64_t),   NULL },
     { "TMR3TimerQueuesDo",                      (void *)(uintptr_t)&TMR3TimerQueuesDo,              &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
Index: /trunk/src/recompiler_new/VBoxRecompiler.c
===================================================================
--- /trunk/src/recompiler_new/VBoxRecompiler.c	(revision 19031)
+++ /trunk/src/recompiler_new/VBoxRecompiler.c	(revision 19032)
@@ -795,6 +795,6 @@
     if (rc == EXCP_DEBUG)
     {
-        TMCpuTickResume(pVM);
-        TMCpuTickPause(pVM);
+        TMCpuTickResume(pVCpu);
+        TMCpuTickPause(pVCpu);
         TMVirtualResume(pVM);
         TMVirtualPause(pVM);
@@ -924,8 +924,8 @@
          * Now we set the execute single instruction flag and enter the cpu_exec loop.
          */
-        TMNotifyStartOfExecution(pVM);
+        TMNotifyStartOfExecution(pVCpu);
         pVM->rem.s.Env.interrupt_request = CPU_INTERRUPT_SINGLE_INSTR;
         rc = cpu_exec(&pVM->rem.s.Env);
-        TMNotifyEndOfExecution(pVM);
+        TMNotifyEndOfExecution(pVCpu);
         switch (rc)
         {
@@ -1051,7 +1051,7 @@
     Assert(pVM->rem.s.fInREM);
 
-    TMNotifyStartOfExecution(pVM);
+    TMNotifyStartOfExecution(pVCpu);
     rc = cpu_exec(&pVM->rem.s.Env);
-    TMNotifyEndOfExecution(pVM);
+    TMNotifyEndOfExecution(pVCpu);
     switch (rc)
     {
@@ -3995,5 +3995,5 @@
 {
     STAM_COUNTER_INC(&gStatCpuGetTSC);
-    return TMCpuTickGet(env->pVM);
+    return TMCpuTickGet(env->pVCpu);
 }
 
