Changeset 81071 in vbox for trunk/src/VBox/HostDrivers/Support
- Timestamp:
- Sep 30, 2019 10:17:28 AM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 133675
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrvGip.cpp
r77727 r81071 173 173 174 174 175 /** 176 * Gets the APIC ID using the best available method. 177 * 178 * @returns APIC ID. 179 * @param pGip The GIP, for SUPGIPGETCPU_XXX. 180 */ 181 DECLINLINE(uint32_t) supdrvGipGetApicId(PSUPGLOBALINFOPAGE pGip) 182 { 183 if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_0B) 184 return ASMGetApicIdExt0B(); 185 if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_8000001E) 186 return ASMGetApicIdExt8000001E(); 187 return ASMGetApicId(); 188 } 189 175 190 176 191 /* … … 212 227 static DECLCALLBACK(void) supdrvGipReInitCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2) 213 228 { 214 PSUPGLOBALINFOPAGE pGip = (PSUPGLOBALINFOPAGE)pvUser1; 215 unsigned iCpu = pGip->aiCpuFromApicId[ASMGetApicId()]; 216 217 if (RT_LIKELY(iCpu < pGip->cCpus && pGip->aCPUs[iCpu].idCpu == idCpu)) 218 supdrvGipReInitCpu(&pGip->aCPUs[iCpu], *(uint64_t *)pvUser2); 229 PSUPGLOBALINFOPAGE pGip = (PSUPGLOBALINFOPAGE)pvUser1; 230 uint32_t const idApic = supdrvGipGetApicId(pGip); 231 if (idApic < RT_ELEMENTS(pGip->aiCpuFromApicId)) 232 { 233 unsigned const iCpu = pGip->aiCpuFromApicId[idApic]; 234 235 if (RT_LIKELY(iCpu < pGip->cCpus && pGip->aCPUs[iCpu].idCpu == idCpu)) 236 supdrvGipReInitCpu(&pGip->aCPUs[iCpu], *(uint64_t *)pvUser2); 237 } 219 238 220 239 NOREF(pvUser2); 221 NOREF(idCpu);222 240 } 223 241 … … 230 248 /** Bitmap of APIC IDs that has been seen (initialized to zero). 231 249 * Used to detect duplicate APIC IDs (paranoia). */ 232 uint8_t volatile bmApicId[ 256/ 8];250 uint8_t volatile bmApicId[1024 / 8]; 233 251 /** Mask of supported GIP CPU getter methods (SUPGIPGETCPU_XXX) (all bits set 234 252 * initially). The callback clears the methods not detected. */ … … 257 275 PSUPGLOBALINFOPAGE pGip = (PSUPGLOBALINFOPAGE)pvUser2; 258 276 uint32_t fSupported = 0; 259 uint16_t idApic; 277 uint32_t idApic; 278 uint32_t uEax, uEbx, uEcx, uEdx; 260 279 int iCpuSet; 261 280 NOREF(pGip); … … 307 326 && (ASMCpuId_EDX(UINT32_C(0x80000001)) & X86_CPUID_EXT_FEATURE_EDX_RDTSCP) ) 308 327 { 309 uint32_t 328 uint32_t uAux; 310 329 ASMReadTscWithAux(&uAux); 311 330 if ((uAux & (RTCPUSET_MAX_CPUS - 1)) == idCpu) … … 335 354 336 355 /* 356 * Check for extended APIC ID methods. 357 */ 358 idApic = UINT32_MAX; 359 uEax = ASMCpuId_EAX(0); 360 if (uEax >= UINT32_C(0xb) && ASMIsValidStdRange(uEax)) 361 { 362 ASMCpuIdExSlow(0xb, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx); 363 if (uEax || uEbx || uEcx || uEdx) 364 { 365 if (RT_LIKELY( uEdx < RT_ELEMENTS(pGip->aiCpuFromApicId) 366 && !ASMBitTest(pState->bmApicId, uEdx))) 367 { 368 if (uEdx == ASMGetApicIdExt0B()) 369 { 370 idApic = uEdx; 371 fSupported |= SUPGIPGETCPU_APIC_ID_EXT_0B; 372 } 373 else 374 AssertMsgFailed(("%#x vs %#x\n", uEdx, ASMGetApicIdExt0B())); 375 } 376 } 377 } 378 379 uEax = ASMCpuId_EAX(UINT32_C(0x80000000)); 380 if (uEax >= UINT32_C(0x8000001e) && ASMIsValidExtRange(uEax)) 381 { 382 ASMCpuIdExSlow(UINT32_C(0x8000001e), 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx); 383 if (uEax || uEbx || uEcx || uEdx) 384 { 385 if (RT_LIKELY( uEax < RT_ELEMENTS(pGip->aiCpuFromApicId) 386 && ( idApic == UINT32_MAX 387 || idApic == uEax) 388 && !ASMBitTest(pState->bmApicId, uEax))) 389 { 390 if (uEax == ASMGetApicIdExt8000001E()) 391 { 392 idApic = uEax; 393 fSupported |= SUPGIPGETCPU_APIC_ID_EXT_8000001E; 394 } 395 else 396 AssertMsgFailed(("%#x vs %#x\n", uEax, ASMGetApicIdExt8000001E())); 397 } 398 } 399 } 400 401 /* 337 402 * Check that the APIC ID is unique. 338 403 */ 339 idApic = ASMGetApicId(); 340 if (RT_LIKELY( idApic < RT_ELEMENTS(pGip->aiCpuFromApicId) 341 && !ASMAtomicBitTestAndSet(pState->bmApicId, idApic))) 404 uEax = ASMGetApicId(); 405 if (RT_LIKELY( uEax < RT_ELEMENTS(pGip->aiCpuFromApicId) 406 && ( idApic == UINT32_MAX 407 || idApic == uEax) 408 && !ASMAtomicBitTestAndSet(pState->bmApicId, uEax))) 409 { 410 idApic = uEax; 342 411 fSupported |= SUPGIPGETCPU_APIC_ID; 343 else 412 } 413 else if ( idApic == UINT32_MAX 414 || idApic >= RT_ELEMENTS(pGip->aiCpuFromApicId) /* parnaoia */ 415 || ASMAtomicBitTestAndSet(pState->bmApicId, idApic)) 344 416 { 345 417 AssertCompile(sizeof(pState->bmApicId) * 8 == RT_ELEMENTS(pGip->aiCpuFromApicId)); 346 418 ASMAtomicCmpXchgU32(&pState->idCpuProblem, idCpu, NIL_RTCPUID); 347 LogRel(("supdrvGipDetectGetGipCpuCallback: idCpu=%#x iCpuSet=%d idApic=%#x - duplicate APIC ID.\n",348 idCpu, iCpuSet, idApic));419 LogRel(("supdrvGipDetectGetGipCpuCallback: idCpu=%#x iCpuSet=%d idApic=%#x/%#x - duplicate APIC ID.\n", 420 idCpu, iCpuSet, uEax, idApic)); 349 421 } 350 422 … … 1276 1348 PSUPGLOBALINFOPAGE pGip = pDevExt->pGip; 1277 1349 int iCpuSet = 0; 1278 uint 16_t idApic = UINT16_MAX;1350 uint32_t idApic; 1279 1351 uint32_t i = 0; 1280 1352 uint64_t u64NanoTS = 0; … … 1312 1384 supdrvGipInitCpu(pGip, &pGip->aCPUs[i], u64NanoTS, pGip->u64CpuHz); 1313 1385 1314 idApic = ASMGetApicId();1386 idApic = supdrvGipGetApicId(pGip); 1315 1387 ASMAtomicWriteU16(&pGip->aCPUs[i].idApic, idApic); 1316 1388 ASMAtomicWriteS16(&pGip->aCPUs[i].iCpuSet, (int16_t)iCpuSet); … … 1326 1398 * Update the APIC ID and CPU set index mappings. 1327 1399 */ 1328 ASMAtomicWriteU16(&pGip->aiCpuFromApicId[idApic], i); 1329 ASMAtomicWriteU16(&pGip->aiCpuFromCpuSetIdx[iCpuSet], i); 1400 if (idApic < RT_ELEMENTS(pGip->aiCpuFromApicId)) 1401 ASMAtomicWriteU16(&pGip->aiCpuFromApicId[idApic], i); 1402 if ((unsigned)iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx)) 1403 ASMAtomicWriteU16(&pGip->aiCpuFromCpuSetIdx[iCpuSet], i); 1330 1404 1331 1405 /* Add this CPU to this set of CPUs we need to calculate the TSC-delta for. */ … … 2364 2438 else 2365 2439 { 2366 unsigned iCpu = pGip->aiCpuFromApicId[ASMGetApicId()]; 2367 if (RT_UNLIKELY(iCpu >= pGip->cCpus)) 2440 unsigned iCpu; 2441 uint32_t idApic = supdrvGipGetApicId(pGip); 2442 if (RT_LIKELY(idApic < RT_ELEMENTS(pGip->aiCpuFromApicId))) 2443 { /* likely */ } 2444 else 2445 return; 2446 iCpu = pGip->aiCpuFromApicId[idApic]; 2447 if (RT_LIKELY(iCpu < pGip->cCpus)) 2448 { /* likely */ } 2449 else 2368 2450 return; 2369 2451 pGipCpu = &pGip->aCPUs[iCpu]; 2370 if (RT_UNLIKELY(pGipCpu->idCpu != idCpu)) 2452 if (RT_LIKELY(pGipCpu->idCpu == idCpu)) 2453 { /* likely */ } 2454 else 2371 2455 return; 2372 2456 } … … 2553 2637 supdrvGipUpdate(pDevExt, NanoTS, u64TSC, idCpu, iTick); 2554 2638 else 2555 supdrvGipUpdatePerCpu(pDevExt, NanoTS, u64TSC, idCpu, ASMGetApicId(), iTick);2639 supdrvGipUpdatePerCpu(pDevExt, NanoTS, u64TSC, idCpu, supdrvGipGetApicId(pDevExt->pGip), iTick); 2556 2640 2557 2641 ASMSetFlags(fEFlags); … … 4806 4890 /* This really shouldn't happen. */ 4807 4891 AssertMsgFailed(("idCpu=%#x iCpuSet=%#x (%d)\n", RTMpCpuId(), iCpuSet, iCpuSet)); 4808 pReq->u.Out.idApic = ASMGetApicId();4892 pReq->u.Out.idApic = supdrvGipGetApicId(pGip); 4809 4893 pReq->u.Out.u64AdjustedTsc = ASMReadTSC(); 4810 4894 ASMSetFlags(fEFlags); … … 4826 4910 pReq->u.Out.idApic = pGip->aCPUs[iGipCpu].idApic; 4827 4911 else 4828 pReq->u.Out.idApic = ASMGetApicId();4912 pReq->u.Out.idApic = supdrvGipGetApicId(pGip); 4829 4913 pReq->u.Out.u64AdjustedTsc = ASMReadTSC(); 4830 4914 ASMSetFlags(fEFlags); -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r80281 r81071 120 120 * @note Implementations ASSUMES up to 32 I/O controls codes in the fast range. 121 121 * @{ */ 122 /** Fast path IOCtl: VMMR0_DO_RAW_RUN */123 #define SUP_IOCTL_FAST_DO_RAW_RUN SUP_CTL_CODE_FAST(64)124 122 /** Fast path IOCtl: VMMR0_DO_HM_RUN */ 125 #define SUP_IOCTL_FAST_DO_HM_RUN SUP_CTL_CODE_FAST(65) 123 #define SUP_IOCTL_FAST_DO_HM_RUN SUP_CTL_CODE_FAST(64) 124 /** Fast path IOCtl: VMMR0_DO_NEM_RUN */ 125 #define SUP_IOCTL_FAST_DO_NEM_RUN SUP_CTL_CODE_FAST(65) 126 126 /** Just a NOP call for profiling the latency of a fast ioctl call to VMMR0. */ 127 127 #define SUP_IOCTL_FAST_DO_NOP SUP_CTL_CODE_FAST(66) 128 /** Fast path IOCtl: VMMR0_DO_NEM_RUN */129 #define SUP_IOCTL_FAST_DO_NEM_RUN SUP_CTL_CODE_FAST(67)130 128 /** First fast path IOCtl number. */ 131 #define SUP_IOCTL_FAST_DO_FIRST SUP_IOCTL_FAST_DO_ RAW_RUN129 #define SUP_IOCTL_FAST_DO_FIRST SUP_IOCTL_FAST_DO_HM_RUN 132 130 /** @} */ 133 131 … … 224 222 * @todo Pending work on next major version change: 225 223 * - Move SUP_IOCTL_FAST_DO_NOP and SUP_VMMR0_DO_NEM_RUN after NEM. 226 * 227 * @remarks 0x002a0000 is used by 5.1. The next version number must be 0x002b0000. 228 */ 229 #define SUPDRV_IOC_VERSION 0x00290009 224 */ 225 #define SUPDRV_IOC_VERSION 0x002b0000 230 226 231 227 /** SUP_IOCTL_COOKIE. */ -
trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
r80281 r81071 613 613 { 614 614 NOREF(pVMR0); 615 static const uintptr_t s_auFunctions[4] = 616 { 617 SUP_IOCTL_FAST_DO_RAW_RUN, 615 static const uintptr_t s_auFunctions[3] = 616 { 618 617 SUP_IOCTL_FAST_DO_HM_RUN, 618 SUP_IOCTL_FAST_DO_NEM_RUN, 619 619 SUP_IOCTL_FAST_DO_NOP, 620 SUP_IOCTL_FAST_DO_NEM_RUN621 620 }; 622 AssertCompile(SUP_VMMR0_DO_ RAW_RUN== 0);623 AssertCompile(SUP_VMMR0_DO_ HM_RUN== 1);621 AssertCompile(SUP_VMMR0_DO_HM_RUN == 0); 622 AssertCompile(SUP_VMMR0_DO_NEM_RUN == 1); 624 623 AssertCompile(SUP_VMMR0_DO_NOP == 2); 625 AssertCompile(SUP_VMMR0_DO_NEM_RUN == 3);626 624 AssertMsgReturn(uOperation < RT_ELEMENTS(s_auFunctions), ("%#x\n", uOperation), VERR_INTERNAL_ERROR); 627 625 return suplibOsIOCtlFast(&g_supLibData, s_auFunctions[uOperation], idCpu); … … 634 632 * The following operations don't belong here. 635 633 */ 636 AssertMsgReturn( uOperation != SUP_VMMR0_DO_ RAW_RUN637 && uOperation != SUP_VMMR0_DO_ HM_RUN634 AssertMsgReturn( uOperation != SUP_VMMR0_DO_HM_RUN 635 && uOperation != SUP_VMMR0_DO_NEM_RUN 638 636 && uOperation != SUP_VMMR0_DO_NOP, 639 637 ("%#x\n", uOperation), … … 721 719 * The following operations don't belong here. 722 720 */ 723 AssertMsgReturn( uOperation != SUP_VMMR0_DO_ RAW_RUN724 && uOperation != SUP_VMMR0_DO_ HM_RUN721 AssertMsgReturn( uOperation != SUP_VMMR0_DO_HM_RUN 722 && uOperation != SUP_VMMR0_DO_NEM_RUN 725 723 && uOperation != SUP_VMMR0_DO_NOP, 726 724 ("%#x\n", uOperation), -
trunk/src/VBox/HostDrivers/Support/SUPLibAll.cpp
r76553 r81071 92 92 iCpuSet &= RTCPUSET_MAX_CPUS - 1; 93 93 iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 94 break; 95 } 96 if (cTries >= 16) 97 { 98 iGipCpu = UINT16_MAX; 99 break; 100 } 101 cTries++; 102 } 103 } 104 else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_0B) 105 { 106 /* Get APIC ID / 0x1b via the slow CPUID instruction, requires looping. */ 107 uint32_t cTries = 0; 108 for (;;) 109 { 110 uint32_t idApic = ASMGetApicIdExt0B(); 111 uTsc = ASMReadTSC(); 112 if (RT_LIKELY(ASMGetApicIdExt0B() == idApic)) 113 { 114 iGipCpu = pGip->aiCpuFromApicId[idApic]; 115 break; 116 } 117 if (cTries >= 16) 118 { 119 iGipCpu = UINT16_MAX; 120 break; 121 } 122 cTries++; 123 } 124 } 125 else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_8000001E) 126 { 127 /* Get APIC ID / 0x8000001e via the slow CPUID instruction, requires looping. */ 128 uint32_t cTries = 0; 129 for (;;) 130 { 131 uint32_t idApic = ASMGetApicIdExt8000001E(); 132 uTsc = ASMReadTSC(); 133 if (RT_LIKELY(ASMGetApicIdExt8000001E() == idApic)) 134 { 135 iGipCpu = pGip->aiCpuFromApicId[idApic]; 94 136 break; 95 137 } … … 204 246 iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]; 205 247 } 248 else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_0B) 249 { 250 /* Get APIC ID via the slow CPUID/0000000B instruction. */ 251 uint32_t idApic = ASMGetApicIdExt0B(); 252 iGipCpu = pGip->aiCpuFromApicId[idApic]; 253 } 254 else if (pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID_EXT_8000001E) 255 { 256 /* Get APIC ID via the slow CPUID/8000001E instruction. */ 257 uint32_t idApic = ASMGetApicIdExt8000001E(); 258 iGipCpu = pGip->aiCpuFromApicId[idApic]; 259 } 206 260 else 207 261 {
Note:
See TracChangeset
for help on using the changeset viewer.