Changeset 92709 in vbox
- Timestamp:
- Dec 2, 2021 1:56:44 PM (3 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/sup.h
r92705 r92709 794 794 * 795 795 * @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 */ 799 DECLINLINE(int64_t) SUPGetTscDelta(PSUPGLOBALINFOPAGE pGip) 800 { 801 #ifdef IN_RING3 802 if (!pGip || pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO) 803 #else 801 804 if (pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO) 805 #endif 802 806 return 0; 803 807 return SUPGetTscDeltaSlow(pGip); -
trunk/src/VBox/VMM/VMMAll/TMAll.cpp
r90346 r92709 189 189 */ 190 190 # 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; 193 194 # else 194 195 uint64_t cTicks = uTsc - pVCpu->tm.s.uTscStartExecuting - SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet); -
trunk/src/VBox/VMM/VMMAll/TMAllCpu.cpp
r90380 r92709 310 310 * exact opposite of what the hardware implements. */ 311 311 # 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); 313 313 # else 314 314 *poffRealTsc = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet); … … 342 342 { 343 343 # ifdef IN_RING3 344 *poffRealTsc = u64Now - (uTscNow + (uint64_t)SUPGetTscDelta( );344 *poffRealTsc = u64Now - (uTscNow + (uint64_t)SUPGetTscDelta(g_pSUPGlobalInfoPage); 345 345 # else 346 346 *poffRealTsc = u64Now - (uTscNow + (uint64_t)SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet)); … … 373 373 # ifdef IN_RING3 374 374 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; 376 377 # else 377 378 uint64_t uCpuHz = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, pVCpu->iHostCpuSet); … … 427 428 * exact opposite of what the hardware implements. */ 428 429 # 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); 430 431 # else 431 432 *poffRealTsc = (uint64_t)0 - pVCpu->tm.s.offTSCRawSrc - (uint64_t)SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet); … … 450 451 451 452 # ifdef IN_RING3 452 *poffRealTsc = u64Now - (*puTscNow + (uint64_t)SUPGetTscDelta( )); /* undoing delta */453 *poffRealTsc = u64Now - (*puTscNow + (uint64_t)SUPGetTscDelta(g_pSUPGlobalInfoPage)); /* undoing delta */ 453 454 # else 454 455 *poffRealTsc = u64Now - (*puTscNow + (uint64_t)SUPGetTscDeltaByCpuSetIndex(pVCpu->iHostCpuSet)); /* undoing delta */ … … 618 619 VMMDECL(uint64_t) TMCpuTicksPerSecond(PVMCC pVM) 619 620 { 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 { 623 626 #ifdef IN_RING3 624 uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage);627 uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGip(pGip); 625 628 #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())); 627 630 #else 628 uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, VMMGetCpu(pVM)->iHostCpuSet);631 uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(pGip, VMMGetCpu(pVM)->iHostCpuSet); 629 632 #endif 630 if (RT_LIKELY(cTSCTicksPerSecond != ~(uint64_t)0)) 631 return cTSCTicksPerSecond; 633 if (RT_LIKELY(cTSCTicksPerSecond != ~(uint64_t)0)) 634 return cTSCTicksPerSecond; 635 } 632 636 } 633 637 return pVM->tm.s.cTSCTicksPerSecond; -
trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
r90346 r92709 57 57 58 58 59 #ifdef IN_RING3 60 /** 61 * @callback_method_impl{FNTIMENANOTSINTERNAL, For driverless mode.} 62 */ 63 static 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 59 73 /** 60 74 * @interface_method_impl{RTTIMENANOTSDATA,pfnRediscover} … … 67 81 DECLCALLBACK(DECLEXPORT(uint64_t)) tmVirtualNanoTSRediscover(PRTTIMENANOTSDATA pData, PRTITMENANOTSEXTRA pExtra) 68 82 { 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). 73 89 */ 74 90 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: 89 108 #ifdef IN_RING0 90 if (pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO)91 pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta : RTTimeNanoTSLegacySyncInvarNoDelta;92 else93 pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarWithDelta : RTTimeNanoTSLegacySyncInvarWithDelta;109 if (pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO) 110 pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta : RTTimeNanoTSLegacySyncInvarNoDelta; 111 else 112 pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarWithDelta : RTTimeNanoTSLegacySyncInvarWithDelta; 94 113 #else 95 if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS)96 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO97 ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta : RTTimeNanoTSLegacySyncInvarNoDelta98 : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim : RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim;99 else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS)100 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO101 ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta : RTTimeNanoTSLegacySyncInvarNoDelta102 : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp : RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp;103 else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_0B)104 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO105 ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta : RTTimeNanoTSLegacySyncInvarNoDelta106 : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicIdExt0B : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicIdExt0B;107 else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_8000001E)108 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO109 ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta : RTTimeNanoTSLegacySyncInvarNoDelta110 : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicIdExt8000001E : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicIdExt8000001E;111 else112 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO113 ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta : RTTimeNanoTSLegacySyncInvarNoDelta114 : 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; 115 134 #endif 116 break;117 118 case SUPGIPMODE_ASYNC_TSC:135 break; 136 137 case SUPGIPMODE_ASYNC_TSC: 119 138 #ifdef IN_RING0 120 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsync : RTTimeNanoTSLegacyAsync;139 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsync : RTTimeNanoTSLegacyAsync; 121 140 #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 else133 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; 134 153 #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 140 164 141 165 /* -
trunk/src/VBox/VMM/VMMR3/TM.cpp
r91988 r92709 251 251 */ 252 252 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 } 283 282 } 284 283 … … 291 290 pVM->tm.s.VirtualGetRawDataR3.pfnBadCpuIndex = tmVirtualNanoTSBadCpuIndex; 292 291 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 } 295 297 /* The rest is done in TMR3InitFinalize() since it's too early to call PDM. */ 296 298 … … 417 419 * override enmTSCMode. 418 420 */ 421 pVM->tm.s.cTSCTicksPerSecondHost = tmR3CalibrateTSC(); 419 422 rc = CFGMR3QueryU64(pCfgHandle, "TSCTicksPerSecond", &pVM->tm.s.cTSCTicksPerSecond); 420 423 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 421 424 { 422 pVM->tm.s.cTSCTicksPerSecond = tmR3CalibrateTSC();425 pVM->tm.s.cTSCTicksPerSecond = pVM->tm.s.cTSCTicksPerSecondHost; 423 426 if ( ( pVM->tm.s.enmTSCMode == TMTSCMODE_DYNAMIC 424 427 || pVM->tm.s.enmTSCMode == TMTSCMODE_VIRT_TSC_EMULATED) … … 442 445 { 443 446 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; 445 448 } 446 449 … … 631 634 pVM->tm.s.enmOriginalTSCMode = pVM->tm.s.enmTSCMode; 632 635 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" 634 638 "TM: TSCTiedToExecution=%RTbool TSCNotTiedToHalt=%RTbool\n", 635 639 pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.cTSCTicksPerSecond, pVM->tm.s.enmTSCMode, tmR3GetTSCModeName(pVM), 640 pVM->tm.s.cTSCTicksPerSecondHost, pVM->tm.s.cTSCTicksPerSecondHost, 636 641 pVM->tm.s.fTSCTiedToExecution, pVM->tm.s.fTSCNotTiedToHalt)); 637 642 … … 860 865 * ASSUME that if the GIP is in invariant TSC mode, it's because the CPU 861 866 * 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) 865 874 return true; 866 875 … … 880 889 ASMCpuId(0x80000007, &uEAX, &uEBX, &uECX, &uEDX); 881 890 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. */ 883 892 return true; 884 893 } … … 902 911 ASMCpuId(0x80000007, &uEAX, &uEBX, &uECX, &uEDX); 903 912 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)) 906 915 return true; 907 916 } … … 992 1001 AssertFailed(); /* This shouldn't happen. */ 993 1002 } 994 /* else: This should only happen in fake SUPLib mode, which we don't really support any more... */ 1003 else 1004 Assert(SUPR3IsDriverless()); 995 1005 996 1006 /* Call this once first to make sure it's initialized. */ … … 998 1008 999 1009 /* 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. 1002 1011 */ 1003 1012 RTThreadYield(); /* Try avoid interruptions between TSC and NanoTS samplings. */ … … 3768 3777 /** @todo figure out what exactly we want here later. */ 3769 3778 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. */ 3772 3783 } 3773 3784 -
trunk/src/VBox/VMM/include/TMInternal.h
r91939 r92709 446 446 VMCPUID idTimerCpu; 447 447 448 /** The number of CPU clock ticks per seconds of the host CPU. */ 449 uint64_t cTSCTicksPerSecondHost; 448 450 /** The number of CPU clock ticks per second (TMCLOCK_TSC). 449 451 * Config variable: TSCTicksPerSecond (64-bit unsigned int)
Note:
See TracChangeset
for help on using the changeset viewer.