VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMGC/VMMGC.cpp@ 17305

Last change on this file since 17305 was 17305, checked in by vboxsync, 16 years ago

VMM: Register %R[pgmpage] and %R[pgmramrange] (logging builds only).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.0 KB
Line 
1/* $Id: VMMGC.cpp 17305 2009-03-03 18:19:29Z vboxsync $ */
2/** @file
3 * VMM - Raw-mode Context.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_VMM
27#include <VBox/vmm.h>
28#include <VBox/trpm.h>
29#include <VBox/pgm.h>
30#include "VMMInternal.h"
31#include <VBox/vm.h>
32#include <VBox/sup.h>
33#include <VBox/err.h>
34#include <VBox/log.h>
35#include <iprt/asm.h>
36#include <iprt/assert.h>
37#include <iprt/initterm.h>
38
39
40/*******************************************************************************
41* Global Variables *
42*******************************************************************************/
43/** Default logger instance. */
44extern "C" DECLIMPORT(RTLOGGERRC) g_Logger;
45extern "C" DECLIMPORT(RTLOGGERRC) g_RelLogger;
46
47
48/*******************************************************************************
49* Internal Functions *
50*******************************************************************************/
51static int vmmGCTest(PVM pVM, unsigned uOperation, unsigned uArg);
52static DECLCALLBACK(int) vmmGCTestTmpPFHandler(PVM pVM, PCPUMCTXCORE pRegFrame);
53static DECLCALLBACK(int) vmmGCTestTmpPFHandlerCorruptFS(PVM pVM, PCPUMCTXCORE pRegFrame);
54
55
56
57/**
58 * The GC entry point.
59 *
60 * @returns VBox status code.
61 * @param pVM The VM to operate on.
62 * @param uOperation Which operation to execute (VMMGCOPERATION).
63 * @param uArg Argument to that operation.
64 */
65VMMRCDECL(int) VMMGCEntry(PVM pVM, unsigned uOperation, unsigned uArg, ...)
66{
67 /* todo */
68 switch (uOperation)
69 {
70 /*
71 * Init RC modules.
72 */
73 case VMMGC_DO_VMMGC_INIT:
74 {
75 /*
76 * Validate the svn revision (uArg).
77 */
78 if (uArg != VMMGetSvnRev())
79 return VERR_VERSION_MISMATCH;
80
81 /*
82 * Initialize the runtime.
83 * (The program timestamp is found in the elipsis.)
84 */
85 va_list va;
86 va_start(va, uArg);
87 uint64_t u64TS = va_arg(va, uint64_t);
88 va_end(va);
89
90 int rc = RTRCInit(u64TS);
91 Log(("VMMGCEntry: VMMGC_DO_VMMGC_INIT - uArg=%u (svn revision) u64TS=%RX64; rc=%Rrc\n", uArg, u64TS, rc));
92 AssertRCReturn(rc, rc);
93
94 rc = PGMRegisterStringFormatTypes();
95 AssertRCReturn(rc, rc);
96
97 return VINF_SUCCESS;
98 }
99
100 /*
101 * Testcase which is used to test interrupt forwarding.
102 * It spins for a while with interrupts enabled.
103 */
104 case VMMGC_DO_TESTCASE_HYPER_INTERRUPT:
105 {
106 uint32_t volatile i = 0;
107 ASMIntEnable();
108 while (i < _2G32)
109 i++;
110 ASMIntDisable();
111 return 0;
112 }
113
114 /*
115 * Testcase which simply returns, this is used for
116 * profiling of the switcher.
117 */
118 case VMMGC_DO_TESTCASE_NOP:
119 return 0;
120
121 /*
122 * Testcase executes a privileged instruction to force a world switch. (in both SVM & VMX)
123 */
124 case VMMGC_DO_TESTCASE_HWACCM_NOP:
125 ASMRdMsr_Low(MSR_IA32_SYSENTER_CS);
126 return 0;
127
128 /*
129 * Delay for ~100us.
130 */
131 case VMMGC_DO_TESTCASE_INTERRUPT_MASKING:
132 {
133 uint64_t u64MaxTicks = (SUPGetCpuHzFromGIP(g_pSUPGlobalInfoPage) != ~(uint64_t)0
134 ? SUPGetCpuHzFromGIP(g_pSUPGlobalInfoPage)
135 : _2G)
136 / 10000;
137 uint64_t u64StartTSC = ASMReadTSC();
138 uint64_t u64TicksNow;
139 uint32_t volatile i = 0;
140
141 do
142 {
143 /* waste some time and protect against getting stuck. */
144 for (uint32_t volatile j = 0; j < 1000; j++, i++)
145 if (i > _2G32)
146 return VERR_GENERAL_FAILURE;
147
148 /* check if we're done.*/
149 u64TicksNow = ASMReadTSC() - u64StartTSC;
150 } while (u64TicksNow < u64MaxTicks);
151
152 return VINF_SUCCESS;
153 }
154
155 /*
156 * Trap testcases and unknown operations.
157 */
158 default:
159 if ( uOperation >= VMMGC_DO_TESTCASE_TRAP_FIRST
160 && uOperation < VMMGC_DO_TESTCASE_TRAP_LAST)
161 return vmmGCTest(pVM, uOperation, uArg);
162 return VERR_INVALID_PARAMETER;
163 }
164}
165
166
167/**
168 * Internal RC logger worker: Flush logger.
169 *
170 * @returns VINF_SUCCESS.
171 * @param pLogger The logger instance to flush.
172 * @remark This function must be exported!
173 */
174VMMRCDECL(int) vmmGCLoggerFlush(PRTLOGGERRC pLogger)
175{
176 PVM pVM = &g_VM;
177 NOREF(pLogger);
178 return VMMGCCallHost(pVM, VMMCALLHOST_VMM_LOGGER_FLUSH, 0);
179}
180
181
182/**
183 * Disables the GC logger temporarily
184 *
185 * @param pVM The VM handle.
186 */
187VMMRCDECL(void) VMMGCLogDisable(PVM pVM)
188{
189 if (pVM->vmm.s.pRCLoggerRC)
190 pVM->vmm.s.pRCLoggerRC->fFlags |= RTLOGFLAGS_DISABLED;
191}
192
193
194/**
195 * Enables the GC logger again
196 *
197 * @param pVM The VM handle.
198 */
199VMMRCDECL(void) VMMGCLogEnable(PVM pVM)
200{
201 if (pVM->vmm.s.pRCLoggerRC)
202 pVM->vmm.s.pRCLoggerRC->fFlags &= ~RTLOGFLAGS_DISABLED;
203}
204
205
206/**
207 * Switches from guest context to host context.
208 *
209 * @param pVM The VM handle.
210 * @param rc The status code.
211 */
212VMMRCDECL(void) VMMGCGuestToHost(PVM pVM, int rc)
213{
214 pVM->vmm.s.pfnGuestToHostRC(rc);
215}
216
217
218/**
219 * Calls the ring-3 host code.
220 *
221 * @returns VBox status code of the ring-3 call.
222 * @param pVM The VM handle.
223 * @param enmOperation The operation.
224 * @param uArg The argument to the operation.
225 */
226VMMRCDECL(int) VMMGCCallHost(PVM pVM, VMMCALLHOST enmOperation, uint64_t uArg)
227{
228/** @todo profile this! */
229 pVM->vmm.s.enmCallHostOperation = enmOperation;
230 pVM->vmm.s.u64CallHostArg = uArg;
231 pVM->vmm.s.rcCallHost = VERR_INTERNAL_ERROR;
232 pVM->vmm.s.pfnGuestToHostRC(VINF_VMM_CALL_HOST);
233 return pVM->vmm.s.rcCallHost;
234}
235
236
237/**
238 * Execute the trap testcase.
239 *
240 * There is some common code here, that's why we're collecting them
241 * like this. Odd numbered variation (uArg) are executed with write
242 * protection (WP) enabled.
243 *
244 * @returns VINF_SUCCESS if it was a testcase setup up to continue and did so successfully.
245 * @returns VERR_NOT_IMPLEMENTED if the testcase wasn't implemented.
246 * @returns VERR_GENERAL_FAILURE if the testcase continued when it shouldn't.
247 *
248 * @param pVM The VM handle.
249 * @param uOperation The testcase.
250 * @param uArg The variation. See function description for odd / even details.
251 *
252 * @remark Careful with the trap 08 testcase and WP, it will tripple
253 * fault the box if the TSS, the Trap8 TSS and the fault TSS
254 * GDTE are in pages which are read-only.
255 * See bottom of SELMR3Init().
256 */
257static int vmmGCTest(PVM pVM, unsigned uOperation, unsigned uArg)
258{
259 /*
260 * Set up the testcase.
261 */
262#if 0
263 switch (uOperation)
264 {
265 default:
266 break;
267 }
268#endif
269
270 /*
271 * Enable WP if odd variation.
272 */
273 if (uArg & 1)
274 vmmGCEnableWP();
275
276 /*
277 * Execute the testcase.
278 */
279 int rc = VERR_NOT_IMPLEMENTED;
280 switch (uOperation)
281 {
282 //case VMMGC_DO_TESTCASE_TRAP_0:
283 //case VMMGC_DO_TESTCASE_TRAP_1:
284 //case VMMGC_DO_TESTCASE_TRAP_2:
285
286 case VMMGC_DO_TESTCASE_TRAP_3:
287 {
288 if (uArg <= 1)
289 rc = vmmGCTestTrap3();
290 break;
291 }
292
293 //case VMMGC_DO_TESTCASE_TRAP_4:
294 //case VMMGC_DO_TESTCASE_TRAP_5:
295 //case VMMGC_DO_TESTCASE_TRAP_6:
296 //case VMMGC_DO_TESTCASE_TRAP_7:
297
298 case VMMGC_DO_TESTCASE_TRAP_8:
299 {
300#ifndef DEBUG_bird /** @todo dynamic check that this won't tripple fault... */
301 if (uArg & 1)
302 break;
303#endif
304 if (uArg <= 1)
305 rc = vmmGCTestTrap8();
306 break;
307 }
308
309 //VMMGC_DO_TESTCASE_TRAP_9,
310 //VMMGC_DO_TESTCASE_TRAP_0A,
311 //VMMGC_DO_TESTCASE_TRAP_0B,
312 //VMMGC_DO_TESTCASE_TRAP_0C,
313
314 case VMMGC_DO_TESTCASE_TRAP_0D:
315 {
316 if (uArg <= 1)
317 rc = vmmGCTestTrap0d();
318 break;
319 }
320
321 case VMMGC_DO_TESTCASE_TRAP_0E:
322 {
323 if (uArg <= 1)
324 rc = vmmGCTestTrap0e();
325 else if (uArg == 2 || uArg == 4)
326 {
327 /*
328 * Test the use of a temporary #PF handler.
329 */
330 rc = TRPMGCSetTempHandler(pVM, X86_XCPT_PF, uArg != 4 ? vmmGCTestTmpPFHandler : vmmGCTestTmpPFHandlerCorruptFS);
331 if (RT_SUCCESS(rc))
332 {
333 rc = vmmGCTestTrap0e();
334
335 /* in case it didn't fire. */
336 int rc2 = TRPMGCSetTempHandler(pVM, X86_XCPT_PF, NULL);
337 if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
338 rc = rc2;
339 }
340 }
341 break;
342 }
343 }
344
345 /*
346 * Re-enable WP.
347 */
348 if (uArg & 1)
349 vmmGCDisableWP();
350
351 return rc;
352}
353
354
355/**
356 * Temporary #PF trap handler for the #PF test case.
357 *
358 * @returns VBox status code (appropriate for GC return).
359 * In this context RT_SUCCESS means to restart the instruction.
360 * @param pVM VM handle.
361 * @param pRegFrame Trap register frame.
362 */
363static DECLCALLBACK(int) vmmGCTestTmpPFHandler(PVM pVM, PCPUMCTXCORE pRegFrame)
364{
365 if (pRegFrame->eip == (uintptr_t)vmmGCTestTrap0e_FaultEIP)
366 {
367 pRegFrame->eip = (uintptr_t)vmmGCTestTrap0e_ResumeEIP;
368 return VINF_SUCCESS;
369 }
370 return VERR_INTERNAL_ERROR;
371}
372
373
374/**
375 * Temporary #PF trap handler for the #PF test case, this one messes up the fs selector.
376 *
377 * @returns VBox status code (appropriate for GC return).
378 * In this context RT_SUCCESS means to restart the instruction.
379 * @param pVM VM handle.
380 * @param pRegFrame Trap register frame.
381 */
382static DECLCALLBACK(int) vmmGCTestTmpPFHandlerCorruptFS(PVM pVM, PCPUMCTXCORE pRegFrame)
383{
384 int rc = vmmGCTestTmpPFHandler(pVM, pRegFrame);
385 pRegFrame->fs = 0x30;
386 return rc;
387}
388
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