VirtualBox

Changeset 92709 in vbox


Ignore:
Timestamp:
Dec 2, 2021 1:56:44 PM (3 years ago)
Author:
vboxsync
Message:

VMM/TM,SUP: Made it thru TM init in driverless mode... bugref:10138

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/sup.h

    r92705 r92709  
    794794 *
    795795 * @returns The TSC delta value (will not return the special INT64_MAX value).
    796  * @remarks Requires GIP to be initialized and valid.
    797  */
    798 DECLINLINE(int64_t) SUPGetTscDelta(void)
    799 {
    800     PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
     796 * @param   pGip    The GIP, NULL is okay in ring-3.
     797 * @remarks Requires GIP to be initialized and valid if pGip isn't NULL.
     798 */
     799DECLINLINE(int64_t) SUPGetTscDelta(PSUPGLOBALINFOPAGE pGip)
     800{
     801#ifdef IN_RING3
     802    if (!pGip || pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO)
     803#else
    801804    if (pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO)
     805#endif
    802806        return 0;
    803807    return SUPGetTscDeltaSlow(pGip);
  • trunk/src/VBox/VMM/VMMAll/TMAll.cpp

    r90346 r92709  
    189189     */
    190190# ifdef IN_RING3
    191     uint64_t       cTicks = uTsc - pVCpu->tm.s.uTscStartExecuting - SUPGetTscDelta();
    192     uint64_t const uCpuHz = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage);
     191    PSUPGLOBALINFOPAGE const pGip = g_pSUPGlobalInfoPage;
     192    uint64_t       cTicks = uTsc - pVCpu->tm.s.uTscStartExecuting - SUPGetTscDelta(pGip);
     193    uint64_t const uCpuHz = pGip ? SUPGetCpuHzFromGip(pGip) : pVM->tm.s.cTSCTicksPerSecondHost;
    193194# else
    194195    uint64_t       cTicks = uTsc - pVCpu->tm.s.uTscStartExecuting - SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet);
  • trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp

    r90380 r92709  
    310310         *        exact opposite of what the hardware implements. */
    311311# ifdef IN_RING3
    312         *poffRealTsc = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDelta();
     312        *poffRealTsc = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDelta(g_pSUPGlobalInfoPage);
    313313# else
    314314        *poffRealTsc = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet);
     
    342342        {
    343343# ifdef IN_RING3
    344             *poffRealTsc = u64Now - (uTscNow + (uint64_t)SUPGetTscDelta();
     344            *poffRealTsc = u64Now - (uTscNow + (uint64_t)SUPGetTscDelta(g_pSUPGlobalInfoPage);
    345345# else
    346346            *poffRealTsc = u64Now - (uTscNow + (uint64_t)SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet));
     
    373373# ifdef IN_RING3
    374374    RT_NOREF_PV(pVCpu);
    375     uint64_t uCpuHz = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage);
     375    PSUPGIP const pGip = g_pSUPGlobalInfoPage;
     376    uint64_t uCpuHz = pGip ? SUPGetCpuHzFromGip(pGip) : pVCpu->pVMR3->tm.s.cTSCTicksPerSecondHost;
    376377# else
    377378    uint64_t uCpuHz = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, pVCpu->iHostCpuSet);
     
    427428         *        exact opposite of what the hardware implements. */
    428429# ifdef IN_RING3
    429         *poffRealTsc     = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDelta();
     430        *poffRealTsc     = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDelta(g_pSUPGlobalInfoPage);
    430431# else
    431432        *poffRealTsc     = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet);
     
    450451
    451452# ifdef IN_RING3
    452         *poffRealTsc     = u64Now - (*puTscNow + (uint64_t)SUPGetTscDelta()); /* undoing delta */
     453        *poffRealTsc     = u64Now - (*puTscNow + (uint64_t)SUPGetTscDelta(g_pSUPGlobalInfoPage)); /* undoing delta */
    453454# else
    454455        *poffRealTsc     = u64Now - (*puTscNow + (uint64_t)SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet)); /* undoing delta */
     
    618619VMMDECL(uint64_t) TMCpuTicksPerSecond(PVMCC pVM)
    619620{
    620     if (   pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET
    621         && g_pSUPGlobalInfoPage->u32Mode != SUPGIPMODE_INVARIANT_TSC)
    622     {
     621    if (pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET)
     622    {
     623        PSUPGLOBALINFOPAGE const pGip = g_pSUPGlobalInfoPage;
     624        if (pGip && pGip->u32Mode != SUPGIPMODE_INVARIANT_TSC)
     625        {
    623626#ifdef IN_RING3
    624         uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage);
     627            uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGip(pGip);
    625628#elif defined(IN_RING0)
    626         uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, (uint32_t)RTMpCpuIdToSetIndex(RTMpCpuId()));
     629            uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(pGip, (uint32_t)RTMpCpuIdToSetIndex(RTMpCpuId()));
    627630#else
    628         uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, VMMGetCpu(pVM)->iHostCpuSet);
     631            uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(pGip, VMMGetCpu(pVM)->iHostCpuSet);
    629632#endif
    630         if (RT_LIKELY(cTSCTicksPerSecond != ~(uint64_t)0))
    631             return cTSCTicksPerSecond;
     633            if (RT_LIKELY(cTSCTicksPerSecond != ~(uint64_t)0))
     634                return cTSCTicksPerSecond;
     635        }
    632636    }
    633637    return pVM->tm.s.cTSCTicksPerSecond;
  • trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp

    r90346 r92709  
    5757
    5858
     59#ifdef IN_RING3
     60/**
     61 * @callback_method_impl{FNTIMENANOTSINTERNAL, For driverless mode.}
     62 */
     63static DECLCALLBACK(uint64_t) tmR3VirtualNanoTSDriverless(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra)
     64{
     65    RT_NOREF(pData);
     66    if (pExtra)
     67        pExtra->uTSCValue = ASMReadTSC();
     68    return RTTimeSystemNanoTS();
     69}
     70#endif
     71
     72
    5973/**
    6074 * @interface_method_impl{RTTIMENANOTSDATA,pfnRediscover}
     
    6781DECLCALLBACK(DECLEXPORT(uint64_t)) tmVirtualNanoTSRediscover(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra)
    6882{
    69     PVM pVM = RT_FROM_MEMBER(pData, VM, CTX_SUFF(tm.s.VirtualGetRawData));
    70 
    71     /*
    72      * We require a valid GIP for the selection below.  Invalid GIP is fatal.
     83    PVM                   pVM = RT_FROM_MEMBER(pData, VM, CTX_SUFF(tm.s.VirtualGetRawData));
     84    PFNTIMENANOTSINTERNAL pfnWorker;
     85
     86    /*
     87     * We require a valid GIP for the selection below.
     88     * Invalid GIP is fatal, though we have to allow no GIP in driverless mode (ring-3 only).
    7389     */
    7490    PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
    75     AssertFatalMsg(RT_VALID_PTR(pGip), ("pVM=%p pGip=%p\n", pVM, pGip));
    76     AssertFatalMsg(pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC, ("pVM=%p pGip=%p u32Magic=%#x\n", pVM, pGip, pGip->u32Magic));
    77     AssertFatalMsg(pGip->u32Mode > SUPGIPMODE_INVALID && pGip->u32Mode < SUPGIPMODE_END,
    78                    ("pVM=%p pGip=%p u32Mode=%#x\n", pVM, pGip, pGip->u32Mode));
    79 
    80     /*
    81      * Determine the new worker.
    82      */
    83     PFNTIMENANOTSINTERNAL   pfnWorker;
    84     bool const              fLFence = RT_BOOL(ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2);
    85     switch (pGip->u32Mode)
    86     {
    87         case SUPGIPMODE_SYNC_TSC:
    88         case SUPGIPMODE_INVARIANT_TSC:
     91#ifdef IN_RING3
     92    if (pGip)
     93#endif
     94    {
     95        AssertFatalMsg(RT_VALID_PTR(pGip), ("pVM=%p pGip=%p\n", pVM, pGip));
     96        AssertFatalMsg(pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC, ("pVM=%p pGip=%p u32Magic=%#x\n", pVM, pGip, pGip->u32Magic));
     97        AssertFatalMsg(pGip->u32Mode > SUPGIPMODE_INVALID && pGip->u32Mode < SUPGIPMODE_END,
     98                       ("pVM=%p pGip=%p u32Mode=%#x\n", pVM, pGip, pGip->u32Mode));
     99
     100        /*
     101         * Determine the new worker.
     102         */
     103        bool const fLFence = RT_BOOL(ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2);
     104        switch (pGip->u32Mode)
     105        {
     106            case SUPGIPMODE_SYNC_TSC:
     107            case SUPGIPMODE_INVARIANT_TSC:
    89108#ifdef IN_RING0
    90             if (pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO)
    91                 pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta    : RTTimeNanoTSLegacySyncInvarNoDelta;
    92             else
    93                 pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarWithDelta  : RTTimeNanoTSLegacySyncInvarWithDelta;
     109                if (pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO)
     110                    pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta    : RTTimeNanoTSLegacySyncInvarNoDelta;
     111                else
     112                    pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarWithDelta  : RTTimeNanoTSLegacySyncInvarWithDelta;
    94113#else
    95             if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS)
    96                 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
    97                           ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta             : RTTimeNanoTSLegacySyncInvarNoDelta
    98                           : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim : RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim;
    99             else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS)
    100                 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
    101                           ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta            : RTTimeNanoTSLegacySyncInvarNoDelta
    102                           : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp : RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp;
    103             else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_0B)
    104                 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    105                           ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta                 : RTTimeNanoTSLegacySyncInvarNoDelta
    106                           : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicIdExt0B : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicIdExt0B;
    107             else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_8000001E)
    108                 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    109                           ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta                       : RTTimeNanoTSLegacySyncInvarNoDelta
    110                           : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicIdExt8000001E : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicIdExt8000001E;
    111             else
    112                 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    113                           ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta            : RTTimeNanoTSLegacySyncInvarNoDelta
    114                           : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId;
     114                if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS)
     115                    pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     116                              ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta             : RTTimeNanoTSLegacySyncInvarNoDelta
     117                              : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim : RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim;
     118                else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS)
     119                    pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     120                              ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta            : RTTimeNanoTSLegacySyncInvarNoDelta
     121                              : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp : RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp;
     122                else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_0B)
     123                    pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     124                              ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta                 : RTTimeNanoTSLegacySyncInvarNoDelta
     125                              : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicIdExt0B : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicIdExt0B;
     126                else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_8000001E)
     127                    pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     128                              ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta                       : RTTimeNanoTSLegacySyncInvarNoDelta
     129                              : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicIdExt8000001E : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicIdExt8000001E;
     130                else
     131                    pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     132                              ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta            : RTTimeNanoTSLegacySyncInvarNoDelta
     133                              : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId;
    115134#endif
    116             break;
    117 
    118         case SUPGIPMODE_ASYNC_TSC:
     135                break;
     136
     137            case SUPGIPMODE_ASYNC_TSC:
    119138#ifdef IN_RING0
    120             pfnWorker = fLFence ? RTTimeNanoTSLFenceAsync : RTTimeNanoTSLegacyAsync;
     139                pfnWorker = fLFence ? RTTimeNanoTSLFenceAsync : RTTimeNanoTSLegacyAsync;
    121140#else
    122             if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS)
    123                 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseIdtrLim     : RTTimeNanoTSLegacyAsyncUseIdtrLim;
    124             else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS)
    125                 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseRdtscp      : RTTimeNanoTSLegacyAsyncUseRdtscp;
    126             else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL)
    127                 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl : RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl;
    128             else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_0B)
    129                 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseApicIdExt0B : RTTimeNanoTSLegacyAsyncUseApicIdExt0B;
    130             else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_8000001E)
    131                 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseApicIdExt8000001E  : RTTimeNanoTSLegacyAsyncUseApicIdExt8000001E;
    132             else
    133                 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseApicId      : RTTimeNanoTSLegacyAsyncUseApicId;
     141                if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS)
     142                    pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseIdtrLim     : RTTimeNanoTSLegacyAsyncUseIdtrLim;
     143                else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS)
     144                    pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseRdtscp      : RTTimeNanoTSLegacyAsyncUseRdtscp;
     145                else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL)
     146                    pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl : RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl;
     147                else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_0B)
     148                    pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseApicIdExt0B : RTTimeNanoTSLegacyAsyncUseApicIdExt0B;
     149                else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_8000001E)
     150                    pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseApicIdExt8000001E  : RTTimeNanoTSLegacyAsyncUseApicIdExt8000001E;
     151                else
     152                    pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseApicId      : RTTimeNanoTSLegacyAsyncUseApicId;
    134153#endif
    135             break;
    136 
    137         default:
    138             AssertFatalMsgFailed(("pVM=%p pGip=%p u32Mode=%#x\n", pVM, pGip, pGip->u32Mode));
    139     }
     154                break;
     155
     156            default:
     157                AssertFatalMsgFailed(("pVM=%p pGip=%p u32Mode=%#x\n", pVM, pGip, pGip->u32Mode));
     158        }
     159    }
     160#ifdef IN_RING3
     161    else
     162        pfnWorker = tmR3VirtualNanoTSDriverless;
     163#endif
    140164
    141165    /*
  • trunk/src/VBox/VMM/VMMR3/TM.cpp

    r91988 r92709  
    251251     */
    252252    PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
    253     pVM->tm.s.pvGIPR3 = (void *)pGip;
    254     AssertMsgReturn(pVM->tm.s.pvGIPR3, ("GIP support is now required!\n"), VERR_TM_GIP_REQUIRED);
    255     AssertMsgReturn((pGip->u32Version >> 16) == (SUPGLOBALINFOPAGE_VERSION >> 16),
    256                     ("Unsupported GIP version %#x! (expected=%#x)\n", pGip->u32Version, SUPGLOBALINFOPAGE_VERSION),
    257                     VERR_TM_GIP_VERSION);
    258 
    259     RTHCPHYS HCPhysGIP;
    260     rc = SUPR3GipGetPhys(&HCPhysGIP);
    261     AssertMsgRCReturn(rc, ("Failed to get GIP physical address!\n"), rc);
    262 
    263     /* Check assumptions made in TMAllVirtual.cpp about the GIP update interval. */
    264     if (    pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC
    265         &&  pGip->u32UpdateIntervalNS >= 250000000 /* 0.25s */)
    266         return VMSetError(pVM, VERR_TM_GIP_UPDATE_INTERVAL_TOO_BIG, RT_SRC_POS,
    267                           N_("The GIP update interval is too big. u32UpdateIntervalNS=%RU32 (u32UpdateHz=%RU32)"),
    268                           pGip->u32UpdateIntervalNS, pGip->u32UpdateHz);
    269 
    270     /* Log GIP info that may come in handy. */
    271     LogRel(("TM: GIP - u32Mode=%d (%s) u32UpdateHz=%u u32UpdateIntervalNS=%u enmUseTscDelta=%d (%s) fGetGipCpu=%#x cCpus=%d\n",
    272             pGip->u32Mode, SUPGetGIPModeName(pGip), pGip->u32UpdateHz, pGip->u32UpdateIntervalNS,
    273             pGip->enmUseTscDelta, SUPGetGIPTscDeltaModeName(pGip), pGip->fGetGipCpu, pGip->cCpus));
    274     LogRel(("TM: GIP - u64CpuHz=%'RU64 (%#RX64)  SUPGetCpuHzFromGip => %'RU64\n",
    275             pGip->u64CpuHz, pGip->u64CpuHz, SUPGetCpuHzFromGip(pGip)));
    276     for (uint32_t iCpuSet = 0; iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx); iCpuSet++)
    277     {
    278         uint16_t iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet];
    279         if (iGipCpu != UINT16_MAX)
    280             LogRel(("TM: GIP - CPU: iCpuSet=%#x idCpu=%#x idApic=%#x iGipCpu=%#x i64TSCDelta=%RI64 enmState=%d u64CpuHz=%RU64(*) cErrors=%u\n",
    281                     iCpuSet, pGip->aCPUs[iGipCpu].idCpu, pGip->aCPUs[iGipCpu].idApic, iGipCpu, pGip->aCPUs[iGipCpu].i64TSCDelta,
    282                     pGip->aCPUs[iGipCpu].enmState, pGip->aCPUs[iGipCpu].u64CpuHz, pGip->aCPUs[iGipCpu].cErrors));
     253    if (pGip || !SUPR3IsDriverless())
     254    {
     255        pVM->tm.s.pvGIPR3 = (void *)pGip;
     256        AssertMsgReturn(pVM->tm.s.pvGIPR3, ("GIP support is now required!\n"), VERR_TM_GIP_REQUIRED);
     257        AssertMsgReturn((pGip->u32Version >> 16) == (SUPGLOBALINFOPAGE_VERSION >> 16),
     258                        ("Unsupported GIP version %#x! (expected=%#x)\n", pGip->u32Version, SUPGLOBALINFOPAGE_VERSION),
     259                        VERR_TM_GIP_VERSION);
     260
     261        /* Check assumptions made in TMAllVirtual.cpp about the GIP update interval. */
     262        if (    pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC
     263            &&  pGip->u32UpdateIntervalNS >= 250000000 /* 0.25s */)
     264            return VMSetError(pVM, VERR_TM_GIP_UPDATE_INTERVAL_TOO_BIG, RT_SRC_POS,
     265                              N_("The GIP update interval is too big. u32UpdateIntervalNS=%RU32 (u32UpdateHz=%RU32)"),
     266                              pGip->u32UpdateIntervalNS, pGip->u32UpdateHz);
     267
     268        /* Log GIP info that may come in handy. */
     269        LogRel(("TM: GIP - u32Mode=%d (%s) u32UpdateHz=%u u32UpdateIntervalNS=%u enmUseTscDelta=%d (%s) fGetGipCpu=%#x cCpus=%d\n",
     270                pGip->u32Mode, SUPGetGIPModeName(pGip), pGip->u32UpdateHz, pGip->u32UpdateIntervalNS,
     271                pGip->enmUseTscDelta, SUPGetGIPTscDeltaModeName(pGip), pGip->fGetGipCpu, pGip->cCpus));
     272        LogRel(("TM: GIP - u64CpuHz=%'RU64 (%#RX64)  SUPGetCpuHzFromGip => %'RU64\n",
     273                pGip->u64CpuHz, pGip->u64CpuHz, SUPGetCpuHzFromGip(pGip)));
     274        for (uint32_t iCpuSet = 0; iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx); iCpuSet++)
     275        {
     276            uint16_t iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet];
     277            if (iGipCpu != UINT16_MAX)
     278                LogRel(("TM: GIP - CPU: iCpuSet=%#x idCpu=%#x idApic=%#x iGipCpu=%#x i64TSCDelta=%RI64 enmState=%d u64CpuHz=%RU64(*) cErrors=%u\n",
     279                        iCpuSet, pGip->aCPUs[iGipCpu].idCpu, pGip->aCPUs[iGipCpu].idApic, iGipCpu, pGip->aCPUs[iGipCpu].i64TSCDelta,
     280                        pGip->aCPUs[iGipCpu].enmState, pGip->aCPUs[iGipCpu].u64CpuHz, pGip->aCPUs[iGipCpu].cErrors));
     281        }
    283282    }
    284283
     
    291290    pVM->tm.s.VirtualGetRawDataR3.pfnBadCpuIndex = tmVirtualNanoTSBadCpuIndex;
    292291    pVM->tm.s.VirtualGetRawDataR3.pu64Prev       = &pVM->tm.s.u64VirtualRawPrev;
    293     pVM->tm.s.VirtualGetRawDataR0.pu64Prev       = MMHyperR3ToR0(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev);
    294     AssertRelease(pVM->tm.s.VirtualGetRawDataR0.pu64Prev);
     292    if (!SUPR3IsDriverless())
     293    {
     294        pVM->tm.s.VirtualGetRawDataR0.pu64Prev   = MMHyperR3ToR0(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev);
     295        AssertRelease(pVM->tm.s.VirtualGetRawDataR0.pu64Prev);
     296    }
    295297    /* The rest is done in TMR3InitFinalize() since it's too early to call PDM. */
    296298
     
    417419     * override enmTSCMode.
    418420     */
     421    pVM->tm.s.cTSCTicksPerSecondHost = tmR3CalibrateTSC();
    419422    rc = CFGMR3QueryU64(pCfgHandle, "TSCTicksPerSecond", &pVM->tm.s.cTSCTicksPerSecond);
    420423    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
    421424    {
    422         pVM->tm.s.cTSCTicksPerSecond = tmR3CalibrateTSC();
     425        pVM->tm.s.cTSCTicksPerSecond = pVM->tm.s.cTSCTicksPerSecondHost;
    423426        if (   (   pVM->tm.s.enmTSCMode == TMTSCMODE_DYNAMIC
    424427                || pVM->tm.s.enmTSCMode == TMTSCMODE_VIRT_TSC_EMULATED)
     
    442445    {
    443446        LogRel(("TM: NEM overrides the /TM/TSCTicksPerSecond=%RU64 setting.\n", pVM->tm.s.cTSCTicksPerSecond));
    444         pVM->tm.s.cTSCTicksPerSecond = tmR3CalibrateTSC();
     447        pVM->tm.s.cTSCTicksPerSecond = pVM->tm.s.cTSCTicksPerSecondHost;
    445448    }
    446449
     
    631634    pVM->tm.s.enmOriginalTSCMode = pVM->tm.s.enmTSCMode;
    632635    CPUMR3SetCR4Feature(pVM, X86_CR4_TSD, ~X86_CR4_TSD);
    633     LogRel(("TM: cTSCTicksPerSecond=%'RU64 (%#RX64) enmTSCMode=%d (%s)\n"
     636    LogRel(("TM:     cTSCTicksPerSecond=%'RU64 (%#RX64) enmTSCMode=%d (%s)\n"
     637            "TM: cTSCTicksPerSecondHost=%'RU64 (%#RX64)\n"
    634638            "TM: TSCTiedToExecution=%RTbool TSCNotTiedToHalt=%RTbool\n",
    635639            pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.enmTSCMode, tmR3GetTSCModeName(pVM),
     640            pVM->tm.s.cTSCTicksPerSecondHost, pVM->tm.s.cTSCTicksPerSecondHost,
    636641            pVM->tm.s.fTSCTiedToExecution, pVM->tm.s.fTSCNotTiedToHalt));
    637642
     
    860865     * ASSUME that if the GIP is in invariant TSC mode, it's because the CPU
    861866     * actually has invariant TSC.
    862      */
    863     PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
    864     if (pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC)
     867     *
     868     * In driverless mode we just assume sync TSC for now regardless of what
     869     * the case actually is.
     870     */
     871    PSUPGLOBALINFOPAGE const pGip       = g_pSUPGlobalInfoPage;
     872    SUPGIPMODE const         enmGipMode = pGip ? (SUPGIPMODE)pGip->u32Mode : SUPGIPMODE_INVARIANT_TSC;
     873    if (enmGipMode == SUPGIPMODE_INVARIANT_TSC)
    865874        return true;
    866875
     
    880889            ASMCpuId(0x80000007, &uEAX, &uEBX, &uECX, &uEDX);
    881890            if (   (uEDX & X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR) /* TscInvariant */
    882                 && pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)       /* No fixed tsc if the gip timer is in async mode. */
     891                && enmGipMode != SUPGIPMODE_ASYNC_TSC)       /* No fixed tsc if the gip timer is in async mode. */
    883892                return true;
    884893        }
     
    902911                ASMCpuId(0x80000007, &uEAX, &uEBX, &uECX, &uEDX);
    903912                if (   (uEDX & X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR) /* TscInvariant */
    904                     && (   pGip->u32Mode == SUPGIPMODE_SYNC_TSC     /* No fixed tsc if the gip timer is in async mode. */
    905                         || pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC))
     913                    && (   enmGipMode == SUPGIPMODE_SYNC_TSC     /* No fixed tsc if the gip timer is in async mode. */
     914                        || enmGipMode == SUPGIPMODE_INVARIANT_TSC))
    906915                    return true;
    907916            }
     
    9921001        AssertFailed(); /* This shouldn't happen. */
    9931002    }
    994     /* else: This should only happen in fake SUPLib mode, which we don't really support any more... */
     1003    else
     1004        Assert(SUPR3IsDriverless());
    9951005
    9961006    /* Call this once first to make sure it's initialized. */
     
    9981008
    9991009    /*
    1000      * Yield the CPU to increase our chances of getting
    1001      * a correct value.
     1010     * Yield the CPU to increase our chances of getting a correct value.
    10021011     */
    10031012    RTThreadYield();                    /* Try avoid interruptions between TSC and NanoTS samplings. */
     
    37683777    /** @todo figure out what exactly we want here later. */
    37693778    NOREF(fWithParavirtEnabled);
    3770     return (   tmR3HasFixedTSC(pVM)                                        /* Host has fixed-rate TSC. */
    3771             && g_pSUPGlobalInfoPage->u32Mode != SUPGIPMODE_ASYNC_TSC);     /* GIP thinks it's monotonic. */
     3779    PSUPGLOBALINFOPAGE pGip;
     3780    return tmR3HasFixedTSC(pVM)                             /* Host has fixed-rate TSC. */
     3781        && (   (pGip = g_pSUPGlobalInfoPage) != NULL        /* Can be NULL in driverless mode. */
     3782            || (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC));    /* GIP thinks it's monotonic. */
    37723783}
    37733784
  • trunk/src/VBox/VMM/include/TMInternal.h

    r91939 r92709  
    446446    VMCPUID                     idTimerCpu;
    447447
     448    /** The number of CPU clock ticks per seconds of the host CPU.   */
     449    uint64_t                    cTSCTicksPerSecondHost;
    448450    /** The number of CPU clock ticks per second (TMCLOCK_TSC).
    449451     * Config variable: TSCTicksPerSecond (64-bit unsigned int)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette