VirtualBox

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

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

InnoTek -> innotek: all the headers and comments.

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