VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstSSM.cpp@ 77922

Last change on this file since 77922 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 26.0 KB
Line 
1/* $Id: tstSSM.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * Saved State Manager Testcase.
4 */
5
6/*
7 * Copyright (C) 2006-2019 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/ssm.h>
23#include "VMInternal.h" /* createFakeVM */
24#include <VBox/vmm/vm.h>
25#include <VBox/vmm/uvm.h>
26#include <VBox/vmm/mm.h>
27#include <VBox/vmm/stam.h>
28
29#include <VBox/log.h>
30#include <VBox/sup.h>
31#include <VBox/err.h>
32#include <VBox/param.h>
33#include <iprt/assert.h>
34#include <iprt/file.h>
35#include <iprt/initterm.h>
36#include <iprt/mem.h>
37#include <iprt/stream.h>
38#include <iprt/string.h>
39#include <iprt/time.h>
40#include <iprt/thread.h>
41#include <iprt/path.h>
42
43
44/*********************************************************************************************************************************
45* Defined Constants And Macros *
46*********************************************************************************************************************************/
47#define TSTSSM_BIG_CONFIG 1
48
49#ifdef TSTSSM_BIG_CONFIG
50# define TSTSSM_ITEM_SIZE (512*_1M)
51#else
52# define TSTSSM_ITEM_SIZE (5*_1M)
53#endif
54
55
56/*********************************************************************************************************************************
57* Global Variables *
58*********************************************************************************************************************************/
59const uint8_t gabPage[PAGE_SIZE] = {0};
60const char gachMem1[] = "sdfg\1asdfa\177hjkl;sdfghjkl;dfghjkl;dfghjkl;\0\0asdf;kjasdf;lkjasd;flkjasd;lfkjasd\0;lfk";
61#ifdef TSTSSM_BIG_CONFIG
62uint8_t gabBigMem[_1M];
63#else
64uint8_t gabBigMem[8*_1M];
65#endif
66
67
68/** initializes gabBigMem with some non zero stuff. */
69void initBigMem(void)
70{
71#if 0
72 uint32_t *puch = (uint32_t *)&gabBigMem[0];
73 uint32_t *puchEnd = (uint32_t *)&gabBigMem[sizeof(gabBigMem)];
74 uint32_t u32 = 0xdeadbeef;
75 for (; puch < puchEnd; puch++)
76 {
77 *puch = u32;
78 u32 += 19;
79 u32 = (u32 << 1) | (u32 >> 31);
80 }
81#else
82 uint8_t *pb = &gabBigMem[0];
83 uint8_t *pbEnd = &gabBigMem[sizeof(gabBigMem)];
84 for (; pb < pbEnd; pb += 16)
85 {
86 char szTmp[17];
87 RTStrPrintf(szTmp, sizeof(szTmp), "aaaa%08Xzzzz", (uint32_t)(uintptr_t)pb);
88 memcpy(pb, szTmp, 16);
89 }
90
91 /* add some zero pages */
92 memset(&gabBigMem[sizeof(gabBigMem) / 4], 0, PAGE_SIZE * 4);
93 memset(&gabBigMem[sizeof(gabBigMem) / 4 * 3], 0, PAGE_SIZE * 4);
94#endif
95}
96
97/**
98 * Execute state save operation.
99 *
100 * @returns VBox status code.
101 * @param pVM The cross context VM handle.
102 * @param pSSM SSM operation handle.
103 */
104DECLCALLBACK(int) Item01Save(PVM pVM, PSSMHANDLE pSSM)
105{
106 uint64_t u64Start = RTTimeNanoTS();
107 NOREF(pVM);
108
109 /*
110 * Test writing some memory block.
111 */
112 int rc = SSMR3PutMem(pSSM, gachMem1, sizeof(gachMem1));
113 if (RT_FAILURE(rc))
114 {
115 RTPrintf("Item01: #1 - SSMR3PutMem -> %Rrc\n", rc);
116 return rc;
117 }
118
119 /*
120 * Test writing a zeroterminated string.
121 */
122 rc = SSMR3PutStrZ(pSSM, "String");
123 if (RT_FAILURE(rc))
124 {
125 RTPrintf("Item01: #1 - SSMR3PutMem -> %Rrc\n", rc);
126 return rc;
127 }
128
129
130 /*
131 * Test the individual integer put functions to see that they all work.
132 * (Testcases are also known as "The Land of The Ugly Code"...)
133 */
134#define ITEM(suff,bits, val) \
135 rc = SSMR3Put##suff(pSSM, val); \
136 if (RT_FAILURE(rc)) \
137 { \
138 RTPrintf("Item01: #" #suff " - SSMR3Put" #suff "(," #val ") -> %Rrc\n", rc); \
139 return rc; \
140 }
141 /* copy & past with the load one! */
142 ITEM(U8, uint8_t, 0xff);
143 ITEM(U8, uint8_t, 0x0);
144 ITEM(U8, uint8_t, 1);
145 ITEM(U8, uint8_t, 42);
146 ITEM(U8, uint8_t, 230);
147 ITEM(S8, int8_t, -128);
148 ITEM(S8, int8_t, 127);
149 ITEM(S8, int8_t, 12);
150 ITEM(S8, int8_t, -76);
151 ITEM(U16, uint16_t, 0xffff);
152 ITEM(U16, uint16_t, 0x0);
153 ITEM(S16, int16_t, 32767);
154 ITEM(S16, int16_t, -32768);
155 ITEM(U32, uint32_t, 4294967295U);
156 ITEM(U32, uint32_t, 0);
157 ITEM(U32, uint32_t, 42);
158 ITEM(U32, uint32_t, 2342342344U);
159 ITEM(S32, int32_t, -2147483647-1);
160 ITEM(S32, int32_t, 2147483647);
161 ITEM(S32, int32_t, 42);
162 ITEM(S32, int32_t, 568459834);
163 ITEM(S32, int32_t, -58758999);
164 ITEM(U64, uint64_t, 18446744073709551615ULL);
165 ITEM(U64, uint64_t, 0);
166 ITEM(U64, uint64_t, 42);
167 ITEM(U64, uint64_t, 593023944758394234ULL);
168 ITEM(S64, int64_t, 9223372036854775807LL);
169 ITEM(S64, int64_t, -9223372036854775807LL - 1);
170 ITEM(S64, int64_t, 42);
171 ITEM(S64, int64_t, 21398723459873LL);
172 ITEM(S64, int64_t, -5848594593453453245LL);
173#undef ITEM
174
175 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
176 RTPrintf("tstSSM: Saved 1st item in %'RI64 ns\n", u64Elapsed);
177 return 0;
178}
179
180/**
181 * Prepare state load operation.
182 *
183 * @returns VBox status code.
184 * @param pVM The cross context VM handle.
185 * @param pSSM SSM operation handle.
186 * @param uVersion The data layout version.
187 * @param uPass The data pass.
188 */
189DECLCALLBACK(int) Item01Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
190{
191 NOREF(pVM); NOREF(uPass);
192 if (uVersion != 0)
193 {
194 RTPrintf("Item01: uVersion=%#x, expected 0\n", uVersion);
195 return VERR_GENERAL_FAILURE;
196 }
197
198 /*
199 * Load the memory block.
200 */
201 char achTmp[sizeof(gachMem1)];
202 int rc = SSMR3GetMem(pSSM, achTmp, sizeof(gachMem1));
203 if (RT_FAILURE(rc))
204 {
205 RTPrintf("Item01: #1 - SSMR3GetMem -> %Rrc\n", rc);
206 return rc;
207 }
208
209 /*
210 * Load the string.
211 */
212 rc = SSMR3GetStrZ(pSSM, achTmp, sizeof(achTmp));
213 if (RT_FAILURE(rc))
214 {
215 RTPrintf("Item01: #2 - SSMR3GetStrZ -> %Rrc\n", rc);
216 return rc;
217 }
218
219 /*
220 * Test the individual integer put functions to see that they all work.
221 * (Testcases are also known as "The Land of The Ugly Code"...)
222 */
223#define ITEM(suff, type, val) \
224 do { \
225 type var = {0}; \
226 rc = SSMR3Get##suff(pSSM, &var); \
227 if (RT_FAILURE(rc)) \
228 { \
229 RTPrintf("Item01: #" #suff " - SSMR3Get" #suff "(," #val ") -> %Rrc\n", rc); \
230 return rc; \
231 } \
232 if (var != val) \
233 { \
234 RTPrintf("Item01: #" #suff " - SSMR3Get" #suff "(," #val ") -> %d returned wrong value!\n", rc); \
235 return VERR_GENERAL_FAILURE; \
236 } \
237 } while (0)
238 /* copy & past with the load one! */
239 ITEM(U8, uint8_t, 0xff);
240 ITEM(U8, uint8_t, 0x0);
241 ITEM(U8, uint8_t, 1);
242 ITEM(U8, uint8_t, 42);
243 ITEM(U8, uint8_t, 230);
244 ITEM(S8, int8_t, -128);
245 ITEM(S8, int8_t, 127);
246 ITEM(S8, int8_t, 12);
247 ITEM(S8, int8_t, -76);
248 ITEM(U16, uint16_t, 0xffff);
249 ITEM(U16, uint16_t, 0x0);
250 ITEM(S16, int16_t, 32767);
251 ITEM(S16, int16_t, -32768);
252 ITEM(U32, uint32_t, 4294967295U);
253 ITEM(U32, uint32_t, 0);
254 ITEM(U32, uint32_t, 42);
255 ITEM(U32, uint32_t, 2342342344U);
256 ITEM(S32, int32_t, -2147483647-1);
257 ITEM(S32, int32_t, 2147483647);
258 ITEM(S32, int32_t, 42);
259 ITEM(S32, int32_t, 568459834);
260 ITEM(S32, int32_t, -58758999);
261 ITEM(U64, uint64_t, 18446744073709551615ULL);
262 ITEM(U64, uint64_t, 0);
263 ITEM(U64, uint64_t, 42);
264 ITEM(U64, uint64_t, 593023944758394234ULL);
265 ITEM(S64, int64_t, 9223372036854775807LL);
266 ITEM(S64, int64_t, -9223372036854775807LL - 1);
267 ITEM(S64, int64_t, 42);
268 ITEM(S64, int64_t, 21398723459873LL);
269 ITEM(S64, int64_t, -5848594593453453245LL);
270#undef ITEM
271
272 return 0;
273}
274
275
276/**
277 * Execute state save operation.
278 *
279 * @returns VBox status code.
280 * @param pVM The cross context VM handle.
281 * @param pSSM SSM operation handle.
282 */
283DECLCALLBACK(int) Item02Save(PVM pVM, PSSMHANDLE pSSM)
284{
285 NOREF(pVM);
286 uint64_t u64Start = RTTimeNanoTS();
287
288 /*
289 * Put the size.
290 */
291 uint32_t cb = sizeof(gabBigMem);
292 int rc = SSMR3PutU32(pSSM, cb);
293 if (RT_FAILURE(rc))
294 {
295 RTPrintf("Item02: PutU32 -> %Rrc\n", rc);
296 return rc;
297 }
298
299 /*
300 * Put 8MB of memory to the file in 3 chunks.
301 */
302 uint8_t *pbMem = &gabBigMem[0];
303 uint32_t cbChunk = cb / 47;
304 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
305 if (RT_FAILURE(rc))
306 {
307 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
308 return rc;
309 }
310 cb -= cbChunk;
311 pbMem += cbChunk;
312
313 /* next piece. */
314 cbChunk *= 19;
315 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
316 if (RT_FAILURE(rc))
317 {
318 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
319 return rc;
320 }
321 cb -= cbChunk;
322 pbMem += cbChunk;
323
324 /* last piece. */
325 cbChunk = cb;
326 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
327 if (RT_FAILURE(rc))
328 {
329 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
330 return rc;
331 }
332
333 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
334 RTPrintf("tstSSM: Saved 2nd item in %'RI64 ns\n", u64Elapsed);
335 return 0;
336}
337
338/**
339 * Prepare state load operation.
340 *
341 * @returns VBox status code.
342 * @param pVM The cross context VM handle.
343 * @param pSSM SSM operation handle.
344 * @param uVersion The data layout version.
345 * @param uPass The data pass.
346 */
347DECLCALLBACK(int) Item02Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
348{
349 NOREF(pVM); NOREF(uPass);
350 if (uVersion != 0)
351 {
352 RTPrintf("Item02: uVersion=%#x, expected 0\n", uVersion);
353 return VERR_GENERAL_FAILURE;
354 }
355
356 /*
357 * Load the size.
358 */
359 uint32_t cb;
360 int rc = SSMR3GetU32(pSSM, &cb);
361 if (RT_FAILURE(rc))
362 {
363 RTPrintf("Item02: SSMR3GetU32 -> %Rrc\n", rc);
364 return rc;
365 }
366 if (cb != sizeof(gabBigMem))
367 {
368 RTPrintf("Item02: loaded size doesn't match the real thing. %#x != %#x\n", cb, sizeof(gabBigMem));
369 return VERR_GENERAL_FAILURE;
370 }
371
372 /*
373 * Load the memory chunk by chunk.
374 */
375 uint8_t *pbMem = &gabBigMem[0];
376 char achTmp[16383];
377 uint32_t cbChunk = sizeof(achTmp);
378 while (cb > 0)
379 {
380 cbChunk -= 7;
381 if (cbChunk < 64)
382 cbChunk = sizeof(achTmp) - (cbChunk % 47);
383 if (cbChunk > cb)
384 cbChunk = cb;
385 rc = SSMR3GetMem(pSSM, &achTmp[0], cbChunk);
386 if (RT_FAILURE(rc))
387 {
388 RTPrintf("Item02: SSMR3GetMem(,,%#x) -> %d offset %#x\n", cbChunk, rc, pbMem - &gabBigMem[0]);
389 return rc;
390 }
391 if (memcmp(achTmp, pbMem, cbChunk))
392 {
393 RTPrintf("Item02: compare failed. mem offset=%#x cbChunk=%#x\n", pbMem - &gabBigMem[0], cbChunk);
394 return VERR_GENERAL_FAILURE;
395 }
396
397 /* next */
398 pbMem += cbChunk;
399 cb -= cbChunk;
400 }
401
402 return 0;
403}
404
405
406/**
407 * Execute state save operation.
408 *
409 * @returns VBox status code.
410 * @param pVM The cross context VM handle.
411 * @param pSSM SSM operation handle.
412 */
413DECLCALLBACK(int) Item03Save(PVM pVM, PSSMHANDLE pSSM)
414{
415 NOREF(pVM);
416 uint64_t u64Start = RTTimeNanoTS();
417
418 /*
419 * Put the size.
420 */
421 uint32_t cb = TSTSSM_ITEM_SIZE;
422 int rc = SSMR3PutU32(pSSM, cb);
423 if (RT_FAILURE(rc))
424 {
425 RTPrintf("Item03: PutU32 -> %Rrc\n", rc);
426 return rc;
427 }
428
429 /*
430 * Put 512 MB page by page.
431 */
432 const uint8_t *pu8Org = &gabBigMem[0];
433 while (cb > 0)
434 {
435 rc = SSMR3PutMem(pSSM, pu8Org, PAGE_SIZE);
436 if (RT_FAILURE(rc))
437 {
438 RTPrintf("Item03: PutMem(,%p,%#x) -> %Rrc\n", pu8Org, PAGE_SIZE, rc);
439 return rc;
440 }
441
442 /* next */
443 cb -= PAGE_SIZE;
444 pu8Org += PAGE_SIZE;
445 if (pu8Org >= &gabBigMem[sizeof(gabBigMem)])
446 pu8Org = &gabBigMem[0];
447 }
448
449 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
450 RTPrintf("tstSSM: Saved 3rd item in %'RI64 ns\n", u64Elapsed);
451 return 0;
452}
453
454/**
455 * Prepare state load operation.
456 *
457 * @returns VBox status code.
458 * @param pVM The cross context VM handle.
459 * @param pSSM SSM operation handle.
460 * @param uVersion The data layout version.
461 * @param uPass The data pass.
462 */
463DECLCALLBACK(int) Item03Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
464{
465 NOREF(pVM); NOREF(uPass);
466 if (uVersion != 123)
467 {
468 RTPrintf("Item03: uVersion=%#x, expected 123\n", uVersion);
469 return VERR_GENERAL_FAILURE;
470 }
471
472 /*
473 * Load the size.
474 */
475 uint32_t cb;
476 int rc = SSMR3GetU32(pSSM, &cb);
477 if (RT_FAILURE(rc))
478 {
479 RTPrintf("Item03: SSMR3GetU32 -> %Rrc\n", rc);
480 return rc;
481 }
482 if (cb != TSTSSM_ITEM_SIZE)
483 {
484 RTPrintf("Item03: loaded size doesn't match the real thing. %#x != %#x\n", cb, TSTSSM_ITEM_SIZE);
485 return VERR_GENERAL_FAILURE;
486 }
487
488 /*
489 * Load the memory page by page.
490 */
491 const uint8_t *pu8Org = &gabBigMem[0];
492 while (cb > 0)
493 {
494 char achPage[PAGE_SIZE];
495 rc = SSMR3GetMem(pSSM, &achPage[0], PAGE_SIZE);
496 if (RT_FAILURE(rc))
497 {
498 RTPrintf("Item03: SSMR3GetMem(,,%#x) -> %Rrc offset %#x\n", PAGE_SIZE, rc, TSTSSM_ITEM_SIZE - cb);
499 return rc;
500 }
501 if (memcmp(achPage, pu8Org, PAGE_SIZE))
502 {
503 RTPrintf("Item03: compare failed. mem offset=%#x\n", TSTSSM_ITEM_SIZE - cb);
504 return VERR_GENERAL_FAILURE;
505 }
506
507 /* next */
508 cb -= PAGE_SIZE;
509 pu8Org += PAGE_SIZE;
510 if (pu8Org >= &gabBigMem[sizeof(gabBigMem)])
511 pu8Org = &gabBigMem[0];
512 }
513
514 return 0;
515}
516
517
518/**
519 * Execute state save operation.
520 *
521 * @returns VBox status code.
522 * @param pVM The cross context VM handle.
523 * @param pSSM SSM operation handle.
524 */
525DECLCALLBACK(int) Item04Save(PVM pVM, PSSMHANDLE pSSM)
526{
527 NOREF(pVM);
528 uint64_t u64Start = RTTimeNanoTS();
529
530 /*
531 * Put the size.
532 */
533 uint32_t cb = 512*_1M;
534 int rc = SSMR3PutU32(pSSM, cb);
535 if (RT_FAILURE(rc))
536 {
537 RTPrintf("Item04: PutU32 -> %Rrc\n", rc);
538 return rc;
539 }
540
541 /*
542 * Put 512 MB page by page.
543 */
544 while (cb > 0)
545 {
546 rc = SSMR3PutMem(pSSM, gabPage, PAGE_SIZE);
547 if (RT_FAILURE(rc))
548 {
549 RTPrintf("Item04: PutMem(,%p,%#x) -> %Rrc\n", gabPage, PAGE_SIZE, rc);
550 return rc;
551 }
552
553 /* next */
554 cb -= PAGE_SIZE;
555 }
556
557 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
558 RTPrintf("tstSSM: Saved 4th item in %'RI64 ns\n", u64Elapsed);
559 return 0;
560}
561
562/**
563 * Prepare state load operation.
564 *
565 * @returns VBox status code.
566 * @param pVM The cross context VM handle.
567 * @param pSSM SSM operation handle.
568 * @param uVersion The data layout version.
569 * @param uPass The data pass.
570 */
571DECLCALLBACK(int) Item04Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
572{
573 NOREF(pVM); NOREF(uPass);
574 if (uVersion != 42)
575 {
576 RTPrintf("Item04: uVersion=%#x, expected 42\n", uVersion);
577 return VERR_GENERAL_FAILURE;
578 }
579
580 /*
581 * Load the size.
582 */
583 uint32_t cb;
584 int rc = SSMR3GetU32(pSSM, &cb);
585 if (RT_FAILURE(rc))
586 {
587 RTPrintf("Item04: SSMR3GetU32 -> %Rrc\n", rc);
588 return rc;
589 }
590 if (cb != 512*_1M)
591 {
592 RTPrintf("Item04: loaded size doesn't match the real thing. %#x != %#x\n", cb, 512*_1M);
593 return VERR_GENERAL_FAILURE;
594 }
595
596 /*
597 * Load the memory page by page.
598 */
599 while (cb > 0)
600 {
601 char achPage[PAGE_SIZE];
602 rc = SSMR3GetMem(pSSM, &achPage[0], PAGE_SIZE);
603 if (RT_FAILURE(rc))
604 {
605 RTPrintf("Item04: SSMR3GetMem(,,%#x) -> %Rrc offset %#x\n", PAGE_SIZE, rc, 512*_1M - cb);
606 return rc;
607 }
608 if (memcmp(achPage, gabPage, PAGE_SIZE))
609 {
610 RTPrintf("Item04: compare failed. mem offset=%#x\n", 512*_1M - cb);
611 return VERR_GENERAL_FAILURE;
612 }
613
614 /* next */
615 cb -= PAGE_SIZE;
616 }
617
618 return 0;
619}
620
621
622/**
623 * Creates a mockup VM structure for testing SSM.
624 *
625 * @returns 0 on success, 1 on failure.
626 * @param ppVM Where to store Pointer to the VM.
627 *
628 * @todo Move this to VMM/VM since it's stuff done by several testcases.
629 */
630static int createFakeVM(PVM *ppVM)
631{
632 /*
633 * Allocate and init the UVM structure.
634 */
635 PUVM pUVM = (PUVM)RTMemPageAllocZ(sizeof(*pUVM));
636 AssertReturn(pUVM, 1);
637 pUVM->u32Magic = UVM_MAGIC;
638 pUVM->vm.s.idxTLS = RTTlsAlloc();
639 int rc = RTTlsSet(pUVM->vm.s.idxTLS, &pUVM->aCpus[0]);
640 if (RT_SUCCESS(rc))
641 {
642 pUVM->aCpus[0].pUVM = pUVM;
643 pUVM->aCpus[0].vm.s.NativeThreadEMT = RTThreadNativeSelf();
644
645 rc = STAMR3InitUVM(pUVM);
646 if (RT_SUCCESS(rc))
647 {
648 rc = MMR3InitUVM(pUVM);
649 if (RT_SUCCESS(rc))
650 {
651 /*
652 * Allocate and init the VM structure.
653 */
654 PVM pVM;
655 rc = SUPR3PageAlloc((sizeof(*pVM) + PAGE_SIZE - 1) >> PAGE_SHIFT, (void **)&pVM);
656 if (RT_SUCCESS(rc))
657 {
658 pVM->enmVMState = VMSTATE_CREATED;
659 pVM->pVMR3 = pVM;
660 pVM->pUVM = pUVM;
661 pVM->cCpus = 1;
662 pVM->aCpus[0].pVMR3 = pVM;
663 pVM->aCpus[0].hNativeThread = RTThreadNativeSelf();
664
665 pUVM->pVM = pVM;
666 *ppVM = pVM;
667 return 0;
668 }
669
670 RTPrintf("Fatal error: failed to allocated pages for the VM structure, rc=%Rrc\n", rc);
671 }
672 else
673 RTPrintf("Fatal error: MMR3InitUVM failed, rc=%Rrc\n", rc);
674 }
675 else
676 RTPrintf("Fatal error: SSMR3InitUVM failed, rc=%Rrc\n", rc);
677 }
678 else
679 RTPrintf("Fatal error: RTTlsSet failed, rc=%Rrc\n", rc);
680
681 *ppVM = NULL;
682 return 1;
683}
684
685
686/**
687 * Destroy the VM structure.
688 *
689 * @param pVM Pointer to the VM.
690 *
691 * @todo Move this to VMM/VM since it's stuff done by several testcases.
692 */
693static void destroyFakeVM(PVM pVM)
694{
695 STAMR3TermUVM(pVM->pUVM);
696 MMR3TermUVM(pVM->pUVM);
697}
698
699
700/**
701 * Entry point.
702 */
703extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
704{
705 RT_NOREF1(envp);
706
707 /*
708 * Init runtime and static data.
709 */
710 RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
711 RTPrintf("tstSSM: TESTING...\n");
712 initBigMem();
713 const char *pszFilename = "SSMTestSave#1";
714
715 /*
716 * Create an fake VM structure and init SSM.
717 */
718 int rc = SUPR3Init(NULL);
719 if (RT_FAILURE(rc))
720 {
721 RTPrintf("Fatal error: SUP Failure! rc=%Rrc\n", rc);
722 return 1;
723 }
724 PVM pVM;
725 if (createFakeVM(&pVM))
726 return 1;
727
728 /*
729 * Register a few callbacks.
730 */
731 rc = SSMR3RegisterInternal(pVM, "SSM Testcase Data Item no.1 (all types)", 1, 0, 256,
732 NULL, NULL, NULL,
733 NULL, Item01Save, NULL,
734 NULL, Item01Load, NULL);
735 if (RT_FAILURE(rc))
736 {
737 RTPrintf("SSMR3Register #1 -> %Rrc\n", rc);
738 return 1;
739 }
740
741 rc = SSMR3RegisterInternal(pVM, "SSM Testcase Data Item no.2 (rand mem)", 2, 0, _1M * 8,
742 NULL, NULL, NULL,
743 NULL, Item02Save, NULL,
744 NULL, Item02Load, NULL);
745 if (RT_FAILURE(rc))
746 {
747 RTPrintf("SSMR3Register #2 -> %Rrc\n", rc);
748 return 1;
749 }
750
751 rc = SSMR3RegisterInternal(pVM, "SSM Testcase Data Item no.3 (big mem)", 0, 123, 512*_1M,
752 NULL, NULL, NULL,
753 NULL, Item03Save, NULL,
754 NULL, Item03Load, NULL);
755 if (RT_FAILURE(rc))
756 {
757 RTPrintf("SSMR3Register #3 -> %Rrc\n", rc);
758 return 1;
759 }
760
761 rc = SSMR3RegisterInternal(pVM, "SSM Testcase Data Item no.4 (big zero mem)", 0, 42, 512*_1M,
762 NULL, NULL, NULL,
763 NULL, Item04Save, NULL,
764 NULL, Item04Load, NULL);
765 if (RT_FAILURE(rc))
766 {
767 RTPrintf("SSMR3Register #4 -> %Rrc\n", rc);
768 return 1;
769 }
770
771 /*
772 * Attempt a save.
773 */
774 uint64_t u64Start = RTTimeNanoTS();
775 rc = SSMR3Save(pVM, pszFilename, NULL, NULL, SSMAFTER_DESTROY, NULL, NULL);
776 if (RT_FAILURE(rc))
777 {
778 RTPrintf("SSMR3Save #1 -> %Rrc\n", rc);
779 return 1;
780 }
781 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
782 RTPrintf("tstSSM: Saved in %'RI64 ns\n", u64Elapsed);
783
784 RTFSOBJINFO Info;
785 rc = RTPathQueryInfo(pszFilename, &Info, RTFSOBJATTRADD_NOTHING);
786 if (RT_FAILURE(rc))
787 {
788 RTPrintf("tstSSM: failed to query file size: %Rrc\n", rc);
789 return 1;
790 }
791 RTPrintf("tstSSM: file size %'RI64 bytes\n", Info.cbObject);
792
793 /*
794 * Attempt a load.
795 */
796 u64Start = RTTimeNanoTS();
797 rc = SSMR3Load(pVM, pszFilename, NULL /*pStreamOps*/, NULL /*pStreamOpsUser*/,
798 SSMAFTER_RESUME, NULL /*pfnProgress*/, NULL /*pvProgressUser*/);
799 if (RT_FAILURE(rc))
800 {
801 RTPrintf("SSMR3Load #1 -> %Rrc\n", rc);
802 return 1;
803 }
804 u64Elapsed = RTTimeNanoTS() - u64Start;
805 RTPrintf("tstSSM: Loaded in %'RI64 ns\n", u64Elapsed);
806
807 /*
808 * Validate it.
809 */
810 u64Start = RTTimeNanoTS();
811 rc = SSMR3ValidateFile(pszFilename, false /* fChecksumIt*/ );
812 if (RT_FAILURE(rc))
813 {
814 RTPrintf("SSMR3ValidateFile #1 -> %Rrc\n", rc);
815 return 1;
816 }
817 u64Elapsed = RTTimeNanoTS() - u64Start;
818 RTPrintf("tstSSM: Validated without checksumming in %'RI64 ns\n", u64Elapsed);
819
820 u64Start = RTTimeNanoTS();
821 rc = SSMR3ValidateFile(pszFilename, true /* fChecksumIt */);
822 if (RT_FAILURE(rc))
823 {
824 RTPrintf("SSMR3ValidateFile #1 -> %Rrc\n", rc);
825 return 1;
826 }
827 u64Elapsed = RTTimeNanoTS() - u64Start;
828 RTPrintf("tstSSM: Validated and checksummed in %'RI64 ns\n", u64Elapsed);
829
830 /*
831 * Open it and read.
832 */
833 u64Start = RTTimeNanoTS();
834 PSSMHANDLE pSSM;
835 rc = SSMR3Open(pszFilename, 0, &pSSM);
836 if (RT_FAILURE(rc))
837 {
838 RTPrintf("SSMR3Open #1 -> %Rrc\n", rc);
839 return 1;
840 }
841 u64Elapsed = RTTimeNanoTS() - u64Start;
842 RTPrintf("tstSSM: Opened in %'RI64 ns\n", u64Elapsed);
843
844 /* negative */
845 u64Start = RTTimeNanoTS();
846 rc = SSMR3Seek(pSSM, "some unit that doesn't exist", 0, NULL);
847 if (rc != VERR_SSM_UNIT_NOT_FOUND)
848 {
849 RTPrintf("SSMR3Seek #1 negative -> %Rrc\n", rc);
850 return 1;
851 }
852 u64Elapsed = RTTimeNanoTS() - u64Start;
853 RTPrintf("tstSSM: Failed seek in %'RI64 ns\n", u64Elapsed);
854
855 /* another negative, now only the instance number isn't matching. */
856 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 0, NULL);
857 if (rc != VERR_SSM_UNIT_NOT_FOUND)
858 {
859 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc\n", rc);
860 return 1;
861 }
862
863 /* 2nd unit */
864 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 2, NULL);
865 if (RT_FAILURE(rc))
866 {
867 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc [2]\n", rc);
868 return 1;
869 }
870 uint32_t uVersion = 0xbadc0ded;
871 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 2, &uVersion);
872 if (RT_FAILURE(rc))
873 {
874 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc [3]\n", rc);
875 return 1;
876 }
877 u64Start = RTTimeNanoTS();
878 rc = Item02Load(NULL, pSSM, uVersion, SSM_PASS_FINAL);
879 if (RT_FAILURE(rc))
880 {
881 RTPrintf("Item02Load #1 -> %Rrc\n", rc);
882 return 1;
883 }
884 u64Elapsed = RTTimeNanoTS() - u64Start;
885 RTPrintf("tstSSM: Loaded 2nd item in %'RI64 ns\n", u64Elapsed);
886
887 /* 1st unit */
888 uVersion = 0xbadc0ded;
889 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.1 (all types)", 1, &uVersion);
890 if (RT_FAILURE(rc))
891 {
892 RTPrintf("SSMR3Seek #1 unit 1 -> %Rrc\n", rc);
893 return 1;
894 }
895 u64Start = RTTimeNanoTS();
896 rc = Item01Load(NULL, pSSM, uVersion, SSM_PASS_FINAL);
897 if (RT_FAILURE(rc))
898 {
899 RTPrintf("Item01Load #1 -> %Rrc\n", rc);
900 return 1;
901 }
902 u64Elapsed = RTTimeNanoTS() - u64Start;
903 RTPrintf("tstSSM: Loaded 1st item in %'RI64 ns\n", u64Elapsed);
904
905 /* 3st unit */
906 uVersion = 0xbadc0ded;
907 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.3 (big mem)", 0, &uVersion);
908 if (RT_FAILURE(rc))
909 {
910 RTPrintf("SSMR3Seek #3 unit 1 -> %Rrc\n", rc);
911 return 1;
912 }
913 u64Start = RTTimeNanoTS();
914 rc = Item03Load(NULL, pSSM, uVersion, SSM_PASS_FINAL);
915 if (RT_FAILURE(rc))
916 {
917 RTPrintf("Item01Load #3 -> %Rrc\n", rc);
918 return 1;
919 }
920 u64Elapsed = RTTimeNanoTS() - u64Start;
921 RTPrintf("tstSSM: Loaded 3rd item in %'RI64 ns\n", u64Elapsed);
922
923 /* close */
924 rc = SSMR3Close(pSSM);
925 if (RT_FAILURE(rc))
926 {
927 RTPrintf("SSMR3Close #1 -> %Rrc\n", rc);
928 return 1;
929 }
930
931 destroyFakeVM(pVM);
932
933 /* delete */
934 RTFileDelete(pszFilename);
935
936 RTPrintf("tstSSM: SUCCESS\n");
937 return 0;
938}
939
940
941#if !defined(VBOX_WITH_HARDENING) || !defined(RT_OS_WINDOWS)
942/**
943 * Main entry point.
944 */
945int main(int argc, char **argv, char **envp)
946{
947 return TrustedMain(argc, argv, envp);
948}
949#endif
950
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