Index: trunk/include/VBox/sup.h
===================================================================
--- trunk/include/VBox/sup.h	(revision 53268)
+++ trunk/include/VBox/sup.h	(revision 53269)
@@ -310,4 +310,6 @@
     /** The timestamp of the last time we update the update frequency. */
     volatile uint64_t   u64NanoTSLastUpdateHz;
+    /** The TSC frequency of the system. */
+    uint64_t            u64CpuHz;
     /** The set of online CPUs. */
     RTCPUSET            OnlineCpuSet;
@@ -322,5 +324,4 @@
     /** The highest number of CPUs possible. */
     uint16_t            cPossibleCpus;
-    /** The highest number of CPUs possible. */
     uint16_t            u16Padding0;
     /** The max CPU ID (RTMpGetMaxCpuId). */
@@ -328,5 +329,5 @@
 
     /** Padding / reserved space for future data. */
-    uint32_t            au32Padding1[29];
+    uint32_t            au32Padding1[27];
 
     /** Table indexed by the CPU APIC ID to get the CPU table index. */
@@ -360,5 +361,5 @@
  * Upper 16 bits is the major version. Major version is only changed with
  * incompatible changes in the GIP. */
-#define SUPGLOBALINFOPAGE_VERSION   0x00040000
+#define SUPGLOBALINFOPAGE_VERSION   0x00050000
 
 /**
@@ -1467,4 +1468,58 @@
 
 /**
+ * Gets the GIP mode name given the GIP mode.
+ *
+ * @returns The name
+ * @param   enmGipMode      The GIP mode.
+ */
+DECLINLINE(const char *) SUPGetGIPModeName(PSUPGLOBALINFOPAGE pGip)
+{
+    Assert(pGip);
+    switch (pGip->u32Mode)
+    {
+        /* case SUPGIPMODE_INVARIANT_TSC:  return "Invariant"; */
+        case SUPGIPMODE_SYNC_TSC:       return "Synchronous";
+        case SUPGIPMODE_ASYNC_TSC:      return "Asynchronous";
+        case SUPGIPMODE_INVALID:        return "Invalid";
+        default:                        return "???";
+    }
+}
+
+
+/**
+ * Checks if the provided TSC frequency is close enough to the computed TSC
+ * frequency of the host.
+ *
+ * @returns true if it's compatible, false otherwise.
+ */
+DECLINLINE(bool) SUPIsTscFreqCompatible(uint64_t u64CpuHz)
+{
+    PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
+    if (   pGip
+        && pGip->u32Mode == SUPGIPMODE_SYNC_TSC)   /** @todo use INVARIANT_TSC */
+    {
+        uint64_t uLo;
+        uint64_t uHi;
+
+        if (pGip->u64CpuHz == u64CpuHz)
+            return true;
+
+        /* Arbitrary tolerance threshold, tweak later if required, perhaps
+           more tolerance on higher frequencies and less tolerance on lower. */
+        uLo = (pGip->u64CpuHz << 10) / 1025;
+        uHi = pGip->u64CpuHz + (pGip->u64CpuHz - uLo);
+        if (   u64CpuHz < uLo
+            || u64CpuHz > uHi)
+        {
+            return false;
+        }
+        return true;
+    }
+    return false;
+}
+
+
+
+/**
  * Applies the TSC delta to the supplied raw TSC value.
  *
@@ -1478,5 +1533,5 @@
  * @remarks Maybe called with interrupts disabled!
  */
