VirtualBox

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

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

VMM: Started refactoring GVM & VM structures for bugref:9217

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1/* $Id: tstInt.cpp 78431 2019-05-07 14:01:45Z vboxsync $ */
2/** @file
3 * SUP Testcase - Test the interrupt gate feature of the support library.
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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <VBox/sup.h>
32#include <VBox/vmm/vm.h>
33#include <VBox/vmm/vmm.h>
34#include <VBox/vmm/gvmm.h>
35#include <iprt/errcore.h>
36#include <VBox/param.h>
37#include <iprt/asm-amd64-x86.h>
38#include <iprt/initterm.h>
39#include <iprt/stream.h>
40#include <iprt/string.h>
41#include <iprt/alloc.h>
42#include <iprt/time.h>
43#include <iprt/path.h>
44
45
46int main(int argc, char **argv)
47{
48 int rcRet = 0;
49 int i;
50 int rc;
51 int cIterations = argc > 1 ? RTStrToUInt32(argv[1]) : 32;
52 if (cIterations == 0)
53 cIterations = 64;
54
55 /*
56 * Init.
57 */
58 RTR3InitExe(argc, &argv, 0);
59 PSUPDRVSESSION pSession;
60 rc = SUPR3Init(&pSession);
61 rcRet += rc != 0;
62 RTPrintf("tstInt: SUPR3Init -> rc=%Rrc\n", rc);
63 char szFile[RTPATH_MAX];
64 if (!rc)
65 {
66 rc = RTPathExecDir(szFile, sizeof(szFile) - sizeof("/VMMR0.r0"));
67 }
68 char szAbsFile[RTPATH_MAX];
69 if (RT_SUCCESS(rc))
70 {
71 strcat(szFile, "/VMMR0.r0");
72 rc = RTPathAbs(szFile, szAbsFile, sizeof(szAbsFile));
73 }
74 if (RT_SUCCESS(rc))
75 {
76 /*
77 * Load VMM code.
78 */
79 rc = SUPR3LoadVMM(szAbsFile);
80 if (RT_SUCCESS(rc))
81 {
82 /*
83 * Create a tiny dummy VM so we can do NOP calls into it using the fast I/O control path.
84 */
85 GVMMCREATEVMREQ CreateVMReq;
86 CreateVMReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
87 CreateVMReq.Hdr.cbReq = sizeof(CreateVMReq);
88 CreateVMReq.pSession = pSession;
89 CreateVMReq.pVMR0 = NIL_RTR0PTR;
90 CreateVMReq.pVMR3 = NULL;
91 CreateVMReq.cCpus = 1;
92 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_GVMM_CREATE_VM, 0, &CreateVMReq.Hdr);
93 if (RT_SUCCESS(rc))
94 {
95 PVM pVM = CreateVMReq.pVMR3;
96 AssertRelease(VALID_PTR(pVM));
97 AssertRelease(pVM->pVMR0 == CreateVMReq.pVMR0);
98 AssertRelease(pVM->pSession == pSession);
99 AssertRelease(pVM->cCpus == 1);
100#ifdef VBOX_WITH_RAW_MODE
101 AssertRelease(pVM->offVMCPU == RT_UOFFSETOF(VM, aCpus));
102#endif
103 pVM->enmVMState = VMSTATE_CREATED;
104 PVMR0 const pVMR0 = pVM->pVMR0;
105
106 rc = SUPR3SetVMForFastIOCtl(pVM->pVMR0);
107 if (!rc)
108 {
109 /*
110 * Call VMM code with invalid function.
111 */
112 for (i = cIterations; i > 0; i--)
113 {
114 rc = SUPR3CallVMMR0(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, NULL);
115 if (rc != VINF_SUCCESS)
116 {
117 RTPrintf("tstInt: SUPR3CallVMMR0 -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
118 rcRet++;
119 break;
120 }
121 }
122 RTPrintf("tstInt: Performed SUPR3CallVMMR0 %d times (rc=%Rrc)\n", cIterations, rc);
123
124 /*
125 * The fast path.
126 */
127 if (rc == VINF_SUCCESS)
128 {
129 RTTimeNanoTS();
130 uint64_t StartTS = RTTimeNanoTS();
131 uint64_t StartTick = ASMReadTSC();
132 uint64_t MinTicks = UINT64_MAX;
133 for (i = 0; i < 1000000; i++)
134 {
135 uint64_t OneStartTick = ASMReadTSC();
136 rc = SUPR3CallVMMR0Fast(pVMR0, VMMR0_DO_NOP, 0);
137 uint64_t Ticks = ASMReadTSC() - OneStartTick;
138 if (Ticks < MinTicks)
139 MinTicks = Ticks;
140
141 if (RT_UNLIKELY(rc != VINF_SUCCESS))
142 {
143 RTPrintf("tstInt: SUPR3CallVMMR0Fast -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
144 rcRet++;
145 break;
146 }
147 }
148 uint64_t Ticks = ASMReadTSC() - StartTick;
149 uint64_t NanoSecs = RTTimeNanoTS() - StartTS;
150
151 RTPrintf("tstInt: SUPR3CallVMMR0Fast - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n",
152 i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks);
153
154 /*
155 * The ordinary path.
156 */
157 RTTimeNanoTS();
158 StartTS = RTTimeNanoTS();
159 StartTick = ASMReadTSC();
160 MinTicks = UINT64_MAX;
161 for (i = 0; i < 1000000; i++)
162 {
163 uint64_t OneStartTick = ASMReadTSC();
164 rc = SUPR3CallVMMR0Ex(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, 0, NULL);
165 uint64_t OneTicks = ASMReadTSC() - OneStartTick;
166 if (OneTicks < MinTicks)
167 MinTicks = OneTicks;
168
169 if (RT_UNLIKELY(rc != VINF_SUCCESS))
170 {
171 RTPrintf("tstInt: SUPR3CallVMMR0Ex -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
172 rcRet++;
173 break;
174 }
175 }
176 Ticks = ASMReadTSC() - StartTick;
177 NanoSecs = RTTimeNanoTS() - StartTS;
178
179 RTPrintf("tstInt: SUPR3CallVMMR0Ex - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n",
180 i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks);
181 }
182 }
183 else
184 {
185 RTPrintf("tstInt: SUPR3SetVMForFastIOCtl failed: %Rrc\n", rc);
186 rcRet++;
187 }
188
189 rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_GVMM_DESTROY_VM, 0, NULL);
190 if (RT_FAILURE(rc))
191 {
192 RTPrintf("tstInt: VMMR0_DO_GVMM_DESTROY_VM failed: %Rrc\n", rc);
193 rcRet++;
194 }
195 }
196 else
197 {
198 RTPrintf("tstInt: VMMR0_DO_GVMM_CREATE_VM failed\n");
199 rcRet++;
200 }
201
202 /*
203 * Unload VMM.
204 */
205 rc = SUPR3UnloadVMM();
206 if (rc)
207 {
208 RTPrintf("tstInt: SUPR3UnloadVMM failed with rc=%Rrc\n", rc);
209 rcRet++;
210 }
211 }
212 else
213 {
214 RTPrintf("tstInt: SUPR3LoadVMM failed with rc=%Rrc\n", rc);
215 rcRet++;
216 }
217
218 /*
219 * Terminate.
220 */
221 rc = SUPR3Term(false /*fForced*/);
222 rcRet += rc != 0;
223 RTPrintf("tstInt: SUPR3Term -> rc=%Rrc\n", rc);
224 }
225
226 return !!rc;
227}
228
Note: See TracBrowser for help on using the repository browser.

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