VirtualBox

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

Last change on this file since 80305 was 80305, checked in by vboxsync, 5 years ago

REM,VMM,tstInt,Devices: Use VMM_COMMON_DEFS when including vm.h so the layout is always right. bugref:9217

  • 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 80305 2019-08-15 17:35:00Z 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/vmm.h>
33#include <VBox/vmm/gvmm.h>
34#include <VBox/vmm/vm.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#ifdef VBOX_BUGREF_9217
98 AssertRelease(pVM->pVMR0ForCall == CreateVMReq.pVMR0);
99#else
100 AssertRelease(pVM->pVMR0 == CreateVMReq.pVMR0);
101#endif
102 AssertRelease(pVM->pSession == pSession);
103 AssertRelease(pVM->cCpus == 1);
104#ifdef VBOX_WITH_RAW_MODE
105 AssertRelease(pVM->offVMCPU == RT_UOFFSETOF(VM, aCpus));
106#endif
107 pVM->enmVMState = VMSTATE_CREATED;
108 PVMR0 const pVMR0 = CreateVMReq.pVMR0;
109
110 rc = SUPR3SetVMForFastIOCtl(pVMR0);
111 if (!rc)
112 {
113 /*
114 * Call VMM code with invalid function.
115 */
116 for (i = cIterations; i > 0; i--)
117 {
118 rc = SUPR3CallVMMR0(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, NULL);
119 if (rc != VINF_SUCCESS)
120 {
121 RTPrintf("tstInt: SUPR3CallVMMR0 -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
122 rcRet++;
123 break;
124 }
125 }
126 RTPrintf("tstInt: Performed SUPR3CallVMMR0 %d times (rc=%Rrc)\n", cIterations, rc);
127
128 /*
129 * The fast path.
130 */
131 if (rc == VINF_SUCCESS)
132 {
133 RTTimeNanoTS();
134 uint64_t StartTS = RTTimeNanoTS();
135 uint64_t StartTick = ASMReadTSC();
136 uint64_t MinTicks = UINT64_MAX;
137 for (i = 0; i < 1000000; i++)
138 {
139 uint64_t OneStartTick = ASMReadTSC();
140 rc = SUPR3CallVMMR0Fast(pVMR0, VMMR0_DO_NOP, 0);
141 uint64_t Ticks = ASMReadTSC() - OneStartTick;
142 if (Ticks < MinTicks)
143 MinTicks = Ticks;
144
145 if (RT_UNLIKELY(rc != VINF_SUCCESS))
146 {
147 RTPrintf("tstInt: SUPR3CallVMMR0Fast -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
148 rcRet++;
149 break;
150 }
151 }
152 uint64_t Ticks = ASMReadTSC() - StartTick;
153 uint64_t NanoSecs = RTTimeNanoTS() - StartTS;
154
155 RTPrintf("tstInt: SUPR3CallVMMR0Fast - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n",
156 i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks);
157
158 /*
159 * The ordinary path.
160 */
161 RTTimeNanoTS();
162 StartTS = RTTimeNanoTS();
163 StartTick = ASMReadTSC();
164 MinTicks = UINT64_MAX;
165 for (i = 0; i < 1000000; i++)
166 {
167 uint64_t OneStartTick = ASMReadTSC();
168 rc = SUPR3CallVMMR0Ex(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, 0, NULL);
169 uint64_t OneTicks = ASMReadTSC() - OneStartTick;
170 if (OneTicks < MinTicks)
171 MinTicks = OneTicks;
172
173 if (RT_UNLIKELY(rc != VINF_SUCCESS))
174 {
175 RTPrintf("tstInt: SUPR3CallVMMR0Ex -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
176 rcRet++;
177 break;
178 }
179 }
180 Ticks = ASMReadTSC() - StartTick;
181 NanoSecs = RTTimeNanoTS() - StartTS;
182
183 RTPrintf("tstInt: SUPR3CallVMMR0Ex - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n",
184 i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks);
185 }
186 }
187 else
188 {
189 RTPrintf("tstInt: SUPR3SetVMForFastIOCtl failed: %Rrc\n", rc);
190 rcRet++;
191 }
192
193 rc = SUPR3CallVMMR0Ex(pVMR0, 0 /*idCpu*/, VMMR0_DO_GVMM_DESTROY_VM, 0, NULL);
194 if (RT_FAILURE(rc))
195 {
196 RTPrintf("tstInt: VMMR0_DO_GVMM_DESTROY_VM failed: %Rrc\n", rc);
197 rcRet++;
198 }
199 }
200 else
201 {
202 RTPrintf("tstInt: VMMR0_DO_GVMM_CREATE_VM failed\n");
203 rcRet++;
204 }
205
206 /*
207 * Unload VMM.
208 */
209 rc = SUPR3UnloadVMM();
210 if (rc)
211 {
212 RTPrintf("tstInt: SUPR3UnloadVMM failed with rc=%Rrc\n", rc);
213 rcRet++;
214 }
215 }
216 else
217 {
218 RTPrintf("tstInt: SUPR3LoadVMM failed with rc=%Rrc\n", rc);
219 rcRet++;
220 }
221
222 /*
223 * Terminate.
224 */
225 rc = SUPR3Term(false /*fForced*/);
226 rcRet += rc != 0;
227 RTPrintf("tstInt: SUPR3Term -> rc=%Rrc\n", rc);
228 }
229
230 return !!rc;
231}
232
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