-DECLINLINE(int) SUPTscDeltaApply(PSUPGLOBALINFOPAGE pGip, uint64_t *puTsc, uint16_t idApic, bool *fDeltaApplied)
+DECLINLINE(int) SUPTscDeltaApply(PSUPGLOBALINFOPAGE pGip, uint64_t *puTsc, uint16_t idApic, bool *pfDeltaApplied)
 {
     PSUPGIPCPU pGipCpu;
@@ -1487,4 +1542,5 @@
     Assert(pGip);
 
+    AssertMsgReturn(idApic < RT_ELEMENTS(pGip->aiCpuFromApicId), ("idApic=%u\n", idApic), VERR_INVALID_CPU_ID);
     iCpu = pGip->aiCpuFromApicId[idApic];
     AssertMsgReturn(iCpu < pGip->cCpus, ("iCpu=%u cCpus=%u\n", iCpu, pGip->cCpus), VERR_INVALID_CPU_INDEX);
@@ -1495,9 +1551,9 @@
     {
         *puTsc -= pGipCpu->i64TSCDelta;
-        if (fDeltaApplied)
-            *fDeltaApplied = true;
+        if (pfDeltaApplied)
+            *pfDeltaApplied = true;
     }
-    else if (fDeltaApplied)
-        *fDeltaApplied = false;
+    else if (pfDeltaApplied)
+        *pfDeltaApplied = false;
 
     return VINF_SUCCESS;
Index: trunk/include/VBox/sup.mac
===================================================================
--- trunk/include/VBox/sup.mac	(revision 53268)
+++ trunk/include/VBox/sup.mac	(revision 53269)
@@ -58,4 +58,5 @@
     .u32UpdateIntervalNS        resd 1
     .u64NanoTSLastUpdateHz      resq 1
+    .u64CpuHz                   resq 1
     .OnlineCpuSet               resq 4
     .PresentCpuSet              resq 4
@@ -66,5 +67,5 @@
     .u16Padding0                resw 1
     .idCpuMax                   resd 1
-    .au32Padding1               resd 29
+    .au32Padding1               resd 27
     .aiCpuFromApicId            resw 256
     .aiCpuFromCpuSetIdx         resw 256
Index: trunk/src/VBox/HostDrivers/Support/SUPDrv.c
===================================================================
--- trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 53268)
+++ trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 53269)
@@ -205,4 +205,8 @@
  *  or offline. */
 static volatile uint32_t    g_cMpOnOffEvents;
+/** TSC reading during start of TSC frequency refinement phase. */
+uint64_t                    g_u64TSCAnchor;
+/** Timestamp (in nanosec) during start of TSC frequency refinement phase. */
+uint64_t                    g_u64NanoTSAnchor;
 
 /**
@@ -5921,11 +5925,14 @@
 
 
-#if 0
-/**
- * Measures the nominal TSC frequency.
+/**
+ * Measures the TSC frequency of the system.
  *
  * Uses a busy-wait method for the async. case as it is intended to help push
  * the CPU frequency up, while for the invariant cases using a sleeping method.
  *
+ * The TSC frequency can vary on systems that are not reported as invariant.
+ * However, on such systems the object of this function is to find out what the
+ * nominal, maximum TSC frequency under normal CPU operation.
+ *
  * @returns VBox status code.
  * @param   pGip        Pointer to the GIP.
@@ -5933,5 +5940,5 @@
  * @remarks Must be called only after measuring the TSC deltas.
  */
