VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/testcase/tstInt.cpp@ 5320

Last change on this file since 5320 was 4829, checked in by vboxsync, 17 years ago

inverted VBOX_WITHOUT_IDT_PATCHING.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/** $Id: tstInt.cpp 4829 2007-09-15 21:55:14Z vboxsync $ */
2/** @file
3 * Testcase: Test the interrupt gate feature of the support library.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <VBox/sup.h>
23#include <VBox/vm.h>
24#include <VBox/vmm.h>
25#include <VBox/err.h>
26#include <VBox/param.h>
27#include <iprt/runtime.h>
28#include <iprt/stream.h>
29#include <iprt/string.h>
30
31
32/**
33 * Makes a path to a file in the executable directory.
34 */
35static char *ExeDirFile(char *pszFile, const char *pszArgv0, const char *pszFilename)
36{
37 char *psz;
38 char *psz2;
39
40 strcpy(pszFile, pszArgv0);
41 psz = strrchr(pszFile, '/');
42 psz2 = strrchr(pszFile, '\\');
43 if (psz < psz2)
44 psz = psz2;
45 if (!psz)
46 psz = strrchr(pszFile, ':');
47 if (!psz)
48 {
49 strcpy(pszFile, "./");
50 psz = &pszFile[1];
51 }
52 strcpy(psz + 1, "VMMR0.r0");
53 return pszFile;
54}
55
56int main(int argc, char **argv)
57{
58 int rcRet = 0;
59 int i;
60 int rc;
61 int cIterations = argc > 1 ? RTStrToUInt32(argv[1]) : 32;
62 if (cIterations == 0)
63 cIterations = 64;
64
65 /*
66 * Init.
67 */
68 RTR3Init();
69 PSUPDRVSESSION pSession;
70 rc = SUPInit(&pSession);
71 rcRet += rc != 0;
72 RTPrintf("tstInt: SUPInit -> rc=%Vrc\n", rc);
73 if (!rc)
74 {
75 /*
76 * Load VMM code.
77 */
78 char szFile[RTPATH_MAX];
79 rc = SUPLoadVMM(ExeDirFile(szFile, argv[0], "VMMR0.r0"));
80 if (!rc)
81 {
82 /*
83 * Create a fake 'VM'.
84 */
85 PVMR0 pVMR0 = NIL_RTR0PTR;
86 PVM pVM = NULL;
87 const unsigned cPages = RT_ALIGN_Z(sizeof(*pVM), PAGE_SIZE) >> PAGE_SHIFT;
88 PSUPPAGE paPages = (PSUPPAGE)RTMemAllocZ(cPages * sizeof(SUPPAGE));
89 if (paPages)
90 rc = SUPLowAlloc(cPages, (void **)&pVM, &pVMR0, &paPages[0]);
91 else
92 rc = VERR_NO_MEMORY;
93 if (VBOX_SUCCESS(rc))
94 {
95 pVM->pVMGC = 0;
96 pVM->pVMR3 = pVM;
97 pVM->pVMR0 = pVMR0;
98 pVM->paVMPagesR3 = paPages;
99 pVM->pSession = pSession;
100
101 rc = SUPSetVMForFastIOCtl(pVMR0);
102 if (!rc)
103 {
104
105 /*
106 * Call VMM code with invalid function.
107 */
108 for (i = cIterations; i > 0; i--)
109 {
110 rc = SUPCallVMMR0(pVMR0, VMMR0_DO_NOP, NULL);
111 if (rc != VINF_SUCCESS)
112 {
113 RTPrintf("tstInt: SUPCallVMMR0 -> rc=%Vrc i=%d Expected VINF_SUCCESS!\n", rc, i);
114 rcRet++;
115 break;
116 }
117 }
118 RTPrintf("tstInt: Performed SUPCallVMMR0 %d times (rc=%Vrc)\n", cIterations, rc);
119
120 /*
121 * Profile it.
122 */
123 if (!rc)
124 {
125 RTTimeNanoTS();
126 uint64_t StartTS = RTTimeNanoTS();
127 uint64_t StartTick = ASMReadTSC();
128 uint64_t MinTicks = UINT64_MAX;
129 for (i = 0; i < 1000000; i++)
130 {
131 uint64_t OneStartTick = ASMReadTSC();
132 rc = SUPCallVMMR0(pVMR0, VMMR0_DO_NOP, NULL);
133 uint64_t Ticks = ASMReadTSC() - OneStartTick;
134 if (Ticks < MinTicks)
135 MinTicks = Ticks;
136
137 if (RT_UNLIKELY(rc != VINF_SUCCESS))
138 {
139 RTPrintf("tstInt: SUPCallVMMR0 -> rc=%Vrc i=%d Expected VINF_SUCCESS!\n", rc, i);
140 rcRet++;
141 break;
142 }
143 }
144 uint64_t Ticks = ASMReadTSC() - StartTick;
145 uint64_t NanoSecs = RTTimeNanoTS() - StartTS;
146
147 RTPrintf("tstInt: SUPCallVMMR0 - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n",
148 i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks);
149
150#ifdef VBOX_WITH_IDT_PATCHING
151 /*
152 * The fast path.
153 */
154 RTTimeNanoTS();
155 StartTS = RTTimeNanoTS();
156 StartTick = ASMReadTSC();
157 MinTicks = UINT64_MAX;
158 for (i = 0; i < 1000000; i++)
159 {
160 uint64_t OneStartTick = ASMReadTSC();
161 rc = SUPCallVMMR0Fast(pVMR0, VMMR0_DO_NOP);
162 uint64_t Ticks = ASMReadTSC() - OneStartTick;
163 if (Ticks < MinTicks)
164 MinTicks = Ticks;
165
166 if (RT_UNLIKELY(rc != VINF_SUCCESS))
167 {
168 RTPrintf("tstInt: SUPCallVMMR0 -> rc=%Vrc i=%d Expected VINF_SUCCESS!\n", rc, i);
169 rcRet++;
170 break;
171 }
172 }
173 Ticks = ASMReadTSC() - StartTick;
174 NanoSecs = RTTimeNanoTS() - StartTS;
175
176 RTPrintf("tstInt: SUPCallVMMR0Fast - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n",
177 i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks);
178#endif /* VBOX_WITH_IDT_PATCHING */
179
180 /*
181 * The ordinary path.
182 */
183 RTTimeNanoTS();
184 StartTS = RTTimeNanoTS();
185 StartTick = ASMReadTSC();
186 MinTicks = UINT64_MAX;
187 for (i = 0; i < 1000000; i++)
188 {
189 uint64_t OneStartTick = ASMReadTSC();
190 rc = SUPCallVMMR0Ex(pVMR0, VMMR0_DO_NOP, 0, NULL);
191 uint64_t Ticks = ASMReadTSC() - OneStartTick;
192 if (Ticks < MinTicks)
193 MinTicks = Ticks;
194
195 if (RT_UNLIKELY(rc != VINF_SUCCESS))
196 {
197 RTPrintf("tstInt: SUPCallVMMR0 -> rc=%Vrc i=%d Expected VINF_SUCCESS!\n", rc, i);
198 rcRet++;
199 break;
200 }
201 }
202 Ticks = ASMReadTSC() - StartTick;
203 NanoSecs = RTTimeNanoTS() - StartTS;
204
205 RTPrintf("tstInt: SUPCallVMMR0Ex - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n",
206 i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks);
207 }
208 }
209 else
210 {
211 RTPrintf("tstInt: SUPSetVMForFastIOCtl failed: %Vrc\n", rc);
212 rcRet++;
213 }
214 }
215 else
216 {
217 RTPrintf("tstInt: SUPContAlloc2(%#zx,,) failed\n", sizeof(*pVM));
218 rcRet++;
219 }
220
221 /*
222 * Unload VMM.
223 */
224 rc = SUPUnloadVMM();
225 if (rc)
226 {
227 RTPrintf("tstInt: SUPUnloadVMM failed with rc=%Vrc\n", rc);
228 rcRet++;
229 }
230 }
231 else
232 {
233 RTPrintf("tstInt: SUPLoadVMM failed with rc=%Vrc\n", rc);
234 rcRet++;
235 }
236
237 /*
238 * Terminate.
239 */
240 rc = SUPTerm();
241 rcRet += rc != 0;
242 RTPrintf("tstInt: SUPTerm -> rc=%Vrc\n", rc);
243 }
244
245 return !!rc;
246}
247
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