Changeset 64255 in vbox
- Timestamp:
- Oct 13, 2016 3:18:21 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/sup.h
r62476 r64255 230 230 * indicate stable data. Use this to make sure that the data items you fetch 231 231 * are consistent. */ 232 volatile uint32_t u32TransactionId;232 volatile uint32_t u32TransactionId; 233 233 /** The interval in TSC ticks between two NanoTS updates. 234 234 * This is the average interval over the last 2, 4 or 8 updates + a little slack. 235 235 * The slack makes the time go a tiny tiny bit slower and extends the interval enough 236 236 * to avoid ending up with too many 1ns increments. */ 237 volatile uint32_t u32UpdateIntervalTSC;237 volatile uint32_t u32UpdateIntervalTSC; 238 238 /** Current nanosecond timestamp. */ 239 volatile uint64_t u64NanoTS;239 volatile uint64_t u64NanoTS; 240 240 /** The TSC at the time of u64NanoTS. */ 241 volatile uint64_t u64TSC;241 volatile uint64_t u64TSC; 242 242 /** Current CPU Frequency. */ 243 volatile uint64_t u64CpuHz;243 volatile uint64_t u64CpuHz; 244 244 /** The TSC delta with reference to the master TSC, subtract from RDTSC. */ 245 volatile int64_t i64TSCDelta;245 volatile int64_t i64TSCDelta; 246 246 /** Number of errors during updating. 247 247 * Typical errors are under/overflows. */ 248 volatile uint32_t cErrors;248 volatile uint32_t cErrors; 249 249 /** Index of the head item in au32TSCHistory. */ 250 volatile uint32_t iTSCHistoryHead;250 volatile uint32_t iTSCHistoryHead; 251 251 /** Array of recent TSC interval deltas. 252 252 * The most recent item is at index iTSCHistoryHead. 253 253 * This history is used to calculate u32UpdateIntervalTSC. 254 254 */ 255 volatile uint32_t au32TSCHistory[8];255 volatile uint32_t au32TSCHistory[8]; 256 256 /** The interval between the last two NanoTS updates. (experiment for now) */ 257 volatile uint32_t u32PrevUpdateIntervalNS;257 volatile uint32_t u32PrevUpdateIntervalNS; 258 258 259 259 /** Reserved for future per processor data. */ 260 volatile uint32_t au32Reserved0[5]; 261 260 volatile uint32_t u32Reserved; 262 261 /** The TSC value read while doing TSC delta measurements across CPUs. */ 263 volatile uint64_t u64TSCSample; 264 262 volatile uint64_t u64TSCSample; 265 263 /** Reserved for future per processor data. */ 266 volatile uint32_t au32Reserved1[1]; 267 268 /** @todo Add topology/NUMA info. */ 264 volatile uint32_t au32Reserved1[3]; 265 269 266 /** The CPU state. */ 270 267 SUPGIPCPUSTATE volatile enmState; … … 273 270 /** The CPU set index of this CPU. */ 274 271 int16_t iCpuSet; 272 /** CPU group number (always zero, except on windows). */ 273 uint16_t iCpuGroup; 274 /** CPU group number (same as iCpuSet, except on windows). */ 275 uint16_t iCpuGroupMember; 275 276 /** The APIC ID of this CPU. */ 276 277 uint16_t idApic; 278 /** @todo Add topology/NUMA info. */ 279 uint32_t iReservedForNumaNode; 277 280 } SUPGIPCPU; 278 281 AssertCompileSize(RTCPUID, 4); … … 280 283 AssertCompileMemberAlignment(SUPGIPCPU, u64NanoTS, 8); 281 284 AssertCompileMemberAlignment(SUPGIPCPU, u64TSC, 8); 285 AssertCompileMemberAlignment(SUPGIPCPU, u64TSCSample, 8); 282 286 283 287 /** Pointer to per cpu data. … … 314 318 315 319 /** @name SUPGIPGETCPU_XXX - methods that aCPUs can be indexed. 320 * 321 * @note Linux offers information via selector 0x78, and Windows via selector 322 * 0x53. But since they both support RDTSCP as well, and because most 323 * CPUs now have RDTSCP, we prefer it over LSL. We can implement more 324 * alternatives if it becomes necessary. 325 * 316 326 * @{ 317 327 */ … … 335 345 * does with RDTSCP. */ 336 346 #define SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS RT_BIT_32(2) 337 /* Linux also offers information via selector 0x78, but we'll settle for 338 RDTSCP for now. */ 347 /** Windows specific RDTSCP variant, where CH gives you the group and CL gives 348 * you the CPU number within that group. 349 * 350 * Use SUPGLOBALINFOPAGE::aidFirstCpuFromCpuGroup to get the group base CPU set 351 * index, then translate the sum of thru aiCpuFromCpuSetIdx to find the aCPUs 352 * entry. 353 * 354 * @note The group number is actually 16-bit wide (ECX[23:8]), but we simplify 355 * it since we only support 256 CPUs/groups at the moment. 356 */ 357 #define SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL RT_BIT_32(3) 339 358 /** @} */ 340 359 … … 381 400 /** The highest number of CPUs possible. */ 382 401 uint16_t cPossibleCpus; 383 uint16_t u16Padding0; 402 /** The highest number of CPU groups possible. */ 403 uint16_t cPossibleCpuGroups; 384 404 /** The max CPU ID (RTMpGetMaxCpuId). */ 385 405 RTCPUID idCpuMax; … … 399 419 /** CPU set index to CPU table index. */ 400 420 uint16_t aiCpuFromCpuSetIdx[RTCPUSET_MAX_CPUS]; 421 /** Table indexed by CPU group index to get the CPU set index of the first 422 * CPU. */ 423 uint16_t aiFirstCpuSetIdxFromCpuGroup[RTCPUSET_MAX_CPUS]; 401 424 402 425 /** Array of per-cpu data. … … 415 438 AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, aCPUs, 256); 416 439 #endif 440 AssertCompile(sizeof(SUPGLOBALINFOPAGE) <= 0x1000); /* Keeping it less or equal to a page for raw-mode (saved state). */ 417 441 418 442 /** Pointer to the global info page. … … 426 450 * Upper 16 bits is the major version. Major version is only changed with 427 451 * incompatible changes in the GIP. */ 428 #define SUPGLOBALINFOPAGE_VERSION 0x000 60001452 #define SUPGLOBALINFOPAGE_VERSION 0x00070000 429 453 430 454 /** … … 569 593 AssertFailed(); 570 594 return UINT64_MAX; 595 } 596 597 598 /** 599 * Gets the pointer to the per CPU data for a CPU given by its set index. 600 * 601 * @returns Pointer to the corresponding per CPU structure, or NULL if invalid. 602 * @param pGip The GIP pointer. 603 * @param iCpuSet The CPU set index of the CPU which we want. 604 */ 605 DECLINLINE(PSUPGIPCPU) SUPGetGipCpuBySetIndex(PSUPGLOBALINFOPAGE pGip, uint32_t iCpuSet) 606 { 607 if (RT_LIKELY( pGip 608 && pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC)) 609 { 610 if (RT_LIKELY(iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx))) 611 { 612 uint16_t iCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 613 if (RT_LIKELY(iCpu < pGip->cCpus)) 614 return &pGip->aCPUs[iCpu]; 615 } 616 } 617 return NULL; 571 618 } 572 619 -
trunk/include/iprt/mangling.h
r62915 r64255 2104 2104 # define RTTimeNanoTSLegacyAsyncUseRdtscp RT_MANGLER(RTTimeNanoTSLegacyAsyncUseRdtscp) 2105 2105 # define RTTimeNanoTSLegacyAsyncUseRdtscp_EndProc RT_MANGLER(RTTimeNanoTSLegacyAsyncUseRdtscp_EndProc) 2106 # define RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl RT_MANGLER(RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl) 2107 # define RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl_EndProc RT_MANGLER(RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl_EndProc) 2106 2108 # define RTTimeNanoTSLegacyAsyncUseIdtrLim RT_MANGLER(RTTimeNanoTSLegacyAsyncUseIdtrLim) 2107 2109 # define RTTimeNanoTSLegacyAsyncUseIdtrLim_EndProc RT_MANGLER(RTTimeNanoTSLegacyAsyncUseIdtrLim_EndProc) … … 2122 2124 # define RTTimeNanoTSLFenceAsyncUseRdtscp RT_MANGLER(RTTimeNanoTSLFenceAsyncUseRdtscp) 2123 2125 # define RTTimeNanoTSLFenceAsyncUseRdtscp_EndProc RT_MANGLER(RTTimeNanoTSLFenceAsyncUseRdtscp_EndProc) 2126 # define RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl RT_MANGLER(RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl) 2127 # define RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl_EndProc RT_MANGLER(RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl_EndProc) 2124 2128 # define RTTimeNanoTSLFenceAsyncUseIdtrLim RT_MANGLER(RTTimeNanoTSLFenceAsyncUseIdtrLim) 2125 2129 # define RTTimeNanoTSLFenceAsyncUseIdtrLim_EndProc RT_MANGLER(RTTimeNanoTSLFenceAsyncUseIdtrLim_EndProc) -
trunk/include/iprt/nt/nt.h
r64237 r64255 2390 2390 /*NTSYSAPI ULONG NTAPI RtlNtStatusToDosError(NTSTATUS rcNt);*/ 2391 2391 2392 /** @def RTL_QUERY_REGISTRY_TYPECHECK 2393 * WDK 8.1+, backported in updates, ignored in older. */ 2394 #if !defined(RTL_QUERY_REGISTRY_TYPECHECK) || defined(DOXYGEN_RUNNING) 2395 # define RTL_QUERY_REGISTRY_TYPECHECK UINT32_C(0x00000100) 2396 #endif 2397 /** @def RTL_QUERY_REGISTRY_TYPECHECK_SHIFT 2398 * WDK 8.1+, backported in updates, ignored in older. */ 2399 #if !defined(RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) || defined(DOXYGEN_RUNNING) 2400 # define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT 24 2401 #endif 2402 2392 2403 2393 2404 RT_C_DECLS_END -
trunk/include/iprt/time.h
r62860 r64255 954 954 RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseApicId(PRTTIMENANOTSDATA pData); 955 955 RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseRdtscp(PRTTIMENANOTSDATA pData); 956 RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl(PRTTIMENANOTSDATA pData); 956 957 RTDECL(uint64_t) RTTimeNanoTSLegacyAsyncUseIdtrLim(PRTTIMENANOTSDATA pData); 957 958 RTDECL(uint64_t) RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId(PRTTIMENANOTSDATA pData); … … 960 961 RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseApicId(PRTTIMENANOTSDATA pData); 961 962 RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseRdtscp(PRTTIMENANOTSDATA pData); 963 RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl(PRTTIMENANOTSDATA pData); 962 964 RTDECL(uint64_t) RTTimeNanoTSLFenceAsyncUseIdtrLim(PRTTIMENANOTSDATA pData); 963 965 RTDECL(uint64_t) RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId(PRTTIMENANOTSDATA pData); -
trunk/src/VBox/HostDrivers/Support/SUPDrvGip.cpp
r64236 r64255 274 274 && RT_IS_POWER_OF_TWO(RTCPUSET_MAX_CPUS)) 275 275 { 276 PSUPGIPCPU pGipCpu = SUPGetGipCpuBySetIndex(pGip, iCpuSet); 277 276 278 /* 277 279 * Check whether the IDTR.LIMIT contains a CPU number. … … 305 307 && (ASMCpuId_EDX(UINT32_C(0x80000001)) & X86_CPUID_EXT_FEATURE_EDX_RDTSCP) ) 306 308 { 307 uint32_t uAux; 309 uint32_t const uGroupedAux = (uint8_t)pGipCpu->iCpuGroupMember | ((uint32_t)pGipCpu->iCpuGroup << 8); 310 uint32_t uAux; 308 311 ASMReadTscWithAux(&uAux); 309 312 if ((uAux & (RTCPUSET_MAX_CPUS - 1)) == idCpu) … … 313 316 if ((uAux & (RTCPUSET_MAX_CPUS - 1)) == idCpu) 314 317 fSupported |= SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS; 318 } 319 320 if ( (uAux & UINT16_MAX) == uGroupedAux 321 && pGipCpu->iCpuGroupMember <= UINT8_MAX) 322 { 323 ASMNopPause(); 324 ASMReadTscWithAux(&uAux); 325 if ((uAux & UINT16_MAX) == uGroupedAux) 326 fSupported |= SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL; 315 327 } 316 328 } … … 1259 1271 static void supdrvGipMpEventOnlineOrInitOnCpu(PSUPDRVDEVEXT pDevExt, RTCPUID idCpu) 1260 1272 { 1261 int iCpuSet = 0;1262 uint16_t idApic = UINT16_MAX;1263 uint 32_t i = 0;1264 uint 64_t u64NanoTS= 0;1265 PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;1273 PSUPGLOBALINFOPAGE pGip = pDevExt->pGip; 1274 int iCpuSet = 0; 1275 uint16_t idApic = UINT16_MAX; 1276 uint32_t i = 0; 1277 uint64_t u64NanoTS = 0; 1266 1278 1267 1279 AssertPtrReturnVoid(pGip); … … 1301 1313 ASMAtomicWriteS16(&pGip->aCPUs[i].iCpuSet, (int16_t)iCpuSet); 1302 1314 ASMAtomicWriteSize(&pGip->aCPUs[i].idCpu, idCpu); 1315 1316 pGip->aCPUs[i].iCpuGroup = 0; 1317 pGip->aCPUs[i].iCpuGroupMember = iCpuSet; 1318 #ifdef RT_OS_WINDOWS 1319 pGip->aCPUs[i].iCpuGroup = supdrvOSGipGetGroupFromCpu(pDevExt, idCpu, &pGip->aCPUs[i].iCpuGroupMember); 1320 #endif 1303 1321 1304 1322 /* … … 1683 1701 pCpu->i64TSCDelta = pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED ? INT64_MAX : 0; 1684 1702 1685 ASMAtomicWriteSize(&pCpu->enmState, SUPGIPCPUSTATE_INVALID); 1686 ASMAtomicWriteU32(&pCpu->idCpu, NIL_RTCPUID); 1687 ASMAtomicWriteS16(&pCpu->iCpuSet, -1); 1688 ASMAtomicWriteU16(&pCpu->idApic, UINT16_MAX); 1703 ASMAtomicWriteSize(&pCpu->enmState, SUPGIPCPUSTATE_INVALID); 1704 ASMAtomicWriteU32(&pCpu->idCpu, NIL_RTCPUID); 1705 ASMAtomicWriteS16(&pCpu->iCpuSet, -1); 1706 ASMAtomicWriteU16(&pCpu->iCpuGroup, 0); 1707 ASMAtomicWriteU16(&pCpu->iCpuGroupMember, UINT16_MAX); 1708 ASMAtomicWriteU16(&pCpu->idApic, UINT16_MAX); 1709 ASMAtomicWriteU32(&pCpu->iReservedForNumaNode, 0); 1689 1710 1690 1711 /* … … 1764 1785 pGip->cPresentCpus = RTMpGetPresentCount(); 1765 1786 pGip->cPossibleCpus = RTMpGetCount(); 1787 pGip->cPossibleCpuGroups = 1; 1766 1788 pGip->idCpuMax = RTMpGetMaxCpuId(); 1767 1789 for (i = 0; i < RT_ELEMENTS(pGip->aiCpuFromApicId); i++) … … 1769 1791 for (i = 0; i < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx); i++) 1770 1792 pGip->aiCpuFromCpuSetIdx[i] = UINT16_MAX; 1793 pGip->aiFirstCpuSetIdxFromCpuGroup[0] = 0; 1794 for (i = 1; i < RT_ELEMENTS(pGip->aiFirstCpuSetIdxFromCpuGroup); i++) 1795 pGip->aiFirstCpuSetIdxFromCpuGroup[i] = UINT16_MAX; 1796 #ifdef RT_OS_WINDOWS 1797 supdrvOSInitGipGroupTable(pDevExt, pGip); 1798 #endif 1771 1799 for (i = 0; i < cCpus; i++) 1772 1800 supdrvGipInitCpu(pGip, &pGip->aCPUs[i], u64NanoTS, 0 /*uCpuHz*/); … … 2394 2422 * run. 2395 2423 */ 2396 if (RT_UNLIKELY(iTick == 1)) 2424 if (RT_LIKELY(iTick != 1)) 2425 { /* likely*/ } 2426 else 2397 2427 { 2398 2428 iCpu = supdrvGipFindOrAllocCpuIndexForCpuId(pGip, idCpu); -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r62664 r64255 215 215 * - nothing. 216 216 */ 217 #define SUPDRV_IOC_VERSION 0x002 60000217 #define SUPDRV_IOC_VERSION 0x00270000 218 218 219 219 /** SUP_IOCTL_COOKIE. */ -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r62664 r64255 800 800 void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser); 801 801 802 /** 803 * Called during GIP initialization to set up the group table and group count. 804 * 805 * This is currently only implemented on windows [lazy bird]. 806 * 807 * @param pDevExt The device globals. 808 * @param pGip The GIP which group table needs initialization. 809 * It's only partially initialized at this point. 810 */ 811 void VBOXCALL supdrvOSInitGipGroupTable(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip); 812 813 /** 814 * Gets the CPU group and member indexes for the given CPU ID. 815 * 816 * This is currently only implemented on windows [lazy bird]. 817 * 818 * @returns CPU group number. 819 * @param pDevExt The device globals. 820 * @param idCpu The ID of the CPU. 821 * @param piCpuGroupMember Where to return the group member number. 822 */ 823 uint16_t VBOXCALL supdrvOSGipGetGroupFromCpu(PSUPDRVDEVEXT pDevExt, RTCPUID idCpu, uint16_t *piCpuGroupMember); 824 802 825 void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession); 803 826 bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc); -
trunk/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
r62490 r64255 131 131 SUPR3GipSetFlags(SUPGIP_FLAGS_TESTING_ENABLE, UINT32_MAX); 132 132 133 RTPrintf("tstGIP-2: cCpus=%d u32UpdateHz=%RU32 u32UpdateIntervalNS=%RU32 u64NanoTSLastUpdateHz=%RX64 u64CpuHz=%RU64 uCpuHzRef=%RU64 u32Mode=%d (%s) fTestMode=%RTbool u32Version=%#x\n", 133 RTPrintf("tstGIP-2: u32Mode=%d (%s) fTestMode=%RTbool u32Version=%#x fGetGipCpu=%#RX32\n", 134 g_pSUPGlobalInfoPage->u32Mode, 135 SUPGetGIPModeName(g_pSUPGlobalInfoPage), 136 fTestMode, 137 g_pSUPGlobalInfoPage->u32Version, 138 g_pSUPGlobalInfoPage->fGetGipCpu); 139 RTPrintf("tstGIP-2: cCpus=%d cPossibleCpus=%d cPossibleCpuGroups=%d cPresentCpus=%d cOnlineCpus=%d\n", 134 140 g_pSUPGlobalInfoPage->cCpus, 141 g_pSUPGlobalInfoPage->cPossibleCpus, 142 g_pSUPGlobalInfoPage->cPossibleCpuGroups, 143 g_pSUPGlobalInfoPage->cPresentCpus, 144 g_pSUPGlobalInfoPage->cOnlineCpus); 145 RTPrintf("tstGIP-2: u32UpdateHz=%RU32 u32UpdateIntervalNS=%RU32 u64NanoTSLastUpdateHz=%RX64 u64CpuHz=%RU64 uCpuHzRef=%RU64\n", 135 146 g_pSUPGlobalInfoPage->u32UpdateHz, 136 147 g_pSUPGlobalInfoPage->u32UpdateIntervalNS, 137 148 g_pSUPGlobalInfoPage->u64NanoTSLastUpdateHz, 138 149 g_pSUPGlobalInfoPage->u64CpuHz, 139 uCpuHzRef, 140 g_pSUPGlobalInfoPage->u32Mode, 141 SUPGetGIPModeName(g_pSUPGlobalInfoPage), 142 fTestMode, 143 g_pSUPGlobalInfoPage->u32Version); 150 uCpuHzRef); 151 144 152 RTPrintf(fHex 145 153 ? "tstGIP-2: it: u64NanoTS delta u64TSC UpIntTSC H TransId CpuHz %sTSC Interval History...\n" -
trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
r62677 r64255 359 359 #endif /* VBOXDRV_WITH_FAST_IO */ 360 360 361 /** Default ZERO value. */ 362 static ULONG g_fOptDefaultZero = 0; 363 /** Registry values. 364 * We wrap these in a struct to ensure they are followed by a little zero 365 * padding in order to limit the chance of trouble on unpatched systems. */ 366 struct 367 { 368 /** The ForceAsync registry value. */ 369 ULONG fOptForceAsyncTsc; 370 /** Padding. */ 371 uint64_t au64Padding[2]; 372 } g_Options = { FALSE, 0, 0 }; 373 /** Registry query table for RtlQueryRegistryValues. */ 374 static RTL_QUERY_REGISTRY_TABLE g_aRegValues[] = 375 { 376 { 377 /* .QueryRoutine = */ NULL, 378 /* .Flags = */ RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, 379 /* .Name = */ L"ForceAsyncTsc", 380 /* .EntryContext = */ &g_Options.fOptForceAsyncTsc, 381 /* .DefaultType = */ (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, 382 /* .DefaultData = */ &g_fOptDefaultZero, 383 /* .DefaultLength = */ sizeof(g_fOptDefaultZero), 384 }, 385 { NULL, 0, NULL, NULL, 0, NULL, 0 } /* terminator entry. */ 386 }; 387 388 /** Pointer to KeQueryMaximumGroupCount. */ 389 static PFNKEQUERYMAXIMUMGROUPCOUNT g_pfnKeQueryMaximumGroupCount = NULL; 390 /** Pointer to KeGetProcessorIndexFromNumber. */ 391 static PFNKEGETPROCESSORINDEXFROMNUMBER g_pfnKeGetProcessorIndexFromNumber = NULL; 392 /** Pointer to KeGetProcessorNumberFromIndex. */ 393 static PFNKEGETPROCESSORNUMBERFROMINDEX g_pfnKeGetProcessorNumberFromIndex = NULL; 394 361 395 #ifdef VBOX_WITH_HARDENING 362 396 /** Pointer to the stub device instance. */ … … 554 588 555 589 /* 590 * Query options first so any overflows on unpatched machines will do less 591 * harm (see MS11-011 / 2393802 / 2011-03-18). 592 * 593 * Unfortunately, pRegPath isn't documented as zero terminated, even if it 594 * quite likely always is, so we have to make a copy here. 595 */ 596 NTSTATUS rcNt; 597 PWSTR pwszCopy = (PWSTR)ExAllocatePoolWithTag(NonPagedPool, pRegPath->Length + sizeof(WCHAR), 'VBox'); 598 if (pwszCopy) 599 { 600 memcpy(pwszCopy, pRegPath->Buffer, pRegPath->Length); 601 pwszCopy[pRegPath->Length / sizeof(WCHAR)] = '\0'; 602 rcNt = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, pwszCopy, 603 g_aRegValues, NULL /*pvContext*/, NULL /*pvEnv*/); 604 ExFreePoolWithTag(pwszCopy, 'VBox'); 605 /* Probably safe to ignore rcNt here. */ 606 } 607 608 /* 609 * Resolve methods we want but isn't available everywhere. 610 */ 611 UNICODE_STRING RoutineName; 612 RtlInitUnicodeString(&RoutineName, L"KeQueryMaximumGroupCount"); 613 g_pfnKeQueryMaximumGroupCount = (PFNKEQUERYMAXIMUMGROUPCOUNT)MmGetSystemRoutineAddress(&RoutineName); 614 615 RtlInitUnicodeString(&RoutineName, L"KeGetProcessorIndexFromNumber"); 616 g_pfnKeGetProcessorIndexFromNumber = (PFNKEGETPROCESSORINDEXFROMNUMBER)MmGetSystemRoutineAddress(&RoutineName); 617 618 RtlInitUnicodeString(&RoutineName, L"KeGetProcessorNumberFromIndex"); 619 g_pfnKeGetProcessorNumberFromIndex = (PFNKEGETPROCESSORNUMBERFROMINDEX)MmGetSystemRoutineAddress(&RoutineName); 620 621 Assert( (g_pfnKeGetProcessorNumberFromIndex != NULL) == (g_pfnKeGetProcessorIndexFromNumber != NULL) 622 && (g_pfnKeGetProcessorNumberFromIndex != NULL) == (g_pfnKeQueryMaximumGroupCount != NULL)); /* all or nothing. */ 623 624 /* 556 625 * Initialize the runtime (IPRT). 557 626 */ 558 NTSTATUS rcNt;559 627 int vrc = RTR0Init(0); 560 628 if (RT_SUCCESS(vrc)) … … 1643 1711 1644 1712 1713 void VBOXCALL supdrvOSInitGipGroupTable(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip) 1714 { 1715 NOREF(pDevExt); 1716 1717 /* 1718 * The indexes are assigned in group order (see initterm-r0drv-nt.cpp). 1719 */ 1720 if ( g_pfnKeQueryMaximumGroupCount 1721 && g_pfnKeGetProcessorIndexFromNumber) 1722 { 1723 unsigned cGroups = g_pfnKeQueryMaximumGroupCount(); 1724 AssertStmt(cGroups > 0, cGroups = 1); 1725 AssertStmt(cGroups < RT_ELEMENTS(pGip->aiFirstCpuSetIdxFromCpuGroup), 1726 cGroups = RT_ELEMENTS(pGip->aiFirstCpuSetIdxFromCpuGroup)); 1727 pGip->cPossibleCpuGroups = cGroups; 1728 1729 KEPROCESSORINDEX idxCpuMin = 0; 1730 for (unsigned iGroup = 0; iGroup < cGroups; iGroup++) 1731 { 1732 PROCESSOR_NUMBER ProcNum; 1733 ProcNum.Group = (USHORT)iGroup; 1734 ProcNum.Number = 0; 1735 ProcNum.Reserved = 0; 1736 KEPROCESSORINDEX idxCpu = g_pfnKeGetProcessorIndexFromNumber(&ProcNum); 1737 Assert(idxCpu != INVALID_PROCESSOR_INDEX); 1738 Assert(idxCpu >= idxCpuMin); 1739 idxCpuMin = idxCpu; 1740 pGip->aiFirstCpuSetIdxFromCpuGroup[iGroup] = (uint16_t)idxCpu; 1741 } 1742 } 1743 else 1744 { 1745 Assert(!g_pfnKeQueryMaximumGroupCount); 1746 Assert(!g_pfnKeGetProcessorIndexFromNumber); 1747 1748 pGip->cPossibleCpuGroups = 1; 1749 pGip->aiFirstCpuSetIdxFromCpuGroup[0] = 0; 1750 } 1751 } 1752 1753 1754 uint16_t VBOXCALL supdrvOSGipGetGroupFromCpu(PSUPDRVDEVEXT pDevExt, RTCPUID idCpu, uint16_t *piCpuGroupMember) 1755 { 1756 NOREF(pDevExt); 1757 1758 /* 1759 * This is just a wrapper around KeGetProcessorNumberFromIndex. 1760 */ 1761 if (g_pfnKeGetProcessorNumberFromIndex) 1762 { 1763 PROCESSOR_NUMBER ProcNum = { UINT16_MAX, UINT8_MAX, 0 }; 1764 NTSTATUS rcNt = g_pfnKeGetProcessorNumberFromIndex(idCpu, &ProcNum); 1765 if (NT_SUCCESS(rcNt)) 1766 { 1767 Assert(ProcNum.Group < g_pfnKeQueryMaximumGroupCount()); 1768 *piCpuGroupMember = ProcNum.Number; 1769 return ProcNum.Group; 1770 } 1771 1772 AssertMsgFailed(("rcNt=%#x for idCpu=%u\n", rcNt, idCpu)); 1773 } 1774 1775 *piCpuGroupMember = 0; 1776 return idCpu; 1777 } 1778 1779 1645 1780 /** 1646 1781 * Initializes any OS specific object creator fields. … … 1680 1815 { 1681 1816 RT_NOREF1(pDevExt); 1682 return false;1817 return g_Options.fOptForceAsyncTsc != 0; 1683 1818 } 1684 1819 -
trunk/src/VBox/Runtime/common/time/timesup.cpp
r62556 r64255 203 203 : pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 204 204 ? RTTimeNanoTSLFenceAsyncUseRdtscp 205 : pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL 206 ? RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl 205 207 : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID 206 208 ? RTTimeNanoTSLFenceAsyncUseApicId … … 239 241 pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 240 242 ? RTTimeNanoTSLegacyAsyncUseRdtscp 243 : pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL 244 ? RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl 241 245 : pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS 242 246 ? RTTimeNanoTSLegacyAsyncUseIdtrLim -
trunk/src/VBox/Runtime/common/time/timesupref.cpp
r62477 r64255 112 112 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsyncUseIdtrLim); 113 113 114 # undef TMPL_GET_CPU_METHOD 115 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL 116 # undef rtTimeNanoTSInternalRef 117 # define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl 118 # include "timesupref.h" 119 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl); 120 114 121 #else /* IN_RC || IN_RING0: Disable interrupts and call getter function. */ 115 122 … … 196 203 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsyncUseIdtrLim); 197 204 205 # undef TMPL_GET_CPU_METHOD 206 # define TMPL_GET_CPU_METHOD SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL 207 # undef rtTimeNanoTSInternalRef 208 # define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl 209 # include "timesupref.h" 210 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl); 211 198 212 #else /* IN_RC || IN_RING0: Disable interrupts and call getter function. */ 199 213 -
trunk/src/VBox/Runtime/common/time/timesupref.h
r62477 r64255 91 91 uint8_t const idApic = ASMGetApicId(); 92 92 uint16_t const iGipCpu = pGip->aiCpuFromApicId[idApic]; 93 # elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 93 # elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS \ 94 || TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL 94 95 # if TMPL_MODE != TMPL_MODE_ASYNC 95 96 uint32_t const u32TransactionId = pGip->aCPUs[0].u32TransactionId; … … 97 98 uint32_t uAux; 98 99 ASMReadTscWithAux(&uAux); 100 # if TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 99 101 uint16_t const iCpuSet = uAux & (RTCPUSET_MAX_CPUS - 1); 102 # else 103 uint16_t const iCpuSet = pGip->aiFirstCpuSetIdxFromCpuGroup[(uAux >> 8) & UINT8_MAX] + (uAux & UINT8_MAX); 104 # endif 100 105 uint16_t const iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 101 106 # elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS … … 124 129 #elif TMPL_MODE != TMPL_MODE_ASYNC \ 125 130 && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID \ 126 && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 131 && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS \ 132 && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL 127 133 uint32_t const u32TransactionId = pGip->aCPUs[0].u32TransactionId; 128 134 ASMCompilerBarrier(); … … 149 155 #endif 150 156 uint64_t u64PrevNanoTS = ASMAtomicUoReadU64(pData->pu64Prev); 151 #if TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 157 #if TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS \ 158 || TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL 152 159 ASMCompilerBarrier(); 153 160 uint32_t uAux2; … … 168 175 # if TMPL_GET_CPU_METHOD == SUPGIPGETCPU_APIC_ID 169 176 if (RT_LIKELY(ASMGetApicId() == idApic)) 170 # elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS 177 # elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS \ 178 || TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL 171 179 if (RT_LIKELY(uAux2 == uAux)) 172 180 # elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS -
trunk/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
r62478 r64255 119 119 else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS) 120 120 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseRdtscp : RTTimeNanoTSLegacyAsyncUseRdtscp; 121 else if (pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL) 122 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseRdtscpGroupChNumCl : RTTimeNanoTSLegacyAsyncUseRdtscpGroupChNumCl; 121 123 else 122 124 pfnWorker = fLFence ? RTTimeNanoTSLFenceAsyncUseApicId : RTTimeNanoTSLegacyAsyncUseApicId;
Note:
See TracChangeset
for help on using the changeset viewer.