VirtualBox

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

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

tstInt: Eliminating the VBOX_BUGREF_9217 preprocessor macro. bugref:9217

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
Line 
1/* $Id: tstInt.cpp 80332 2019-08-16 20:07:11Z 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 AssertRelease(pVM->pVMR0ForCall == CreateVMReq.pVMR0);
98 AssertRelease(pVM->pSession == pSession);
99 AssertRelease(pVM->cCpus == 1);
100 pVM->enmVMState = VMSTATE_CREATED;
101 PVMR0 const pVMR0 = CreateVMReq.pVMR0;
102
103 rc = SUPR3SetVMForFastIOCtl(pVMR0);
104 if (!rc)
105 {
106 /*
107 * Call VMM code with invalid function.
108 */
109 for (i = cIterations; i > 0; i--)
110 {
111 rc = SUPR3CallVMMR0(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, NULL);
112 if (rc != VINF_SUCCESS)
113 {
114 RTPrintf("tstInt: SUPR3CallVMMR0 -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
115 rcRet++;
116 break;
117 }
118 }
119 RTPrintf("tstInt: Performed SUPR3CallVMMR0 %d times (rc=%Rrc)\n", cIterations, rc);
120
121 /*
122 * The fast path.
123 */
124 if (rc == VINF_SUCCESS)
125 {
126 RTTimeNanoTS();
127 uint64_t StartTS = RTTimeNanoTS();
128 uint64_t StartTick = ASMReadTSC();
129 uint64_t MinTicks = UINT64_MAX;
130 for (i = 0; i < 1000000; i++)
131 {
132 uint64_t OneStartTick = ASMReadTSC();
133 rc = SUPR3CallVMMR0Fast(pVMR0, VMMR0_DO_NOP, 0);
134 uint64_t Ticks = ASMReadTSC() - OneStartTick;
135 if (Ticks < MinTicks)
136 MinTicks = Ticks;
137
138 if (RT_UNLIKELY(rc != VINF_SUCCESS))
139 {
140 RTPrintf("tstInt: SUPR3CallVMMR0Fast -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
141 rcRet++;
142 break;
143 }
144 }
145 uint64_t Ticks = ASMReadTSC() - StartTick;
146 uint64_t NanoSecs = RTTimeNanoTS() - StartTS;
147
148 RTPrintf("tstInt: SUPR3CallVMMR0Fast - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n",
149 i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks);
150
151 /*
152 * The ordinary 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 = SUPR3CallVMMR0Ex(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, 0, NULL);
162 uint64_t OneTicks = ASMReadTSC() - OneStartTick;
163 if (OneTicks < MinTicks)
164 MinTicks = OneTicks;
165
166 if (RT_UNLIKELY(rc != VINF_SUCCESS))
167 {
168 RTPrintf("tstInt: SUPR3CallVMMR0Ex -> rc=%Rrc 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: SUPR3CallVMMR0Ex - %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 }
179 }
180 else
181 {
182 RTPrintf("tstInt: SUPR3SetVMForFastIOCtl failed: %Rrc\n", rc);
183 rcRet++;
184 }
185
186 rc = SUPR3CallVMMR0Ex(pVMR0, 0 /*idCpu*/, VMMR0_DO_GVMM_DESTROY_VM, 0, NULL);
187 if (RT_FAILURE(rc))
188 {
189 RTPrintf("tstInt: VMMR0_DO_GVMM_DESTROY_VM failed: %Rrc\n", rc);
190 rcRet++;
191 }
192 }
193 else
194 {
195 RTPrintf("tstInt: VMMR0_DO_GVMM_CREATE_VM failed\n");
196 rcRet++;
197 }
198
199 /*
200 * Unload VMM.
201 */
202 rc = SUPR3UnloadVMM();
203 if (rc)
204 {
205 RTPrintf("tstInt: SUPR3UnloadVMM failed with rc=%Rrc\n", rc);
206 rcRet++;
207 }
208 }
209 else
210 {
211 RTPrintf("tstInt: SUPR3LoadVMM failed with rc=%Rrc\n", rc);
212 rcRet++;
213 }
214
215 /*
216 * Terminate.
217 */
218 rc = SUPR3Term(false /*fForced*/);
219 rcRet += rc != 0;
220 RTPrintf("tstInt: SUPR3Term -> rc=%Rrc\n", rc);
221 }
222
223 return !!rc;
224}
225
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