-static int supdrvGipMeasureNominalTscFreq(PSUPGLOBALINFOPAGE pGip)
+static int supdrvGipMeasureTscFreq(PSUPGLOBALINFOPAGE pGip)
 {
     int cTriesLeft = 4;
@@ -5944,5 +5951,5 @@
     {
         RTCCUINTREG uFlags;
-        uint64_t    u64NanoTs;
+        uint64_t    u64NanoTsBefore;
         uint64_t    u64NanoTsAfter;
         uint64_t    u64TscBefore;
@@ -5955,12 +5962,12 @@
          * Especially important on Windows where the granularity is terrible.
          */
-        u64NanoTs = RTTimeSystemNanoTS();
-        while (RTTimeSystemNanoTS() == u64NanoTs)
+        u64NanoTsBefore = RTTimeSystemNanoTS();
+        while (RTTimeSystemNanoTS() == u64NanoTsBefore)
             ASMNopPause();
 
-        uFlags       = ASMIntDisableFlags();
-        idApicBefore = ASMGetApicId();
-        u64TscBefore = ASMReadTSC();
-        u64NanoTs    = RTTimeSystemNanoTS();
+        uFlags          = ASMIntDisableFlags();
+        idApicBefore    = ASMGetApicId();
+        u64TscBefore    = ASMReadTSC();
+        u64NanoTsBefore = RTTimeSystemNanoTS();
         ASMSetFlags(uFlags);
 
@@ -5971,5 +5978,5 @@
              * Shorter interval produces more variance in the frequency (esp. Windows).
              */
-            RTThreadSleep(200);   /* Sleeping shorter produces a tad more variance in the frequency than I'd like. */
+            RTThreadSleep(200);
             u64NanoTsAfter = RTTimeSystemNanoTS();
             while (RTTimeSystemNanoTS() == u64NanoTsAfter)
@@ -5979,9 +5986,9 @@
         else
         {
-            /* Busy wait, ramps up the CPU frequency on async systems. */
+            /* Busy-wait keeping the frequency up and measure. */
             for (;;)
             {
                 u64NanoTsAfter = RTTimeSystemNanoTS();
-                if (u64NanoTsAfter < RT_NS_100MS + u64NanoTs)
+                if (u64NanoTsAfter < RT_NS_100MS + u64NanoTsBefore)
                     ASMNopPause();
                 else
@@ -5991,6 +5998,6 @@
 
         uFlags      = ASMIntDisableFlags();
+        idApicAfter = ASMGetApicId();
         u64TscAfter = ASMReadTSC();
-        idApicAfter = ASMGetApicId();
         ASMSetFlags(uFlags);
 
@@ -5998,43 +6005,28 @@
         if (supdrvIsInvariantTsc())
         {
-            PSUPGIPCPU pGipCpuBefore;
-            PSUPGIPCPU pGipCpuAfter;
-
-            uint16_t iCpuBefore = pGip->aiCpuFromApicId[idApicBefore];
-            uint16_t iCpuAfter  = pGip->aiCpuFromApicId[idApicAfter];
-            AssertMsgReturn(iCpuBefore < pGip->cCpus, ("iCpuBefore=%u cCpus=%u\n", iCpuBefore, pGip->cCpus), VERR_INVALID_CPU_INDEX);
-            AssertMsgReturn(iCpuAfter  < pGip->cCpus, ("iCpuAfter=%u cCpus=%u\n", iCpuAfter, pGip->cCpus), VERR_INVALID_CPU_INDEX);
-            pGipCpuBefore = &pGip->aCPUs[iCpuBefore];
-            pGipCpuAfter  = &pGip->aCPUs[iCpuAfter];
-
-            if (   pGipCpuBefore->i64TSCDelta != INT64_MAX
-                && pGipCpuAfter->i64TSCDelta  != INT64_MAX)
-            {
-                u64TscBefore -= pGipCpuBefore->i64TSCDelta;
-                u64TscAfter  -= pGipCpuAfter->i64TSCDelta;
-
-                SUPR0Printf("vboxdrv: TSC frequency is %lu Hz - invariant, kernel timer granularity is %lu Ns\n",
-                            ((u64TscAfter - u64TscBefore) * RT_NS_1SEC_64) / (u64NanoTsAfter - u64NanoTs),
-                            RTTimerGetSystemGranularity());
-                return VINF_SUCCESS;
-            }
-            else
-            {
-                SUPR0Printf("vboxdrv: supdrvGipMeasureNominalTscFreq: iCpuBefore=%u iCpuAfter=%u cTriesLeft=%u\n", iCpuBefore,
-                            iCpuAfter, cTriesLeft);
-            }
-        }
-        else
-        {
-            SUPR0Printf("vboxdrv: TSC frequency is %lu Hz - maybe variant, kernel timer granularity is %lu Ns\n",
-                        ((u64TscAfter - u64TscBefore) * RT_NS_1SEC_64) / (u64NanoTsAfter - u64NanoTs),
-                        RTTimerGetSystemGranularity());
-            return VINF_SUCCESS;
-        }
+            int rc;
+            bool fAppliedBefore;
+            bool fAppliedAfter;
+            rc = SUPTscDeltaApply(pGip, &u64TscBefore, idApicBefore, &fAppliedBefore);   AssertRCReturn(rc, rc);
+            rc = SUPTscDeltaApply(pGip, &u64TscAfter,  idApicAfter,  &fAppliedAfter);    AssertRCReturn(rc, rc);
+
+            if (   !fAppliedBefore
+                || !fAppliedAfter)
+            {
+                SUPR0Printf("vboxdrv: supdrvGipMeasureTscFreq: idApicBefore=%u idApicAfter=%u cTriesLeft=%u\n",
+                            idApicBefore, idApicAfter, cTriesLeft);
+                continue;
+            }
+        }
+
+        /*
+         * Update GIP.
+         */
+        pGip->u64CpuHz = ((u64TscAfter - u64TscBefore) * RT_NS_1SEC_64) / (u64NanoTsAfter - u64NanoTsBefore);
+        return VINF_SUCCESS;
     }
 
     return VERR_SUPDRV_TSC_FREQ_MEASUREMENT_FAILED;
 }
-#endif
 
 
@@ -6128,38 +6120,42 @@
 #endif
 
-#if 0
-                /** @todo refactor later and use the nominal TSC rate for invariant case as
-                 *        the real and constant TSC rate. */
-                supdrvGipMeasureNominalTscFreq(pGip);
-#endif
-
-                /*
-                 * Create the timer.
-                 * If CPU_ALL isn't supported we'll have to fall back to synchronous mode.
-                 */
-                if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC)
-                {
-                    rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, RTTIMER_FLAGS_CPU_ALL, supdrvGipAsyncTimer, pDevExt);
-                    if (rc == VERR_NOT_SUPPORTED)
-                    {
-                        OSDBGPRINT(("supdrvGipCreate: omni timer not supported, falling back to synchronous mode\n"));
-                        pGip->u32Mode = SUPGIPMODE_SYNC_TSC;
-                    }
-                }
-                if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)
-                    rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, 0 /* fFlags */, supdrvGipSyncTimer, pDevExt);
+                rc = supdrvGipMeasureTscFreq(pGip);
                 if (RT_SUCCESS(rc))
                 {
+                    if (supdrvIsInvariantTsc())
+                    {
+                        for (iCpu = 0; iCpu < pGip->cCpus; iCpu++)
+                            pGip->aCPUs[iCpu].u64CpuHz = pGip->u64CpuHz;
+                    }
+
                     /*
-                     * We're good.
+                     * Create the timer.
+                     * If CPU_ALL isn't supported we'll have to fall back to synchronous mode.
                      */
-                    Log(("supdrvGipCreate: %u ns interval.\n", u32Interval));
-                    g_pSUPGlobalInfoPage = pGip;
-                    return VINF_SUCCESS;
-                }
-                else
-                {
-                    OSDBGPRINT(("supdrvGipCreate: failed create GIP timer at %u ns interval. rc=%Rrc\n", u32Interval, rc));
-                    Assert(!pDevExt->pGipTimer);
+                    if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC)
+                    {
+                        rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, RTTIMER_FLAGS_CPU_ALL, supdrvGipAsyncTimer, pDevExt);
+                        if (rc == VERR_NOT_SUPPORTED)
+                        {
+                            OSDBGPRINT(("supdrvGipCreate: omni timer not supported, falling back to synchronous mode\n"));
+                            pGip->u32Mode = SUPGIPMODE_SYNC_TSC;
+                        }
+                    }
+                    if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)
+                        rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, 0 /* fFlags */, supdrvGipSyncTimer, pDevExt);
+                    if (RT_SUCCESS(rc))
+                    {
+                        /*
+                         * We're good.
+                         */
+                        Log(("supdrvGipCreate: %u ns interval.\n", u32Interval));
+                        g_pSUPGlobalInfoPage = pGip;
+                        return VINF_SUCCESS;
+                    }
+                    else
+                    {
+                        OSDBGPRINT(("supdrvGipCreate: failed create GIP timer at %u ns interval. rc=%Rrc\n", u32Interval, rc));
+                        Assert(!pDevExt->pGipTimer);
+                    }
                 }
             }
