VirtualBox

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

Last change on this file since 1184 was 1027, checked in by vboxsync, 18 years ago

Initial GIP change. Missing detection of SMP systems with TSC drift.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.7 KB
Line 
1/* $Id: VMMGC.cpp 1027 2007-02-22 20:29:35Z vboxsync $ */
2/** @file
3 * VMM - Guest Context.
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung 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 * Delay for ~100us.
101 */
102 case VMMGC_DO_TESTCASE_INTERRUPT_MASKING:
103 {
104 uint64_t u64MaxTicks = (SUPGetCpuHzFromGIP(g_pSUPGlobalInfoPage) != ~(uint64_t)0
105 ? SUPGetCpuHzFromGIP(g_pSUPGlobalInfoPage)
106 : _2G)
107 / 10000;
108 uint64_t u64StartTSC = ASMReadTSC();
109 uint64_t u64TicksNow;
110 uint32_t volatile i = 0;
111
112 do
113 {
114 /* waste some time and protect against getting stuck. */
115 for (uint32_t volatile j = 0; j < 1000; j++, i++)
116 if (i > _2G32)
117 return VERR_GENERAL_FAILURE;
118
119 /* check if we're done.*/
120 u64TicksNow = ASMReadTSC() - u64StartTSC;
121 } while (u64TicksNow < u64MaxTicks);
122
123 return VINF_SUCCESS;
124 }
125
126 /*
127 * Trap testcases and unknown operations.
128 */
129 default:
130 if ( uOperation >= VMMGC_DO_TESTCASE_TRAP_FIRST
131 && uOperation < VMMGC_DO_TESTCASE_TRAP_LAST)
132 return vmmGCTest(pVM, uOperation, uArg);
133 return VERR_INVALID_PARAMETER;
134 }
135}
136
137
138/**
139 * Internal GC logger worker: Flush logger.
140 *
141 * @returns VINF_SUCCESS.
142 * @param pLogger The logger instance to flush.
143 * @remark This function must be exported!
144 */
145VMMGCDECL(int) vmmGCLoggerFlush(PRTLOGGERGC pLogger)
146{
147 PVM pVM = &g_VM;
148 NOREF(pLogger);
149 return VMMGCCallHost(pVM, VMMCALLHOST_VMM_LOGGER_FLUSH, 0);
150}
151
152
153/**
154 * Switches from guest context to host context.
155 *
156 * @param pVM The VM handle.
157 * @param rc The status code.
158 */
159VMMGCDECL(void) VMMGCGuestToHost(PVM pVM, int rc)
160{
161 pVM->vmm.s.pfnGCGuestToHost(rc);
162}
163
164
165/**
166 * Calls the ring-3 host code.
167 *
168 * @returns VBox status code of the ring-3 call.
169 * @param pVM The VM handle.
170 * @param enmOperation The operation.
171 * @param uArg The argument to the operation.
172 */
173VMMGCDECL(int) VMMGCCallHost(PVM pVM, VMMCALLHOST enmOperation, uint64_t uArg)
174{
175/** @todo profile this! */
176 pVM->vmm.s.enmCallHostOperation = enmOperation;
177 pVM->vmm.s.u64CallHostArg = uArg;
178 pVM->vmm.s.rcCallHost = VERR_INTERNAL_ERROR;
179 pVM->vmm.s.pfnGCGuestToHost(VINF_VMM_CALL_HOST);
180 return pVM->vmm.s.rcCallHost;
181}
182
183
184/**
185 * Execute the trap testcase.
186 *
187 * There is some common code here, that's why we're collecting them
188 * like this. Odd numbered variation (uArg) are executed with write
189 * protection (WP) enabled.
190 *
191 * @returns VINF_SUCCESS if it was a testcase setup up to continue and did so successfully.
192 * @returns VERR_NOT_IMPLEMENTED if the testcase wasn't implemented.
193 * @returns VERR_GENERAL_FAILURE if the testcase continued when it shouldn't.
194 *
195 * @param pVM The VM handle.
196 * @param uOperation The testcase.
197 * @param uArg The variation. See function description for odd / even details.
198 *
199 * @remark Careful with the trap 08 testcase and WP, it will tripple
200 * fault the box if the TSS, the Trap8 TSS and the fault TSS
201 * GDTE are in pages which are read-only.
202 * See bottom of SELMR3Init().
203 */
204static int vmmGCTest(PVM pVM, unsigned uOperation, unsigned uArg)
205{
206 /*
207 * Set up the testcase.
208 */
209#if 0
210 switch (uOperation)
211 {
212 default:
213 break;
214 }
215#endif
216
217 /*
218 * Enable WP if odd variation.
219 */
220 if (uArg & 1)
221 vmmGCEnableWP();
222
223 /*
224 * Execute the testcase.
225 */
226 int rc = VERR_NOT_IMPLEMENTED;
227 switch (uOperation)
228 {
229 //case VMMGC_DO_TESTCASE_TRAP_0:
230 //case VMMGC_DO_TESTCASE_TRAP_1:
231 //case VMMGC_DO_TESTCASE_TRAP_2:
232
233 case VMMGC_DO_TESTCASE_TRAP_3:
234 {
235 if (uArg <= 1)
236 rc = vmmGCTestTrap3();
237 break;
238 }
239
240 //case VMMGC_DO_TESTCASE_TRAP_4:
241 //case VMMGC_DO_TESTCASE_TRAP_5:
242 //case VMMGC_DO_TESTCASE_TRAP_6:
243 //case VMMGC_DO_TESTCASE_TRAP_7:
244
245 case VMMGC_DO_TESTCASE_TRAP_8:
246 {
247#ifndef DEBUG_bird /** @todo dynamic check that this won't tripple fault... */
248 if (uArg & 1)
249 break;
250#endif
251 if (uArg <= 1)
252 rc = vmmGCTestTrap8();
253 break;
254 }
255
256 //VMMGC_DO_TESTCASE_TRAP_9,
257 //VMMGC_DO_TESTCASE_TRAP_0A,
258 //VMMGC_DO_TESTCASE_TRAP_0B,
259 //VMMGC_DO_TESTCASE_TRAP_0C,
260
261 case VMMGC_DO_TESTCASE_TRAP_0D:
262 {
263 if (uArg <= 1)
264 rc = vmmGCTestTrap0d();
265 break;
266 }
267
268 case VMMGC_DO_TESTCASE_TRAP_0E:
269 {
270 if (uArg <= 1)
271 rc = vmmGCTestTrap0e();
272 else if (uArg == 2 || uArg == 4)
273 {
274 /*
275 * Test the use of a temporary #PF handler.
276 */
277 rc = TRPMGCSetTempHandler(pVM, X86_XCPT_PF, uArg != 4 ? vmmGCTestTmpPFHandler : vmmGCTestTmpPFHandlerCorruptFS);
278 if (VBOX_SUCCESS(rc))
279 {
280 rc = vmmGCTestTrap0e();
281
282 /* in case it didn't fire. */
283 int rc2 = TRPMGCSetTempHandler(pVM, X86_XCPT_PF, NULL);
284 if (VBOX_FAILURE(rc2) && VBOX_SUCCESS(rc))
285 rc = rc2;
286 }
287 }
288 break;
289 }
290 }
291
292 /*
293 * Re-enable WP.
294 */
295 if (uArg & 1)
296 vmmGCDisableWP();
297
298 return rc;
299}
300
301
302/**
303 * Temporary #PF trap handler for the #PF test case.
304 *
305 * @returns VBox status code (appropriate for GC return).
306 * In this context VBOX_SUCCESS means to restart the instruction.
307 * @param pVM VM handle.
308 * @param pRegFrame Trap register frame.
309 */
310static DECLCALLBACK(int) vmmGCTestTmpPFHandler(PVM pVM, PCPUMCTXCORE pRegFrame)
311{
312 if (pRegFrame->eip == (uintptr_t)vmmGCTestTrap0e_FaultEIP)
313 {
314 pRegFrame->eip = (uintptr_t)vmmGCTestTrap0e_ResumeEIP;
315 return VINF_SUCCESS;
316 }
317 return VERR_INTERNAL_ERROR;
318}
319
320
321/**
322 * Temporary #PF trap handler for the #PF test case, this one messes up the fs selector.
323 *
324 * @returns VBox status code (appropriate for GC return).
325 * In this context VBOX_SUCCESS means to restart the instruction.
326 * @param pVM VM handle.
327 * @param pRegFrame Trap register frame.
328 */
329static DECLCALLBACK(int) vmmGCTestTmpPFHandlerCorruptFS(PVM pVM, PCPUMCTXCORE pRegFrame)
330{
331 int rc = vmmGCTestTmpPFHandler(pVM, pRegFrame);
332 pRegFrame->fs = 0x30;
333 return rc;
334}
335
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