- Timestamp:
- Oct 15, 2014 12:41:35 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/sup.h
r52618 r53063 1434 1434 SUPR3DECL(int) SUPR3ResumeSuspendedKeyboards(void); 1435 1435 1436 1437 /** 1438 * Measure the TSC-delta for the specified CPU. 1439 * 1440 * @returns VBox status code. 1441 * @param idCpu The CPU to measure the TSC-delta for. 1442 * @param fAsync Whether the measurement is asynchronous, returns 1443 * immediately after signalling a measurement 1444 * request. 1445 * @param fForce Whether to perform a measurement even if the 1446 * specified CPU has a (possibly) valid TSC delta. 1447 * @param cRetries Number of times to retry failed delta 1448 * measurements. 1449 */ 1450 SUPR3DECL(int) SUPR3TscDeltaMeasure(RTCPUID idCpu, bool fAsync, bool fForce, uint8_t cRetries); 1451 1436 1452 /** @} */ 1437 1453 #endif /* IN_RING3 */ -
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r53058 r53063 154 154 static int supdrvIOCtl_LoggerSettings(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPLOGGERSETTINGS pReq); 155 155 static int supdrvIOCtl_MsrProber(PSUPDRVDEVEXT pDevExt, PSUPMSRPROBER pReq); 156 static int supdrvIOCtl_TscDeltaMeasure(PSUPDRVDEVEXT pDevExt, PSUPTSCDELTAMEASURE pReq); 156 157 static int supdrvGipCreate(PSUPDRVDEVEXT pDevExt); 157 158 static void supdrvGipDestroy(PSUPDRVDEVEXT pDevExt); … … 2242 2243 } 2243 2244 2245 case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_TSC_DELTA_MEASURE): 2246 { 2247 /* validate */ 2248 PSUPTSCDELTAMEASURE pReq = (PSUPTSCDELTAMEASURE)pReqHdr; 2249 REQ_CHECK_SIZES(SUP_IOCTL_TSC_DELTA_MEASURE); 2250 2251 pReqHdr->rc = supdrvIOCtl_TscDeltaMeasure(pDevExt, pReq); 2252 return 0; 2253 } 2254 2244 2255 default: 2245 2256 Log(("Unknown IOCTL %#lx\n", (long)uIOCtl)); … … 6642 6653 static int supdrvMeasureTscDeltaOne(PSUPDRVDEVEXT pDevExt, uint32_t idxWorker) 6643 6654 { 6644 PSUPGLOBALINFOPAGE pGip = pDevExt->pGip; 6645 RTCPUID idMaster = pDevExt->idGipMaster; 6646 uint32_t idxMaster = supdrvGipCpuIndexFromCpuId(pGip, idMaster); 6647 PSUPGIPCPU pGipCpuWorker = &pGip->aCPUs[idxWorker]; 6648 int rc = VERR_CPU_OFFLINE; 6649 6650 if (idxWorker == idxMaster) 6655 int rc; 6656 PSUPGLOBALINFOPAGE pGip; 6657 PSUPGIPCPU pGipCpuWorker; 6658 RTCPUID idMaster; 6659 6660 AssertReturn(pDevExt, VERR_INVALID_PARAMETER); 6661 AssertReturn(pDevExt->pGip, VERR_INVALID_PARAMETER); 6662 6663 pGip = pDevExt->pGip; 6664 idMaster = pDevExt->idGipMaster; 6665 pGipCpuWorker = &pGip->aCPUs[idxWorker]; 6666 6667 if (pGipCpuWorker->idCpu == idMaster) 6651 6668 { 6652 6669 ASMAtomicWriteS64(&pGipCpuWorker->i64TSCDelta, 0); … … 6656 6673 /* Set the master TSC as the initiator. */ 6657 6674 while (ASMAtomicCmpXchgU32(&g_idTscDeltaInitiator, idMaster, NIL_RTCPUID) == false) 6658 ASMNopPause(); 6675 { 6676 /* 6677 * Sleep here rather than spin as there is a parallel measurement 6678 * being executed and that can take a good while to be done. 6679 */ 6680 RTThreadSleep(1); 6681 } 6659 6682 6660 6683 if (RTCpuSetIsMember(&pGip->OnlineCpuSet, pGipCpuWorker->idCpu)) … … 6670 6693 } 6671 6694 } 6695 else 6696 rc = VERR_CPU_OFFLINE; 6672 6697 6673 6698 ASMAtomicWriteU32(&g_idTscDeltaInitiator, NIL_RTCPUID); … … 7314 7339 } 7315 7340 7341 7316 7342 /** 7317 7343 * Resume built-in keyboard on MacBook Air and Pro hosts. … … 7329 7355 } 7330 7356 7357 7358 /** 7359 * Service a TSC-delta measurement request. 7360 * 7361 * @returns VBox status code. 7362 * @param pDevExt Pointer to the device instance data. 7363 * @param pReq Pointer to the TSC-delta measurement request. 7364 */ 7365 static int supdrvIOCtl_TscDeltaMeasure(PSUPDRVDEVEXT pDevExt, PSUPTSCDELTAMEASURE pReq) 7366 { 7367 PSUPGLOBALINFOPAGE pGip; 7368 RTCPUID idCpuWorker; 7369 int rc = VERR_CPU_NOT_FOUND; 7370 int16_t cTries; 7371 RTMSINTERVAL cMsWaitRetry; 7372 uint16_t iCpu; 7373 7374 /* 7375 * Validate. 7376 */ 7377 AssertReturn(pDevExt, VERR_INVALID_PARAMETER); 7378 AssertReturn(pReq, VERR_INVALID_PARAMETER); 7379 AssertReturn(pDevExt->pGip, VERR_INVALID_PARAMETER); 7380 idCpuWorker = pReq->u.In.idCpu; 7381 if (idCpuWorker == NIL_RTCPUID) 7382 return VERR_INVALID_CPU_ID; 7383 7384 #ifdef SUPDRV_USE_TSC_DELTA_THREAD 7385 if (pReq->u.In.fAsync) 7386 { 7387 /** @todo Async. doesn't implement options like retries, waiting. We'll need 7388 * to pass those options to the thread somehow and implement it in the 7389 * thread. Check if anyone uses/needs fAsync before implementing this. */ 7390 RTCpuSetAdd(&pDevExt->TscDeltaCpuSet, idCpu); 7391 RTSpinlockAcquire(pDevExt->hTscDeltaSpinlock); 7392 if ( pDevExt->enmTscDeltaState == kSupDrvTscDeltaState_Listening 7393 || pDevExt->enmTscDeltaState == kSupDrvTscDeltaState_Measuring) 7394 { 7395 pDevExt->enmTscDeltaState = kSupDrvTscDeltaState_WaitAndMeasure; 7396 } 7397 RTSpinlockRelease(pDevExt->hTscDeltaSpinlock); 7398 RTThreadUserSignal(pDevExt->hTscDeltaThread); 7399 return VINF_SUCCESS; 7400 } 7401 #endif 7402 7403 cTries = RT_MAX(pReq->u.In.cRetries + 1, 10); 7404 cMsWaitRetry = RT_MAX(pReq->u.In.cMsWaitRetry, 5); 7405 pGip = pDevExt->pGip; 7406 for (iCpu = 0; iCpu < pGip->cCpus; iCpu++) 7407 { 7408 PSUPGIPCPU pGipCpuWorker = &pGip->aCPUs[iCpu]; 7409 if (pGipCpuWorker->idCpu == idCpuWorker) 7410 { 7411 if ( pGipCpuWorker->i64TSCDelta != INT64_MAX 7412 && !pReq->u.In.fForce) 7413 return VINF_SUCCESS; 7414 7415 while (!cTries--) 7416 { 7417 rc = supdrvMeasureTscDeltaOne(pDevExt, iCpu); 7418 if (RT_SUCCESS(rc)) 7419 { 7420 Assert(pGipCpuWorker->i64TSCDelta != INT64_MAX); 7421 break; 7422 } 7423 7424 if (cMsWaitRetry) 7425 RTThreadSleep(cMsWaitRetry); 7426 } 7427 7428 break; 7429 } 7430 } 7431 return rc; 7432 } 7433 -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r53002 r53063 215 215 * - (none). 216 216 */ 217 #define SUPDRV_IOC_VERSION 0x001b000 0217 #define SUPDRV_IOC_VERSION 0x001b0001 218 218 219 219 /** SUP_IOCTL_COOKIE. */ … … 1471 1471 1472 1472 1473 /** @name SUP_IOCTL_TSC_DELTA_MEASURE 1474 * Measure the TSC-delta between the specified CPU and the master TSC. 1475 * 1476 * @{ 1477 */ 1478 #define SUP_IOCTL_TSC_DELTA_MEASURE SUP_CTL_CODE_SIZE(36, SUP_IOCTL_TSC_DELTA_MEASURE_SIZE) 1479 #define SUP_IOCTL_TSC_DELTA_MEASURE_SIZE sizeof(SUPTSCDELTAMEASURE) 1480 #define SUP_IOCTL_TSC_DELTA_MEASURE_SIZE_IN sizeof(SUPTSCDELTAMEASURE) 1481 #define SUP_IOCTL_TSC_DELTA_MEASURE_SIZE_OUT sizeof(SUPREQHDR) 1482 typedef struct SUPTSCDELTAMEASURE 1483 { 1484 /** The header. */ 1485 SUPREQHDR Hdr; 1486 1487 /** Input/output union. */ 1488 union 1489 { 1490 struct 1491 { 1492 /** Which CPU to take the TSC-delta measurement for. */ 1493 RTCPUID idCpu; 1494 /** Number of times to retry on failure (specify 0 for default). */ 1495 uint8_t cRetries; 1496 /** Number of milliseconds to wait before each retry. */ 1497 uint8_t cMsWaitRetry; 1498 /** Whether to force taking a measurement if one exists already. */ 1499 bool fForce; 1500 /** Whether to do the measurement asynchronously (if possible). */ 1501 bool fAsync; 1502 /** Padding for future. */ 1503 uint64_t auPadding[3]; 1504 } In; 1505 } u; 1506 } SUPTSCDELTAMEASURE, *PSUPTSCDELTAMEASURE; 1507 AssertCompileMemberAlignment(SUPTSCDELTAMEASURE, u, 8); 1508 /** @} */ 1509 1510 1473 1511 #pragma pack() /* paranoia */ 1474 1512 -
trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
r53059 r53063 280 280 CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION; 281 281 const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x001b0000 282 ? 0x001b000 0282 ? 0x001b0001 283 283 : SUPDRV_IOC_VERSION & 0xffff0000; 284 284 CookieReq.u.In.u32MinVersion = uMinVersion; … … 2176 2176 } 2177 2177 2178 2179 SUPR3DECL(int) SUPR3TscDeltaMeasure(RTCPUID idCpu, bool fAsync, bool fForce, uint8_t cRetries, uint8_t cMsWaitRetry) 2180 { 2181 SUPTSCDELTAMEASURE Req; 2182 Req.Hdr.u32Cookie = g_u32Cookie; 2183 Req.Hdr.u32SessionCookie = g_u32SessionCookie; 2184 Req.Hdr.cbIn = SUP_IOCTL_TSC_DELTA_MEASURE_SIZE_IN; 2185 Req.Hdr.cbOut = SUP_IOCTL_TSC_DELTA_MEASURE_SIZE_OUT; 2186 Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; 2187 Req.Hdr.rc = VERR_INTERNAL_ERROR; 2188 2189 Req.u.In.cRetries = cRetries; 2190 Req.u.In.fAsync = fAsync; 2191 Req.u.In.fForce = fForce; 2192 Req.u.In.idCpu = idCpu; 2193 Req.u.In.cMsWaitRetry = cMsWaitRetry; 2194 2195 int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_TSC_DELTA_MEASURE, &Req, SUP_IOCTL_TSC_DELTA_MEASURE_SIZE); 2196 if (RT_SUCCESS(rc)) 2197 rc = Req.Hdr.rc; 2198 return rc; 2199 } 2200
Note:
See TracChangeset
for help on using the changeset viewer.