@@ -6281,4 +6277,59 @@
 
     ASMSetFlags(fOldFlags);
+
+    if (supdrvIsInvariantTsc())
+    {
+        /*
+         * Refine the TSC frequency measurement over a longer interval. Ideally, we want to keep the
+         * interval as small as possible while gaining the most consistent and accurate frequency
+         * (compared to what the host OS might have measured).
+         *
+         * In theory, we gain more accuracy with  longer intervals, but we want VMs to startup with the
+         * same TSC frequency whenever possible so we need to keep the interval short.
+         */
+        uint8_t            idApic;
+        uint64_t           u64NanoTS;
+        PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;
+        const int          cSeconds = 3;
+        if (RT_UNLIKELY(iTick == 3))    /* Helps with more consistent values across multiple runs (esp. Windows). */
+        {
+            u64NanoTS = RTTimeSystemNanoTS();
+            while (RTTimeSystemNanoTS() == u64NanoTS)
+                ASMNopPause();
+            fOldFlags         = ASMIntDisableFlags();
+            idApic            = ASMGetApicId();
+            g_u64TSCAnchor    = ASMReadTSC();
+            g_u64NanoTSAnchor = RTTimeSystemNanoTS();
+            ASMSetFlags(fOldFlags);
+            SUPTscDeltaApply(pGip, &g_u64TSCAnchor, idApic, NULL /* pfDeltaApplied */);
+            ++g_u64TSCAnchor;
+        }
+        else if (g_u64TSCAnchor)
+        {
+            uint64_t u64DeltaNanoTS;
+            u64NanoTS = RTTimeSystemNanoTS();
+            while (RTTimeSystemNanoTS() == u64NanoTS)
+                ASMNopPause();
+            fOldFlags = ASMIntDisableFlags();
+            idApic    = ASMGetApicId();
+            u64TSC    = ASMReadTSC();
+            u64NanoTS = RTTimeSystemNanoTS();
+            ASMSetFlags(fOldFlags);
+            SUPTscDeltaApply(pGip, &u64TSC, idApic, NULL /* pfDeltaApplied */);
+            u64DeltaNanoTS = u64NanoTS - g_u64NanoTSAnchor;
+            if (u64DeltaNanoTS >= cSeconds * RT_NS_1SEC_64)
+            {
+                uint16_t iCpu;
+                if (u64DeltaNanoTS < UINT32_MAX)
+                    pGip->u64CpuHz = ASMMultU64ByU32DivByU32(u64TSC - g_u64TSCAnchor, RT_NS_1SEC, u64DeltaNanoTS);
+                else
+                    pGip->u64CpuHz = (u64TSC - g_u64TSCAnchor) / (u64DeltaNanoTS / RT_NS_1SEC);
+
+                for (iCpu = 0; iCpu < pGip->cCpus; iCpu++)
+                    pGip->aCPUs[iCpu].u64CpuHz = pGip->u64CpuHz;
+                g_u64TSCAnchor = 0;
+            }
+        }
+    }
 }
 
