VirtualBox

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

Last change on this file since 10450 was 10450, checked in by vboxsync, 17 years ago

Added VMMGetSvnRev() (exported) and changed VMMR0Init and VMMGCInit check the the revision is the same. (We've got private interface between ring-3 and ring-0 and GC, not to mention shared structures, so this check is really long overdue.)

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