VirtualBox

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

Last change on this file since 101665 was 99775, checked in by vboxsync, 18 months ago

*: Mark functions as static if not used outside of a given compilation unit. Enables the compiler to optimize inlining, reduces the symbol tables, exposes unused functions and in some rare cases exposes mismtaches between function declarations and definitions, but most importantly reduces the number of parfait reports for the extern-function-no-forward-declaration category. This should not result in any functional changes, bugref:3409

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.7 KB
Line 
1/* $Id: tstVMMR0CallHost-1.cpp 99775 2023-05-12 12:21:58Z vboxsync $ */
2/** @file
3 * Testcase for the VMMR0JMPBUF operations.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include <iprt/errcore.h>
33#include <VBox/param.h>
34#include <iprt/alloca.h>
35#include <iprt/initterm.h>
36#include <iprt/rand.h>
37#include <iprt/string.h>
38#include <iprt/stream.h>
39#include <iprt/test.h>
40
41#define IN_VMM_R0
42#define IN_RING0 /* pretent we're in Ring-0 to get the prototypes. */
43#include <VBox/vmm/vmm.h>
44#include "VMMInternal.h"
45
46
47/*********************************************************************************************************************************
48* Global Variables *
49*********************************************************************************************************************************/
50/** The jump buffer. */
51static VMMR0JMPBUF g_Jmp;
52/** The mirror jump buffer. */
53static VMMR0JMPBUF g_JmpMirror;
54/** The number of jumps we've done. */
55static unsigned volatile g_cJmps;
56/** Number of bytes allocated last time we called foo(). */
57static size_t volatile g_cbFoo;
58/** Number of bytes used last time we called foo(). */
59static intptr_t volatile g_cbFooUsed;
60/** Set if we're in a long jump. */
61static bool g_fInLongJmp;
62
63
64static int foo(int i, int iZero, int iMinusOne)
65{
66 NOREF(iZero);
67
68 /* allocate a buffer which we fill up to the end. */
69 size_t cb = (i % 1555) + 32;
70 g_cbFoo = cb;
71 char *pv = (char *)alloca(cb);
72 RTStrPrintf(pv, cb, "i=%d%*s\n", i, cb, "");
73#if defined(RT_ARCH_AMD64)
74 g_cbFooUsed = (uintptr_t)g_Jmp.rsp - (uintptr_t)pv;
75 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);
76#elif defined(RT_ARCH_X86)
77 g_cbFooUsed = (uintptr_t)g_Jmp.esp - (uintptr_t)pv;
78 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);
79#endif
80
81 /* Twice in a row, every 7th time. */
82 if ((i % 7) <= 1)
83 {
84 g_cJmps++;
85 g_fInLongJmp = true;
86 int rc = vmmR0CallRing3LongJmp(&g_Jmp, 42);
87 g_fInLongJmp = false;
88 if (!rc)
89 return i + 10000;
90 return -1;
91 }
92 NOREF(iMinusOne);
93 return i;
94}
95
96
97static DECLCALLBACK(int) tst2(intptr_t i, intptr_t i2)
98{
99 RTTESTI_CHECK_MSG_RET(i >= 0 && i <= 8192, ("i=%d is out of range [0..8192]\n", i), 1);
100 RTTESTI_CHECK_MSG_RET(i2 == 0, ("i2=%d is out of range [0]\n", i2), 1);
101 int iExpect = (i % 7) <= 1 ? i + 10000 : i;
102 int rc = foo(i, 0, -1);
103 RTTESTI_CHECK_MSG_RET(rc == iExpect, ("i=%d rc=%d expected=%d\n", i, rc, iExpect), 1);
104 return 0;
105}
106
107
108static DECLCALLBACK(DECL_NO_INLINE(RT_NOTHING, int)) stackRandom(PVMMR0JMPBUF pJmpBuf, PFNVMMR0SETJMP pfn, PVM pVM, PVMCPU pVCpu)
109{
110#ifdef RT_ARCH_AMD64
111 uint32_t cbRand = RTRandU32Ex(1, 96);
112#else
113 uint32_t cbRand = 1;
114#endif
115 uint8_t volatile *pabFuzz = (uint8_t volatile *)alloca(cbRand);
116 memset((void *)pabFuzz, 0xfa, cbRand);
117 int rc = vmmR0CallRing3SetJmp(pJmpBuf, pfn, pVM, pVCpu);
118 memset((void *)pabFuzz, 0xaf, cbRand);
119 return rc;
120}
121
122
123static void tst(int iFrom, int iTo, int iInc)
124{
125 RT_BZERO(&g_Jmp, RT_UOFFSETOF(VMMR0JMPBUF, cbStackBuf));
126 g_Jmp.cbStackValid = _1M;
127 memset((void *)g_Jmp.pvStackBuf, '\0', g_Jmp.cbStackBuf);
128 g_cbFoo = 0;
129 g_cJmps = 0;
130 g_cbFooUsed = 0;
131 g_fInLongJmp = false;
132
133 for (int i = iFrom, iItr = 0; i != iTo; i += iInc, iItr++)
134 {
135 g_fInLongJmp = false;
136 int rc = stackRandom(&g_Jmp, (PFNVMMR0SETJMP)(uintptr_t)tst2, (PVM)(uintptr_t)i, 0);
137 RTTESTI_CHECK_MSG_RETV(rc == (g_fInLongJmp ? 42 : 0),
138 ("i=%d rc=%d setjmp; cbFoo=%#x cbFooUsed=%#x fInLongJmp=%d\n",
139 i, rc, g_cbFoo, g_cbFooUsed, g_fInLongJmp));
140
141 }
142 RTTESTI_CHECK_MSG_RETV(g_cJmps, ("No jumps!"));
143}
144
145
146int main()
147{
148 /*
149 * Init.
150 */
151 RTTEST hTest;
152 RTEXITCODE rcExit = RTTestInitAndCreate("tstVMMR0CallHost-1", &hTest);
153 if (rcExit != RTEXITCODE_SUCCESS)
154 return rcExit;
155 RTTestBanner(hTest);
156
157 g_Jmp.cbStackBuf = HOST_PAGE_SIZE;
158 g_Jmp.pvStackBuf = (uintptr_t)RTTestGuardedAllocTail(hTest, g_Jmp.cbStackBuf);
159 g_Jmp.pMirrorBuf = (uintptr_t)&g_JmpMirror;
160
161 /*
162 * Run two test with about 1000 long jumps each.
163 */
164 RTTestSub(hTest, "Increasing stack usage");
165 tst(0, 7000, 1);
166 RTTestSub(hTest, "Decreasing stack usage");
167 tst(7599, 0, -1);
168
169 return RTTestSummaryAndDestroy(hTest);
170}
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