@@ -7069,5 +7120,5 @@
  * @param   pDevExt     Pointer to the device instance data.
  */
-static SUPGIPMODE supdrvGipDeterminTscMode(PSUPDRVDEVEXT pDevExt)
+static SUPGIPMODE supdrvGipDetermineTscMode(PSUPDRVDEVEXT pDevExt)
 {
 #if 0
@@ -7191,5 +7242,5 @@
     pGip->u32Magic              = SUPGLOBALINFOPAGE_MAGIC;
     pGip->u32Version            = SUPGLOBALINFOPAGE_VERSION;
-    pGip->u32Mode               = supdrvGipDeterminTscMode(pDevExt);
+    pGip->u32Mode               = supdrvGipDetermineTscMode(pDevExt);
     pGip->cCpus                 = (uint16_t)cCpus;
     pGip->cPages                = (uint16_t)(cbGip / PAGE_SIZE);
@@ -7384,8 +7435,11 @@
     ASMAtomicWriteU32(&pGipCpu->u32UpdateIntervalTSC, u32UpdateIntervalTSC + u32UpdateIntervalTSCSlack);
 
+    if (supdrvIsInvariantTsc())
+        return;
+
     /*
      * CpuHz.
      */
-    u64CpuHz = ASMMult2xU32RetU64(u32UpdateIntervalTSC, RT_NS_1SEC_64);
+    u64CpuHz = ASMMult2xU32RetU64(u32UpdateIntervalTSC, RT_NS_1SEC);
     u64CpuHz /= pGip->u32UpdateIntervalNS;
     ASMAtomicWriteU64(&pGipCpu->u64CpuHz, u64CpuHz);
Index: trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
===================================================================
--- trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h	(revision 53268)
+++ trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h	(revision 53269)
@@ -215,5 +215,5 @@
  *          - (none).
  */
-#define SUPDRV_IOC_VERSION                              0x001c0001
+#define SUPDRV_IOC_VERSION                              0x001d0000
 
 /** SUP_IOCTL_COOKIE. */
Index: trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
===================================================================
--- trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c	(revision 53268)
+++ trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c	(revision 53269)
@@ -418,6 +418,6 @@
 #endif
                     {
-                        printk(KERN_INFO "vboxdrv: TSC mode is %s, kernel timer mode is 'normal'.\n",
-                               g_DevExt.pGip->u32Mode == SUPGIPMODE_SYNC_TSC ? "'synchronous'" : "'asynchronous'");
+                        printk(KERN_INFO "vboxdrv: TSC mode is '%s', tentative frequency %llu Hz.\n",
+                               SUPGetGIPModeName(g_DevExt.pGip), g_DevExt.pGip->u64CpuHz);
                         LogFlow(("VBoxDrv::ModuleInit returning %#x\n", rc));
                         printk(KERN_DEBUG "vboxdrv: Successfully loaded version "
Index: trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
===================================================================
--- trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c	(revision 53268)
+++ trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c	(revision 53269)
@@ -226,4 +226,6 @@
         if (RT_SUCCESS(rc))
         {
+            cmn_err(CE_CONT, "!tsc::mode %s @ tentative %lu Hz\n", SUPGetGIPModeName(g_DevExt.pGip), g_DevExt.pGip->u64CpuHz);
+
             /*
              * Initialize the session hash table.
Index: trunk/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp	(revision 53268)
+++ trunk/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp	(revision 53269)
@@ -97,13 +97,12 @@
         if (g_pSUPGlobalInfoPage)
         {
-            RTPrintf("tstGIP-2: cCpus=%d  u32UpdateHz=%RU32  u32UpdateIntervalNS=%RU32  u64NanoTSLastUpdateHz=%RX64  u32Mode=%d (%s) u32Version=%#x\n",
+            RTPrintf("tstGIP-2: cCpus=%d  u32UpdateHz=%RU32  u32UpdateIntervalNS=%RU32  u64NanoTSLastUpdateHz=%RX64  u64CpuHz=%RU64  u32Mode=%d (%s) u32Version=%#x\n",
                      g_pSUPGlobalInfoPage->cCpus,
                      g_pSUPGlobalInfoPage->u32UpdateHz,
                      g_pSUPGlobalInfoPage->u32UpdateIntervalNS,
                      g_pSUPGlobalInfoPage->u64NanoTSLastUpdateHz,
+                     g_pSUPGlobalInfoPage->u64CpuHz,
                      g_pSUPGlobalInfoPage->u32Mode,
-                     g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC       ? "sync"
-                     : g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_ASYNC_TSC    ? "async"
-                     :                                                            "???",
+                     SUPGetGIPModeName(g_pSUPGlobalInfoPage),
                      g_pSUPGlobalInfoPage->u32Version);
             RTPrintf(fHex
Index: trunk/src/VBox/VMM/VMMR3/TM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 53268)
+++ trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 53269)
@@ -258,8 +258,8 @@
                           N_("The GIP update interval is too big. u32UpdateIntervalNS=%RU32 (u32UpdateHz=%RU32)"),
                           g_pSUPGlobalInfoPage->u32UpdateIntervalNS, g_pSUPGlobalInfoPage->u32UpdateHz);
-    LogRel(("TM: GIP - u32Mode=%d (%s) u32UpdateHz=%u\n", g_pSUPGlobalInfoPage->u32Mode,
-            g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC ? "SyncTSC"
-            : g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_ASYNC_TSC ? "AsyncTSC" : "Unknown",
-            g_pSUPGlobalInfoPage->u32UpdateHz));
+    LogRel(("TM: GIP - u32Mode=%d (%s) u32UpdateHz=%u u32UpdateIntervalNS=%u\n", g_pSUPGlobalInfoPage->u32Mode,
+            SUPGetGIPModeName(g_pSUPGlobalInfoPage), g_pSUPGlobalInfoPage->u32UpdateHz,
+            g_pSUPGlobalInfoPage->u32UpdateIntervalNS));
+    LogRel(("TM: GIP - u64CpuHz=%#RX64 (%'RU64)\n", g_pSUPGlobalInfoPage->u64CpuHz));
 
     /*
