/** * Lazily populates the specified address space. * * @param pUVM The user mode VM handle. * @param hAlias The alias. */ static void dbgfR3AsLazyPopulate(PUVM pUVM, RTDBGAS hAlias) { DBGF_AS_DB_LOCK_WRITE(pUVM); uintptr_t iAlias = DBGF_AS_ALIAS_2_INDEX(hAlias); if (!pUVM->dbgf.s.afAsAliasPopuplated[iAlias]) { RTDBGAS hDbgAs = pUVM->dbgf.s.ahAsAliases[iAlias]; if (hAlias == DBGF_AS_R0 && pUVM->pVM) PDMR3LdrEnumModules(pUVM->pVM, dbgfR3AsLazyPopulateR0Callback, hDbgAs); else if (hAlias == DBGF_AS_RC && pUVM->pVM && !HMIsEnabled(pUVM->pVM)) { LogRel(("DBGF: Lazy init of RC address space\n")); PDMR3LdrEnumModules(pUVM->pVM, dbgfR3AsLazyPopulateRCCallback, hDbgAs); #ifdef VBOX_WITH_RAW_MODE PATMR3DbgPopulateAddrSpace(pUVM->pVM, hDbgAs); #endif } else if (hAlias == DBGF_AS_PHYS && pUVM->pVM) { /** @todo Lazy load pc and vga bios symbols or the EFI stuff. */ } pUVM->dbgf.s.afAsAliasPopuplated[iAlias] = true; } DBGF_AS_DB_UNLOCK_WRITE(pUVM); }
/** * Lazily populates the specified address space. * * @param pUVM The user mode VM handle. * @param hAlias The alias. */ static void dbgfR3AsLazyPopulate(PUVM pUVM, RTDBGAS hAlias) { DBGF_AS_DB_LOCK_WRITE(pUVM); uintptr_t iAlias = DBGF_AS_ALIAS_2_INDEX(hAlias); if (!pUVM->dbgf.s.afAsAliasPopuplated[iAlias]) { RTDBGAS hAs = pUVM->dbgf.s.ahAsAliases[iAlias]; if (hAlias == DBGF_AS_R0 && pUVM->pVM) PDMR3LdrEnumModules(pUVM->pVM, dbgfR3AsLazyPopulateR0Callback, hAs); /** @todo what do we do about DBGF_AS_RC? */ pUVM->dbgf.s.afAsAliasPopuplated[iAlias] = true; } DBGF_AS_DB_UNLOCK_WRITE(pUVM); }
/** * We delay certain * Initialize the debug info for a VM. */ int dbgfR3SymLazyInit(PVM pVM) { if (pVM->dbgf.s.fSymInited) return VINF_SUCCESS; #ifdef HAVE_DBGHELP if (SymInitialize(pVM, NULL, FALSE)) { pVM->dbgf.s.fSymInited = true; SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_AUTO_PUBLICS | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS); /* * Enumerate all modules loaded by PDM and add them to the symbol database. */ PDMR3LdrEnumModules(pVM, dbgfR3EnumModules, NULL); return VINF_SUCCESS; } return win32Error(pVM); #else return VINF_SUCCESS; #endif }
/** * Entry point. */ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp) { RT_NOREF1(envp); /* * Init runtime and the test environment. */ RTTEST hTest; RTEXITCODE rcExit = RTTestInitExAndCreate(argc, &argv, RTR3INIT_FLAGS_SUPLIB, "tstVMM", &hTest); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; /* * Parse arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--cpus", 'c', RTGETOPT_REQ_UINT8 }, { "--test", 't', RTGETOPT_REQ_STRING }, { "--stat", 's', RTGETOPT_REQ_NOTHING }, }; enum { kTstVMMTest_VMM, kTstVMMTest_TM, kTstVMMTest_MSRs, kTstVMMTest_KnownMSRs, kTstVMMTest_MSRExperiments } enmTestOpt = kTstVMMTest_VMM; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'c': g_cCpus = ValueUnion.u8; break; case 't': if (!strcmp("vmm", ValueUnion.psz)) enmTestOpt = kTstVMMTest_VMM; else if (!strcmp("tm", ValueUnion.psz)) enmTestOpt = kTstVMMTest_TM; else if (!strcmp("msr", ValueUnion.psz) || !strcmp("msrs", ValueUnion.psz)) enmTestOpt = kTstVMMTest_MSRs; else if (!strcmp("known-msr", ValueUnion.psz) || !strcmp("known-msrs", ValueUnion.psz)) enmTestOpt = kTstVMMTest_KnownMSRs; else if (!strcmp("msr-experiments", ValueUnion.psz)) enmTestOpt = kTstVMMTest_MSRExperiments; else { RTPrintf("tstVMM: unknown test: '%s'\n", ValueUnion.psz); return 1; } break; case 's': g_fStat = true; break; case 'h': RTPrintf("usage: tstVMM [--cpus|-c cpus] [-s] [--test <vmm|tm|msrs|known-msrs>]\n"); return 1; case 'V': RTPrintf("$Revision$\n"); return 0; default: return RTGetOptPrintError(ch, &ValueUnion); } } /* * Create the test VM. */ RTPrintf(TESTCASE ": Initializing...\n"); PVM pVM; PUVM pUVM; int rc = VMR3Create(g_cCpus, NULL, NULL, NULL, tstVMMConfigConstructor, NULL, &pVM, &pUVM); if (RT_SUCCESS(rc)) { PDMR3LdrEnumModules(pVM, tstVMMLdrEnum, NULL); RTStrmFlush(g_pStdOut); RTThreadSleep(256); /* * Do the requested testing. */ switch (enmTestOpt) { case kTstVMMTest_VMM: { RTTestSub(hTest, "VMM"); rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)VMMDoTest, 1, pVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc); if (g_fStat) STAMR3Dump(pUVM, "*"); break; } case kTstVMMTest_TM: { RTTestSub(hTest, "TM"); for (VMCPUID idCpu = 1; idCpu < g_cCpus; idCpu++) { rc = VMR3ReqCallNoWaitU(pUVM, idCpu, (PFNRT)tstTMWorker, 2, pVM, hTest); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMR3ReqCall failed: rc=%Rrc\n", rc); } rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)tstTMWorker, 2, pVM, hTest); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc); if (g_fStat) STAMR3Dump(pUVM, "*"); break; } case kTstVMMTest_MSRs: { RTTestSub(hTest, "MSRs"); if (g_cCpus == 1) { rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoBruteForceMsrs, 1, pVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoBruteForceMsrs failed: rc=%Rrc\n", rc); } else RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n"); break; } case kTstVMMTest_KnownMSRs: { RTTestSub(hTest, "Known MSRs"); if (g_cCpus == 1) { rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoKnownMsrs, 1, pVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoKnownMsrs failed: rc=%Rrc\n", rc); } else RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n"); break; } case kTstVMMTest_MSRExperiments: { RTTestSub(hTest, "MSR Experiments"); if (g_cCpus == 1) { rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoMsrExperiments, 1, pVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoMsrExperiments failed: rc=%Rrc\n", rc); } else RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n"); break; } } /* * Cleanup. */ rc = VMR3PowerOff(pUVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMR3PowerOff failed: rc=%Rrc\n", rc); rc = VMR3Destroy(pUVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMR3Destroy failed: rc=%Rrc\n", rc); VMR3ReleaseUVM(pUVM); } else RTTestFailed(hTest, "VMR3Create failed: rc=%Rrc\n", rc); return RTTestSummaryAndDestroy(hTest); }
int main(int argc, char **argv) { /* * Init runtime and the test environment. */ int rc = RTR3InitAndSUPLib(); if (RT_FAILURE(rc)) { RTPrintf("tstVMM: RTR3InitAndSUPLib failed: %Rrc\n", rc); return 1; } RTTEST hTest; rc = RTTestCreate("tstVMM", &hTest); if (RT_FAILURE(rc)) { RTPrintf("tstVMM: RTTestCreate failed: %Rrc\n", rc); return 1; } /* * Parse arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--cpus", 'c', RTGETOPT_REQ_UINT8 }, { "--test", 't', RTGETOPT_REQ_STRING }, }; enum { kTstVMMTest_VMM, kTstVMMTest_TM } enmTestOpt = kTstVMMTest_VMM; int ch; int i = 1; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'c': g_cCpus = ValueUnion.u8; break; case 't': if (!strcmp("vmm", ValueUnion.psz)) enmTestOpt = kTstVMMTest_VMM; else if (!strcmp("tm", ValueUnion.psz)) enmTestOpt = kTstVMMTest_TM; else { RTPrintf("tstVMM: unknown test: '%s'\n", ValueUnion.psz); return 1; } break; case 'h': RTPrintf("usage: tstVMM [--cpus|-c cpus] [--test <vmm|tm>]\n"); return 1; case 'V': RTPrintf("$Revision: $\n"); return 0; default: return RTGetOptPrintError(ch, &ValueUnion); } } /* * Create the test VM. */ RTPrintf(TESTCASE ": Initializing...\n"); PVM pVM; rc = VMR3Create(g_cCpus, NULL, NULL, NULL, tstVMMConfigConstructor, NULL, &pVM); if (RT_SUCCESS(rc)) { PDMR3LdrEnumModules(pVM, tstVMMLdrEnum, NULL); RTStrmFlush(g_pStdOut); RTThreadSleep(256); /* * Do the requested testing. */ switch (enmTestOpt) { case kTstVMMTest_VMM: { RTTestSub(hTest, "VMM"); rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)VMMDoTest, 1, pVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc); break; } case kTstVMMTest_TM: { RTTestSub(hTest, "TM"); for (VMCPUID idCpu = 1; idCpu < g_cCpus; idCpu++) { rc = VMR3ReqCallNoWait(pVM, idCpu, (PFNRT)tstTMWorker, 2, pVM, hTest); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMR3ReqCall failed: rc=%Rrc\n", rc); } rc = VMR3ReqCallWait(pVM, 0 /*idDstCpu*/, (PFNRT)tstTMWorker, 2, pVM, hTest); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc); break; } } STAMR3Dump(pVM, "*"); /* * Cleanup. */ rc = VMR3PowerOff(pVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMR3PowerOff failed: rc=%Rrc\n", rc); rc = VMR3Destroy(pVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMR3Destroy failed: rc=%Rrc\n", rc); } else RTTestFailed(hTest, "VMR3Create failed: rc=%Rrc\n", rc); return RTTestSummaryAndDestroy(hTest); }