Changeset 54270 in vbox
- Timestamp:
- Feb 18, 2015 4:11:34 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/sup.h
r54258 r54270 437 437 /** The TSC of the cores are non-stop and have a constant frequency. */ 438 438 SUPGIPMODE_INVARIANT_TSC, 439 /** End of valid GIP mode values (exclusive). */ 440 SUPGIPMODE_END, 439 441 /** The usual 32-bit hack. */ 440 442 SUPGIPMODE_32BIT_HACK = 0x7fffffff -
trunk/include/iprt/mangling.h
r54202 r54270 1719 1719 # define RTTimeMilliTS RT_MANGLER(RTTimeMilliTS) 1720 1720 # define RTTimeNanoTS RT_MANGLER(RTTimeNanoTS) 1721 # define RTTimeNanoTSLegacyAsync RT_MANGLER(RTTimeNanoTSLegacyAsync) 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) 1731 # define RTTimeNanoTSLFenceAsync RT_MANGLER(RTTimeNanoTSLFenceAsync) 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) 1721 # define RTTimeNanoTSLegacyAsync RT_MANGLER(RTTimeNanoTSLegacyAsync) 1722 # define RTTimeNanoTSLegacyAsync_EndProc RT_MANGLER(RTTimeNanoTSLegacyAsync_EndProc) 1723 # define RTTimeNanoTSLegacyAsyncUseApicId RT_MANGLER(RTTimeNanoTSLegacyAsyncUseApicId) 1724 # define RTTimeNanoTSLegacyAsyncUseApicId_EndProc RT_MANGLER(RTTimeNanoTSLegacyAsyncUseApicId_EndProc) 1725 # define RTTimeNanoTSLegacyAsyncUseRdtscp RT_MANGLER(RTTimeNanoTSLegacyAsyncUseRdtscp) 1726 # define RTTimeNanoTSLegacyAsyncUseRdtscp_EndProc RT_MANGLER(RTTimeNanoTSLegacyAsyncUseRdtscp_EndProc) 1727 # define RTTimeNanoTSLegacyAsyncUseIdtrLim RT_MANGLER(RTTimeNanoTSLegacyAsyncUseIdtrLim) 1728 # define RTTimeNanoTSLegacyAsyncUseIdtrLim_EndProc RT_MANGLER(RTTimeNanoTSLegacyAsyncUseIdtrLim_EndProc) 1729 # define RTTimeNanoTSLegacySyncInvarNoDelta RT_MANGLER(RTTimeNanoTSLegacySyncInvarNoDelta) 1730 # define RTTimeNanoTSLegacySyncInvarNoDelta_EndProc RT_MANGLER(RTTimeNanoTSLegacySyncInvarNoDelta_EndProc) 1731 # define RTTimeNanoTSLegacySyncInvarWithDelta RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDelta) 1732 # define RTTimeNanoTSLegacySyncInvarWithDelta_EndProc RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDelta_EndProc) 1733 # define RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId) 1734 # define RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId_EndProc RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId_EndProc) 1735 # define RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp) 1736 # define RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp_EndProc RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp_EndProc) 1737 # define RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim) 1738 # define RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim_EndProc RT_MANGLER(RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim_EndProc) 1739 # define RTTimeNanoTSLFenceAsync RT_MANGLER(RTTimeNanoTSLFenceAsync) 1740 # define RTTimeNanoTSLFenceAsync_EndProc RT_MANGLER(RTTimeNanoTSLFenceAsync_EndProc) 1741 # define RTTimeNanoTSLFenceAsyncUseApicId RT_MANGLER(RTTimeNanoTSLFenceAsyncUseApicId) 1742 # define RTTimeNanoTSLFenceAsyncUseApicId_EndProc RT_MANGLER(RTTimeNanoTSLFenceAsyncUseApicId_EndProc) 1743 # define RTTimeNanoTSLFenceAsyncUseRdtscp RT_MANGLER(RTTimeNanoTSLFenceAsyncUseRdtscp) 1744 # define RTTimeNanoTSLFenceAsyncUseRdtscp_EndProc RT_MANGLER(RTTimeNanoTSLFenceAsyncUseRdtscp_EndProc) 1745 # define RTTimeNanoTSLFenceAsyncUseIdtrLim RT_MANGLER(RTTimeNanoTSLFenceAsyncUseIdtrLim) 1746 # define RTTimeNanoTSLFenceAsyncUseIdtrLim_EndProc RT_MANGLER(RTTimeNanoTSLFenceAsyncUseIdtrLim_EndProc) 1747 # define RTTimeNanoTSLFenceSyncInvarNoDelta RT_MANGLER(RTTimeNanoTSLFenceSyncInvarNoDelta) 1748 # define RTTimeNanoTSLFenceSyncInvarNoDelta_EndProc RT_MANGLER(RTTimeNanoTSLFenceSyncInvarNoDelta_EndProc) 1749 # define RTTimeNanoTSLFenceSyncInvarWithDelta RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDelta) 1750 # define RTTimeNanoTSLFenceSyncInvarWithDelta_EndProc RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDelta_EndProc) 1751 # define RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId) 1752 # define RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId_EndProc RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId_EndProc) 1753 # define RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp) 1754 # define RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp_EndProc RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp_EndProc) 1755 # define RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim) 1756 # define RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim_EndProc RT_MANGLER(RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim_EndProc) 1741 1757 # define RTTimeNormalize RT_MANGLER(RTTimeNormalize) 1742 1758 # define RTTimeNow RT_MANGLER(RTTimeNow) -
trunk/include/iprt/time.h
r54202 r54270 840 840 DECLCALLBACKMEMBER(uint64_t, pfnRediscover)(PRTTIMENANOTSDATA pData); 841 841 842 /** Just a dummy alignment member. */ 843 void *pvDummy; 842 /** 843 * Callback for when some CPU index related stuff goes wrong. 844 * 845 * @returns Nanosecond timestamp. 846 * @param pData Pointer to this structure. 847 * @param idApic The APIC ID if available, otherwise (UINT16_MAX-1). 848 * @param iCpuSet The CPU set index if available, otherwise 849 * (UINT16_MAX-1). 850 * @param iGipCpu The GIP CPU array index if available, otherwise 851 * (UINT16_MAX-1). 852 */ 853 DECLCALLBACKMEMBER(uint64_t, pfnBadCpuIndex)(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu); 844 854 845 855 /** Number of 1ns steps because of overshooting the period. */ … … 862 872 DECLR3CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS)); 863 873 DECLR3CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData)); 864 RTR3PTR pvDummy;874 DECLR3CALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu)); 865 875 uint32_t c1nsSteps; 866 876 uint32_t cExpired; … … 881 891 DECLR0CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS)); 882 892 DECLR0CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData)); 883 RTR0PTR pvDummy;893 DECLR0CALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu)); 884 894 uint32_t c1nsSteps; 885 895 uint32_t cExpired; … … 900 910 DECLRCCALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS)); 901 911 DECLRCCALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData)); 902 RCPTRTYPE(void *) pvDummy;912 DECLRCCALLBACKMEMBER(uint64_t, pfnBadCpuIndex,(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu)); 903 913 uint32_t c1nsSteps; 904 914 uint32_t cExpired; … … 914 924 /** Pointer to an internal RTTimeNanoTS worker (assembly). */ 915 925 typedef FNTIMENANOTSINTERNAL *PFNTIMENANOTSINTERNAL; 916 926 RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarNoDelta(PRTTIMENANOTSDATA pData); 927 RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarNoDelta(PRTTIMENANOTSDATA pData); 928 #ifdef IN_RING3 929 RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseApicId(PRTTIMENANOTSDATA pData); 930 RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseRdtscp(PRTTIMENANOTSDATA pData); 931 RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseIdtrLim(PRTTIMENANOTSDATA pData); 932 RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId(PRTTIMENANOTSDATA pData); 933 RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp(PRTTIMENANOTSDATA pData); 934 RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim(PRTTIMENANOTSDATA pData); 935 RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseApicId(PRTTIMENANOTSDATA pData); 936 RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseRdtscp(PRTTIMENANOTSDATA pData); 937 RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseIdtrLim(PRTTIMENANOTSDATA pData); 938 RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId(PRTTIMENANOTSDATA pData); 939 RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp(PRTTIMENANOTSDATA pData); 940 RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim(PRTTIMENANOTSDATA pData); 941 #else 917 942 RTDECL(uint64_t) RTTimeNanoTSLegacyAsync(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); 943 RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDelta(PRTTIMENANOTSDATA pData); 922 944 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); 945 RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDelta(PRTTIMENANOTSDATA pData); 946 #endif 927 947 928 948 /** @} */ -
trunk/src/VBox/Runtime/VBox/VBoxRTImp.def
r54207 r54270 1337 1337 RTTimeMilliTS 1338 1338 RTTimeNanoTS 1339 RTTimeNanoTSLegacyInvariantNoDelta 1340 RTTimeNanoTSLegacyInvariantWithDelta 1341 RTTimeNanoTSLegacySyncNoDelta 1342 RTTimeNanoTSLegacySyncWithDelta 1343 RTTimeNanoTSLegacyAsync 1344 RTTimeNanoTSLFenceInvariantNoDelta 1345 RTTimeNanoTSLFenceInvariantWithDelta 1346 RTTimeNanoTSLFenceSyncNoDelta 1347 RTTimeNanoTSLFenceSyncWithDelta 1348 RTTimeNanoTSLFenceAsync 1339 RTTimeNanoTSLegacySyncInvarNoDelta 1340 RTTimeNanoTSLFenceSyncInvarNoDelta 1341 RTTimeNanoTSLegacyAsyncUseApicId 1342 RTTimeNanoTSLegacyAsyncUseRdtscp 1343 RTTimeNanoTSLegacyAsyncUseIdtrLim 1344 RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId 1345 RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp 1346 RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim 1347 RTTimeNanoTSLFenceAsyncUseApicId 1348 RTTimeNanoTSLFenceAsyncUseRdtscp 1349 RTTimeNanoTSLFenceAsyncUseIdtrLim 1350 RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId 1351 RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp 1352 RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim 1349 1353 RTTimeNormalize 1350 1354 RTTimeNow -
trunk/src/VBox/Runtime/common/time/timesup.cpp
r54252 r54270 52 52 static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalFallback(PRTTIMENANOTSDATA pData); 53 53 static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalRediscover(PRTTIMENANOTSDATA pData); 54 static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalBadCpuIndex(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu); 54 55 #endif 55 56 … … 65 66 static RTTIMENANOTSDATA g_TimeNanoTSData = 66 67 { 67 /* .pu64Prev = */ &g_TimeNanoTSPrev,68 /* .pfnBad = */ rtTimeNanoTSInternalBitch,69 /* .pfnRediscover = */ rtTimeNanoTSInternalRediscover,70 /* .p vDummy = */ NULL,71 /* .c1nsSteps = */ 0,72 /* .cExpired = */ 0,73 /* .cBadPrev = */ 0,74 /* .cUpdateRaces = */ 068 /* .pu64Prev = */ &g_TimeNanoTSPrev, 69 /* .pfnBad = */ rtTimeNanoTSInternalBitch, 70 /* .pfnRediscover = */ rtTimeNanoTSInternalRediscover, 71 /* .pfnBadCpuIndex = */ rtTimeNanoTSInternalBadCpuIndex, 72 /* .c1nsSteps = */ 0, 73 /* .cExpired = */ 0, 74 /* .cBadPrev = */ 0, 75 /* .cUpdateRaces = */ 0 75 76 }; 76 77 77 /** The index into g_apfnWorkers for the function to use. 78 * This cannot be a pointer because that'll break down in GC due to code relocation. */ 79 static uint32_t g_iWorker = 0; 78 # ifdef IN_RC 80 79 /** Array of rtTimeNanoTSInternal worker functions. 81 80 * This array is indexed by g_iWorker. */ 82 81 static const PFNTIMENANOTSINTERNAL g_apfnWorkers[] = 83 82 { 84 # define RTTIMENANO_WORKER_DETECT083 # define RTTIMENANO_WORKER_DETECT 0 85 84 rtTimeNanoTSInternalRediscover, 86 85 87 # define RTTIMENANO_WORKER_LEGACY_SYNC_NO_DELTA188 RTTimeNanoTSLegacySync NoDelta,89 # define RTTIMENANO_WORKER_LEGACY_SYNC_WITH_DELTA290 RTTimeNanoTSLegacySync WithDelta,91 # define RTTIMENANO_WORKER_LEGACY_ASYNC386 # define RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_NO_DELTA 1 87 RTTimeNanoTSLegacySyncInvarNoDelta, 88 # define RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_WITH_DELTA 2 89 RTTimeNanoTSLegacySyncInvarWithDelta, 90 # define RTTIMENANO_WORKER_LEGACY_ASYNC 3 92 91 RTTimeNanoTSLegacyAsync, 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 92 93 # define RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_NO_DELTA 4 94 RTTimeNanoTSLFenceSyncInvarNoDelta, 95 # define RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_WITH_DELTA 5 96 RTTimeNanoTSLFenceSyncInvarWithDelta, 97 # define RTTIMENANO_WORKER_LFENCE_ASYNC 6 103 98 RTTimeNanoTSLFenceAsync, 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 99 100 # define RTTIMENANO_WORKER_FALLBACK 7 110 101 rtTimeNanoTSInternalFallback, 111 102 }; 112 113 114 /** 115 * Helper function that's used by the assembly routines when something goes bust. 116 * 117 * @param pData Pointer to the data structure. 118 * @param u64NanoTS The calculated nano ts. 119 * @param u64DeltaPrev The delta relative to the previously returned timestamp. 120 * @param u64PrevNanoTS The previously returned timestamp (as it was read it). 121 */ 122 static DECLCALLBACK(void) rtTimeNanoTSInternalBitch(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS) 103 /** The index into g_apfnWorkers for the function to use. 104 * @remarks This cannot be a pointer because that'll break down in RC due to 105 * code relocation. */ 106 static uint32_t g_iWorker = RTTIMENANO_WORKER_DETECT; 107 # else 108 /** Pointer to the worker */ 109 static PFNTIMENANOTSINTERNAL g_pfnWorker = rtTimeNanoTSInternalRediscover; 110 # endif /* IN_RC */ 111 112 113 /** 114 * @interface_method_impl{RTTIMENANOTSDATA, pfnBad} 115 */ 116 static DECLCALLBACK(void) rtTimeNanoTSInternalBitch(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, 117 uint64_t u64PrevNanoTS) 123 118 { 124 119 pData->cBadPrev++; … … 130 125 u64DeltaPrev, u64PrevNanoTS, u64NanoTS)); 131 126 } 127 128 /** 129 * @interface_method_impl{RTTIMENANOTSDATA, pfnBadCpuIndex} 130 */ 131 static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalBadCpuIndex(PRTTIMENANOTSDATA pData, uint16_t idApic, 132 uint16_t iCpuSet, uint16_t iGipCpu) 133 { 134 # ifndef IN_RC 135 AssertMsgFailed(("idApic=%#x iCpuSet=%#x iGipCpu=%#x\n", idApic, iCpuSet, iGipCpu)); 136 return RTTimeSystemNanoTS(); 137 # else 138 RTAssertReleasePanic(); 139 return 0; 140 # endif 141 } 142 132 143 133 144 /** … … 147 158 return RTTimeSystemNanoTS(); 148 159 # else 160 RTAssertReleasePanic(); 149 161 return 0; 150 162 # endif … … 158 170 static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalRediscover(PRTTIMENANOTSDATA pData) 159 171 { 160 uint32_t iWorker; 161 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 172 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 173 # ifdef IN_RC 174 uint32_t iWorker; 175 # else 176 PFNTIMENANOTSINTERNAL pfnWorker; 177 # endif 162 178 if ( pGip 163 179 && pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC … … 167 183 { 168 184 if (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2) 169 iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC 170 ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 171 ? RTTIMENANO_WORKER_LFENCE_INVAR_NO_DELTA : RTTIMENANO_WORKER_LFENCE_INVAR_WITH_DELTA 172 : pGip->u32Mode == SUPGIPMODE_SYNC_TSC 173 ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 174 ? RTTIMENANO_WORKER_LFENCE_SYNC_NO_DELTA : RTTIMENANO_WORKER_LFENCE_SYNC_WITH_DELTA 175 : RTTIMENANO_WORKER_LFENCE_ASYNC; 185 { 186 # ifdef IN_RC 187 iWorker = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC 188 ? RTTIMENANO_WORKER_LFENCE_ASYNC 189 : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 190 ? RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_NO_DELTA 191 : RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_WITH_DELTA; 192 # elif defined(IN_RING0) 193 pfnWorker = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC 194 ? RTTimeNanoTSLFenceAsync 195 : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 196 ? RTTimeNanoTSLFenceSyncInvarNoDelta 197 : RTTimeNanoTSLFenceSyncInvarWithDelta; 198 # else 199 if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC) 200 pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS 201 ? RTTimeNanoTSLFenceAsyncUseIdtrLim 202 : pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 203 ? RTTimeNanoTSLFenceAsyncUseRdtscp 204 : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID 205 ? RTTimeNanoTSLFenceAsyncUseApicId 206 : rtTimeNanoTSInternalFallback; 207 else 208 pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS 209 ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO 210 ? RTTimeNanoTSLFenceSyncInvarNoDelta 211 : RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim 212 : pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 213 ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO 214 ? RTTimeNanoTSLFenceSyncInvarNoDelta 215 : RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp 216 : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID 217 ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 218 ? RTTimeNanoTSLFenceSyncInvarNoDelta 219 : RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId 220 : rtTimeNanoTSInternalFallback; 221 # endif 222 } 176 223 else 177 iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC 178 ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 179 ? RTTIMENANO_WORKER_LEGACY_INVAR_NO_DELTA : RTTIMENANO_WORKER_LEGACY_INVAR_WITH_DELTA 180 : pGip->u32Mode == SUPGIPMODE_SYNC_TSC 181 ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 182 ? RTTIMENANO_WORKER_LEGACY_SYNC_NO_DELTA : RTTIMENANO_WORKER_LEGACY_SYNC_WITH_DELTA 183 : RTTIMENANO_WORKER_LEGACY_ASYNC; 224 { 225 # ifdef IN_RC 226 iWorker = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC 227 ? RTTIMENANO_WORKER_LEGACY_ASYNC 228 : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 229 ? RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_NO_DELTA : RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_WITH_DELTA; 230 # elif defined(IN_RING0) 231 pfnWorker = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC 232 ? RTTimeNanoTSLegacyAsync 233 : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 234 ? RTTimeNanoTSLegacySyncInvarNoDelta 235 : RTTimeNanoTSLegacySyncInvarWithDelta; 236 # else 237 if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC) 238 pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 239 ? RTTimeNanoTSLegacyAsyncUseRdtscp 240 : pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS 241 ? RTTimeNanoTSLegacyAsyncUseIdtrLim 242 : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID 243 ? RTTimeNanoTSLegacyAsyncUseApicId 244 : rtTimeNanoTSInternalFallback; 245 else 246 pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 247 ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO 248 ? RTTimeNanoTSLegacySyncInvarNoDelta 249 : RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp 250 : pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS 251 ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO 252 ? RTTimeNanoTSLegacySyncInvarNoDelta 253 : RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim 254 : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID 255 ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 256 ? RTTimeNanoTSLegacySyncInvarNoDelta 257 : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId 258 : rtTimeNanoTSInternalFallback; 259 # endif 260 } 184 261 } 185 262 else 263 # ifdef IN_RC 186 264 iWorker = RTTIMENANO_WORKER_FALLBACK; 187 265 # else 266 pfnWorker = rtTimeNanoTSInternalFallback; 267 # endif 268 269 # ifdef IN_RC 188 270 ASMAtomicWriteU32((uint32_t volatile *)&g_iWorker, iWorker); 189 271 return g_apfnWorkers[iWorker](pData); 272 # else 273 ASMAtomicWritePtr((void * volatile *)&g_pfnWorker, (void *)(uintptr_t)pfnWorker); 274 return pfnWorker(pData); 275 # endif 190 276 } 191 277 … … 199 285 { 200 286 #if !defined(IN_GUEST) && !defined(RT_NO_GIP) 287 # ifdef IN_RC 201 288 return g_apfnWorkers[g_iWorker](&g_TimeNanoTSData); 289 # else 290 return g_pfnWorker(&g_TimeNanoTSData); 291 # endif 202 292 #else 203 293 return RTTimeSystemNanoTS(); -
trunk/src/VBox/Runtime/common/time/timesupA.asm
r54202 r54270 29 29 %include "iprt/asmdefs.mac" 30 30 %include "VBox/sup.mac" 31 32 ; 33 ; Use the C reference implementation for now. 34 ; 35 %error "This is out of date, use C code. Not worth it for a couple of ticks in some functions and equal or worse performance in others." 36 This is out of date 37 This is out of date 38 This is out of date 31 39 32 40 -
trunk/src/VBox/Runtime/common/time/timesupref.cpp
r54202 r54270 37 37 #include <iprt/asm-amd64-x86.h> 38 38 #include <VBox/sup.h> 39 #ifdef IN_RC 40 # include <VBox/vmm/vmm.h> 41 # include <VBox/vmm/vm.h> 42 #endif 39 43 #include "internal/time.h" 40 44 41 45 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) 46 #define TMPL_MODE_SYNC_INVAR_NO_DELTA 1 47 #define TMPL_MODE_SYNC_INVAR_WITH_DELTA 2 48 #define TMPL_MODE_ASYNC 3 49 49 50 50 51 51 /* 52 * Use the CPUID instruction for some kind of serialization. 53 */ 54 #define GIP_MODE GIP_MODE_SYNC_NO_DELTA 55 #undef USE_LFENCE 56 #define NEED_TRANSACTION_ID 57 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncNoDelta 52 * Use the XCHG instruction for some kind of serialization. 53 */ 54 #define TMPL_READ_FENCE() ASMReadFence() 55 56 #undef TMPL_MODE 57 #define TMPL_MODE TMPL_MODE_SYNC_INVAR_NO_DELTA 58 #undef TMPL_GET_CPU_METHOD 59 #define TMPL_GET_CPU_METHOD 0 60 #undef rtTimeNanoTSInternalRef 61 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarNoDelta 58 62 #include "timesupref.h" 59 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncNoDelta); 60 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 70 #ifdef IN_RC 71 # undef NEED_TRANSACTION_ID 63 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarNoDelta); 64 65 #ifdef IN_RING3 66 67 # undef TMPL_MODE 68 # define TMPL_MODE TMPL_MODE_SYNC_INVAR_WITH_DELTA 69 # undef TMPL_GET_CPU_METHOD 70 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_APIC_ID 71 # undef rtTimeNanoTSInternalRef 72 # define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId 73 # include "timesupref.h" 74 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId); 75 76 # undef TMPL_GET_CPU_METHOD 77 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 78 # undef rtTimeNanoTSInternalRef 79 # define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp 80 # include "timesupref.h" 81 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp); 82 83 # undef TMPL_GET_CPU_METHOD 84 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS 85 # undef rtTimeNanoTSInternalRef 86 # define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim 87 # include "timesupref.h" 88 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim); 89 90 # undef TMPL_MODE 91 # define TMPL_MODE TMPL_MODE_ASYNC 92 # undef TMPL_GET_CPU_METHOD 93 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_APIC_ID 94 # undef rtTimeNanoTSInternalRef 95 # define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsyncUseApicId 96 # include "timesupref.h" 97 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsyncUseApicId); 98 99 # undef TMPL_GET_CPU_METHOD 100 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 101 # undef rtTimeNanoTSInternalRef 102 # define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsyncUseRdtscp 103 # include "timesupref.h" 104 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsyncUseRdtscp); 105 106 # undef TMPL_GET_CPU_METHOD 107 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS 108 # undef rtTimeNanoTSInternalRef 109 # define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsyncUseIdtrLim 110 # include "timesupref.h" 111 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsyncUseIdtrLim); 112 113 #else /* IN_RC || IN_RING0: Disable interrupts and call getter function. */ 114 115 # undef TMPL_MODE 116 # define TMPL_MODE TMPL_MODE_SYNC_INVAR_WITH_DELTA 117 # undef TMPL_GET_CPU_METHOD 118 # define TMPL_GET_CPU_METHOD UINT32_MAX 119 # undef rtTimeNanoTSInternalRef 120 # define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDelta 121 # include "timesupref.h" 122 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDelta); 123 124 # undef TMPL_MODE 125 # define TMPL_MODE TMPL_MODE_ASYNC 126 # undef rtTimeNanoTSInternalRef 127 # define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsync 128 # include "timesupref.h" 129 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsync); 130 72 131 #endif 73 #undef rtTimeNanoTSInternalRef74 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsync75 #include "timesupref.h"76 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsync);77 78 #undef GIP_MODE79 #define GIP_MODE GIP_MODE_INVARIANT_NO_DELTA80 #undef NEED_TRANSACTION_ID81 #define NEED_TRANSACTION_ID82 #undef rtTimeNanoTSInternalRef83 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyInvariantNoDelta84 #include "timesupref.h"85 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyInvariantNoDelta);86 87 #undef GIP_MODE88 #define GIP_MODE GIP_MODE_INVARIANT_WITH_DELTA89 #undef rtTimeNanoTSInternalRef90 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyInvariantWithDelta91 #include "timesupref.h"92 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyInvariantWithDelta);93 132 94 133 … … 96 135 * Use LFENCE for load serialization. 97 136 */ 98 #undef GIP_MODE 99 #define GIP_MODE GIP_MODE_SYNC_NO_DELTA 100 #define USE_LFENCE 101 #undef NEED_TRANSACTION_ID 102 #define NEED_TRANSACTION_ID 137 #undef TMPL_READ_FENCE 138 #define TMPL_READ_FENCE() ASMReadFenceSSE2() 139 140 #undef TMPL_MODE 141 #define TMPL_MODE TMPL_MODE_SYNC_INVAR_NO_DELTA 142 #undef TMPL_GET_CPU_METHOD 143 #define TMPL_GET_CPU_METHOD 0 103 144 #undef rtTimeNanoTSInternalRef 104 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncNoDelta145 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarNoDelta 105 146 #include "timesupref.h" 106 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncNoDelta); 107 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 117 #ifdef IN_RC 118 # undef NEED_TRANSACTION_ID 147 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarNoDelta); 148 149 #ifdef IN_RING3 150 151 # undef TMPL_MODE 152 # define TMPL_MODE TMPL_MODE_SYNC_INVAR_WITH_DELTA 153 # undef TMPL_GET_CPU_METHOD 154 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_APIC_ID 155 # undef rtTimeNanoTSInternalRef 156 # define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId 157 # include "timesupref.h" 158 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId); 159 160 # undef TMPL_GET_CPU_METHOD 161 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 162 # undef rtTimeNanoTSInternalRef 163 # define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp 164 # include "timesupref.h" 165 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp); 166 167 # undef TMPL_GET_CPU_METHOD 168 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS 169 # undef rtTimeNanoTSInternalRef 170 # define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim 171 # include "timesupref.h" 172 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim); 173 174 # undef TMPL_MODE 175 # define TMPL_MODE TMPL_MODE_ASYNC 176 # undef TMPL_GET_CPU_METHOD 177 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_APIC_ID 178 # undef rtTimeNanoTSInternalRef 179 # define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsyncUseApicId 180 # include "timesupref.h" 181 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsyncUseApicId); 182 183 # undef TMPL_GET_CPU_METHOD 184 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 185 # undef rtTimeNanoTSInternalRef 186 # define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsyncUseRdtscp 187 # include "timesupref.h" 188 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsyncUseRdtscp); 189 190 # undef TMPL_GET_CPU_METHOD 191 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS 192 # undef rtTimeNanoTSInternalRef 193 # define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsyncUseIdtrLim 194 # include "timesupref.h" 195 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsyncUseIdtrLim); 196 197 #else /* IN_RC || IN_RING0: Disable interrupts and call getter function. */ 198 199 # undef TMPL_MODE 200 # define TMPL_MODE TMPL_MODE_SYNC_INVAR_WITH_DELTA 201 # undef TMPL_GET_CPU_METHOD 202 # define TMPL_GET_CPU_METHOD UINT32_MAX 203 # undef rtTimeNanoTSInternalRef 204 # define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDelta 205 # include "timesupref.h" 206 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDelta); 207 208 # undef TMPL_MODE 209 # define TMPL_MODE TMPL_MODE_ASYNC 210 # undef rtTimeNanoTSInternalRef 211 # define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsync 212 # include "timesupref.h" 213 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsync); 214 119 215 #endif 120 #undef rtTimeNanoTSInternalRef121 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsync122 #include "timesupref.h"123 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsync);124 125 #undef GIP_MODE126 #define GIP_MODE GIP_MODE_INVARIANT_NO_DELTA127 #undef NEED_TRANSACTION_ID128 #define NEED_TRANSACTION_ID129 #undef rtTimeNanoTSInternalRef130 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceInvariantNoDelta131 #include "timesupref.h"132 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceInvariantNoDelta);133 134 #undef GIP_MODE135 #define GIP_MODE GIP_MODE_INVARIANT_WITH_DELTA136 #undef rtTimeNanoTSInternalRef137 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceInvariantWithDelta138 #include "timesupref.h"139 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceInvariantWithDelta);140 216 141 217 -
trunk/src/VBox/Runtime/common/time/timesupref.h
r54202 r54270 45 45 { 46 46 uint64_t u64Delta; 47 #if IS_GIP_MODE_WITH_DELTA(GIP_MODE)47 #if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA 48 48 int64_t i64TscDelta; 49 # ifdef IN_RING3 50 PSUPGIPCPU pGipCpuAttemptedTscRecalibration = NULL; 51 # endif 49 52 #endif 50 53 uint32_t u32NanoTSFactor0; … … 53 56 uint32_t u32UpdateIntervalTSC; 54 57 uint64_t u64PrevNanoTS; 58 AssertCompile(RT_IS_POWER_OF_TWO(RTCPUSET_MAX_CPUS)); 55 59 56 60 /* … … 59 63 for (;;) 60 64 { 65 #ifndef IN_RING3 /* This simplifies and improves everything. */ 66 RTCCUINTREG const uFlags = ASMIntDisableFlags(); 67 #endif 68 69 /* 70 * Check that the GIP is sane and that the premises for this worker function 71 * hasn't changed (CPU onlined with bad delta or missing features). 72 */ 61 73 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 62 #ifdef IN_RING3 63 if (RT_UNLIKELY(!pGip || pGip->u32Magic != SUPGLOBALINFOPAGE_MAGIC)) 64 return pData->pfnRediscover(pData); 65 #endif 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 if ( RT_LIKELY(pGip) 75 && RT_LIKELY(pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC) 76 #if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA 77 && RT_LIKELY(pGip->enmUseTscDelta >= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO) 78 #else 79 && RT_LIKELY(pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO) 80 #endif 81 #if defined(IN_RING3) && TMPL_GET_CPU_METHOD != 0 && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID 82 && RT_LIKELY(pGip->fGetGipCpu & TMPL_GET_CPU_METHOD) 83 #endif 84 ) 85 { 86 /* 87 * Resolve pGipCpu if needed. If the instruction is serializing, we 88 * read the transaction id first if possible. 89 */ 90 #if TMPL_MODE == TMPL_MODE_ASYNC || TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA 91 # if defined(IN_RING0) 92 uint32_t const iCpuSet = RTMpCpuIdToSetIndex(RTMpCpuId()); 93 uint16_t const iGipCpu = iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx) 94 ? pGip->aiCpuFromCpuSetIdx[iCpuSet] : UINT16_MAX; 95 # elif defined(IN_RC) 96 uint32_t const iCpuSet = VMMGetCpu(&g_VM)->iHostCpuSet; 97 uint16_t const iGipCpu = iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx) 98 ? pGip->aiCpuFromCpuSetIdx[iCpuSet] : UINT16_MAX; 99 # elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_APIC_ID 100 # if TMPL_MODE != TMPL_MODE_ASYNC 101 uint32_t const u32TransactionId = pGip->aCPUs[0].u32TransactionId; 102 # endif 103 uint8_t const idApic = ASMGetApicId(); 104 uint16_t const iGipCpu = pGip->aiCpuFromApicId[idApic]; 105 # elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 106 # if TMPL_MODE != TMPL_MODE_ASYNC 107 uint32_t const u32TransactionId = pGip->aCPUs[0].u32TransactionId; 108 # endif 109 uint32_t uAux; 110 ASMReadTscWithAux(&uAux); 111 uint16_t const iCpuSet = uAux & (RTCPUSET_MAX_CPUS - 1); 112 uint16_t const iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 113 # elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS 114 uint16_t const cbLim = ASMGetIdtrLimit(); 115 uint16_t const iCpuSet = (cbLim - 256 * (ARCH_BITS == 64 ? 16 : 8)) & (RTCPUSET_MAX_CPUS - 1); 116 uint16_t const iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 74 117 # else 75 uint32_t u32TransactionId = pGip->aCPUs[0].u32TransactionId; 76 # endif 77 # ifdef USE_LFENCE 78 ASMReadFenceSSE2(); 118 # error "What?" 119 # endif 120 if (RT_LIKELY(iGipCpu < pGip->cCpus)) 121 { 122 PSUPGIPCPU pGipCpu = &pGip->aCPUs[iGipCpu]; 123 #else 124 { 125 #endif 126 /* 127 * Get the transaction ID if necessary and we haven't already 128 * read it before a serializing instruction above. We can skip 129 * this for ASYNC_TSC mode in ring-0 and raw-mode context since 130 * we disable interrupts. 131 */ 132 #if TMPL_MODE == TMPL_MODE_ASYNC && defined(IN_RING3) 133 uint32_t const u32TransactionId = pGipCpu->u32TransactionId; 134 ASMCompilerBarrier(); 135 TMPL_READ_FENCE(); 136 #elif TMPL_MODE != TMPL_MODE_ASYNC \ 137 && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID \ 138 && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 139 uint32_t const u32TransactionId = pGip->aCPUs[0].u32TransactionId; 140 ASMCompilerBarrier(); 141 TMPL_READ_FENCE(); 142 #endif 143 144 /* 145 * Gather all the data we need. The mess at the end is to make 146 * sure all loads are done before we recheck the transaction ID 147 * without triggering serializing twice. 148 */ 149 u32NanoTSFactor0 = pGip->u32UpdateIntervalNS; 150 #if TMPL_MODE == TMPL_MODE_ASYNC 151 u32UpdateIntervalTSC = pGipCpu->u32UpdateIntervalTSC; 152 u64NanoTS = pGipCpu->u64NanoTS; 153 u64TSC = pGipCpu->u64TSC; 154 #else 155 u32UpdateIntervalTSC = pGip->aCPUs[0].u32UpdateIntervalTSC; 156 u64NanoTS = pGip->aCPUs[0].u64NanoTS; 157 u64TSC = pGip->aCPUs[0].u64TSC; 158 # if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA 159 i64TscDelta = pGipCpu->i64TSCDelta; 160 # endif 161 #endif 162 #if TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 163 u64PrevNanoTS = ASMAtomicUoReadU64(pData->pu64Prev); 164 ASMCompilerBarrier(); 165 uint32_t uAux2; 166 u64Delta = ASMReadTscWithAux(&uAux2); /* serializing */ 167 #else 168 u64Delta = ASMReadTSC(); 169 u64PrevNanoTS = ASMAtomicUoReadU64(pData->pu64Prev); 170 ASMCompilerBarrier(); 171 # if TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID /* getting APIC will serialize */ \ 172 && (defined(IN_RING3) || TMPL_MODE != TMPL_MODE_ASYNC) 173 TMPL_READ_FENCE(); /* Expensive (~30 ticks). Would like convincing argumentation that let us remove it. */ 174 # endif 175 #endif 176 177 /* 178 * Check that we didn't change CPU. 179 */ 180 #if defined(IN_RING3) && ( TMPL_MODE == TMPL_MODE_ASYNC || TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA ) 181 # if TMPL_GET_CPU_METHOD == SUPGIPGETCPU_APIC_ID 182 if (RT_LIKELY(ASMGetApicId() == idApic)) 183 # elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 184 if (RT_LIKELY(uAux2 == uAux)) 185 # elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS 186 if (RT_LIKELY(ASMGetIdtrLimit() == cbLim)) 187 # endif 188 #endif 189 { 190 /* 191 * Check the transaction ID (see above for R0/RC + ASYNC). 192 */ 193 #if defined(IN_RING3) || TMPL_MODE != TMPL_MODE_ASYNC 194 # if TMPL_MODE == TMPL_MODE_ASYNC 195 if (RT_LIKELY(pGipCpu->u32TransactionId == u32TransactionId && !(u32TransactionId & 1) )) 79 196 # 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; 88 #else 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); 99 100 #ifdef NEED_TRANSACTION_ID 101 # if GIP_MODE == GIP_MODE_ASYNC || IS_GIP_MODE_WITH_DELTA(GIP_MODE) 102 if (RT_UNLIKELY(u8ApicId != ASMGetApicId())) 103 continue; 104 # elif defined(USE_LFENCE) 105 ASMWriteFenceSSE(); 197 if (RT_LIKELY(pGip->aCPUs[0].u32TransactionId == u32TransactionId && !(u32TransactionId & 1) )) 198 # endif 199 #endif 200 { 201 202 /* 203 * Apply the TSC delta. If the delta is invalid and the 204 * execution allows it, try trigger delta recalibration. 205 */ 206 #if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA && defined(IN_RING3) 207 if (RT_LIKELY( i64TscDelta != INT64_MAX 208 || pGipCpu == pGipCpuAttemptedTscRecalibration)) 209 #endif 210 { 211 #if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA 212 # ifndef IN_RING3 213 if (RT_LIKELY(i64TscDelta != INT64_MAX)) 214 # endif 215 u64Delta -= i64TscDelta; 216 #endif 217 218 /* 219 * Bingo! We've got a consistent set of data. 220 */ 221 #ifndef IN_RING3 222 ASMSetFlags(uFlags); 223 #endif 224 break; 225 } 226 #if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA && defined(IN_RING3) 227 /* 228 * Call into the support driver to try make it recalculate the delta. We 229 * remember which GIP CPU structure we're probably working on so we won't 230 * end up in a loop if the driver for some reason cannot get the job done. 231 */ 232 else /* else is unecessary, but helps checking the preprocessor spaghetti. */ 233 { 234 pGipCpuAttemptedTscRecalibration = pGipCpu; 235 uint64_t u64TscTmp; 236 uint16_t idApicUpdate; 237 int rc = SUPR3ReadTsc(&u64TscTmp, &idApicUpdate); 238 if (RT_SUCCESS(rc) && idApicUpdate <= RT_ELEMENTS(pGip->aiCpuFromApicId)) 239 { 240 uint32_t iUpdateGipCpu = pGip->aiCpuFromApicId[idApicUpdate]; 241 if (iUpdateGipCpu < pGip->cCpus) 242 pGipCpuAttemptedTscRecalibration = &pGip->aCPUs[iUpdateGipCpu]; 243 } 244 } 245 #endif 246 } 247 } 248 249 /* 250 * No joy must try again. 251 */ 252 #ifndef IN_RING3 253 ASMSetFlags(uFlags); 254 #endif 255 ASMNopPause(); 256 continue; 257 } 258 259 #if TMPL_MODE == TMPL_MODE_ASYNC || TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA 260 /* 261 * We've got a bad CPU or APIC index of some kind. 262 */ 263 else /* else is unecessary, but helps checking the preprocessor spaghetti. */ 264 { 265 # ifndef IN_RING3 266 ASMSetFlags(uFlags); 267 # endif 268 # if defined(IN_RING0) || defined(IN_RC) || TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID 269 return pData->pfnBadCpuIndex(pData, UINT16_MAX-1, iCpuSet, iGipCpu); 106 270 # else 107 ASMWriteFence(); 108 # endif 109 # if GIP_MODE == GIP_MODE_ASYNC 110 if (RT_UNLIKELY( pGipCpu->u32TransactionId != u32TransactionId 111 || (u32TransactionId & 1))) 112 continue; 113 # else 114 if (RT_UNLIKELY( pGip->aCPUs[0].u32TransactionId != u32TransactionId 115 || (u32TransactionId & 1))) 116 continue; 117 # endif 118 #endif 119 break; 271 return pData->pfnBadCpuIndex(pData, idApic, UINT16_MAX-1, iGipCpu); 272 # endif 273 } 274 #endif 275 } 276 277 /* 278 * Something changed in the GIP config or it was unmapped, figure out 279 * the right worker function to use now. 280 */ 281 #ifndef IN_RING3 282 ASMSetFlags(uFlags); 283 #endif 284 return pData->pfnRediscover(pData); 120 285 } 121 286 … … 124 289 */ 125 290 u64Delta -= u64TSC; 126 #if IS_GIP_MODE_WITH_DELTA(GIP_MODE)127 if (RT_LIKELY(i64TscDelta != INT64_MAX))128 u64Delta -= i64TscDelta;129 #endif130 291 if (RT_UNLIKELY(u64Delta > u32UpdateIntervalTSC)) 131 292 { -
trunk/src/VBox/Runtime/r3/win/VBoxRT-win32.def
r54207 r54270 28 28 ASMMultU64ByU32DivByU32 29 29 30 RTTimeNanoTSLegacyInvariantNoDelta 31 RTTimeNanoTSLegacyInvariantWithDelta 32 RTTimeNanoTSLegacySyncNoDelta 33 RTTimeNanoTSLegacySyncWithDelta 34 RTTimeNanoTSLegacyAsync 35 RTTimeNanoTSLFenceInvariantNoDelta 36 RTTimeNanoTSLFenceInvariantWithDelta 37 RTTimeNanoTSLFenceSyncNoDelta 38 RTTimeNanoTSLFenceSyncWithDelta 39 RTTimeNanoTSLFenceAsync 30 RTTimeNanoTSLegacySyncInvarNoDelta 31 RTTimeNanoTSLFenceSyncInvarNoDelta 32 RTTimeNanoTSLegacyAsyncUseApicId 33 RTTimeNanoTSLegacyAsyncUseRdtscp 34 RTTimeNanoTSLegacyAsyncUseIdtrLim 35 RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId 36 RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp 37 RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim 38 RTTimeNanoTSLFenceAsyncUseApicId 39 RTTimeNanoTSLFenceAsyncUseRdtscp 40 RTTimeNanoTSLFenceAsyncUseIdtrLim 41 RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId 42 RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp 43 RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim 40 44 -
trunk/src/VBox/Runtime/r3/win/VBoxRT-win64.def
r54207 r54270 40 40 ASMNopPause 41 41 42 RTTimeNanoTSLegacyInvariantNoDelta 43 RTTimeNanoTSLegacyInvariantWithDelta 44 RTTimeNanoTSLegacySyncNoDelta 45 RTTimeNanoTSLegacySyncWithDelta 46 RTTimeNanoTSLegacyAsync 47 RTTimeNanoTSLFenceInvariantNoDelta 48 RTTimeNanoTSLFenceInvariantWithDelta 49 RTTimeNanoTSLFenceSyncNoDelta 50 RTTimeNanoTSLFenceSyncWithDelta 51 RTTimeNanoTSLFenceAsync 42 RTTimeNanoTSLegacySyncInvarNoDelta 43 RTTimeNanoTSLFenceSyncInvarNoDelta 44 RTTimeNanoTSLegacyAsyncUseApicId 45 RTTimeNanoTSLegacyAsyncUseRdtscp 46 RTTimeNanoTSLegacyAsyncUseIdtrLim 47 RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId 48 RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp 49 RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim 50 RTTimeNanoTSLFenceAsyncUseApicId 51 RTTimeNanoTSLFenceAsyncUseRdtscp 52 RTTimeNanoTSLFenceAsyncUseIdtrLim 53 RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId 54 RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp 55 RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim 52 56 -
trunk/src/VBox/Runtime/testcase/Makefile.kmk
r52297 r54270 371 371 $(PATH_STAGE_LIB)/DisasmRC$(VBOX_SUFF_LIB) \ 372 372 $(PATH_STAGE_LIB)/RuntimeRC$(VBOX_SUFF_LIB) 373 if eq ($(VBOX_LDR_FMT32),pe)373 if1of ($(VBOX_LDR_FMT32),lx pe) 374 374 tstLdrObj_LIBS += \ 375 $(PATH_STAGE_LIB)/VMMRCBuiltin$(VBOX_SUFF_LIB) 376 endif # PE 377 ifeq ($(VBOX_LDR_FMT32),lx) 378 tstLdrObj_LIBS += \ 379 $(PATH_STAGE_LIB)/VMMRCBuiltin$(VBOX_SUFF_LIB) 375 $(PATH_STAGE_LIB)/VMMRCBuiltin$(VBOX_SUFF_LIB) \ 376 $(PATH_STAGE_LIB)/VMMRCImp$(VBOX_SUFF_LIB) 380 377 endif 381 378 endif # VBOX_WITH_RAW_MODE -
trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
r53789 r54270 44 44 45 45 /** 46 * Helper function that's used by the assembly routines when something goes bust. 47 * 48 * @param pData Pointer to the data structure. 49 * @param u64NanoTS The calculated nano ts. 50 * @param u64DeltaPrev The delta relative to the previously returned timestamp. 51 * @param u64PrevNanoTS The previously returned timestamp (as it was read it). 52 */ 53 DECLEXPORT(void) tmVirtualNanoTSBad(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS) 54 { 55 //PVM pVM = (PVM)((uint8_t *)pData - RT_OFFSETOF(VM, CTXALLSUFF(s.tm.VirtualGetRawData))); 46 * @interface_method_impl{RTTIMENANOTSDATA, pfnBadPrev} 47 */ 48 DECLEXPORT(void) tmVirtualNanoTSBadPrev(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, 49 uint64_t u64PrevNanoTS) 50 { 51 PVM pVM = RT_FROM_MEMBER(pData, VM, CTX_SUFF(tm.s.VirtualGetRawData)); 56 52 pData->cBadPrev++; 57 53 if ((int64_t)u64DeltaPrev < 0) 58 LogRel(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 \n",59 u64DeltaPrev, u64PrevNanoTS, u64NanoTS ));54 LogRel(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 pVM=%p\n", 55 u64DeltaPrev, u64PrevNanoTS, u64NanoTS, pVM)); 60 56 else 61 Log(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 (debugging?)\n", 62 u64DeltaPrev, u64PrevNanoTS, u64NanoTS)); 63 } 64 65 66 /** 67 * Called the first time somebody asks for the time or when the GIP 68 * is mapped/unmapped. 69 * 70 * This should never ever happen. 57 Log(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 pVM=%p (debugging?)\n", 58 u64DeltaPrev, u64PrevNanoTS, u64NanoTS, pVM)); 59 } 60 61 62 /** 63 * @interface_method_impl{RTTIMENANOTSDATA, pfnRediscover} 64 * 65 * This is the initial worker, so the first call in each context ends up here. 66 * It is also used should the delta rating of the host CPUs change or if the 67 * fGetGipCpu feature the current worker relies upon becomes unavailable. The 68 * last two events may occur as CPUs are taken online. 71 69 */ 72 70 DECLEXPORT(uint64_t) tmVirtualNanoTSRediscover(PRTTIMENANOTSDATA pData) 73 71 { 74 NOREF(pData); 75 //PVM pVM = (PVM)((uint8_t *)pData - RT_OFFSETOF(VM, CTXALLSUFF(s.tm.VirtualGetRawData))); 72 PVM pVM = RT_FROM_MEMBER(pData, VM, CTX_SUFF(tm.s.VirtualGetRawData)); 73 74 /* 75 * We require a valid GIP for the selection below. Invalid GIP is fatal. 76 */ 76 77 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; 77 AssertFatalMsgFailed(("pGip=%p u32Magic=%#x\n", pGip, VALID_PTR(pGip) ? pGip->u32Magic : 0)); 78 AssertFatalMsg(RT_VALID_PTR(pGip), ("pVM=%p pGip=%p\n", pVM, pGip)); 79 AssertFatalMsg(pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC, ("pVM=%p pGip=%p u32Magic=%#x\n", pVM, pGip, pGip->u32Magic)); 80 AssertFatalMsg(pGip->u32Mode > SUPGIPMODE_INVALID && pGip->u32Mode < SUPGIPMODE_END, 81 ("pVM=%p pGip=%p u32Mode=%#x\n", pVM, pGip, pGip->u32Mode)); 82 83 /* 84 * Determine the new worker. 85 */ 86 PFNTIMENANOTSINTERNAL pfnWorker; 87 bool const fLFence = RT_BOOL(ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2); 88 switch (pGip->u32Mode) 89 { 90 case SUPGIPMODE_SYNC_TSC: 91 case SUPGIPMODE_INVARIANT_TSC: 92 #if defined(IN_RC) || defined(IN_RING0) 93 if (pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO) 94 pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta : RTTimeNanoTSLegacySyncInvarNoDelta; 95 else 96 pfnWorker = fLFence ? RTTimeNanoTSLFenceSyncInvarWithDelta : RTTimeNanoTSLegacySyncInvarWithDelta; 97 #else 98 if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS) 99 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO 100 ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta : RTTimeNanoTSLegacySyncInvarNoDelta 101 : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim : RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim; 102 else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS) 103 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO 104 ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta : RTTimeNanoTSLegacySyncInvarNoDelta 105 : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp : RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp; 106 else 107 pfnWorker = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 108 ? fLFence ? RTTimeNanoTSLFenceSyncInvarNoDelta : RTTimeNanoTSLegacySyncInvarNoDelta 109 : fLFence ? RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId; 110 #endif 111 break; 112 113 case SUPGIPMODE_ASYNC_TSC: 114 #if defined(IN_RC) || defined(IN_RING0) 115 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsync : RTTimeNanoTSLegacyAsync; 116 #else 117 if (pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS) 118 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseIdtrLim : RTTimeNanoTSLegacyAsyncUseIdtrLim; 119 else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS) 120 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseRdtscp : RTTimeNanoTSLegacyAsyncUseRdtscp; 121 else 122 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseApicId : RTTimeNanoTSLegacyAsyncUseApicId; 123 #endif 124 break; 125 126 default: 127 AssertFatalMsgFailed(("pVM=%p pGip=%p u32Mode=%#x\n", pVM, pGip, pGip->u32Mode)); 128 } 129 130 /* 131 * Update the pfnVirtualGetRaw pointer and call the worker we selected. 132 */ 133 ASMAtomicWritePtr((void * volatile *)&CTX_SUFF(pVM->tm.s.pfnVirtualGetRaw), (void *)(uintptr_t)pfnWorker); 134 return pfnWorker(pData); 135 } 136 137 138 /** 139 * @interface_method_impl{RTTIMENANOTSDATA, pfnBadGipIndex} 140 */ 141 DECLEXPORT(uint64_t) tmVirtualNanoTSBadCpuIndex(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu) 142 { 143 PVM pVM = RT_FROM_MEMBER(pData, VM, CTX_SUFF(tm.s.VirtualGetRawData)); 144 AssertFatalMsgFailed(("pVM=%p idApic=%#x iCpuSet=%#x iGipCpu=%#x\n", pVM, idApic, iCpuSet, iGipCpu)); 78 145 #ifndef _MSC_VER 79 return 0; /* gcc false positive warning */146 return UINT64_MAX; 80 147 #endif 81 148 } 82 149 83 84 #if 185 150 86 151 /** … … 100 165 return u64; 101 166 } 102 103 #else104 105 /**106 * This is (mostly) the same as rtTimeNanoTSInternal() except107 * for the two globals which live in TM.108 *109 * @returns Nanosecond timestamp.110 * @param pVM Pointer to the VM.111 */112 static uint64_t tmVirtualGetRawNanoTS(PVM pVM)113 {114 uint64_t u64Delta;115 uint32_t u32NanoTSFactor0;116 uint64_t u64TSC;117 uint64_t u64NanoTS;118 uint32_t u32UpdateIntervalTSC;119 uint64_t u64PrevNanoTS;120 121 /*122 * Read the GIP data and the previous value.123 */124 for (;;)125 {126 uint32_t u32TransactionId;127 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;128 #ifdef IN_RING3129 if (RT_UNLIKELY(!pGip || pGip->u32Magic != SUPGLOBALINFOPAGE_MAGIC))130 return RTTimeSystemNanoTS();131 #endif132 133 if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)134 {135 u32TransactionId = pGip->aCPUs[0].u32TransactionId;136 #ifdef RT_OS_L4137 Assert((u32TransactionId & 1) == 0);138 #endif139 u32UpdateIntervalTSC = pGip->aCPUs[0].u32UpdateIntervalTSC;140 u64NanoTS = pGip->aCPUs[0].u64NanoTS;141 u64TSC = pGip->aCPUs[0].u64TSC;142 u32NanoTSFactor0 = pGip->u32UpdateIntervalNS;143 u64Delta = ASMReadTSC();144 u64PrevNanoTS = ASMAtomicReadU64(&pVM->tm.s.u64VirtualRawPrev);145 if (RT_UNLIKELY( pGip->aCPUs[0].u32TransactionId != u32TransactionId146 || (u32TransactionId & 1)))147 continue;148 }149 else150 {151 /* SUPGIPMODE_ASYNC_TSC */152 PSUPGIPCPU pGipCpu;153 154 uint8_t u8ApicId = ASMGetApicId();155 if (RT_LIKELY(u8ApicId < RT_ELEMENTS(pGip->aCPUs)))156 pGipCpu = &pGip->aCPUs[u8ApicId];157 else158 {159 AssertMsgFailed(("%x\n", u8ApicId));160 pGipCpu = &pGip->aCPUs[0];161 }162 163 u32TransactionId = pGipCpu->u32TransactionId;164 #ifdef RT_OS_L4165 Assert((u32TransactionId & 1) == 0);166 #endif167 u32UpdateIntervalTSC = pGipCpu->u32UpdateIntervalTSC;168 u64NanoTS = pGipCpu->u64NanoTS;169 u64TSC = pGipCpu->u64TSC;170 u32NanoTSFactor0 = pGip->u32UpdateIntervalNS;171 u64Delta = ASMReadTSC();172 u64PrevNanoTS = ASMAtomicReadU64(&pVM->tm.s.u64VirtualRawPrev);173 #ifdef IN_RC174 Assert(!(ASMGetFlags() & X86_EFL_IF));175 #else176 if (RT_UNLIKELY(u8ApicId != ASMGetApicId()))177 continue;178 if (RT_UNLIKELY( pGipCpu->u32TransactionId != u32TransactionId179 || (u32TransactionId & 1)))180 continue;181 #endif182 }183 break;184 }185 186 /*187 * Calc NanoTS delta.188 */189 u64Delta -= u64TSC;190 if (u64Delta > u32UpdateIntervalTSC)191 {192 /*193 * We've expired the interval, cap it. If we're here for the 2nd194 * time without any GIP update in-between, the checks against195 * pVM->tm.s.u64VirtualRawPrev below will force 1ns stepping.196 */197 u64Delta = u32UpdateIntervalTSC;198 }199 #if !defined(_MSC_VER) || defined(RT_ARCH_AMD64) /* GCC makes very pretty code from these two inline calls, while MSC cannot. */200 u64Delta = ASMMult2xU32RetU64((uint32_t)u64Delta, u32NanoTSFactor0);201 u64Delta = ASMDivU64ByU32RetU32(u64Delta, u32UpdateIntervalTSC);202 #else203 __asm204 {205 mov eax, dword ptr [u64Delta]206 mul dword ptr [u32NanoTSFactor0]207 div dword ptr [u32UpdateIntervalTSC]208 mov dword ptr [u64Delta], eax209 xor edx, edx210 mov dword ptr [u64Delta + 4], edx211 }212 #endif213 214 /*215 * Calculate the time and compare it with the previously returned value.216 *217 * Since this function is called *very* frequently when the VM is running218 * and then mostly on EMT, we can restrict the valid range of the delta219 * (-1s to 2*GipUpdates) and simplify/optimize the default path.220 */221 u64NanoTS += u64Delta;222 uint64_t u64DeltaPrev = u64NanoTS - u64PrevNanoTS;223 if (RT_LIKELY(u64DeltaPrev < 1000000000 /* 1s */))224 /* frequent - less than 1s since last call. */;225 else if ( (int64_t)u64DeltaPrev < 0226 && (int64_t)u64DeltaPrev + u32NanoTSFactor0 * 2 > 0)227 {228 /* occasional - u64NanoTS is in the 'past' relative to previous returns. */229 ASMAtomicIncU32(&pVM->tm.s.CTX_SUFF(VirtualGetRawData).c1nsSteps);230 u64NanoTS = u64PrevNanoTS + 1;231 #ifndef IN_RING3232 VM_FF_SET(pVM, VM_FF_TO_R3); /* S10 hack */233 #endif234 }235 else if (u64PrevNanoTS)236 {237 /* Something has gone bust, if negative offset it's real bad. */238 ASMAtomicIncU32(&pVM->tm.s.CTX_SUFF(VirtualGetRawData).cBadPrev);239 if ((int64_t)u64DeltaPrev < 0)240 LogRel(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 u64Delta=%#RX64\n",241 u64DeltaPrev, u64PrevNanoTS, u64NanoTS, u64Delta));242 else243 Log(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 u64Delta=%#RX64 (debugging?)\n",244 u64DeltaPrev, u64PrevNanoTS, u64NanoTS, u64Delta));245 #ifdef DEBUG_bird246 /** @todo there are some hickups during boot and reset that can cause 2-5 seconds delays. Investigate... */247 AssertMsg(u64PrevNanoTS > UINT64_C(100000000000) /* 100s */,248 ("u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 u64Delta=%#RX64\n",249 u64DeltaPrev, u64PrevNanoTS, u64NanoTS, u64Delta));250 #endif251 }252 /* else: We're resuming (see TMVirtualResume). */253 if (RT_LIKELY(ASMAtomicCmpXchgU64(&pVM->tm.s.u64VirtualRawPrev, u64NanoTS, u64PrevNanoTS)))254 return u64NanoTS;255 256 /*257 * Attempt updating the previous value, provided we're still ahead of it.258 *259 * There is no point in recalculating u64NanoTS because we got preempted or if260 * we raced somebody while the GIP was updated, since these are events261 * that might occur at any point in the return path as well.262 */263 for (int cTries = 50;;)264 {265 u64PrevNanoTS = ASMAtomicReadU64(&pVM->tm.s.u64VirtualRawPrev);266 if (u64PrevNanoTS >= u64NanoTS)267 break;268 if (ASMAtomicCmpXchgU64(&pVM->tm.s.u64VirtualRawPrev, u64NanoTS, u64PrevNanoTS))269 break;270 AssertBreak(--cTries <= 0);271 if (cTries < 25 && !VM_IS_EMT(pVM)) /* give up early */272 break;273 }274 275 return u64NanoTS;276 }277 278 #endif279 167 280 168 -
trunk/src/VBox/VMM/VMMR0/VMMR0.def
r54207 r54270 88 88 RTCrc32 89 89 RTOnceSlow 90 RTTimeNanoTSLegacyInvariantNoDelta 91 RTTimeNanoTSLegacyInvariantWithDelta 92 RTTimeNanoTSLegacySyncNoDelta 93 RTTimeNanoTSLegacySyncWithDelta 90 RTTimeNanoTSLegacySyncInvarNoDelta 91 RTTimeNanoTSLegacySyncInvarWithDelta 94 92 RTTimeNanoTSLegacyAsync 95 RTTimeNanoTSLFenceInvariantNoDelta 96 RTTimeNanoTSLFenceInvariantWithDelta 97 RTTimeNanoTSLFenceSyncNoDelta 98 RTTimeNanoTSLFenceSyncWithDelta 93 RTTimeNanoTSLFenceSyncInvarNoDelta 94 RTTimeNanoTSLFenceSyncInvarWithDelta 99 95 RTTimeNanoTSLFenceAsync 100 96 RTTimeSystemNanoTS -
trunk/src/VBox/VMM/VMMR3/TM.cpp
r54252 r54270 271 271 * Setup the VirtualGetRaw backend. 272 272 */ 273 pVM->tm.s.VirtualGetRawDataR3.pu64Prev = &pVM->tm.s.u64VirtualRawPrev; 274 pVM->tm.s.VirtualGetRawDataR3.pfnBad = tmVirtualNanoTSBad; 275 pVM->tm.s.VirtualGetRawDataR3.pfnRediscover = tmVirtualNanoTSRediscover; 276 if (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2) 277 { 278 if (pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC) 279 pVM->tm.s.pfnVirtualGetRawR3 = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 280 ? RTTimeNanoTSLFenceInvariantNoDelta : RTTimeNanoTSLFenceInvariantWithDelta; 281 else if (pGip->u32Mode == SUPGIPMODE_SYNC_TSC) 282 pVM->tm.s.pfnVirtualGetRawR3 = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 283 ? RTTimeNanoTSLFenceSyncNoDelta : RTTimeNanoTSLFenceSyncWithDelta; 284 else 285 pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLFenceAsync; 286 } 287 else 288 { 289 if (pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC) 290 pVM->tm.s.pfnVirtualGetRawR3 = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 291 ? RTTimeNanoTSLegacyInvariantNoDelta : RTTimeNanoTSLegacyInvariantWithDelta; 292 else if (pGip->u32Mode == SUPGIPMODE_SYNC_TSC) 293 pVM->tm.s.pfnVirtualGetRawR3 = pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO 294 ? RTTimeNanoTSLegacySyncNoDelta : RTTimeNanoTSLegacySyncWithDelta; 295 else 296 pVM->tm.s.pfnVirtualGetRawR3 = RTTimeNanoTSLegacyAsync; 297 } 298 299 pVM->tm.s.VirtualGetRawDataRC.pu64Prev = MMHyperR3ToRC(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev); 300 pVM->tm.s.VirtualGetRawDataR0.pu64Prev = MMHyperR3ToR0(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev); 273 pVM->tm.s.pfnVirtualGetRawR3 = tmVirtualNanoTSRediscover; 274 pVM->tm.s.VirtualGetRawDataR3.pfnRediscover = tmVirtualNanoTSRediscover; 275 pVM->tm.s.VirtualGetRawDataR3.pfnBad = tmVirtualNanoTSBadPrev; 276 pVM->tm.s.VirtualGetRawDataR3.pfnBadCpuIndex = tmVirtualNanoTSBadCpuIndex; 277 pVM->tm.s.VirtualGetRawDataR3.pu64Prev = &pVM->tm.s.u64VirtualRawPrev; 278 pVM->tm.s.VirtualGetRawDataRC.pu64Prev = MMHyperR3ToRC(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev); 279 pVM->tm.s.VirtualGetRawDataR0.pu64Prev = MMHyperR3ToR0(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev); 301 280 AssertRelease(pVM->tm.s.VirtualGetRawDataR0.pu64Prev); 302 281 /* The rest is done in TMR3InitFinalize since it's too early to call PDM. */ … … 1038 1017 1039 1018 /** 1040 * Translation of pfnVirtualGetRawR3 to symbol names.1041 *1042 * @remarks This is a global variable because some gcc versions have their1043 * attribute/visibility warnings messed up.1044 */1045 static const struct1046 {1047 PFNTIMENANOTSINTERNAL pfnR3Worker;1048 const char *pszName;1049 } g_aNanoTsWorkers[] =1050 {1051 #define ENTRY(a) { a, #a }1052 ENTRY(RTTimeNanoTSLegacyAsync),1053 ENTRY(RTTimeNanoTSLegacyInvariantNoDelta),1054 ENTRY(RTTimeNanoTSLegacyInvariantWithDelta),1055 ENTRY(RTTimeNanoTSLegacySyncNoDelta),1056 ENTRY(RTTimeNanoTSLegacySyncWithDelta),1057 ENTRY(RTTimeNanoTSLFenceAsync),1058 ENTRY(RTTimeNanoTSLFenceInvariantNoDelta),1059 ENTRY(RTTimeNanoTSLFenceInvariantWithDelta),1060 ENTRY(RTTimeNanoTSLFenceSyncNoDelta),1061 ENTRY(RTTimeNanoTSLFenceSyncWithDelta),1062 #undef ENTRY1063 };1064 1065 1066 /**1067 * Translates TM::pfnVirtualGetRawR3 to a symbol name that we can find in ring-01068 * and raw-mode context.1069 *1070 * @returns Symbol name.1071 * @param pfnWorkerR3 The TM::pfnVirtualGetRawR3 value.1072 */1073 static const char *tmR3GetRTTimeNanoName(PFNTIMENANOTSINTERNAL pfnR3Worker)1074 {1075 for (uint32_t iNanoTs = 0; iNanoTs < RT_ELEMENTS(g_aNanoTsWorkers); iNanoTs++)1076 if (pfnR3Worker == g_aNanoTsWorkers[iNanoTs].pfnR3Worker)1077 return g_aNanoTsWorkers[iNanoTs].pszName;1078 AssertFatalFailed();1079 return NULL;1080 }1081 1082 1083 /**1084 1019 * Finalizes the TM initialization. 1085 1020 * … … 1094 1029 * Resolve symbols. 1095 1030 */ 1096 const char *pszRTTimeNanoTS = tmR3GetRTTimeNanoName(pVM->tm.s.pfnVirtualGetRawR3);1097 1031 if (!HMIsEnabled(pVM)) 1098 1032 { 1099 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad", &pVM->tm.s.VirtualGetRawDataRC.pfnBad); 1033 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBadPrev", &pVM->tm.s.VirtualGetRawDataRC.pfnBad); 1034 AssertRCReturn(rc, rc); 1035 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBadCpuIndex", &pVM->tm.s.VirtualGetRawDataRC.pfnBadCpuIndex); 1100 1036 AssertRCReturn(rc, rc); 1101 1037 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover", &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover); 1102 1038 AssertRCReturn(rc, rc); 1103 rc = PDMR3LdrGetSymbolRC(pVM, NULL, pszRTTimeNanoTS, &pVM->tm.s.pfnVirtualGetRawRC); 1104 AssertRCReturn(rc, rc); 1105 } 1106 1107 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSBad", &pVM->tm.s.VirtualGetRawDataR0.pfnBad); 1039 pVM->tm.s.pfnVirtualGetRawRC = pVM->tm.s.VirtualGetRawDataRC.pfnRediscover; 1040 } 1041 1042 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSBadPrev", &pVM->tm.s.VirtualGetRawDataR0.pfnBad); 1043 AssertRCReturn(rc, rc); 1044 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSBadCpuIndex", &pVM->tm.s.VirtualGetRawDataR0.pfnBadCpuIndex); 1108 1045 AssertRCReturn(rc, rc); 1109 1046 rc = PDMR3LdrGetSymbolR0(pVM, NULL, "tmVirtualNanoTSRediscover", &pVM->tm.s.VirtualGetRawDataR0.pfnRediscover); 1110 1047 AssertRCReturn(rc, rc); 1111 rc = PDMR3LdrGetSymbolR0(pVM, NULL, pszRTTimeNanoTS, &pVM->tm.s.pfnVirtualGetRawR0); 1112 AssertRCReturn(rc, rc); 1048 pVM->tm.s.pfnVirtualGetRawR0 = pVM->tm.s.VirtualGetRawDataR0.pfnRediscover; 1113 1049 1114 1050 #ifndef VBOX_WITHOUT_NS_ACCOUNTING … … 1140 1076 VMM_INT_DECL(void) TMR3Relocate(PVM pVM, RTGCINTPTR offDelta) 1141 1077 { 1142 int rc;1143 1078 LogFlow(("TMR3Relocate\n")); 1144 NOREF(offDelta);1145 1079 1146 1080 pVM->tm.s.paTimerQueuesR0 = MMHyperR3ToR0(pVM, pVM->tm.s.paTimerQueuesR3); … … 1148 1082 if (!HMIsEnabled(pVM)) 1149 1083 { 1150 pVM->tm.s.pvGIPRC = MMHyperR3ToRC(pVM, pVM->tm.s.pvGIPR3); 1151 pVM->tm.s.paTimerQueuesRC = MMHyperR3ToRC(pVM, pVM->tm.s.paTimerQueuesR3); 1152 pVM->tm.s.VirtualGetRawDataRC.pu64Prev = MMHyperR3ToRC(pVM, (void *)&pVM->tm.s.u64VirtualRawPrev); 1153 AssertFatal(pVM->tm.s.VirtualGetRawDataRC.pu64Prev); 1154 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSBad", &pVM->tm.s.VirtualGetRawDataRC.pfnBad); 1155 AssertFatalRC(rc); 1156 rc = PDMR3LdrGetSymbolRC(pVM, NULL, "tmVirtualNanoTSRediscover", &pVM->tm.s.VirtualGetRawDataRC.pfnRediscover); 1157 AssertFatalRC(rc); 1158 const char *pszRTTimeNanoTS = tmR3GetRTTimeNanoName(pVM->tm.s.pfnVirtualGetRawR3); 1159 rc = PDMR3LdrGetSymbolRC(pVM, NULL, pszRTTimeNanoTS, &pVM->tm.s.pfnVirtualGetRawRC); 1160 AssertFatalRC(rc); 1084 pVM->tm.s.pvGIPRC = MMHyperR3ToRC(pVM, pVM->tm.s.pvGIPR3); 1085 pVM->tm.s.paTimerQueuesRC = MMHyperR3ToRC(pVM, pVM->tm.s.paTimerQueuesR3); 1086 pVM->tm.s.VirtualGetRawDataRC.pu64Prev += offDelta; 1087 pVM->tm.s.VirtualGetRawDataRC.pfnBad += offDelta; 1088 pVM->tm.s.VirtualGetRawDataRC.pfnBadCpuIndex += offDelta; 1089 pVM->tm.s.VirtualGetRawDataRC.pfnRediscover += offDelta; 1090 pVM->tm.s.pfnVirtualGetRawRC += offDelta; 1161 1091 } 1162 1092 -
trunk/src/VBox/VMM/VMMRC/VMMRC.def
r54207 r54270 65 65 MMGCRamWriteNoTrapHandler 66 66 MMGCRamReadNoTrapHandler 67 VMMGetCpu 67 68 VMMGetSvnRev 68 69 VMMRCProbeFire … … 92 93 RTAssertShouldPanic 93 94 RTLogDefaultInstance 94 RTTimeNanoTSLegacyInvariantNoDelta 95 RTTimeNanoTSLegacyInvariantWithDelta 96 RTTimeNanoTSLegacySyncNoDelta 97 RTTimeNanoTSLegacySyncWithDelta 95 RTTimeNanoTSLegacySyncInvarNoDelta 96 RTTimeNanoTSLegacySyncInvarWithDelta 98 97 RTTimeNanoTSLegacyAsync 99 RTTimeNanoTSLFenceInvariantNoDelta 100 RTTimeNanoTSLFenceInvariantWithDelta 101 RTTimeNanoTSLFenceSyncNoDelta 102 RTTimeNanoTSLFenceSyncWithDelta 98 RTTimeNanoTSLFenceSyncInvarNoDelta 99 RTTimeNanoTSLFenceSyncInvarWithDelta 103 100 RTTimeNanoTSLFenceAsync 104 101 RTTimeNanoTS -
trunk/src/VBox/VMM/include/TMInternal.h
r54202 r54270 766 766 int tmVirtualPauseLocked(PVM pVM); 767 767 int tmVirtualResumeLocked(PVM pVM); 768 DECLEXPORT(void) tmVirtualNanoTSBad(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS); 768 DECLEXPORT(void) tmVirtualNanoTSBadPrev(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, 769 uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS); 769 770 DECLEXPORT(uint64_t) tmVirtualNanoTSRediscover(PRTTIMENANOTSDATA pData); 771 DECLEXPORT(uint64_t) tmVirtualNanoTSBadCpuIndex(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu); 770 772 771 773 #ifdef IN_RING3
Note:
See TracChangeset
for help on using the changeset viewer.