int main(int argc, char **argv) { int rcRet = 0; /* error count. */ RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB); /* * Doesn't work and I'm sick of rebooting the machine to try figure out * what the heck is going wrong. (Linux sucks at this) */ RTPrintf(TESTCASE ": This testcase hits a bunch of breakpoint assertions which\n" TESTCASE ": causes kernel panics on linux regardless of what\n" TESTCASE ": RTAssertDoBreakpoint returns. Only checked AMD-V on linux.\n"); /** @todo Make tstVMM-Hm to cause kernel panics. */ return 1; /* * Create empty VM. */ RTPrintf(TESTCASE ": Initializing...\n"); PVM pVM; PUVM pUVM; int rc = VMR3Create(1, NULL, NULL, NULL, tstVmmHmConfigConstructor, NULL, &pVM, &pUVM); if (RT_SUCCESS(rc)) { /* * Do testing. */ RTPrintf(TESTCASE ": Testing...\n"); rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)VMMDoHmTest, 1, pVM); AssertRC(rc); STAMR3Dump(pUVM, "*"); /* * Cleanup. */ rc = VMR3Destroy(pUVM); if (RT_FAILURE(rc)) { RTPrintf(TESTCASE ": error: failed to destroy vm! rc=%d\n", rc); rcRet++; } VMR3ReleaseUVM(pUVM); } else { RTPrintf(TESTCASE ": fatal error: failed to create vm! rc=%d\n", rc); rcRet++; } return rcRet; }
/** * Functions that tests passing a va_list * argument in a request, * similar to VMSetRuntimeError. */ static void PassVA(PUVM pUVM, const char *pszFormat, ...) { /* 1st test */ va_list va1; va_start(va1, pszFormat); int rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)PassVACallback, 5, pUVM, _4K, _1G, pszFormat, &va1); va_end(va1); NOREF(rc); /* 2nd test */ va_list va2; va_start(va2, pszFormat); PassVA2(pUVM, pszFormat, va2); va_end(va2); }
/** * Functions that tests passing a va_list * argument in a request, * similar to VMSetRuntimeError. */ static void PassVA2(PUVM pUVM, const char *pszFormat, va_list va) { #if 0 /** @todo test if this is a GCC problem only or also happens with AMD64+VCC80... */ void *pvVA = &va; #else va_list va2; va_copy(va2, va); void *pvVA = &va2; #endif int rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)PassVACallback, 5, pUVM, _4K, _1G, pszFormat, pvVA); NOREF(rc); #if 1 va_end(va2); #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[]) { int rcErrors = 0; /* * Initialize the runtime. */ RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB); #ifndef AUTO_TEST_ARGS if (argc < 2) { RTPrintf("syntax: %s command [args]\n" "\n" "command Command to run under child process in fork.\n" "[args] Arguments to command.\n", argv[0]); return 1; } #endif /* * Create empty VM. */ RTPrintf(TESTCASE ": Initializing...\n"); PVM pVM; PUVM pUVM; int rc = VMR3Create(1, NULL, NULL, NULL, NULL, NULL, &pVM, &pUVM); if (RT_SUCCESS(rc)) { /* * Do testing. */ int iCowTester = 0; char cCowTester = 'a'; #ifndef AUTO_TEST_ARGS int cArgs = argc - 1; char **ppszArgs = &argv[1]; #else int cArgs = 2; char *ppszArgs[3]; ppszArgs[0] = (char *)"/bin/sleep"; ppszArgs[1] = (char *)"3"; ppszArgs[2] = NULL; #endif RTPrintf(TESTCASE ": forking current process...\n"); pid_t pid = fork(); if (pid < 0) { /* Bad. fork() failed! */ RTPrintf(TESTCASE ": error: fork() failed.\n"); rcErrors++; } else if (pid == 0) { /* * The child process. * Write to some local variables to trigger copy-on-write if it's used. */ RTPrintf(TESTCASE ": running child process...\n"); RTPrintf(TESTCASE ": writing local variables...\n"); iCowTester = 2; cCowTester = 'z'; RTPrintf(TESTCASE ": calling execv() with command-line:\n"); for (int i = 0; i < cArgs; i++) RTPrintf(TESTCASE ": ppszArgs[%d]=%s\n", i, ppszArgs[i]); execv(ppszArgs[0], ppszArgs); RTPrintf(TESTCASE ": error: execv() returned to caller. errno=%d.\n", errno); _exit(-1); } else { /* * The parent process. * Wait for child & run VMM test to ensure things are fine. */ int result; while (waitpid(pid, &result, 0) < 0) ; if (!WIFEXITED(result) || WEXITSTATUS(result) != 0) { RTPrintf(TESTCASE ": error: failed to run child process. errno=%d\n", errno); rcErrors++; } if (rcErrors == 0) { RTPrintf(TESTCASE ": fork() returned fine.\n"); RTPrintf(TESTCASE ": testing VM after fork.\n"); VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)VMMDoTest, 1, pVM); STAMR3Dump(pUVM, "*"); } } if (rcErrors > 0) RTPrintf(TESTCASE ": error: %d error(s) during fork(). Cannot proceed to test the VM.\n", rcErrors); else RTPrintf(TESTCASE ": fork() and VM test, SUCCESS.\n"); /* * Cleanup. */ rc = VMR3PowerOff(pUVM); if (!RT_SUCCESS(rc)) { RTPrintf(TESTCASE ": error: failed to power off vm! rc=%Rrc\n", rc); rcErrors++; } rc = VMR3Destroy(pUVM); if (!RT_SUCCESS(rc)) { RTPrintf(TESTCASE ": error: failed to destroy vm! rc=%Rrc\n", rc); rcErrors++; } VMR3ReleaseUVM(pUVM); } else { RTPrintf(TESTCASE ": fatal error: failed to create vm! rc=%Rrc\n", rc); rcErrors++; } return rcErrors; }
/** * Entry point. */ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp) { int rcRet = 1; int rc; RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB); /* * Parse input. */ if (argc <= 1) { syntax(); return 1; } bool fPowerOn = false; uint32_t u32WarpDrive = 100; /* % */ uint64_t cbMem = ~0ULL; const char *pszSavedState = NULL; const char *pszRawMem = NULL; uint64_t offRawMem = 0; const char *pszScript = NULL; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { /* check that it's on short form */ if (argv[i][2]) { if ( strcmp(argv[i], "--help") && strcmp(argv[i], "-help")) RTPrintf("tstAnimate: Syntax error: Unknown argument '%s'.\n", argv[i]); else syntax(); return 1; } /* check for 2nd argument */ switch (argv[i][1]) { case 'r': case 'o': case 'c': case 'm': case 'w': case 'z': if (i + 1 < argc) break; RTPrintf("tstAnimate: Syntax error: '%s' takes a 2nd argument.\n", argv[i]); return 1; } /* process argument */ switch (argv[i][1]) { case 'r': pszRawMem = argv[++i]; break; case 'z': pszSavedState = argv[++i]; break; case 'o': { rc = RTStrToUInt64Ex(argv[++i], NULL, 0, &offRawMem); if (RT_FAILURE(rc)) { RTPrintf("tstAnimate: Syntax error: Invalid offset given to -o.\n"); return 1; } break; } case 'm': { char *pszNext; rc = RTStrToUInt64Ex(argv[++i], &pszNext, 0, &cbMem); if (RT_FAILURE(rc)) { RTPrintf("tstAnimate: Syntax error: Invalid memory size given to -m.\n"); return 1; } switch (*pszNext) { case 'G': cbMem *= _1G; pszNext++; break; case 'M': cbMem *= _1M; pszNext++; break; case 'K': cbMem *= _1K; pszNext++; break; case '\0': break; default: RTPrintf("tstAnimate: Syntax error: Invalid memory size given to -m.\n"); return 1; } if (*pszNext) { RTPrintf("tstAnimate: Syntax error: Invalid memory size given to -m.\n"); return 1; } break; } case 's': pszScript = argv[++i]; break; case 'p': fPowerOn = true; break; case 'w': { rc = RTStrToUInt32Ex(argv[++i], NULL, 0, &u32WarpDrive); if (RT_FAILURE(rc)) { RTPrintf("tstAnimate: Syntax error: Invalid number given to -w.\n"); return 1; } break; } case 'h': case 'H': case '?': syntax(); return 1; default: RTPrintf("tstAnimate: Syntax error: Unknown argument '%s'.\n", argv[i]); return 1; } } else { RTPrintf("tstAnimate: Syntax error at arg no. %d '%s'.\n", i, argv[i]); syntax(); return 1; } } /* * Check that the basic requirements are met. */ if (pszRawMem && pszSavedState) { RTPrintf("tstAnimate: Syntax error: Either -z or -r, not both.\n"); return 1; } if (!pszRawMem && !pszSavedState) { RTPrintf("tstAnimate: Syntax error: The -r argument is compulsory.\n"); return 1; } /* * Open the files. */ RTFILE FileRawMem = NIL_RTFILE; if (pszRawMem) { rc = RTFileOpen(&FileRawMem, pszRawMem, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); if (RT_FAILURE(rc)) { RTPrintf("tstAnimate: error: Failed to open '%s': %Rrc\n", pszRawMem, rc); return 1; } } RTFILE FileScript = NIL_RTFILE; if (pszScript) { rc = RTFileOpen(&FileScript, pszScript, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); if (RT_FAILURE(rc)) { RTPrintf("tstAnimate: error: Failed to open '%s': %Rrc\n", pszScript, rc); return 1; } } /* * Figure the memsize if not specified. */ if (cbMem == ~0ULL) { if (FileRawMem != NIL_RTFILE) { rc = RTFileGetSize(FileRawMem, &cbMem); AssertReleaseRC(rc); cbMem -= offRawMem; cbMem &= ~(PAGE_SIZE - 1); } else { RTPrintf("tstAnimate: error: too lazy to figure out the memsize in a saved state.\n"); return 1; } } RTPrintf("tstAnimate: info: cbMem=0x%llx bytes\n", cbMem); /* * Open a release log. */ static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; PRTLOGGER pRelLogger; rc = RTLogCreate(&pRelLogger, RTLOGFLAGS_PREFIX_TIME_PROG, "all", "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_FILE, "./tstAnimate.log"); if (RT_SUCCESS(rc)) RTLogRelSetDefaultInstance(pRelLogger); else RTPrintf("tstAnimate: rtLogCreateEx failed - %Rrc\n", rc); /* * Create empty VM. */ PVM pVM; PUVM pUVM; rc = VMR3Create(1, NULL, NULL, NULL, cfgmR3CreateDefault, &cbMem, &pVM, &pUVM); if (RT_SUCCESS(rc)) { /* * Load memory. */ if (FileRawMem != NIL_RTFILE) rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)loadMem, 3, pVM, FileRawMem, &offRawMem); else rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)SSMR3Load, 7, pVM, pszSavedState, (uintptr_t)NULL /*pStreamOps*/, (uintptr_t)NULL /*pvUser*/, SSMAFTER_DEBUG_IT, (uintptr_t)NULL /*pfnProgress*/, (uintptr_t)NULL /*pvProgressUser*/); if (RT_SUCCESS(rc)) { /* * Load register script. */ if (FileScript != NIL_RTFILE) rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)scriptRun, 2, pVM, FileScript); if (RT_SUCCESS(rc)) { if (fPowerOn) { /* * Adjust warpspeed? */ if (u32WarpDrive != 100) { rc = TMR3SetWarpDrive(pUVM, u32WarpDrive); if (RT_FAILURE(rc)) RTPrintf("warning: TMVirtualSetWarpDrive(,%u) -> %Rrc\n", u32WarpDrive, rc); } /* * Start the thing with single stepping and stuff enabled. * (Try make sure we don't execute anything in raw mode.) */ RTPrintf("info: powering on the VM...\n"); RTLogGroupSettings(NULL, "+REM_DISAS.e.l.f"); #ifdef VBOX_WITH_REM rc = REMR3DisasEnableStepping(pVM, true); #else rc = VERR_NOT_IMPLEMENTED; /** @todo need some EM single-step indicator */ #endif if (RT_SUCCESS(rc)) { rc = EMR3SetExecutionPolicy(pUVM, EMEXECPOLICY_RECOMPILE_RING0, true); AssertReleaseRC(rc); rc = EMR3SetExecutionPolicy(pUVM, EMEXECPOLICY_RECOMPILE_RING3, true); AssertReleaseRC(rc); DBGFR3Info(pUVM, "cpumguest", "verbose", NULL); if (fPowerOn) rc = VMR3PowerOn(pUVM); if (RT_SUCCESS(rc)) { RTPrintf("info: VM is running\n"); signal(SIGINT, SigInterrupt); while (!g_fSignaled) RTThreadSleep(1000); } else RTPrintf("error: Failed to power on the VM: %Rrc\n", rc); } else RTPrintf("error: Failed to enabled singlestepping: %Rrc\n", rc); } else { /* * Don't start it, just enter the debugger. */ RTPrintf("info: entering debugger...\n"); DBGFR3Info(pUVM, "cpumguest", "verbose", NULL); signal(SIGINT, SigInterrupt); while (!g_fSignaled) RTThreadSleep(1000); } RTPrintf("info: shutting down the VM...\n"); } /* execScript complains */ } else if (FileRawMem == NIL_RTFILE) /* loadMem complains, SSMR3Load doesn't */ RTPrintf("tstAnimate: error: SSMR3Load failed: rc=%Rrc\n", rc); rcRet = RT_SUCCESS(rc) ? 0 : 1; /* * Cleanup. */ rc = VMR3Destroy(pUVM); if (!RT_SUCCESS(rc)) { RTPrintf("tstAnimate: error: failed to destroy vm! rc=%Rrc\n", rc); rcRet++; } VMR3ReleaseUVM(pUVM); } else { RTPrintf("tstAnimate: fatal error: failed to create vm! rc=%Rrc\n", rc); rcRet++; } return rcRet; }