Changeset 54202 in vbox
- Timestamp:
- Feb 13, 2015 5:13:44 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 98264
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/mangling.h
r53901 r54202 1720 1720 # define RTTimeNanoTS RT_MANGLER(RTTimeNanoTS) 1721 1721 # define RTTimeNanoTSLegacyAsync RT_MANGLER(RTTimeNanoTSLegacyAsync) 1722 # define RTTimeNanoTSLegacySync RT_MANGLER(RTTimeNanoTSLegacySync) 1722 # define RTTimeNanoTSLegacyAsync_EndProc RT_MANGLER(RTTimeNanoTSLegacyAsync_EndProc) 1723 # define RTTimeNanoTSLegacyInvariantNoDelta RT_MANGLER(RTTimeNanoTSLegacyInvariantNoDelta) 1724 # define RTTimeNanoTSLegacyInvariantNoDelta_EndProc RT_MANGLER(RTTimeNanoTSLegacyInvariantNoDelta_EndProc) 1725 # define RTTimeNanoTSLegacyInvariantWithDelta RT_MANGLER(RTTimeNanoTSLegacyInvariantWithDelta) 1726 # define RTTimeNanoTSLegacyInvariantWithDelta_EndProc RT_MANGLER(RTTimeNanoTSLegacyInvariantWithDelta_EndProc) 1727 # define RTTimeNanoTSLegacySyncNoDelta RT_MANGLER(RTTimeNanoTSLegacySyncNoDelta) 1728 # define RTTimeNanoTSLegacySyncNoDelta_EndProc RT_MANGLER(RTTimeNanoTSLegacySyncNoDelta_EndProc) 1729 # define RTTimeNanoTSLegacySyncWithDelta RT_MANGLER(RTTimeNanoTSLegacySyncWithDelta) 1730 # define RTTimeNanoTSLegacySyncWithDelta_EndProc RT_MANGLER(RTTimeNanoTSLegacySyncWithDelta_EndProc) 1723 1731 # define RTTimeNanoTSLFenceAsync RT_MANGLER(RTTimeNanoTSLFenceAsync) 1724 # define RTTimeNanoTSLFenceSync RT_MANGLER(RTTimeNanoTSLFenceSync) 1732 # define RTTimeNanoTSLFenceAsync_EndProc RT_MANGLER(RTTimeNanoTSLFenceAsync_EndProc) 1733 # define RTTimeNanoTSLFenceInvariantNoDelta RT_MANGLER(RTTimeNanoTSLFenceInvariantNoDelta) 1734 # define RTTimeNanoTSLFenceInvariantNoDelta_EndProc RT_MANGLER(RTTimeNanoTSLFenceInvariantNoDelta_EndProc) 1735 # define RTTimeNanoTSLFenceInvariantWithDelta RT_MANGLER(RTTimeNanoTSLFenceInvariantWithDelta) 1736 # define RTTimeNanoTSLFenceInvariantWithDelta_EndProc RT_MANGLER(RTTimeNanoTSLFenceInvariantWithDelta_EndProc) 1737 # define RTTimeNanoTSLFenceSyncNoDelta RT_MANGLER(RTTimeNanoTSLFenceSyncNoDelta) 1738 # define RTTimeNanoTSLFenceSyncNoDelta_EndProc RT_MANGLER(RTTimeNanoTSLFenceSyncNoDelta_EndProc) 1739 # define RTTimeNanoTSLFenceSyncWithDelta RT_MANGLER(RTTimeNanoTSLFenceSyncWithDelta) 1740 # define RTTimeNanoTSLFenceSyncWithDelta_EndProc RT_MANGLER(RTTimeNanoTSLFenceSyncWithDelta_EndProc) 1725 1741 # define RTTimeNormalize RT_MANGLER(RTTimeNormalize) 1726 1742 # define RTTimeNow RT_MANGLER(RTTimeNow) -
trunk/include/iprt/time.h
r51770 r54202 4 4 5 5 /* 6 * Copyright (C) 2006-201 2Oracle Corporation6 * Copyright (C) 2006-2015 Oracle Corporation 7 7 * 8 8 * This file is part of VirtualBox Open Source Edition (OSE), as … … 915 915 typedef FNTIMENANOTSINTERNAL *PFNTIMENANOTSINTERNAL; 916 916 917 RTDECL(uint64_t) RTTimeNanoTSLegacySync(PRTTIMENANOTSDATA pData);918 917 RTDECL(uint64_t) RTTimeNanoTSLegacyAsync(PRTTIMENANOTSDATA pData); 919 RTDECL(uint64_t) RTTimeNanoTSLFenceSync(PRTTIMENANOTSDATA pData); 918 RTDECL(uint64_t) RTTimeNanoTSLegacyInvariantNoDelta(PRTTIMENANOTSDATA pData); 919 RTDECL(uint64_t) RTTimeNanoTSLegacyInvariantWithDelta(PRTTIMENANOTSDATA pData); 920 RTDECL(uint64_t) RTTimeNanoTSLegacySyncNoDelta(PRTTIMENANOTSDATA pData); 921 RTDECL(uint64_t) RTTimeNanoTSLegacySyncWithDelta(PRTTIMENANOTSDATA pData); 920 922 RTDECL(uint64_t) RTTimeNanoTSLFenceAsync(PRTTIMENANOTSDATA pData); 923 RTDECL(uint64_t) RTTimeNanoTSLFenceInvariantNoDelta(PRTTIMENANOTSDATA pData); 924 RTDECL(uint64_t) RTTimeNanoTSLFenceInvariantWithDelta(PRTTIMENANOTSDATA pData); 925 RTDECL(uint64_t) RTTimeNanoTSLFenceSyncNoDelta(PRTTIMENANOTSDATA pData); 926 RTDECL(uint64_t) RTTimeNanoTSLFenceSyncWithDelta(PRTTIMENANOTSDATA pData); 927 921 928 /** @} */ 922 929 -
trunk/src/VBox/Runtime/common/time/timesup.cpp
r53430 r54202 5 5 6 6 /* 7 * Copyright (C) 2006-201 4Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 82 82 static const PFNTIMENANOTSINTERNAL g_apfnWorkers[] = 83 83 { 84 # define RTTIMENANO_WORKER_DETECT 084 # define RTTIMENANO_WORKER_DETECT 0 85 85 rtTimeNanoTSInternalRediscover, 86 # define RTTIMENANO_WORKER_SYNC_CPUID 1 87 RTTimeNanoTSLegacySync, 88 # define RTTIMENANO_WORKER_ASYNC_CPUID 2 86 87 # define RTTIMENANO_WORKER_LEGACY_SYNC_NO_DELTA 1 88 RTTimeNanoTSLegacySyncNoDelta, 89 # define RTTIMENANO_WORKER_LEGACY_SYNC_WITH_DELTA 2 90 RTTimeNanoTSLegacySyncWithDelta, 91 # define RTTIMENANO_WORKER_LEGACY_ASYNC 3 89 92 RTTimeNanoTSLegacyAsync, 90 # define RTTIMENANO_WORKER_SYNC_LFENCE 3 91 RTTimeNanoTSLFenceSync, 92 # define RTTIMENANO_WORKER_ASYNC_LFENCE 4 93 # define RTTIMENANO_WORKER_LEGACY_INVAR_NO_DELTA 4 94 RTTimeNanoTSLFenceInvariantNoDelta, 95 # define RTTIMENANO_WORKER_LEGACY_INVAR_WITH_DELTA 5 96 RTTimeNanoTSLFenceInvariantWithDelta, 97 98 # define RTTIMENANO_WORKER_LFENCE_SYNC_NO_DELTA 6 99 RTTimeNanoTSLFenceSyncNoDelta, 100 # define RTTIMENANO_WORKER_LFENCE_SYNC_WITH_DELTA 7 101 RTTimeNanoTSLFenceSyncWithDelta, 102 # define RTTIMENANO_WORKER_LFENCE_ASYNC 8 93 103 RTTimeNanoTSLFenceAsync, 94 # define RTTIMENANO_WORKER_FALLBACK 5 104 # define RTTIMENANO_WORKER_LFENCE_INVAR_NO_DELTA 9 105 RTTimeNanoTSLFenceInvariantNoDelta, 106 # define RTTIMENANO_WORKER_LFENCE_INVAR_WITH_DELTA 10 107 RTTimeNanoTSLFenceInvariantWithDelta, 108 109 # define RTTIMENANO_WORKER_FALLBACK 11 95 110 rtTimeNanoTSInternalFallback, 96 111 }; … … 138 153 139 154 /** 155 * Checks if we really need to apply the delta values. 156 * 157 * Getting the delta for a CPU is _very_ expensive, it more than doubles the 158 * execution time for RTTimeNanoTS. 159 * 160 * @returns true if deltas needs to be applied, false if not. 161 * @param pGip The GIP. 162 */ 163 static bool rtTimeNanoTsInternalReallyNeedDeltas(PSUPGLOBALINFOPAGE pGip) 164 { 165 if (!pGip->fOsTscDeltasInSync) 166 { 167 uint32_t i = pGip->cCpus; 168 while (i-- > 0) 169 if ( pGip->aCPUs[i].enmState == SUPGIPCPUSTATE_ONLINE 170 && ( pGip->aCPUs[i].i64TSCDelta > 384 171 || pGip->aCPUs[i].i64TSCDelta < -384) ) 172 return true; 173 } 174 return false; 175 } 176 177 178 /** 140 179 * Called the first time somebody asks for the time or when the GIP 141 180 * is mapped/unmapped. … … 152 191 { 153 192 if (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2) 154 iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC || pGip->u32Mode == SUPGIPMODE_SYNC_TSC 155 ? RTTIMENANO_WORKER_SYNC_LFENCE 156 : RTTIMENANO_WORKER_ASYNC_LFENCE; 193 iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC 194 ? rtTimeNanoTsInternalReallyNeedDeltas(pGip) 195 ? RTTIMENANO_WORKER_LFENCE_INVAR_WITH_DELTA : RTTIMENANO_WORKER_LFENCE_INVAR_NO_DELTA 196 : pGip->u32Mode == SUPGIPMODE_SYNC_TSC 197 ? false /** @todo !rtTimeNanoTsInternalReallyNeedDeltas(pGip) */ 198 ? RTTIMENANO_WORKER_LFENCE_SYNC_WITH_DELTA : RTTIMENANO_WORKER_LFENCE_SYNC_NO_DELTA 199 : RTTIMENANO_WORKER_LFENCE_ASYNC; 157 200 else 158 iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC || pGip->u32Mode == SUPGIPMODE_SYNC_TSC 159 ? RTTIMENANO_WORKER_SYNC_CPUID 160 : RTTIMENANO_WORKER_ASYNC_CPUID; 201 iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC 202 ? rtTimeNanoTsInternalReallyNeedDeltas(pGip) 203 ? RTTIMENANO_WORKER_LEGACY_INVAR_WITH_DELTA : RTTIMENANO_WORKER_LEGACY_INVAR_NO_DELTA 204 : pGip->u32Mode == SUPGIPMODE_SYNC_TSC 205 ? false /** @todo rtTimeNanoTsInternalReallyNeedDeltas(pGip) */ 206 ? RTTIMENANO_WORKER_LEGACY_SYNC_WITH_DELTA : RTTIMENANO_WORKER_LEGACY_SYNC_NO_DELTA 207 : RTTIMENANO_WORKER_LEGACY_ASYNC; 161 208 } 162 209 else 163 210 iWorker = RTTIMENANO_WORKER_FALLBACK; 164 211 165 ASMAtomic XchgU32((uint32_t volatile *)&g_iWorker, iWorker);212 ASMAtomicWriteU32((uint32_t volatile *)&g_iWorker, iWorker); 166 213 return g_apfnWorkers[iWorker](pData); 167 214 } -
trunk/src/VBox/Runtime/common/time/timesupA.asm
r53470 r54202 74 74 %endif 75 75 76 77 76 BEGINCODE 78 77 … … 83 82 %undef ASYNC_GIP 84 83 %undef USE_LFENCE 84 %undef WITH_TSC_DELTA 85 %undef NEED_APIC_ID 85 86 %define NEED_TRANSACTION_ID 86 %define NEED_TO_SAVE_REGS 87 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLegacySync 87 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLegacySyncNoDelta 88 %include "timesupA.mac" 89 90 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLegacyInvariantNoDelta 91 %include "timesupA.mac" 92 93 %define WITH_TSC_DELTA 94 %define NEED_APIC_ID 95 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLegacySyncWithDelta 96 %include "timesupA.mac" 97 98 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLegacyInvariantWithDelta 88 99 %include "timesupA.mac" 89 100 90 101 %define ASYNC_GIP 102 %undef WITH_TSC_DELTA 103 %define NEED_APIC_ID 91 104 %ifdef IN_RC 92 105 %undef NEED_TRANSACTION_ID … … 95 108 %include "timesupA.mac" 96 109 97 %undef ASYNC_GIP98 %define INVARIANT_GIP99 %ifdef IN_RC100 %undef NEED_TRANSACTION_ID101 %endif102 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLegacyInvariant103 ;%include "timesupA.mac"104 ;; @todo r=bird: later.105 110 106 111 ; 107 112 ; Alternative implementation that employs lfence instead of cpuid. 108 113 ; 109 %undef INVARIANT_GIP114 %undef ASYNC_GIP 110 115 %define USE_LFENCE 116 %undef WITH_TSC_DELTA 117 %undef NEED_APIC_ID 111 118 %define NEED_TRANSACTION_ID 112 %undef NEED_TO_SAVE_REGS 113 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLFenceSync 119 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLFenceSyncNoDelta 120 %include "timesupA.mac" 121 122 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLFenceInvariantNoDelta 123 %include "timesupA.mac" 124 125 %define WITH_TSC_DELTA 126 %define NEED_APIC_ID 127 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLFenceSyncWithDelta 128 %include "timesupA.mac" 129 130 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLFenceInvariantWithDelta 114 131 %include "timesupA.mac" 115 132 116 133 %define ASYNC_GIP 134 %undef WITH_TSC_DELTA 135 %define NEED_APIC_ID 117 136 %ifdef IN_RC 118 137 %undef NEED_TRANSACTION_ID … … 121 140 %include "timesupA.mac" 122 141 123 %undef ASYNC_GIP124 %define INVARIANT_GIP125 %define NEED_TRANSACTION_ID126 %define rtTimeNanoTSInternalAsm RTTimeNanoTSLFenceInvariant127 ;%include "timesupA.mac"128 ;; @todo r=bird: later.129 130 142 131 143 %endif ; !IN_GUEST -
trunk/src/VBox/Runtime/common/time/timesupA.mac
r53470 r54202 72 72 73 73 ; 74 ; Load pGip and calc pGipCPU, setting u32ApicIdPlus if necessary.74 ; Load pGip. 75 75 ; 76 76 %ifdef IMPORTED_SUPLIB … … 88 88 cmp dword [esi + SUPGLOBALINFOPAGE.u32Magic], SUPGLOBALINFOPAGE_MAGIC 89 89 jne .Rediscover 90 %ifdef ASYNC_GIP 90 91 ; 92 ; Calc pGipCPU, setting u32ApicIdPlus if necessary. 93 ; 94 %ifdef NEED_APIC_ID 91 95 ; u8ApicId = ASMGetApicId(); 92 96 mov eax, 1 … … 95 99 mov u32ApicIdPlus, ebx 96 100 %endif 97 ; pGipCpu = &pGip->aCPU[pGip->aiCpuFromApicId[u8ApicId]];101 ; pGipCpu/pGipCpuDelta = &pGip->aCPU[pGip->aiCpuFromApicId[u8ApicId]]; 98 102 shr ebx, 24 99 103 movzx ebx, word [esi + ebx * 2 + SUPGLOBALINFOPAGE.aiCpuFromApicId] … … 101 105 mul ebx 102 106 lea edi, [esi + eax + SUPGLOBALINFOPAGE.aCPUs] ; edi == &pGip->aCPU[u8ApicId]; 103 %else104 lea edi, [esi + SUPGLOBALINFOPAGE.aCPUs] ; edi == &pGip->aCPU[0];105 107 %endif 106 108 … … 109 111 ; Serialized loading of u32TransactionId. 110 112 ; 113 %ifdef ASYNC_GIP 111 114 mov ebx, [edi + SUPGIPCPU.u32TransactionId] 115 %else 116 mov ebx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32TransactionId] 117 %endif 112 118 mov u32TransactionId, ebx 113 119 %ifdef USE_LFENCE … … 119 125 120 126 ; 121 ; Load the data and TSC .127 ; Load the data and TSC with delta applied. 122 128 ; 123 129 mov eax, [esi + SUPGLOBALINFOPAGE.u32UpdateIntervalNS] 124 mov u32UpdateIntervalNS, eax ; esi is now free 130 mov u32UpdateIntervalNS, eax 131 %ifdef ASYNC_GIP ; esi is now free. 125 132 mov edx, [edi + SUPGIPCPU.u32UpdateIntervalTSC] 133 %else 134 mov edx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32UpdateIntervalTSC] 135 %endif 126 136 mov u32UpdateIntervalTSC, edx 137 127 138 rdtsc 128 ;; @todo r-bird: Deltas are only valid in INVARIANT mode according to SUPDrv.c macro. 129 ;; edi is pointing to aCpu[0] in INVARIANT and SYNC. Code does more harm than good atm => disabled. 130 ;; (Just drop the SUPTscDeltaApply macro btw.) Sketched what is needed for invariant in timesupA.asm, more work .cpp files in IPRT and VMM. 131 ; SUPTscDeltaApply edi ; Apply inter-cpu TSC-delta to have the normalized TSC value in edx:eax 139 %ifdef WITH_TSC_DELTA 140 cmp dword [edi + SUPGIPCPU.i64TSCDelta], 0xffffffff 141 je .TscDeltaPossiblyInvalid 142 .TscDeltaValid: 143 sub eax, dword [edi + SUPGIPCPU.i64TSCDelta] 144 sbb edx, dword [edi + SUPGIPCPU.i64TSCDelta + 4] 145 .TscDeltaNotValid: ; edi is now free. 146 %endif 147 148 %ifdef ASYNC_GIP 132 149 mov ecx, [edi + SUPGIPCPU.u64NanoTS] 150 mov esi, [edi + SUPGIPCPU.u64NanoTS + 4] 151 %else 152 mov ecx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64NanoTS] 153 mov ebx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64NanoTS + 4] 154 %endif 133 155 mov u64CurNanoTS, ecx 134 mov esi, [edi + SUPGIPCPU.u64NanoTS + 4] 135 mov u64CurNanoTS_Hi, esi 136 mov ebx, [edi + SUPGIPCPU.u64TSC] 137 mov u64TSC, ebx 138 mov ecx, [edi + SUPGIPCPU.u64TSC + 4] 139 mov u64TSC_Hi, ecx 156 mov u64CurNanoTS_Hi, ebx 157 %ifdef ASYNC_GIP 158 mov ecx, [edi + SUPGIPCPU.u64TSC] 159 mov ebx, [edi + SUPGIPCPU.u64TSC + 4] 160 %else 161 mov ecx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64TSC] 162 mov ebx, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64TSC + 4] 163 %endif 164 mov u64TSC, ecx 165 mov u64TSC_Hi, ebx 140 166 141 167 ; u64PrevNanoTS = ASMAtomicReadU64(pu64Prev); 142 168 ; This serializes load/save. And with the dependency on the 143 169 ; RDTSC result, we try to make sure it has completed as well. 170 %ifdef ASYNC_GIP 144 171 mov esi, pData 145 172 mov esi, [esi + RTTIMENANOTSDATA.pu64Prev] 173 %else 174 mov edi, pData 175 mov edi, [esi + RTTIMENANOTSDATA.pu64Prev] 176 %endif 146 177 mov ebx, eax 147 178 mov ecx, edx 179 %ifdef ASYNC_GIP 148 180 lock cmpxchg8b [esi] 181 %else 182 lock cmpxchg8b [edi] 183 %endif 149 184 mov u64PrevNanoTS, eax 150 185 mov u64PrevNanoTS_Hi, edx … … 156 191 ; We've already serialized all the loads and stores at this point. 157 192 ; 158 %ifdef ASYNC_GIP193 %ifdef NEED_APIC_ID 159 194 mov u64RetNanoTS, ebx 160 195 mov u64RetNanoTS_Hi, ecx … … 165 200 jne .ReadGip 166 201 %endif 202 %ifdef ASYNC_GIP 167 203 mov esi, [edi + SUPGIPCPU.u32TransactionId] 204 %else 205 mov esi, [esi + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32TransactionId] 206 %endif 168 207 cmp esi, u32TransactionId 169 208 jne .ReadGip … … 386 425 jmp .Done 387 426 427 428 %ifdef WITH_TSC_DELTA 429 ;; 430 ;; Unlikely branch for when we think the TSC delta might be invalid. 431 ;; 432 .TscDeltaPossiblyInvalid: 433 cmp dword [edi + SUPGIPCPU.i64TSCDelta + 4], 0x7fffffff 434 jne .TscDeltaValid 435 jmp .TscDeltaNotValid 436 %endif 437 388 438 ; 389 439 ; Cleanup variables … … 423 473 %define TmpVar2 [rbp - 38h] 424 474 %ifdef NEED_TRANSACTION_ID 425 %ifdef ASYNC_GIP475 %ifdef NEED_APIC_ID 426 476 %define SavedR14 [rbp - 40h] 427 477 %define SavedR15 [rbp - 48h] … … 431 481 %define pData rdi 432 482 433 %define u64TSC rsi 434 %define pGip rsi 435 %define pGipCPU r8 483 %ifdef ASYNC_GIP 484 %define u64TSC rsi 485 %define pGip rsi 486 %ifdef NEED_APIC_ID 487 %define pGipCPU r8 488 %endif 489 %else 490 %define u64TSC r8 491 %define pGip rsi 492 %ifdef NEED_APIC_ID 493 %define pGipCPU r8 494 %endif 495 %endif 436 496 %define u32TransactionId r9d 437 497 %define u64CurNanoTS r10 … … 444 504 %undef u32ApicIdPlus 445 505 %ifdef NEED_TRANSACTION_ID 446 %ifdef ASYNC_GIP506 %ifdef NEED_APIC_ID 447 507 %define u64SavedRetNanoTS r14 448 508 %define u32ApicIdPlus r15d … … 485 545 486 546 ; 487 ; Load pGip and calc pGipCPU, setting u32ApicIdPlus if necessary. 488 ; Finding the GIP is fun... 547 ; Load pGip - finding the GIP is fun... 489 548 ; 490 549 %ifdef RT_OS_WINDOWS … … 514 573 jne .Rediscover 515 574 516 %ifdef ASYNC_GIP 575 ; 576 ; pGipCPU, setting u32ApicIdPlus if necessary. 577 ; 578 %ifdef NEED_APIC_ID 517 579 ; u8ApicId = ASMGetApicId(); 518 580 mov eax, 1 … … 521 583 mov u32ApicIdPlus, ebx 522 584 %endif 523 ; pGipC pu= &pGip->aCPU[pGip->aiCpuFromApicId[u8ApicId]];585 ; pGipCPU = &pGip->aCPU[pGip->aiCpuFromApicId[u8ApicId]]; 524 586 shr ebx, 24 525 587 movzx eax, word [pGip + rbx * 2 + SUPGLOBALINFOPAGE.aiCpuFromApicId] 526 588 imul eax, SUPGIPCPU_size 527 589 lea pGipCPU, [pGip + rax + SUPGLOBALINFOPAGE.aCPUs] 528 %else529 lea pGipCPU, [pGip + SUPGLOBALINFOPAGE.aCPUs]530 590 %endif 531 591 … … 534 594 ; Serialized loading of u32TransactionId. 535 595 ; 596 %ifdef ASYNC_GIP 536 597 mov u32TransactionId, [pGipCPU + SUPGIPCPU.u32TransactionId] 598 %else 599 mov u32TransactionId, [pGip + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32TransactionId] 600 %endif 537 601 %ifdef USE_LFENCE 538 602 lfence … … 545 609 ; Load the data and TSC. 546 610 ; 547 mov u32UpdateIntervalNS, [pGip + SUPGLOBALINFOPAGE.u32UpdateIntervalNS] ; before u64TSC 611 mov u32UpdateIntervalNS, [pGip + SUPGLOBALINFOPAGE.u32UpdateIntervalNS] 612 %ifdef ASYNC_GIP 548 613 mov u32UpdateIntervalTSC, [pGipCPU + SUPGIPCPU.u32UpdateIntervalTSC] 614 %else 615 mov u32UpdateIntervalTSC, [pGip + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32UpdateIntervalTSC] 616 %endif 617 549 618 rdtsc 550 ;; @todo r-bird: Deltas are only valid in INVARIANT mode according to SUPDrv.c macro.551 ;; pGipCPU is pointing to aCpu[0] in INVARIANT and SYNC. Code is 32-bit, i.e. inefficient. Code does more harm than good atm => disabled.552 ;; (Just drop the SUPTscDeltaApply macro btw.) Sketched what is needed for invariant in timesupA.asm, more work .cpp files in IPRT and VMM.553 ; SUPTscDeltaApply pGipCPU554 619 mov u64PrevNanoTS, [pData + RTTIMENANOTSDATA.pu64Prev] 555 620 mov u64PrevNanoTS, [u64PrevNanoTS] 556 621 shl rdx, 32 557 %ifdef u64SavedRetNanoTS ; doing this here saves a tick or so. 622 or rax, rdx ; rax is u64RetNanoTS. 623 %ifdef WITH_TSC_DELTA 624 mov rdx, [pGipCPU + SUPGIPCPU.i64TSCDelta] 625 mov u64CurNanoTS, 0x7fffffffffffffff ; INT64_MAX - temporarily borrowing u64CurNanoTS 626 cmp rdx, u64CurNanoTS 627 je .TscDeltaNotValid 628 sub rax, rdx 629 .TscDeltaNotValid: 630 %endif 631 %ifdef u64SavedRetNanoTS ; doing this here may save a tick or so? 558 632 mov u64SavedRetNanoTS, rax 559 or u64SavedRetNanoTS, rdx 560 %else 561 or rax, rdx ; rax is u64RetNanoTS. 562 %endif 633 %endif 634 635 %ifdef ASYNC_GIP 563 636 mov u64CurNanoTS, [pGipCPU + SUPGIPCPU.u64NanoTS] 564 mov u64TSC, [pGipCPU + SUPGIPCPU.u64TSC] 637 mov u64TSC, [pGipCPU + SUPGIPCPU.u64TSC] ; transhes pGIP! 638 %else 639 mov u64CurNanoTS, [pGip + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64NanoTS] 640 mov u64TSC, [pGip + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u64TSC] ; trashes pGipCPU! 641 %endif 642 565 643 566 644 %ifdef NEED_TRANSACTION_ID … … 573 651 ; CPUID is serializing, so the async path is safe by default. 574 652 ; 575 %ifdef ASYNC_GIP653 %ifdef NEED_APIC_ID 576 654 mov eax, 1 577 655 cpuid … … 581 659 lock xor qword TmpVar, rax 582 660 %endif 661 %ifdef ASYNC_GIP 583 662 cmp u32TransactionId, [pGipCPU + SUPGIPCPU.u32TransactionId] 663 %else 664 cmp u32TransactionId, [pGip + SUPGLOBALINFOPAGE.aCPUs + SUPGIPCPU.u32TransactionId] 665 %endif 584 666 jne .ReadGip 585 667 test u32TransactionId, 1 -
trunk/src/VBox/Runtime/common/time/timesupref.cpp
r48935 r54202 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 40 40 41 41 42 #define GIP_MODE_SYNC_NO_DELTA 1 43 #define GIP_MODE_SYNC_WITH_DELTA 2 44 #define GIP_MODE_ASYNC 3 45 #define GIP_MODE_INVARIANT_NO_DELTA 4 46 #define GIP_MODE_INVARIANT_WITH_DELTA 5 47 #define IS_GIP_MODE_WITH_DELTA(a_enmMode) \ 48 ((a_enmMode) == GIP_MODE_SYNC_WITH_DELTA || (a_enmMode) == GIP_MODE_INVARIANT_WITH_DELTA) 49 50 42 51 /* 43 52 * Use the CPUID instruction for some kind of serialization. 44 53 */ 45 # undef ASYNC_GIP54 #define GIP_MODE GIP_MODE_SYNC_NO_DELTA 46 55 #undef USE_LFENCE 47 56 #define NEED_TRANSACTION_ID 48 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySync 57 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncNoDelta 49 58 #include "timesupref.h" 50 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySync );59 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncNoDelta); 51 60 52 #define ASYNC_GIP 61 #undef GIP_MODE 62 #define GIP_MODE GIP_MODE_SYNC_NO_DELTA 63 #undef rtTimeNanoTSInternalRef 64 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncWithDelta 65 #include "timesupref.h" 66 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncWithDelta); 67 68 #undef GIP_MODE 69 #define GIP_MODE GIP_MODE_ASYNC 53 70 #ifdef IN_RC 54 71 # undef NEED_TRANSACTION_ID … … 59 76 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsync); 60 77 78 #undef GIP_MODE 79 #define GIP_MODE GIP_MODE_INVARIANT_NO_DELTA 80 #undef NEED_TRANSACTION_ID 81 #define NEED_TRANSACTION_ID 82 #undef rtTimeNanoTSInternalRef 83 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyInvariantNoDelta 84 #include "timesupref.h" 85 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyInvariantNoDelta); 86 87 #undef GIP_MODE 88 #define GIP_MODE GIP_MODE_INVARIANT_WITH_DELTA 89 #undef rtTimeNanoTSInternalRef 90 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyInvariantWithDelta 91 #include "timesupref.h" 92 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyInvariantWithDelta); 93 61 94 62 95 /* 63 96 * Use LFENCE for load serialization. 64 97 */ 65 #undef ASYNC_GIP 98 #undef GIP_MODE 99 #define GIP_MODE GIP_MODE_SYNC_NO_DELTA 66 100 #define USE_LFENCE 67 101 #undef NEED_TRANSACTION_ID 68 102 #define NEED_TRANSACTION_ID 69 103 #undef rtTimeNanoTSInternalRef 70 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSync 104 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncNoDelta 71 105 #include "timesupref.h" 72 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSync );106 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncNoDelta); 73 107 74 #define ASYNC_GIP 108 #undef GIP_MODE 109 #define GIP_MODE GIP_MODE_SYNC_WITH_DELTA 110 #undef rtTimeNanoTSInternalRef 111 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncWithDelta 112 #include "timesupref.h" 113 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncWithDelta); 114 115 #undef GIP_MODE 116 #define GIP_MODE GIP_MODE_ASYNC 75 117 #ifdef IN_RC 76 118 # undef NEED_TRANSACTION_ID … … 81 123 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsync); 82 124 125 #undef GIP_MODE 126 #define GIP_MODE GIP_MODE_INVARIANT_NO_DELTA 127 #undef NEED_TRANSACTION_ID 128 #define NEED_TRANSACTION_ID 129 #undef rtTimeNanoTSInternalRef 130 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceInvariantNoDelta 131 #include "timesupref.h" 132 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceInvariantNoDelta); 133 134 #undef GIP_MODE 135 #define GIP_MODE GIP_MODE_INVARIANT_WITH_DELTA 136 #undef rtTimeNanoTSInternalRef 137 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceInvariantWithDelta 138 #include "timesupref.h" 139 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceInvariantWithDelta); 140 83 141 84 142 #endif /* !IN_GUEST && !RT_NO_GIP */ -
trunk/src/VBox/Runtime/common/time/timesupref.h
r53430 r54202 5 5 6 6 /* 7 * Copyright (C) 2006-201 4Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 45 45 { 46 46 uint64_t u64Delta; 47 #if IS_GIP_MODE_WITH_DELTA(GIP_MODE) 48 int64_t i64TscDelta; 49 #endif 47 50 uint32_t u32NanoTSFactor0; 48 51 uint64_t u64TSC; … … 61 64 return pData->pfnRediscover(pData); 62 65 #endif 63 64 #ifdef ASYNC_GIP 65 uint8_t u8ApicId = ASMGetApicId(); 66 PSUPGIPCPU pGipCpu = &pGip->aCPUs[pGip->aiCpuFromApicId[u8ApicId]]; 66 #if GIP_MODE == GIP_MODE_ASYNC || IS_GIP_MODE_WITH_DELTA(GIP_MODE) 67 uint8_t const u8ApicId = ASMGetApicId(); 68 PSUPGIPCPU pGipCpu = &pGip->aCPUs[pGip->aiCpuFromApicId[u8ApicId]]; 69 #endif 70 71 #ifdef NEED_TRANSACTION_ID 72 # if GIP_MODE == GIP_MODE_ASYNC 73 uint32_t u32TransactionId = pGipCpu->u32TransactionId; 74 # else 75 uint32_t u32TransactionId = pGip->aCPUs[0].u32TransactionId; 76 # endif 77 # ifdef USE_LFENCE 78 ASMReadFenceSSE2(); 79 # else 80 ASMReadFence(); 81 # endif 82 #endif 83 84 #if GIP_MODE == GIP_MODE_ASYNC 85 u32UpdateIntervalTSC = pGipCpu->u32UpdateIntervalTSC; 86 u64NanoTS = pGipCpu->u64NanoTS; 87 u64TSC = pGipCpu->u64TSC; 67 88 #else 68 PSUPGIPCPU pGipCpu = &pGip->aCPUs[0]; 69 #endif 89 u32UpdateIntervalTSC = pGip->aCPUs[0].u32UpdateIntervalTSC; 90 u64NanoTS = pGip->aCPUs[0].u64NanoTS; 91 u64TSC = pGip->aCPUs[0].u64TSC; 92 # if IS_GIP_MODE_WITH_DELTA(GIP_MODE) 93 i64TscDelta = pGipCpu->i64TSCDelta; 94 # endif 95 #endif 96 u32NanoTSFactor0 = pGip->u32UpdateIntervalNS; 97 u64Delta = ASMReadTSC(); 98 u64PrevNanoTS = ASMAtomicReadU64(pData->pu64Prev); 70 99 71 100 #ifdef NEED_TRANSACTION_ID 72 uint32_t u32TransactionId = pGipCpu->u32TransactionId; 73 uint32_t volatile Tmp1; 74 ASMAtomicXchgU32(&Tmp1, u32TransactionId); 75 #endif 76 77 u32UpdateIntervalTSC = pGipCpu->u32UpdateIntervalTSC; 78 u64NanoTS = pGipCpu->u64NanoTS; 79 u64TSC = pGipCpu->u64TSC; 80 u32NanoTSFactor0 = pGip->u32UpdateIntervalNS; 81 u64Delta = ASMReadTSC(); 82 u64PrevNanoTS = ASMAtomicReadU64(pData->pu64Prev); 83 84 #ifdef NEED_TRANSACTION_ID 85 # ifdef ASYNC_GIP 101 # if GIP_MODE == GIP_MODE_ASYNC || IS_GIP_MODE_WITH_DELTA(GIP_MODE) 86 102 if (RT_UNLIKELY(u8ApicId != ASMGetApicId())) 87 103 continue; 88 # elif !defined(RT_ARCH_X86) 89 uint32_t volatile Tmp2; 90 ASMAtomicXchgU32(&Tmp2, u64Delta); 91 # endif 92 if (RT_UNLIKELY( pGipCpu->u32TransactionId != u32TransactionId 93 || (u32TransactionId & 1))) 104 # elif defined(USE_LFENCE) 105 ASMWriteFenceSSE(); 106 # else 107 ASMWriteFence(); 108 # endif 109 # if GIP_MODE == GIP_MODE_ASYNC 110 if (RT_UNLIKELY( pGipCpu->u32TransactionId != u32TransactionId 111 || (u32TransactionId & 1))) 94 112 continue; 113 # else 114 if (RT_UNLIKELY( pGip->aCPUs[0].u32TransactionId != u32TransactionId 115 || (u32TransactionId & 1))) 116 continue; 117 # endif 95 118 #endif 96 119 break; … … 101 124 */ 102 125 u64Delta -= u64TSC; 126 #if IS_GIP_MODE_WITH_DELTA(GIP_MODE) 127 if (RT_LIKELY(i64TscDelta != INT64_MAX)) 128 u64Delta -= i64TscDelta; 129 #endif 103 130 if (RT_UNLIKELY(u64Delta > u32UpdateIntervalTSC)) 104 131 { -
trunk/src/VBox/VMM/VMMR3/TM.cpp
r54195 r54202 168 168 *******************************************************************************/ 169 169 static bool tmR3HasFixedTSC(PVM pVM); 170 static bool tmR3ReallyNeedDeltas(PSUPGLOBALINFOPAGE pGip); 170 171 static const char * tmR3GetTSCModeName(PVM pVM); 171 172 static uint64_t tmR3CalibrateTSC(PVM pVM); … … 274 275 if (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2) 275 276 { 276 if ( g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_INVARIANT_TSC 277 || g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC) 278 pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLFenceSync; 277 if (g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_INVARIANT_TSC) 278 pVM->tm.s.pfnVirtualGetRawR3 = tmR3ReallyNeedDeltas(g_pSUPGlobalInfoPage) 279 ? RTTimeNanoTSLFenceInvariantWithDelta : RTTimeNanoTSLFenceInvariantNoDelta; 280 else if (g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC) 281 pVM->tm.s.pfnVirtualGetRawR3 = false /** @todo tmR3ReallyNeedDeltas(g_pSUPGlobalInfoPage) */ 282 ? RTTimeNanoTSLFenceSyncWithDelta : RTTimeNanoTSLFenceSyncNoDelta; 279 283 else 280 284 pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLFenceAsync; … … 282 286 else 283 287 { 284 if ( g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_INVARIANT_TSC 285 || g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC) 286 pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLegacySync; 288 if (g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_INVARIANT_TSC) 289 pVM->tm.s.pfnVirtualGetRawR3 = tmR3ReallyNeedDeltas(g_pSUPGlobalInfoPage) 290 ? RTTimeNanoTSLegacyInvariantWithDelta : RTTimeNanoTSLegacyInvariantNoDelta; 291 else if (g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC) 292 pVM->tm.s.pfnVirtualGetRawR3 = false /** @todo tmR3ReallyNeedDeltas(g_pSUPGlobalInfoPage) */ 293 ? RTTimeNanoTSLegacySyncWithDelta : RTTimeNanoTSLegacySyncNoDelta; 287 294 else 288 295 pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLegacyAsync; … … 937 944 938 945 /** 946 * Checks if we really need to apply the delta values when calculating time. 947 * 948 * Getting the delta for a CPU is _very_ expensive, it more than doubles the 949 * execution time for RTTimeNanoTS. 950 * 951 * @returns true if deltas needs to be applied, false if not. 952 * @param pGip The GIP. 953 */ 954 static bool tmR3ReallyNeedDeltas(PSUPGLOBALINFOPAGE pGip) 955 { 956 if (!pGip->fOsTscDeltasInSync) 957 { 958 uint32_t i = pGip->cCpus; 959 while (i-- > 0) 960 if ( pGip->aCPUs[i].enmState == SUPGIPCPUSTATE_ONLINE 961 && ( pGip->aCPUs[i].i64TSCDelta > 384 962 || pGip->aCPUs[i].i64TSCDelta < -384) ) 963 return true; 964 } 965 return false; 966 } 967 968 969 /** 939 970 * Calibrate the CPU tick. 940 971 * … … 1029 1060 1030 1061 /** 1062 * Translates TM::pfnVirtualGetRawR3 to a symbol name that we can find in ring-0 1063 * and raw-mode context. 1064 * 1065 * @returns Symbol name. 1066 * @param pfnWorkerR3 The TM::pfnVirtualGetRawR3 value. 1067 */ 1068 static const char *tmR3GetRTTimeNanoName(PFNTIMENANOTSINTERNAL pfnWorkerR3) 1069 { 1070 /* 1071 * Translation of pfnVirtualGetRawR3 to symbol names. 1072 */ 1073 static const struct 1074 { 1075 PFNTIMENANOTSINTERNAL pfnR3Worker; 1076 const char *pszName; 1077 } s_aNanoTsWorkers[] = 1078 { 1079 #define ENTRY(a) { a, #a } 1080 ENTRY(RTTimeNanoTSLegacyAsync), 1081 ENTRY(RTTimeNanoTSLegacyInvariantNoDelta), 1082 ENTRY(RTTimeNanoTSLegacyInvariantWithDelta), 1083 ENTRY(RTTimeNanoTSLegacySyncNoDelta), 1084 ENTRY(RTTimeNanoTSLegacySyncWithDelta), 1085 ENTRY(RTTimeNanoTSLFenceAsync), 1086 ENTRY(RTTimeNanoTSLFenceInvariantNoDelta), 1087 ENTRY(RTTimeNanoTSLFenceInvariantWithDelta), 1088 ENTRY(RTTimeNanoTSLFenceSyncNoDelta), 1089 ENTRY(RTTimeNanoTSLFenceSyncWithDelta), 1090 #undef ENTRY 1091 }; 1092 uint32_t iNanoTs; 1093 for (iNanoTs = 0; iNanoTs < RT_ELEMENTS(s_aNanoTsWorkers); iNanoTs++) 1094 if (pfnWorkerR3 == s_aNanoTsWorkers[iNanoTs].pfnR3Worker) 1095 return s_aNanoTsWorkers[iNanoTs].pszName; 1096 AssertFatal(iNanoTs < RT_ELEMENTS(s_aNanoTsWorkers)); 1097 return NULL; 1098 } 1099 1100 1101 /** 1031 1102 * Finalizes the TM initialization. 1032 1103 * … … 1041 1112 * Resolve symbols. 1042 1113 */ 1114 const char *pszRTTimeNanoTS = tmR3GetRTTimeNanoName(pVM->tm.s.pfnVirtualGetRawR3); 1043 1115 if (!HMIsEnabled(pVM)) 1044 1116 { 1045 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad", &pVM->tm.s.VirtualGetRawDataRC.pfnBad);1117 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad", &pVM->tm.s.VirtualGetRawDataRC.pfnBad); 1046 1118 AssertRCReturn(rc, rc); 1047 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover", &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover);1119 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover", &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover); 1048 1120 AssertRCReturn(rc, rc); 1049 if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLFenceSync) 1050 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLFenceSync", &pVM->tm.s.pfnVirtualGetRawRC); 1051 else if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLFenceAsync) 1052 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLFenceAsync", &pVM->tm.s.pfnVirtualGetRawRC); 1053 else if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLegacySync) 1054 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLegacySync", &pVM->tm.s.pfnVirtualGetRawRC); 1055 else if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLegacyAsync) 1056 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLegacyAsync", &pVM->tm.s.pfnVirtualGetRawRC); 1057 else 1058 AssertFatalFailed(); 1121 rc = PDMR3LdrGetSymbolRC(pVM, NULL, pszRTTimeNanoTS, &pVM->tm.s.pfnVirtualGetRawRC); 1059 1122 AssertRCReturn(rc, rc); 1060 1123 } 1061 1124 1062 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSBad", &pVM->tm.s.VirtualGetRawDataR0.pfnBad);1125 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSBad", &pVM->tm.s.VirtualGetRawDataR0.pfnBad); 1063 1126 AssertRCReturn(rc, rc); 1064 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSRediscover", &pVM->tm.s.VirtualGetRawDataR0.pfnRediscover);1127 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSRediscover", &pVM->tm.s.VirtualGetRawDataR0.pfnRediscover); 1065 1128 AssertRCReturn(rc, rc); 1066 if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLFenceSync) 1067 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "RTTimeNanoTSLFenceSync", &pVM->tm.s.pfnVirtualGetRawR0); 1068 else if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLFenceAsync) 1069 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "RTTimeNanoTSLFenceAsync", &pVM->tm.s.pfnVirtualGetRawR0); 1070 else if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLegacySync) 1071 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "RTTimeNanoTSLegacySync", &pVM->tm.s.pfnVirtualGetRawR0); 1072 else if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLegacyAsync) 1073 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "RTTimeNanoTSLegacyAsync", &pVM->tm.s.pfnVirtualGetRawR0); 1074 else 1075 AssertFatalFailed(); 1129 rc = PDMR3LdrGetSymbolR0(pVM, NULL, pszRTTimeNanoTS, &pVM->tm.s.pfnVirtualGetRawR0); 1076 1130 AssertRCReturn(rc, rc); 1077 1131 … … 1116 1170 pVM->tm.s.VirtualGetRawDataRC.pu64Prev = MMHyperR3ToRC(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev); 1117 1171 AssertFatal(pVM->tm.s.VirtualGetRawDataRC.pu64Prev); 1118 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad", &pVM->tm.s.VirtualGetRawDataRC.pfnBad);1172 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad", &pVM->tm.s.VirtualGetRawDataRC.pfnBad); 1119 1173 AssertFatalRC(rc); 1120 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover", &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover);1174 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover", &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover); 1121 1175 AssertFatalRC(rc); 1122 1123 if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLFenceSync) 1124 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLFenceSync", &pVM->tm.s.pfnVirtualGetRawRC); 1125 else if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLFenceAsync) 1126 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLFenceAsync", &pVM->tm.s.pfnVirtualGetRawRC); 1127 else if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLegacySync) 1128 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLegacySync", &pVM->tm.s.pfnVirtualGetRawRC); 1129 else if (pVM->tm.s.pfnVirtualGetRawR3 == RTTimeNanoTSLegacyAsync) 1130 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "RTTimeNanoTSLegacyAsync", &pVM->tm.s.pfnVirtualGetRawRC); 1131 else 1132 AssertFatalFailed(); 1176 const char *pszRTTimeNanoTS = tmR3GetRTTimeNanoName(pVM->tm.s.pfnVirtualGetRawR3); 1177 rc = PDMR3LdrGetSymbolRC(pVM, NULL, pszRTTimeNanoTS, &pVM->tm.s.pfnVirtualGetRawRC); 1133 1178 AssertFatalRC(rc); 1134 1179 } -
trunk/src/VBox/VMM/include/TMInternal.h
r54195 r54202 420 420 /** Pointer to the ring-3 tmVirtualGetRawNanoTS worker function. */ 421 421 R3PTRTYPE(PFNTIMENANOTSINTERNAL) pfnVirtualGetRawR3; 422 /** Pointer to the ring- 3tmVirtualGetRawNanoTS worker function. */422 /** Pointer to the ring-0 tmVirtualGetRawNanoTS worker function. */ 423 423 R0PTRTYPE(PFNTIMENANOTSINTERNAL) pfnVirtualGetRawR0; 424 /** Pointer to the r ing-3tmVirtualGetRawNanoTS worker function. */424 /** Pointer to the raw-mode tmVirtualGetRawNanoTS worker function. */ 425 425 RCPTRTYPE(PFNTIMENANOTSINTERNAL) pfnVirtualGetRawRC; 426 426 /** Alignment. */
Note:
See TracChangeset
for help on using the changeset viewer.