VBoxNetBaseService::~VBoxNetBaseService() { /* * Close the interface connection. */ if (m) { shutdown(); if (m->m_hIf != INTNET_HANDLE_INVALID) { INTNETIFCLOSEREQ CloseReq; CloseReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; CloseReq.Hdr.cbReq = sizeof(CloseReq); CloseReq.pSession = m->m_pSession; CloseReq.hIf = m->m_hIf; m->m_hIf = INTNET_HANDLE_INVALID; int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_CLOSE, 0, &CloseReq.Hdr); AssertRC(rc); } if (m->m_pSession != NIL_RTR0PTR) { SUPR3Term(false /*fForced*/); m->m_pSession = NIL_RTR0PTR; } RTCritSectDelete(&m->m_csThis); delete m; m = NULL; } }
int main(int argc, char **argv) { int rc; RTR3InitExe(argc, &argv, 0); rc = SUPR3Init(NULL); if (RT_SUCCESS(rc)) { SUPPAGINGMODE enmMode = SUPR3GetPagingMode(); switch (enmMode) { case SUPPAGINGMODE_INVALID: RTPrintf("SUPPAGINGMODE_INVALID\n"); break; case SUPPAGINGMODE_32_BIT: RTPrintf("SUPPAGINGMODE_32_BIT\n"); break; case SUPPAGINGMODE_32_BIT_GLOBAL: RTPrintf("SUPPAGINGMODE_32_BIT_GLOBAL\n"); break; case SUPPAGINGMODE_PAE: RTPrintf("SUPPAGINGMODE_PAE\n"); break; case SUPPAGINGMODE_PAE_GLOBAL: RTPrintf("SUPPAGINGMODE_PAE_GLOBAL\n"); break; case SUPPAGINGMODE_PAE_NX: RTPrintf("SUPPAGINGMODE_PAE_NX\n"); break; case SUPPAGINGMODE_PAE_GLOBAL_NX: RTPrintf("SUPPAGINGMODE_PAE_GLOBAL_NX\n"); break; case SUPPAGINGMODE_AMD64: RTPrintf("SUPPAGINGMODE_AMD64\n"); break; case SUPPAGINGMODE_AMD64_GLOBAL: RTPrintf("SUPPAGINGMODE_AMD64_GLOBAL\n"); break; case SUPPAGINGMODE_AMD64_NX: RTPrintf("SUPPAGINGMODE_AMD64_NX\n"); break; case SUPPAGINGMODE_AMD64_GLOBAL_NX: RTPrintf("SUPPAGINGMODE_AMD64_GLOBAL_NX\n"); break; default: RTPrintf("Unknown mode %d\n", enmMode); rc = VERR_INTERNAL_ERROR; break; } int rc2 = SUPR3Term(false /*fForced*/); RTPrintf("SUPR3Term -> rc=%Rrc\n", rc2); } else RTPrintf("SUPR3Init -> rc=%Rrc\n", rc); return !RT_SUCCESS(rc); }
int main(int argc, char **argv) { int rc; RTR3InitExe(argc, &argv, 0); rc = SUPR3Init(NULL); RTPrintf("tstInit: SUPR3Init -> rc=%Rrc\n", rc); if (!rc) { rc = SUPR3Term(false /*fForced*/); RTPrintf("tstInit: SUPR3Term -> rc=%Rrc\n", rc); } return rc; }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); /* * Parse args */ static const RTGETOPTDEF g_aOptions[] = { { "--iterations", 'i', RTGETOPT_REQ_INT32 }, { "--hex", 'h', RTGETOPT_REQ_NOTHING }, { "--decimal", 'd', RTGETOPT_REQ_NOTHING }, { "--spin", 's', RTGETOPT_REQ_NOTHING } }; uint32_t cIterations = 40; bool fHex = true; bool fSpin = false; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'i': cIterations = ValueUnion.u32; break; case 'd': fHex = false; break; case 'h': fHex = true; break; case 's': fSpin = true; break; default: return RTGetOptPrintError(ch, &ValueUnion); } } /* * Init */ PSUPDRVSESSION pSession = NIL_RTR0PTR; int rc = SUPR3Init(&pSession); if (RT_SUCCESS(rc)) { if (g_pSUPGlobalInfoPage) { RTPrintf("tstGIP-2: u32UpdateHz=%RU32 u32UpdateIntervalNS=%RU32 u64NanoTSLastUpdateHz=%RX64 u32Mode=%d (%s) u32Version=%#x\n", g_pSUPGlobalInfoPage->u32UpdateHz, g_pSUPGlobalInfoPage->u32UpdateIntervalNS, g_pSUPGlobalInfoPage->u64NanoTSLastUpdateHz, g_pSUPGlobalInfoPage->u32Mode, g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC ? "sync" : g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_ASYNC_TSC ? "async" : "???", g_pSUPGlobalInfoPage->u32Version); RTPrintf(fHex ? "tstGIP-2: it: u64NanoTS delta u64TSC UpIntTSC H TransId CpuHz TSC Interval History...\n" : "tstGIP-2: it: u64NanoTS delta u64TSC UpIntTSC H TransId CpuHz TSC Interval History...\n"); static SUPGIPCPU s_aaCPUs[2][RT_ELEMENTS(g_pSUPGlobalInfoPage->aCPUs)]; for (uint32_t i = 0; i < cIterations; i++) { /* copy the data */ memcpy(&s_aaCPUs[i & 1][0], &g_pSUPGlobalInfoPage->aCPUs[0], sizeof(g_pSUPGlobalInfoPage->aCPUs)); /* display it & find something to spin on. */ uint32_t u32TransactionId = 0; uint32_t volatile *pu32TransactionId = NULL; for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(g_pSUPGlobalInfoPage->aCPUs); iCpu++) if ( g_pSUPGlobalInfoPage->aCPUs[iCpu].u64CpuHz > 0 && g_pSUPGlobalInfoPage->aCPUs[iCpu].u64CpuHz != _4G + 1) { PSUPGIPCPU pPrevCpu = &s_aaCPUs[!(i & 1)][iCpu]; PSUPGIPCPU pCpu = &s_aaCPUs[i & 1][iCpu]; RTPrintf(fHex ? "tstGIP-2: %4d/%d: %016llx %09llx %016llx %08x %d %08x %15llu %08x %08x %08x %08x %08x %08x %08x %08x (%d)\n" : "tstGIP-2: %4d/%d: %016llu %09llu %016llu %010u %d %010u %15llu %08x %08x %08x %08x %08x %08x %08x %08x (%d)\n", i, iCpu, pCpu->u64NanoTS, i ? pCpu->u64NanoTS - pPrevCpu->u64NanoTS : 0, pCpu->u64TSC, pCpu->u32UpdateIntervalTSC, pCpu->iTSCHistoryHead, pCpu->u32TransactionId, pCpu->u64CpuHz, pCpu->au32TSCHistory[0], pCpu->au32TSCHistory[1], pCpu->au32TSCHistory[2], pCpu->au32TSCHistory[3], pCpu->au32TSCHistory[4], pCpu->au32TSCHistory[5], pCpu->au32TSCHistory[6], pCpu->au32TSCHistory[7], pCpu->cErrors); if (!pu32TransactionId) { pu32TransactionId = &g_pSUPGlobalInfoPage->aCPUs[iCpu].u32TransactionId; u32TransactionId = pCpu->u32TransactionId; } } /* wait a bit / spin */ if (!fSpin) RTThreadSleep(9); else while (u32TransactionId == *pu32TransactionId) /* nop */; } } else { RTPrintf("tstGIP-2: g_pSUPGlobalInfoPage is NULL\n"); rc = -1; } SUPR3Term(false /*fForced*/); } else RTPrintf("tstGIP-2: SUPR3Init failed: %Rrc\n", rc); return !!rc; }
int main(int argc, char **argv) { int rcRet = 0; int i; int rc; int cIterations = argc > 1 ? RTStrToUInt32(argv[1]) : 32; if (cIterations == 0) cIterations = 64; /* * Init. */ RTR3InitExe(argc, &argv, 0); PSUPDRVSESSION pSession; rc = SUPR3Init(&pSession); rcRet += rc != 0; RTPrintf("tstInt: SUPR3Init -> rc=%Rrc\n", rc); char szFile[RTPATH_MAX]; if (!rc) { rc = RTPathExecDir(szFile, sizeof(szFile) - sizeof("/VMMR0.r0")); } char szAbsFile[RTPATH_MAX]; if (RT_SUCCESS(rc)) { strcat(szFile, "/VMMR0.r0"); rc = RTPathAbs(szFile, szAbsFile, sizeof(szAbsFile)); } if (RT_SUCCESS(rc)) { /* * Load VMM code. */ rc = SUPR3LoadVMM(szAbsFile); if (RT_SUCCESS(rc)) { /* * Create a fake 'VM'. */ PVMR0 pVMR0 = NIL_RTR0PTR; PVM pVM = NULL; const unsigned cPages = RT_ALIGN_Z(sizeof(*pVM), PAGE_SIZE) >> PAGE_SHIFT; PSUPPAGE paPages = (PSUPPAGE)RTMemAllocZ(cPages * sizeof(SUPPAGE)); if (paPages) rc = SUPR3LowAlloc(cPages, (void **)&pVM, &pVMR0, &paPages[0]); else rc = VERR_NO_MEMORY; if (RT_SUCCESS(rc)) { pVM->pVMRC = 0; pVM->pVMR3 = pVM; pVM->pVMR0 = pVMR0; pVM->paVMPagesR3 = paPages; pVM->pSession = pSession; pVM->enmVMState = VMSTATE_CREATED; rc = SUPR3SetVMForFastIOCtl(pVMR0); if (!rc) { /* * Call VMM code with invalid function. */ for (i = cIterations; i > 0; i--) { rc = SUPR3CallVMMR0(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, NULL); if (rc != VINF_SUCCESS) { RTPrintf("tstInt: SUPR3CallVMMR0 -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i); rcRet++; break; } } RTPrintf("tstInt: Performed SUPR3CallVMMR0 %d times (rc=%Rrc)\n", cIterations, rc); /* * The fast path. */ if (rc == VINF_SUCCESS) { RTTimeNanoTS(); uint64_t StartTS = RTTimeNanoTS(); uint64_t StartTick = ASMReadTSC(); uint64_t MinTicks = UINT64_MAX; for (i = 0; i < 1000000; i++) { uint64_t OneStartTick = ASMReadTSC(); rc = SUPR3CallVMMR0Fast(pVMR0, VMMR0_DO_NOP, 0); uint64_t Ticks = ASMReadTSC() - OneStartTick; if (Ticks < MinTicks) MinTicks = Ticks; if (RT_UNLIKELY(rc != VINF_SUCCESS)) { RTPrintf("tstInt: SUPR3CallVMMR0Fast -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i); rcRet++; break; } } uint64_t Ticks = ASMReadTSC() - StartTick; uint64_t NanoSecs = RTTimeNanoTS() - StartTS; RTPrintf("tstInt: SUPR3CallVMMR0Fast - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n", i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks); /* * The ordinary path. */ RTTimeNanoTS(); StartTS = RTTimeNanoTS(); StartTick = ASMReadTSC(); MinTicks = UINT64_MAX; for (i = 0; i < 1000000; i++) { uint64_t OneStartTick = ASMReadTSC(); rc = SUPR3CallVMMR0Ex(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, 0, NULL); uint64_t OneTicks = ASMReadTSC() - OneStartTick; if (OneTicks < MinTicks) MinTicks = OneTicks; if (RT_UNLIKELY(rc != VINF_SUCCESS)) { RTPrintf("tstInt: SUPR3CallVMMR0Ex -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i); rcRet++; break; } } Ticks = ASMReadTSC() - StartTick; NanoSecs = RTTimeNanoTS() - StartTS; RTPrintf("tstInt: SUPR3CallVMMR0Ex - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n", i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks); } } else { RTPrintf("tstInt: SUPR3SetVMForFastIOCtl failed: %Rrc\n", rc); rcRet++; } } else { RTPrintf("tstInt: SUPR3ContAlloc(%#zx,,) failed\n", sizeof(*pVM)); rcRet++; } /* * Unload VMM. */ rc = SUPR3UnloadVMM(); if (rc) { RTPrintf("tstInt: SUPR3UnloadVMM failed with rc=%Rrc\n", rc); rcRet++; } } else { RTPrintf("tstInt: SUPR3LoadVMM failed with rc=%Rrc\n", rc); rcRet++; } /* * Terminate. */ rc = SUPR3Term(false /*fForced*/); rcRet += rc != 0; RTPrintf("tstInt: SUPR3Term -> rc=%Rrc\n", rc); }
int main(int argc, char **argv) { RTTEST hTest; RTEXITCODE rcExit = RTTestInitExAndCreate(argc, &argv, 0 /*fRtInit*/, "tstSupTscDelta", &hTest); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; /* * Parse args */ static const RTGETOPTDEF g_aOptions[] = { { "--iterations", 'i', RTGETOPT_REQ_INT32 }, { "--delay", 'd', RTGETOPT_REQ_INT32 }, }; uint32_t cIterations = 0; /* Currently 0 so that it doesn't upset testing. */ uint32_t cMsSleepBetweenIterations = 10; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'd': cMsSleepBetweenIterations = ValueUnion.u32; break; case 'i': cIterations = ValueUnion.u32; break; default: return RTGetOptPrintError(ch, &ValueUnion); } } if (!cIterations) return RTTestSkipAndDestroy(hTest, "Nothing to do. The --iterations argument is 0 or not given."); /* * Init */ PSUPDRVSESSION pSession = NIL_RTR0PTR; int rc = SUPR3Init(&pSession); if (RT_SUCCESS(rc)) { PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; if (pGip) { if (pGip->enmUseTscDelta < SUPGIPUSETSCDELTA_PRACTICALLY_ZERO) return RTTestSkipAndDestroy(hTest, "No deltas to play with: enmUseTscDelta=%d\n", pGip->enmUseTscDelta); /* * Init stats. */ struct { int64_t iLowest; int64_t iHighest; int64_t iTotal; uint64_t uAbsMin; uint64_t uAbsMax; uint64_t uAbsTotal; } aCpuStats[RTCPUSET_MAX_CPUS]; RT_ZERO(aCpuStats); for (uint32_t i = 0; i < pGip->cCpus; i++) { aCpuStats[i].iLowest = INT64_MAX; aCpuStats[i].iHighest = INT64_MIN; aCpuStats[i].uAbsMin = UINT64_MAX; } /* * Do the work. */ for (uint32_t iIteration = 0; ; iIteration++) { /* * Display the current deltas and gather statistics. */ RTPrintf("tstSupTscDelta: Iteration #%u results:", iIteration); for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++) { int64_t iTscDelta = pGip->aCPUs[iCpu].i64TSCDelta; /* print */ if ((iCpu % 4) == 0) RTPrintf("\ntstSupTscDelta:"); if (pGip->aCPUs[iCpu].enmState != SUPGIPCPUSTATE_ONLINE) RTPrintf(" %02x: offline ", iCpu); else if (iTscDelta != INT64_MAX) RTPrintf(" %02x: %-12lld", iCpu, iTscDelta); else RTPrintf(" %02x: INT64_MAX ", iCpu); /* stats */ if ( iTscDelta != INT64_MAX && pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_ONLINE) { if (aCpuStats[iCpu].iLowest > iTscDelta) aCpuStats[iCpu].iLowest = iTscDelta; if (aCpuStats[iCpu].iHighest < iTscDelta) aCpuStats[iCpu].iHighest = iTscDelta; aCpuStats[iCpu].iTotal += iTscDelta; uint64_t uAbsTscDelta = iTscDelta >= 0 ? (uint64_t)iTscDelta : (uint64_t)-iTscDelta; if (aCpuStats[iCpu].uAbsMin > uAbsTscDelta) aCpuStats[iCpu].uAbsMin = uAbsTscDelta; if (aCpuStats[iCpu].uAbsMax < uAbsTscDelta) aCpuStats[iCpu].uAbsMax = uAbsTscDelta; aCpuStats[iCpu].uAbsTotal += uAbsTscDelta; } } if (((pGip->cCpus - 1) % 4) != 0) RTPrintf("\n"); /* * Done? */ if (iIteration + 1 >= cIterations) break; /* * Force a new measurement. */ RTThreadSleep(cMsSleepBetweenIterations); for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++) if (pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_ONLINE) { rc = SUPR3TscDeltaMeasure(pGip->aCPUs[iCpu].idCpu, false /*fAsync*/, true /*fForce*/, 64, 16 /*ms*/); if (RT_FAILURE(rc)) RTTestFailed(hTest, "SUPR3TscDeltaMeasure failed on %#x: %Rrc", pGip->aCPUs[iCpu].idCpu, rc); } } /* * Display statistics that we've gathered. */ RTPrintf("tstSupTscDelta: Results:\n"); int64_t iLowest = INT64_MAX; int64_t iHighest = INT64_MIN; int64_t iTotal = 0; uint32_t cTotal = 0; for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++) { if (pGip->aCPUs[iCpu].enmState != SUPGIPCPUSTATE_ONLINE) RTPrintf("tstSupTscDelta: %02x: offline\n", iCpu); else { RTPrintf("tstSupTscDelta: %02x: lowest=%-12lld highest=%-12lld average=%-12lld spread=%-12lld\n", iCpu, aCpuStats[iCpu].iLowest, aCpuStats[iCpu].iHighest, aCpuStats[iCpu].iTotal / cIterations, aCpuStats[iCpu].iHighest - aCpuStats[iCpu].iLowest); RTPrintf( "tstSupTscDelta: absmin=%-12llu absmax=%-12llu absavg=%-12llu idCpu=%#4x idApic=%#4x\n", aCpuStats[iCpu].uAbsMin, aCpuStats[iCpu].uAbsMax, aCpuStats[iCpu].uAbsTotal / cIterations, pGip->aCPUs[iCpu].idCpu, pGip->aCPUs[iCpu].idApic); if (iLowest > aCpuStats[iCpu].iLowest) iLowest = aCpuStats[iCpu].iLowest; if (iHighest < aCpuStats[iCpu].iHighest) iHighest = aCpuStats[iCpu].iHighest; iTotal += aCpuStats[iCpu].iHighest; cTotal += cIterations; } } RTPrintf("tstSupTscDelta: all: lowest=%-12lld highest=%-12lld average=%-12lld spread=%-12lld\n", iLowest, iHighest, iTotal / cTotal, iHighest - iLowest); } else RTTestFailed(hTest, "g_pSUPGlobalInfoPage is NULL"); SUPR3Term(false /*fForced*/); } else RTTestFailed(hTest, "SUPR3Init failed: %Rrc", rc); return RTTestSummaryAndDestroy(hTest); }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); /* * Parse args */ static const RTGETOPTDEF g_aOptions[] = { { "--iterations", 'i', RTGETOPT_REQ_INT32 }, { "--hex", 'h', RTGETOPT_REQ_NOTHING }, { "--decimal", 'd', RTGETOPT_REQ_NOTHING }, { "--spin", 's', RTGETOPT_REQ_NOTHING }, { "--reference", 'r', RTGETOPT_REQ_UINT64 }, /* reference value of CpuHz, display the * CpuHz deviation in a separate column. */ }; uint32_t cIterations = 40; bool fHex = true; bool fSpin = false; int ch; uint64_t uCpuHzRef = 0; uint64_t uCpuHzOverallDeviation = 0; int64_t iCpuHzMaxDeviation = 0; int32_t cCpuHzOverallDevCnt = 0; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'i': cIterations = ValueUnion.u32; break; case 'd': fHex = false; break; case 'h': fHex = true; break; case 's': fSpin = true; break; case 'r': uCpuHzRef = ValueUnion.u64; break; default: return RTGetOptPrintError(ch, &ValueUnion); } } /* * Init */ PSUPDRVSESSION pSession = NIL_RTR0PTR; int rc = SUPR3Init(&pSession); if (RT_SUCCESS(rc)) { if (g_pSUPGlobalInfoPage) { RTPrintf("tstGIP-2: cCpus=%d u32UpdateHz=%RU32 u32UpdateIntervalNS=%RU32 u64NanoTSLastUpdateHz=%RX64 u64CpuHz=%RU64 uCpuHzRef=%RU64 u32Mode=%d (%s) u32Version=%#x\n", g_pSUPGlobalInfoPage->cCpus, g_pSUPGlobalInfoPage->u32UpdateHz, g_pSUPGlobalInfoPage->u32UpdateIntervalNS, g_pSUPGlobalInfoPage->u64NanoTSLastUpdateHz, g_pSUPGlobalInfoPage->u64CpuHz, uCpuHzRef, g_pSUPGlobalInfoPage->u32Mode, SUPGetGIPModeName(g_pSUPGlobalInfoPage), g_pSUPGlobalInfoPage->u32Version); RTPrintf(fHex ? "tstGIP-2: it: u64NanoTS delta u64TSC UpIntTSC H TransId CpuHz %sTSC Interval History...\n" : "tstGIP-2: it: u64NanoTS delta u64TSC UpIntTSC H TransId CpuHz %sTSC Interval History...\n", uCpuHzRef ? " CpuHz deviation " : ""); static SUPGIPCPU s_aaCPUs[2][256]; for (uint32_t i = 0; i < cIterations; i++) { /* copy the data */ memcpy(&s_aaCPUs[i & 1][0], &g_pSUPGlobalInfoPage->aCPUs[0], g_pSUPGlobalInfoPage->cCpus * sizeof(g_pSUPGlobalInfoPage->aCPUs[0])); /* display it & find something to spin on. */ uint32_t u32TransactionId = 0; uint32_t volatile *pu32TransactionId = NULL; for (unsigned iCpu = 0; iCpu < g_pSUPGlobalInfoPage->cCpus; iCpu++) if ( g_pSUPGlobalInfoPage->aCPUs[iCpu].u64CpuHz > 0 && g_pSUPGlobalInfoPage->aCPUs[iCpu].u64CpuHz != _4G + 1) { char szCpuHzDeviation[32]; PSUPGIPCPU pPrevCpu = &s_aaCPUs[!(i & 1)][iCpu]; PSUPGIPCPU pCpu = &s_aaCPUs[i & 1][iCpu]; if (uCpuHzRef) { int64_t iCpuHzDeviation = pCpu->u64CpuHz - uCpuHzRef; uint64_t uCpuHzDeviation = RT_ABS(iCpuHzDeviation); if (uCpuHzDeviation > 999999999) RTStrPrintf(szCpuHzDeviation, sizeof(szCpuHzDeviation), "%17s ", "?"); else { /* Wait until the history validation code takes effect. */ if (pCpu->u32TransactionId > 23 + (8 * 2) + 1) { if (RT_ABS(iCpuHzDeviation) > RT_ABS(iCpuHzMaxDeviation)) iCpuHzMaxDeviation = iCpuHzDeviation; uCpuHzOverallDeviation += uCpuHzDeviation; cCpuHzOverallDevCnt++; } uint32_t uPct = (uint32_t)(uCpuHzDeviation * 100000 / uCpuHzRef + 5); RTStrPrintf(szCpuHzDeviation, sizeof(szCpuHzDeviation), "%10RI64%3d.%02d%% ", iCpuHzDeviation, uPct / 1000, (uPct % 1000) / 10); } } else szCpuHzDeviation[0] = '\0'; RTPrintf(fHex ? "tstGIP-2: %4d/%d: %016llx %09llx %016llx %08x %d %08x %15llu %s%08x %08x %08x %08x %08x %08x %08x %08x (%d)\n" : "tstGIP-2: %4d/%d: %016llu %09llu %016llu %010u %d %010u %15llu %s%08x %08x %08x %08x %08x %08x %08x %08x (%d)\n", i, iCpu, pCpu->u64NanoTS, i ? pCpu->u64NanoTS - pPrevCpu->u64NanoTS : 0, pCpu->u64TSC, pCpu->u32UpdateIntervalTSC, pCpu->iTSCHistoryHead, pCpu->u32TransactionId, pCpu->u64CpuHz, szCpuHzDeviation, pCpu->au32TSCHistory[0], pCpu->au32TSCHistory[1], pCpu->au32TSCHistory[2], pCpu->au32TSCHistory[3], pCpu->au32TSCHistory[4], pCpu->au32TSCHistory[5], pCpu->au32TSCHistory[6], pCpu->au32TSCHistory[7], pCpu->cErrors); if (!pu32TransactionId) { pu32TransactionId = &g_pSUPGlobalInfoPage->aCPUs[iCpu].u32TransactionId; u32TransactionId = pCpu->u32TransactionId; } } /* wait a bit / spin */ if (!fSpin) RTThreadSleep(9); else { if (pu32TransactionId) { uint32_t uTmp; while ( u32TransactionId == (uTmp = *pu32TransactionId) || (uTmp & 1)) ASMNopPause(); } else RTThreadSleep(1); } } /* * Display TSC deltas. * * First iterative over the APIC ID array to get mostly consistent CPUID to APIC ID mapping. * Then iterate over the offline CPUs. It is possible that there's a race between the online/offline * states between the two iterations, but that cannot be helped from ring-3 anyway and not a biggie. */ RTPrintf("tstGIP-2: TSC deltas:\n"); RTPrintf("tstGIP-2: idApic: i64TSCDelta\n"); for (unsigned i = 0; i < RT_ELEMENTS(g_pSUPGlobalInfoPage->aiCpuFromApicId); i++) { uint16_t iCpu = g_pSUPGlobalInfoPage->aiCpuFromApicId[i]; if (iCpu != UINT16_MAX) { RTPrintf("tstGIP-2: %7d: %lld\n", g_pSUPGlobalInfoPage->aCPUs[iCpu].idApic, g_pSUPGlobalInfoPage->aCPUs[iCpu].i64TSCDelta); } } for (unsigned iCpu = 0; iCpu < g_pSUPGlobalInfoPage->cCpus; iCpu++) if (g_pSUPGlobalInfoPage->aCPUs[iCpu].idApic == UINT16_MAX) RTPrintf("tstGIP-2: offline: %lld\n", g_pSUPGlobalInfoPage->aCPUs[iCpu].i64TSCDelta); RTPrintf("tstGIP-2: enmUseTscDelta=%d fGetGipCpu=%#x\n", g_pSUPGlobalInfoPage->enmUseTscDelta, g_pSUPGlobalInfoPage->fGetGipCpu); if ( uCpuHzRef && cCpuHzOverallDevCnt) { uint32_t uPct = (uint32_t)(uCpuHzOverallDeviation * 100000 / cCpuHzOverallDevCnt / uCpuHzRef + 5); RTPrintf("tstGIP-2: Average CpuHz deviation: %d.%02d%%\n", uPct / 1000, (uPct % 1000) / 10); uint32_t uMaxPct = (uint32_t)(RT_ABS(iCpuHzMaxDeviation) * 100000 / uCpuHzRef + 5); RTPrintf("tstGIP-2: Maximum CpuHz deviation: %d.%02d%% (%RI64 ticks)\n", uMaxPct / 1000, (uMaxPct % 1000) / 10, iCpuHzMaxDeviation); } } else { RTPrintf("tstGIP-2: g_pSUPGlobalInfoPage is NULL\n"); rc = -1; } SUPR3Term(false /*fForced*/); } else RTPrintf("tstGIP-2: SUPR3Init failed: %Rrc\n", rc); return !!rc; }
int main(int argc, char **argv) { int rc; int rcRet = 0; RTR3InitExe(argc, &argv, 0); rc = SUPR3Init(NULL); RTPrintf("tstContiguous: SUPR3Init -> rc=%Rrc\n", rc); rcRet += rc != 0; if (!rc) { /* * Allocate a bit of contiguous memory. */ RTHCPHYS HCPhys; void *pv = SUPR3ContAlloc(8, NIL_RTR0PTR, &HCPhys); rcRet += pv == NULL || HCPhys == 0; if (pv && HCPhys) { memset(pv, 0xff, PAGE_SIZE * 8); pv = SUPR3ContAlloc(5, NIL_RTR0PTR, &HCPhys); rcRet += pv == NULL || HCPhys == 0; if (pv && HCPhys) { memset(pv, 0x7f, PAGE_SIZE * 5); rc = SUPR3ContFree(pv, 5); rcRet += rc != 0; if (rc) RTPrintf("tstContiguous: SUPR3ContFree failed! rc=%Rrc\n", rc); void *apv[128]; for (unsigned i = 0; i < RT_ELEMENTS(apv); i++) { apv[i] = SUPR3ContAlloc(1 + (i % 11), NIL_RTR0PTR, &HCPhys); if (!apv[i]) { RTPrintf("tstContiguous: i=%d: failed to allocate %d pages\n", i, 1 + (i % 11)); rcRet++; } } for (unsigned i = 0; i < RT_ELEMENTS(apv); i++) if (apv[i]) { rc = SUPR3ContFree(apv[i], 1 + (i % 11)); rcRet += rc != 0; if (rc) RTPrintf("tstContiguous: i=%d SUPR3ContFree failed! rc=%Rrc\n", i, rc); } } else RTPrintf("tstContiguous: SUPR3ContAlloc (2nd) failed!\n"); } else RTPrintf("tstContiguous: SUPR3ContAlloc failed!\n"); rc = SUPR3Term(false /*fForced*/); RTPrintf("tstContiguous: SUPR3Term -> rc=%Rrc\n", rc); rcRet += rc != 0; } return rcRet ? 1 : 0; }