VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp@ 94249

Last change on this file since 94249 was 93554, checked in by vboxsync, 3 years ago

VMM: Changed PAGE_SIZE -> GUEST_PAGE_SIZE / HOST_PAGE_SIZE, PAGE_SHIFT -> GUEST_PAGE_SHIFT / HOST_PAGE_SHIFT, and PAGE_OFFSET_MASK -> GUEST_PAGE_OFFSET_MASK / HOST_PAGE_OFFSET_MASK. Also removed most usage of ASMMemIsZeroPage and ASMMemZeroPage since the host and guest page size doesn't need to be the same any more. Some work left to do in the page pool code. bugref:9898

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.4 KB
Line 
1/* $Id: tstVMMR0CallHost-1.cpp 93554 2022-02-02 22:57:02Z vboxsync $ */
2/** @file
3 * Testcase for the VMMR0JMPBUF operations.
4 */
5
6/*
7 * Copyright (C) 2006-2022 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 <iprt/errcore.h>
23#include <VBox/param.h>
24#include <iprt/alloca.h>
25#include <iprt/initterm.h>
26#include <iprt/rand.h>
27#include <iprt/string.h>
28#include <iprt/stream.h>
29#include <iprt/test.h>
30
31#define IN_VMM_R0
32#define IN_RING0 /* pretent we're in Ring-0 to get the prototypes. */
33#include <VBox/vmm/vmm.h>
34#include "VMMInternal.h"
35
36
37/*********************************************************************************************************************************
38* Global Variables *
39*********************************************************************************************************************************/
40/** The jump buffer. */
41static VMMR0JMPBUF g_Jmp;
42/** The mirror jump buffer. */
43static VMMR0JMPBUF g_JmpMirror;
44/** The number of jumps we've done. */
45static unsigned volatile g_cJmps;
46/** Number of bytes allocated last time we called foo(). */
47static size_t volatile g_cbFoo;
48/** Number of bytes used last time we called foo(). */
49static intptr_t volatile g_cbFooUsed;
50/** Set if we're in a long jump. */
51static bool g_fInLongJmp;
52
53
54int foo(int i, int iZero, int iMinusOne)
55{
56 NOREF(iZero);
57
58 /* allocate a buffer which we fill up to the end. */
59 size_t cb = (i % 1555) + 32;
60 g_cbFoo = cb;
61 char *pv = (char *)alloca(cb);
62 RTStrPrintf(pv, cb, "i=%d%*s\n", i, cb, "");
63#if defined(RT_ARCH_AMD64)
64 g_cbFooUsed = (uintptr_t)g_Jmp.rsp - (uintptr_t)pv;
65 RTTESTI_CHECK_MSG_RET(g_cbFooUsed < VMM_STACK_SIZE - 128, ("%p - %p -> %#x; cb=%#x i=%d\n", g_Jmp.rsp, pv, g_cbFooUsed, cb, i), -15);
66#elif defined(RT_ARCH_X86)
67 g_cbFooUsed = (uintptr_t)g_Jmp.esp - (uintptr_t)pv;
68 RTTESTI_CHECK_MSG_RET(g_cbFooUsed < (intptr_t)VMM_STACK_SIZE - 128, ("%p - %p -> %#x; cb=%#x i=%d\n", g_Jmp.esp, pv, g_cbFooUsed, cb, i), -15);
69#endif
70
71 /* Twice in a row, every 7th time. */
72 if ((i % 7) <= 1)
73 {
74 g_cJmps++;
75 g_fInLongJmp = true;
76 int rc = vmmR0CallRing3LongJmp(&g_Jmp, 42);
77 g_fInLongJmp = false;
78 if (!rc)
79 return i + 10000;
80 return -1;
81 }
82 NOREF(iMinusOne);
83 return i;
84}
85
86
87DECLCALLBACK(int) tst2(intptr_t i, intptr_t i2)
88{
89 RTTESTI_CHECK_MSG_RET(i >= 0 && i <= 8192, ("i=%d is out of range [0..8192]\n", i), 1);
90 RTTESTI_CHECK_MSG_RET(i2 == 0, ("i2=%d is out of range [0]\n", i2), 1);
91 int iExpect = (i % 7) <= 1 ? i + 10000 : i;
92 int rc = foo(i, 0, -1);
93 RTTESTI_CHECK_MSG_RET(rc == iExpect, ("i=%d rc=%d expected=%d\n", i, rc, iExpect), 1);
94 return 0;
95}
96
97
98DECLCALLBACK(DECL_NO_INLINE(RT_NOTHING, int)) stackRandom(PVMMR0JMPBUF pJmpBuf, PFNVMMR0SETJMP pfn, PVM pVM, PVMCPU pVCpu)
99{
100#ifdef RT_ARCH_AMD64
101 uint32_t cbRand = RTRandU32Ex(1, 96);
102#else
103 uint32_t cbRand = 1;
104#endif
105 uint8_t volatile *pabFuzz = (uint8_t volatile *)alloca(cbRand);
106 memset((void *)pabFuzz, 0xfa, cbRand);
107 int rc = vmmR0CallRing3SetJmp(pJmpBuf, pfn, pVM, pVCpu);
108 memset((void *)pabFuzz, 0xaf, cbRand);
109 return rc;
110}
111
112
113void tst(int iFrom, int iTo, int iInc)
114{
115 RT_BZERO(&g_Jmp, RT_UOFFSETOF(VMMR0JMPBUF, cbStackBuf));
116 g_Jmp.cbStackValid = _1M;
117 memset((void *)g_Jmp.pvStackBuf, '\0', g_Jmp.cbStackBuf);
118 g_cbFoo = 0;
119 g_cJmps = 0;
120 g_cbFooUsed = 0;
121 g_fInLongJmp = false;
122
123 for (int i = iFrom, iItr = 0; i != iTo; i += iInc, iItr++)
124 {
125 g_fInLongJmp = false;
126 int rc = stackRandom(&g_Jmp, (PFNVMMR0SETJMP)(uintptr_t)tst2, (PVM)(uintptr_t)i, 0);
127 RTTESTI_CHECK_MSG_RETV(rc == (g_fInLongJmp ? 42 : 0),
128 ("i=%d rc=%d setjmp; cbFoo=%#x cbFooUsed=%#x fInLongJmp=%d\n",
129 i, rc, g_cbFoo, g_cbFooUsed, g_fInLongJmp));
130
131 }
132 RTTESTI_CHECK_MSG_RETV(g_cJmps, ("No jumps!"));
133}
134
135
136int main()
137{
138 /*
139 * Init.
140 */
141 RTTEST hTest;
142 RTEXITCODE rcExit = RTTestInitAndCreate("tstVMMR0CallHost-1", &hTest);
143 if (rcExit != RTEXITCODE_SUCCESS)
144 return rcExit;
145 RTTestBanner(hTest);
146
147 g_Jmp.cbStackBuf = HOST_PAGE_SIZE;
148 g_Jmp.pvStackBuf = (uintptr_t)RTTestGuardedAllocTail(hTest, g_Jmp.cbStackBuf);
149 g_Jmp.pMirrorBuf = (uintptr_t)&g_JmpMirror;
150
151 /*
152 * Run two test with about 1000 long jumps each.
153 */
154 RTTestSub(hTest, "Increasing stack usage");
155 tst(0, 7000, 1);
156 RTTestSub(hTest, "Decreasing stack usage");
157 tst(7599, 0, -1);
158
159 return RTTestSummaryAndDestroy(hTest);
160}
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