VirtualBox

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

Last change on this file since 86719 was 85506, checked in by vboxsync, 4 years ago

SUP: Added a PRTERRINFO parameter to SUPR3LoadVMM. bugref:9801

  • 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 85506 2020-07-29 10:07:17Z vboxsync $ */
2/** @file
3 * SUP Testcase - Test the interrupt gate feature of the support library.
4 */
5
6/*
7 * Copyright (C) 2006-2020 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 RTERRINFOSTATIC ErrInfo;
80 rc = SUPR3LoadVMM(szAbsFile, RTErrInfoInitStatic(&ErrInfo));
81 if (RT_SUCCESS(rc))
82 {
83 /*
84 * Create a tiny dummy VM so we can do NOP calls into it using the fast I/O control path.
85 */
86 GVMMCREATEVMREQ CreateVMReq;
87 CreateVMReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
88 CreateVMReq.Hdr.cbReq = sizeof(CreateVMReq);
89 CreateVMReq.pSession = pSession;
90 CreateVMReq.pVMR0 = NIL_RTR0PTR;
91 CreateVMReq.pVMR3 = NULL;
92 CreateVMReq.cCpus = 1;
93 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_GVMM_CREATE_VM, 0, &CreateVMReq.Hdr);
94 if (RT_SUCCESS(rc))
95 {
96 PVM pVM = CreateVMReq.pVMR3;
97 AssertRelease(VALID_PTR(pVM));
98 AssertRelease(pVM->pVMR0ForCall == CreateVMReq.pVMR0);
99 AssertRelease(pVM->pSession == pSession);
100 AssertRelease(pVM->cCpus == 1);
101 pVM->enmVMState = VMSTATE_CREATED;
102 PVMR0 const pVMR0 = CreateVMReq.pVMR0;
103
104 rc = SUPR3SetVMForFastIOCtl(pVMR0);
105 if (!rc)
106 {
107 /*
108 * Call VMM code with invalid function.
109 */
110 for (i = cIterations; i > 0; i--)
111 {
112 rc = SUPR3CallVMMR0(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, NULL);
113 if (rc != VINF_SUCCESS)
114 {
115 RTPrintf("tstInt: SUPR3CallVMMR0 -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
116 rcRet++;
117 break;
118 }
119 }
120 RTPrintf("tstInt: Performed SUPR3CallVMMR0 %d times (rc=%Rrc)\n", cIterations, rc);
121
122 /*
123 * The fast path.
124 */
125 if (rc == VINF_SUCCESS)
126 {
127 RTTimeNanoTS();
128 uint64_t StartTS = RTTimeNanoTS();
129 uint64_t StartTick = ASMReadTSC();
130 uint64_t MinTicks = UINT64_MAX;
131 for (i = 0; i < 1000000; i++)
132 {
133 uint64_t OneStartTick = ASMReadTSC();
134 rc = SUPR3CallVMMR0Fast(pVMR0, VMMR0_DO_NOP, 0);
135 uint64_t Ticks = ASMReadTSC() - OneStartTick;
136 if (Ticks < MinTicks)
137 MinTicks = Ticks;
138
139 if (RT_UNLIKELY(rc != VINF_SUCCESS))
140 {
141 RTPrintf("tstInt: SUPR3CallVMMR0Fast -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
142 rcRet++;
143 break;
144 }
145 }
146 uint64_t Ticks = ASMReadTSC() - StartTick;
147 uint64_t NanoSecs = RTTimeNanoTS() - StartTS;
148
149 RTPrintf("tstInt: SUPR3CallVMMR0Fast - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n",
150 i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks);
151
152 /*
153 * The ordinary path.
154 */
155 RTTimeNanoTS();
156 StartTS = RTTimeNanoTS();
157 StartTick = ASMReadTSC();
158 MinTicks = UINT64_MAX;
159 for (i = 0; i < 1000000; i++)
160 {
161 uint64_t OneStartTick = ASMReadTSC();
162 rc = SUPR3CallVMMR0Ex(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, 0, NULL);
163 uint64_t OneTicks = ASMReadTSC() - OneStartTick;
164 if (OneTicks < MinTicks)
165 MinTicks = OneTicks;
166
167 if (RT_UNLIKELY(rc != VINF_SUCCESS))
168 {
169 RTPrintf("tstInt: SUPR3CallVMMR0Ex -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
170 rcRet++;
171 break;
172 }
173 }
174 Ticks = ASMReadTSC() - StartTick;
175 NanoSecs = RTTimeNanoTS() - StartTS;
176
177 RTPrintf("tstInt: SUPR3CallVMMR0Ex - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n",
178 i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks);
179 }
180 }
181 else
182 {
183 RTPrintf("tstInt: SUPR3SetVMForFastIOCtl failed: %Rrc\n", rc);
184 rcRet++;
185 }
186
187 rc = SUPR3CallVMMR0Ex(pVMR0, 0 /*idCpu*/, VMMR0_DO_GVMM_DESTROY_VM, 0, NULL);
188 if (RT_FAILURE(rc))
189 {
190 RTPrintf("tstInt: VMMR0_DO_GVMM_DESTROY_VM failed: %Rrc\n", rc);
191 rcRet++;
192 }
193 }
194 else
195 {
196 RTPrintf("tstInt: VMMR0_DO_GVMM_CREATE_VM failed\n");
197 rcRet++;
198 }
199
200 /*
201 * Unload VMM.
202 */
203 rc = SUPR3UnloadVMM();
204 if (rc)
205 {
206 RTPrintf("tstInt: SUPR3UnloadVMM failed with rc=%Rrc\n", rc);
207 rcRet++;
208 }
209 }
210 else
211 {
212 RTPrintf("tstInt: SUPR3LoadVMM failed with rc=%Rrc%#RTeim\n", rc, &ErrInfo.Core);
213 rcRet++;
214 }
215
216 /*
217 * Terminate.
218 */
219 rc = SUPR3Term(false /*fForced*/);
220 rcRet += rc != 0;
221 RTPrintf("tstInt: SUPR3Term -> rc=%Rrc\n", rc);
222 }
223
224 return !!rc;
225}
226
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