VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstVMM.cpp@ 68022

Last change on this file since 68022 was 68022, checked in by vboxsync, 7 years ago

TMCpuTickGetDeadlineAndTscOffset: build fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 14.4 KB
Line 
1/* $Id: tstVMM.cpp 68022 2017-07-18 13:18:58Z vboxsync $ */
2/** @file
3 * VMM Testcase.
4 */
5
6/*
7 * Copyright (C) 2006-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <VBox/vmm/vm.h>
23#include <VBox/vmm/vmm.h>
24#include <VBox/vmm/cpum.h>
25#include <VBox/vmm/tm.h>
26#include <VBox/vmm/pdmapi.h>
27#include <VBox/err.h>
28#include <VBox/log.h>
29#include <iprt/assert.h>
30#include <iprt/ctype.h>
31#include <iprt/getopt.h>
32#include <iprt/initterm.h>
33#include <iprt/message.h>
34#include <iprt/semaphore.h>
35#include <iprt/stream.h>
36#include <iprt/string.h>
37#include <iprt/test.h>
38#include <iprt/thread.h>
39
40#include <iprt/win/windows.h>
41
42
43/*********************************************************************************************************************************
44* Defined Constants And Macros *
45*********************************************************************************************************************************/
46#define TESTCASE "tstVMM"
47
48
49
50/*********************************************************************************************************************************
51* Global Variables *
52*********************************************************************************************************************************/
53static uint32_t g_cCpus = 1;
54static bool g_fStat = false; /* don't create log files on the testboxes */
55
56
57/*********************************************************************************************************************************
58* Internal Functions *
59*********************************************************************************************************************************/
60VMMR3DECL(int) VMMDoTest(PVM pVM); /* Linked into VMM, see ../VMMTests.cpp. */
61VMMR3DECL(int) VMMDoBruteForceMsrs(PVM pVM); /* Ditto. */
62VMMR3DECL(int) VMMDoKnownMsrs(PVM pVM); /* Ditto. */
63VMMR3DECL(int) VMMDoMsrExperiments(PVM pVM); /* Ditto. */
64
65
66/** Dummy timer callback. */
67static DECLCALLBACK(void) tstTMDummyCallback(PVM pVM, PTMTIMER pTimer, void *pvUser)
68{
69 NOREF(pVM);
70 NOREF(pTimer);
71 NOREF(pvUser);
72}
73
74
75/**
76 * This is called on each EMT and will beat TM.
77 *
78 * @returns VINF_SUCCESS, test failure is reported via RTTEST.
79 * @param pVM Pointer to the VM.
80 * @param hTest The test handle.
81 */
82DECLCALLBACK(int) tstTMWorker(PVM pVM, RTTEST hTest)
83{
84 VMCPUID idCpu = VMMGetCpuId(pVM);
85 RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "idCpu=%d STARTING\n", idCpu);
86
87 /*
88 * Create the test set.
89 */
90 int rc;
91 PTMTIMER apTimers[5];
92 for (size_t i = 0; i < RT_ELEMENTS(apTimers); i++)
93 {
94 rc = TMR3TimerCreateInternal(pVM, i & 1 ? TMCLOCK_VIRTUAL : TMCLOCK_VIRTUAL_SYNC,
95 tstTMDummyCallback, NULL, "test timer", &apTimers[i]);
96 RTTEST_CHECK_RET(hTest, RT_SUCCESS(rc), rc);
97 }
98
99 /*
100 * The run loop.
101 */
102 unsigned uPrevPct = 0;
103 uint32_t const cLoops = 100000;
104 for (uint32_t iLoop = 0; iLoop < cLoops; iLoop++)
105 {
106 size_t cLeft = RT_ELEMENTS(apTimers);
107 unsigned i = iLoop % RT_ELEMENTS(apTimers);
108 while (cLeft-- > 0)
109 {
110 PTMTIMER pTimer = apTimers[i];
111
112 if ( cLeft == RT_ELEMENTS(apTimers) / 2
113 && TMTimerIsActive(pTimer))
114 {
115 rc = TMTimerStop(pTimer);
116 RTTEST_CHECK_MSG(hTest, RT_SUCCESS(rc), (hTest, "TMTimerStop: %Rrc\n", rc));
117 }
118 else
119 {
120 rc = TMTimerSetMicro(pTimer, 50 + cLeft);
121 RTTEST_CHECK_MSG(hTest, RT_SUCCESS(rc), (hTest, "TMTimerSetMicro: %Rrc\n", rc));
122 }
123
124 /* next */
125 i = (i + 1) % RT_ELEMENTS(apTimers);
126 }
127
128 if (i % 3)
129 TMR3TimerQueuesDo(pVM);
130
131 /* Progress report. */
132 unsigned uPct = (unsigned)(100.0 * iLoop / cLoops);
133 if (uPct != uPrevPct)
134 {
135 uPrevPct = uPct;
136 if (!(uPct % 10))
137 RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "idCpu=%d - %3u%%\n", idCpu, uPct);
138 }
139 }
140
141 RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "idCpu=%d DONE\n", idCpu);
142 return 0;
143}
144
145
146/** PDMR3LdrEnumModules callback, see FNPDMR3ENUM. */
147static DECLCALLBACK(int)
148tstVMMLdrEnum(PVM pVM, const char *pszFilename, const char *pszName, RTUINTPTR ImageBase, size_t cbImage,
149 PDMLDRCTX enmCtx, void *pvUser)
150{
151 NOREF(pVM); NOREF(pszFilename); NOREF(enmCtx); NOREF(pvUser); NOREF(cbImage);
152 RTPrintf("tstVMM: %RTptr %s\n", ImageBase, pszName);
153 return VINF_SUCCESS;
154}
155
156static DECLCALLBACK(int)
157tstVMMConfigConstructor(PUVM pUVM, PVM pVM, void *pvUser)
158{
159 RT_NOREF2(pUVM, pvUser);
160 int rc = CFGMR3ConstructDefaultTree(pVM);
161 if (RT_SUCCESS(rc))
162 {
163 PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
164 if (g_cCpus < 2)
165 {
166 rc = CFGMR3InsertInteger(pRoot, "HMEnabled", false);
167 RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc),
168 ("CFGMR3InsertInteger(pRoot,\"HMEnabled\",) -> %Rrc\n", rc), rc);
169 }
170 else if (g_cCpus > 1)
171 {
172 CFGMR3RemoveValue(pRoot, "NumCPUs");
173 rc = CFGMR3InsertInteger(pRoot, "NumCPUs", g_cCpus);
174 RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc),
175 ("CFGMR3InsertInteger(pRoot,\"NumCPUs\",) -> %Rrc\n", rc), rc);
176
177 CFGMR3RemoveValue(pRoot, "HwVirtExtForced");
178 rc = CFGMR3InsertInteger(pRoot, "HwVirtExtForced", true);
179 RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc),
180 ("CFGMR3InsertInteger(pRoot,\"HwVirtExtForced\",) -> %Rrc\n", rc), rc);
181 PCFGMNODE pHwVirtExt = CFGMR3GetChild(pRoot, "HWVirtExt");
182 CFGMR3RemoveNode(pHwVirtExt);
183 rc = CFGMR3InsertNode(pRoot, "HWVirtExt", &pHwVirtExt);
184 RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc),
185 ("CFGMR3InsertNode(pRoot,\"HWVirtExt\",) -> %Rrc\n", rc), rc);
186 rc = CFGMR3InsertInteger(pHwVirtExt, "Enabled", true);
187 RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc),
188 ("CFGMR3InsertInteger(pHwVirtExt,\"Enabled\",) -> %Rrc\n", rc), rc);
189 rc = CFGMR3InsertInteger(pHwVirtExt, "64bitEnabled", false);
190 RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc),
191 ("CFGMR3InsertInteger(pHwVirtExt,\"64bitEnabled\",) -> %Rrc\n", rc), rc);
192 }
193 }
194 return rc;
195}
196
197
198/**
199 * Entry point.
200 */
201extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
202{
203 RT_NOREF1(envp);
204
205 /*
206 * Init runtime and the test environment.
207 */
208 RTTEST hTest;
209 RTEXITCODE rcExit = RTTestInitExAndCreate(argc, &argv, RTR3INIT_FLAGS_SUPLIB, "tstVMM", &hTest);
210 if (rcExit != RTEXITCODE_SUCCESS)
211 return rcExit;
212
213 /*
214 * Parse arguments.
215 */
216 static const RTGETOPTDEF s_aOptions[] =
217 {
218 { "--cpus", 'c', RTGETOPT_REQ_UINT8 },
219 { "--test", 't', RTGETOPT_REQ_STRING },
220 { "--stat", 's', RTGETOPT_REQ_NOTHING },
221 };
222 enum
223 {
224 kTstVMMTest_VMM, kTstVMMTest_TM, kTstVMMTest_MSRs, kTstVMMTest_KnownMSRs, kTstVMMTest_MSRExperiments
225 } enmTestOpt = kTstVMMTest_VMM;
226
227 int ch;
228 RTGETOPTUNION ValueUnion;
229 RTGETOPTSTATE GetState;
230 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
231 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
232 {
233 switch (ch)
234 {
235 case 'c':
236 g_cCpus = ValueUnion.u8;
237 break;
238
239 case 't':
240 if (!strcmp("vmm", ValueUnion.psz))
241 enmTestOpt = kTstVMMTest_VMM;
242 else if (!strcmp("tm", ValueUnion.psz))
243 enmTestOpt = kTstVMMTest_TM;
244 else if (!strcmp("msr", ValueUnion.psz) || !strcmp("msrs", ValueUnion.psz))
245 enmTestOpt = kTstVMMTest_MSRs;
246 else if (!strcmp("known-msr", ValueUnion.psz) || !strcmp("known-msrs", ValueUnion.psz))
247 enmTestOpt = kTstVMMTest_KnownMSRs;
248 else if (!strcmp("msr-experiments", ValueUnion.psz))
249 enmTestOpt = kTstVMMTest_MSRExperiments;
250 else
251 {
252 RTPrintf("tstVMM: unknown test: '%s'\n", ValueUnion.psz);
253 return 1;
254 }
255 break;
256
257 case 's':
258 g_fStat = true;
259 break;
260
261 case 'h':
262 RTPrintf("usage: tstVMM [--cpus|-c cpus] [-s] [--test <vmm|tm|msrs|known-msrs>]\n");
263 return 1;
264
265 case 'V':
266 RTPrintf("$Revision: 68022 $\n");
267 return 0;
268
269 default:
270 return RTGetOptPrintError(ch, &ValueUnion);
271 }
272 }
273
274#if 1
275 HMODULE hmod;
276 //SetLastError(0);
277 //hmod = LoadLibraryW(L"c:\\tmp\\testdir\\nodot");
278 //RTPrintf("c:\\tmp\\testdir\\nodot -> %p %#x\n", hmod, GetLastError());
279 //
280 //SetLastError(0);
281 //hmod = LoadLibraryW(L"c:\\tmp\\testdir\\trailingdot.");
282 //RTPrintf("c:\\tmp\\testdir\\trailingdot. -> %p %#x\n", hmod, GetLastError());
283
284 RTPrintf("\n=======>\n");
285 SetLastError(0);
286 hmod = LoadLibraryW(L"\\\\localhost\\c\\tmp\\VBoxRes.dll");
287 RTPrintf("\\\\localhost\\c\\tmp\\VBoxRes.dll -> %p %#x\n", hmod, GetLastError());
288
289 RTPrintf("\n=======>\n");
290 SetLastError(0);
291 hmod = LoadLibraryW(L"\\\\?\\UNC\\localhost\\c\\tmp\\VBoxRes.dll");
292 RTPrintf("\\\\?\\UNC\\localhost\\c\\tmp\\VBoxRes.dll -> %p %#x\n", hmod, GetLastError());
293
294#else
295
296 /*
297 * Create the test VM.
298 */
299 RTPrintf(TESTCASE ": Initializing...\n");
300 PVM pVM;
301 PUVM pUVM;
302 int rc = VMR3Create(g_cCpus, NULL, NULL, NULL, tstVMMConfigConstructor, NULL, &pVM, &pUVM);
303 if (RT_SUCCESS(rc))
304 {
305 PDMR3LdrEnumModules(pVM, tstVMMLdrEnum, NULL);
306 RTStrmFlush(g_pStdOut);
307 RTThreadSleep(256);
308
309 /*
310 * Do the requested testing.
311 */
312 switch (enmTestOpt)
313 {
314 case kTstVMMTest_VMM:
315 {
316 RTTestSub(hTest, "VMM");
317 rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)VMMDoTest, 1, pVM);
318 if (RT_FAILURE(rc))
319 RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc);
320 if (g_fStat)
321 STAMR3Dump(pUVM, "*");
322 break;
323 }
324
325 case kTstVMMTest_TM:
326 {
327 RTTestSub(hTest, "TM");
328 for (VMCPUID idCpu = 1; idCpu < g_cCpus; idCpu++)
329 {
330 rc = VMR3ReqCallNoWaitU(pUVM, idCpu, (PFNRT)tstTMWorker, 2, pVM, hTest);
331 if (RT_FAILURE(rc))
332 RTTestFailed(hTest, "VMR3ReqCall failed: rc=%Rrc\n", rc);
333 }
334
335 rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)tstTMWorker, 2, pVM, hTest);
336 if (RT_FAILURE(rc))
337 RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc);
338 if (g_fStat)
339 STAMR3Dump(pUVM, "*");
340 break;
341 }
342
343 case kTstVMMTest_MSRs:
344 {
345 RTTestSub(hTest, "MSRs");
346 if (g_cCpus == 1)
347 {
348 rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoBruteForceMsrs, 1, pVM);
349 if (RT_FAILURE(rc))
350 RTTestFailed(hTest, "VMMDoBruteForceMsrs failed: rc=%Rrc\n", rc);
351 }
352 else
353 RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n");
354 break;
355 }
356
357 case kTstVMMTest_KnownMSRs:
358 {
359 RTTestSub(hTest, "Known MSRs");
360 if (g_cCpus == 1)
361 {
362 rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoKnownMsrs, 1, pVM);
363 if (RT_FAILURE(rc))
364 RTTestFailed(hTest, "VMMDoKnownMsrs failed: rc=%Rrc\n", rc);
365 }
366 else
367 RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n");
368 break;
369 }
370
371 case kTstVMMTest_MSRExperiments:
372 {
373 RTTestSub(hTest, "MSR Experiments");
374 if (g_cCpus == 1)
375 {
376 rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoMsrExperiments, 1, pVM);
377 if (RT_FAILURE(rc))
378 RTTestFailed(hTest, "VMMDoMsrExperiments failed: rc=%Rrc\n", rc);
379 }
380 else
381 RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n");
382 break;
383 }
384
385 }
386
387 /*
388 * Cleanup.
389 */
390 rc = VMR3PowerOff(pUVM);
391 if (RT_FAILURE(rc))
392 RTTestFailed(hTest, "VMR3PowerOff failed: rc=%Rrc\n", rc);
393 rc = VMR3Destroy(pUVM);
394 if (RT_FAILURE(rc))
395 RTTestFailed(hTest, "VMR3Destroy failed: rc=%Rrc\n", rc);
396 VMR3ReleaseUVM(pUVM);
397 }
398 else
399 RTTestFailed(hTest, "VMR3Create failed: rc=%Rrc\n", rc);
400#endif
401 return RTTestSummaryAndDestroy(hTest);
402}
403
404
405#if !defined(VBOX_WITH_HARDENING) || !defined(RT_OS_WINDOWS)
406/**
407 * Main entry point.
408 */
409int main(int argc, char **argv, char **envp)
410{
411 return TrustedMain(argc, argv, envp);
412}
413#endif
414
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette