VirtualBox

source: vbox/trunk/src/VBox/VMM/EM.cpp@ 14672

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

Reschedule right away to start in the right state. Gets rid of lost interrupts when restoring hwaccm enabled states

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 152.0 KB
Line 
1/* $Id: EM.cpp 14570 2008-11-25 13:09:30Z vboxsync $ */
2/** @file
3 * EM - Execution Monitor / Manager.
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/** @page pg_em EM - The Execution Monitor / Manager
23 *
24 * The Execution Monitor/Manager is responsible for running the VM, scheduling
25 * the right kind of execution (Raw-mode, Hardware Assisted, Recompiled or
26 * Interpreted), and keeping the CPU states in sync. The function
27 * EMR3ExecuteVM() is the 'main-loop' of the VM, while each of the execution
28 * modes has different inner loops (emR3RawExecute, emR3HwAccExecute, and
29 * emR3RemExecute).
30 *
31 * The interpreted execution is only used to avoid switching between
32 * raw-mode/hwaccm and the recompiler when fielding virtualization traps/faults.
33 * The interpretation is thus implemented as part of EM.
34 *
35 * @see grp_em
36 */
37
38/*******************************************************************************
39* Header Files *
40*******************************************************************************/
41#define LOG_GROUP LOG_GROUP_EM
42#include <VBox/em.h>
43#include <VBox/vmm.h>
44#ifdef VBOX_WITH_VMI
45# include <VBox/parav.h>
46#endif
47#include <VBox/patm.h>
48#include <VBox/csam.h>
49#include <VBox/selm.h>
50#include <VBox/trpm.h>
51#include <VBox/iom.h>
52#include <VBox/dbgf.h>
53#include <VBox/pgm.h>
54#include <VBox/rem.h>
55#include <VBox/tm.h>
56#include <VBox/mm.h>
57#include <VBox/ssm.h>
58#include <VBox/pdmapi.h>
59#include <VBox/pdmcritsect.h>
60#include <VBox/pdmqueue.h>
61#include <VBox/hwaccm.h>
62#include <VBox/patm.h>
63#include "EMInternal.h"
64#include <VBox/vm.h>
65#include <VBox/cpumdis.h>
66#include <VBox/dis.h>
67#include <VBox/disopcode.h>
68#include <VBox/dbgf.h>
69
70#include <VBox/log.h>
71#include <iprt/thread.h>
72#include <iprt/assert.h>
73#include <iprt/asm.h>
74#include <iprt/semaphore.h>
75#include <iprt/string.h>
76#include <iprt/avl.h>
77#include <iprt/stream.h>
78#include <VBox/param.h>
79#include <VBox/err.h>
80
81
82/*******************************************************************************
83* Internal Functions *
84*******************************************************************************/
85static DECLCALLBACK(int) emR3Save(PVM pVM, PSSMHANDLE pSSM);
86static DECLCALLBACK(int) emR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version);
87static int emR3Debug(PVM pVM, int rc);
88static int emR3RemStep(PVM pVM);
89static int emR3RemExecute(PVM pVM, bool *pfFFDone);
90static int emR3RawResumeHyper(PVM pVM);
91static int emR3RawStep(PVM pVM);
92DECLINLINE(int) emR3RawHandleRC(PVM pVM, PCPUMCTX pCtx, int rc);
93DECLINLINE(int) emR3RawUpdateForceFlag(PVM pVM, PCPUMCTX pCtx, int rc);
94static int emR3RawForcedActions(PVM pVM, PCPUMCTX pCtx);
95static int emR3RawExecute(PVM pVM, bool *pfFFDone);
96DECLINLINE(int) emR3RawExecuteInstruction(PVM pVM, const char *pszPrefix, int rcGC = VINF_SUCCESS);
97static int emR3HighPriorityPostForcedActions(PVM pVM, int rc);
98static int emR3ForcedActions(PVM pVM, int rc);
99static int emR3RawGuestTrap(PVM pVM);
100static int emR3PatchTrap(PVM pVM, PCPUMCTX pCtx, int gcret);
101
102
103/**
104 * Initializes the EM.
105 *
106 * @returns VBox status code.
107 * @param pVM The VM to operate on.
108 */
109VMMR3DECL(int) EMR3Init(PVM pVM)
110{
111 LogFlow(("EMR3Init\n"));
112 /*
113 * Assert alignment and sizes.
114 */
115 AssertRelease(!(RT_OFFSETOF(VM, em.s) & 31));
116 AssertRelease(sizeof(pVM->em.s) <= sizeof(pVM->em.padding));
117 AssertReleaseMsg(sizeof(pVM->em.s.u.FatalLongJump) <= sizeof(pVM->em.s.u.achPaddingFatalLongJump),
118 ("%d bytes, padding %d\n", sizeof(pVM->em.s.u.FatalLongJump), sizeof(pVM->em.s.u.achPaddingFatalLongJump)));
119
120 /*
121 * Init the structure.
122 */
123 pVM->em.s.offVM = RT_OFFSETOF(VM, em.s);
124 int rc = CFGMR3QueryBool(CFGMR3GetRoot(pVM), "RawR3Enabled", &pVM->fRawR3Enabled);
125 if (RT_FAILURE(rc))
126 pVM->fRawR3Enabled = true;
127 rc = CFGMR3QueryBool(CFGMR3GetRoot(pVM), "RawR0Enabled", &pVM->fRawR0Enabled);
128 if (RT_FAILURE(rc))
129 pVM->fRawR0Enabled = true;
130 Log(("EMR3Init: fRawR3Enabled=%d fRawR0Enabled=%d\n", pVM->fRawR3Enabled, pVM->fRawR0Enabled));
131 pVM->em.s.enmState = EMSTATE_NONE;
132 pVM->em.s.fForceRAW = false;
133
134 pVM->em.s.pCtx = CPUMQueryGuestCtxPtr(pVM);
135 pVM->em.s.pPatmGCState = PATMR3QueryGCStateHC(pVM);
136 AssertMsg(pVM->em.s.pPatmGCState, ("PATMR3QueryGCStateHC failed!\n"));
137
138 /*
139 * Saved state.
140 */
141 rc = SSMR3RegisterInternal(pVM, "em", 0, EM_SAVED_STATE_VERSION, 16,
142 NULL, emR3Save, NULL,
143 NULL, emR3Load, NULL);
144 if (RT_FAILURE(rc))
145 return rc;
146
147 /*
148 * Statistics.
149 */
150#ifdef VBOX_WITH_STATISTICS
151 PEMSTATS pStats;
152 rc = MMHyperAlloc(pVM, sizeof(*pStats), 0, MM_TAG_EM, (void **)&pStats);
153 if (RT_FAILURE(rc))
154 return rc;
155 pVM->em.s.pStatsR3 = pStats;
156 pVM->em.s.pStatsR0 = MMHyperR3ToR0(pVM, pStats);
157 pVM->em.s.pStatsRC = MMHyperR3ToRC(pVM, pStats);
158
159 STAM_REG(pVM, &pStats->StatRZEmulate, STAMTYPE_PROFILE, "/EM/RZ/Interpret", STAMUNIT_TICKS_PER_CALL, "Profiling of EMInterpretInstruction.");
160 STAM_REG(pVM, &pStats->StatR3Emulate, STAMTYPE_PROFILE, "/EM/R3/Interpret", STAMUNIT_TICKS_PER_CALL, "Profiling of EMInterpretInstruction.");
161
162 STAM_REG(pVM, &pStats->StatRZInterpretSucceeded, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success", STAMUNIT_OCCURENCES, "The number of times an instruction was successfully interpreted.");
163 STAM_REG(pVM, &pStats->StatR3InterpretSucceeded, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success", STAMUNIT_OCCURENCES, "The number of times an instruction was successfully interpreted.");
164
165 STAM_REG_USED(pVM, &pStats->StatRZAnd, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/And", STAMUNIT_OCCURENCES, "The number of times AND was successfully interpreted.");
166 STAM_REG_USED(pVM, &pStats->StatR3And, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/And", STAMUNIT_OCCURENCES, "The number of times AND was successfully interpreted.");
167 STAM_REG_USED(pVM, &pStats->StatRZAdd, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Add", STAMUNIT_OCCURENCES, "The number of times ADD was successfully interpreted.");
168 STAM_REG_USED(pVM, &pStats->StatR3Add, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Add", STAMUNIT_OCCURENCES, "The number of times ADD was successfully interpreted.");
169 STAM_REG_USED(pVM, &pStats->StatRZAdc, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Adc", STAMUNIT_OCCURENCES, "The number of times ADC was successfully interpreted.");
170 STAM_REG_USED(pVM, &pStats->StatR3Adc, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Adc", STAMUNIT_OCCURENCES, "The number of times ADC was successfully interpreted.");
171 STAM_REG_USED(pVM, &pStats->StatRZSub, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Sub", STAMUNIT_OCCURENCES, "The number of times SUB was successfully interpreted.");
172 STAM_REG_USED(pVM, &pStats->StatR3Sub, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Sub", STAMUNIT_OCCURENCES, "The number of times SUB was successfully interpreted.");
173 STAM_REG_USED(pVM, &pStats->StatRZCpuId, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/CpuId", STAMUNIT_OCCURENCES, "The number of times CPUID was successfully interpreted.");
174 STAM_REG_USED(pVM, &pStats->StatR3CpuId, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/CpuId", STAMUNIT_OCCURENCES, "The number of times CPUID was successfully interpreted.");
175 STAM_REG_USED(pVM, &pStats->StatRZDec, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Dec", STAMUNIT_OCCURENCES, "The number of times DEC was successfully interpreted.");
176 STAM_REG_USED(pVM, &pStats->StatR3Dec, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Dec", STAMUNIT_OCCURENCES, "The number of times DEC was successfully interpreted.");
177 STAM_REG_USED(pVM, &pStats->StatRZHlt, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Hlt", STAMUNIT_OCCURENCES, "The number of times HLT was successfully interpreted.");
178 STAM_REG_USED(pVM, &pStats->StatR3Hlt, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Hlt", STAMUNIT_OCCURENCES, "The number of times HLT was successfully interpreted.");
179 STAM_REG_USED(pVM, &pStats->StatRZInc, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Inc", STAMUNIT_OCCURENCES, "The number of times INC was successfully interpreted.");
180 STAM_REG_USED(pVM, &pStats->StatR3Inc, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Inc", STAMUNIT_OCCURENCES, "The number of times INC was successfully interpreted.");
181 STAM_REG_USED(pVM, &pStats->StatRZInvlPg, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Invlpg", STAMUNIT_OCCURENCES, "The number of times INVLPG was successfully interpreted.");
182 STAM_REG_USED(pVM, &pStats->StatR3InvlPg, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Invlpg", STAMUNIT_OCCURENCES, "The number of times INVLPG was successfully interpreted.");
183 STAM_REG_USED(pVM, &pStats->StatRZIret, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Iret", STAMUNIT_OCCURENCES, "The number of times IRET was successfully interpreted.");
184 STAM_REG_USED(pVM, &pStats->StatR3Iret, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Iret", STAMUNIT_OCCURENCES, "The number of times IRET was successfully interpreted.");
185 STAM_REG_USED(pVM, &pStats->StatRZLLdt, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/LLdt", STAMUNIT_OCCURENCES, "The number of times LLDT was successfully interpreted.");
186 STAM_REG_USED(pVM, &pStats->StatR3LLdt, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/LLdt", STAMUNIT_OCCURENCES, "The number of times LLDT was successfully interpreted.");
187 STAM_REG_USED(pVM, &pStats->StatRZLIdt, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/LIdt", STAMUNIT_OCCURENCES, "The number of times LIDT was successfully interpreted.");
188 STAM_REG_USED(pVM, &pStats->StatR3LIdt, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/LIdt", STAMUNIT_OCCURENCES, "The number of times LIDT was successfully interpreted.");
189 STAM_REG_USED(pVM, &pStats->StatRZLGdt, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/LGdt", STAMUNIT_OCCURENCES, "The number of times LGDT was successfully interpreted.");
190 STAM_REG_USED(pVM, &pStats->StatR3LGdt, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/LGdt", STAMUNIT_OCCURENCES, "The number of times LGDT was successfully interpreted.");
191 STAM_REG_USED(pVM, &pStats->StatRZMov, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Mov", STAMUNIT_OCCURENCES, "The number of times MOV was successfully interpreted.");
192 STAM_REG_USED(pVM, &pStats->StatR3Mov, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Mov", STAMUNIT_OCCURENCES, "The number of times MOV was successfully interpreted.");
193 STAM_REG_USED(pVM, &pStats->StatRZMovCRx, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/MovCRx", STAMUNIT_OCCURENCES, "The number of times MOV CRx was successfully interpreted.");
194 STAM_REG_USED(pVM, &pStats->StatR3MovCRx, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/MovCRx", STAMUNIT_OCCURENCES, "The number of times MOV CRx was successfully interpreted.");
195 STAM_REG_USED(pVM, &pStats->StatRZMovDRx, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/MovDRx", STAMUNIT_OCCURENCES, "The number of times MOV DRx was successfully interpreted.");
196 STAM_REG_USED(pVM, &pStats->StatR3MovDRx, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/MovDRx", STAMUNIT_OCCURENCES, "The number of times MOV DRx was successfully interpreted.");
197 STAM_REG_USED(pVM, &pStats->StatRZOr, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Or", STAMUNIT_OCCURENCES, "The number of times OR was successfully interpreted.");
198 STAM_REG_USED(pVM, &pStats->StatR3Or, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Or", STAMUNIT_OCCURENCES, "The number of times OR was successfully interpreted.");
199 STAM_REG_USED(pVM, &pStats->StatRZPop, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Pop", STAMUNIT_OCCURENCES, "The number of times POP was successfully interpreted.");
200 STAM_REG_USED(pVM, &pStats->StatR3Pop, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Pop", STAMUNIT_OCCURENCES, "The number of times POP was successfully interpreted.");
201 STAM_REG_USED(pVM, &pStats->StatRZRdtsc, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Rdtsc", STAMUNIT_OCCURENCES, "The number of times RDTSC was successfully interpreted.");
202 STAM_REG_USED(pVM, &pStats->StatR3Rdtsc, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Rdtsc", STAMUNIT_OCCURENCES, "The number of times RDTSC was successfully interpreted.");
203 STAM_REG_USED(pVM, &pStats->StatRZSti, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Sti", STAMUNIT_OCCURENCES, "The number of times STI was successfully interpreted.");
204 STAM_REG_USED(pVM, &pStats->StatR3Sti, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Sti", STAMUNIT_OCCURENCES, "The number of times STI was successfully interpreted.");
205 STAM_REG_USED(pVM, &pStats->StatRZXchg, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Xchg", STAMUNIT_OCCURENCES, "The number of times XCHG was successfully interpreted.");
206 STAM_REG_USED(pVM, &pStats->StatR3Xchg, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Xchg", STAMUNIT_OCCURENCES, "The number of times XCHG was successfully interpreted.");
207 STAM_REG_USED(pVM, &pStats->StatRZXor, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Xor", STAMUNIT_OCCURENCES, "The number of times XOR was successfully interpreted.");
208 STAM_REG_USED(pVM, &pStats->StatR3Xor, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Xor", STAMUNIT_OCCURENCES, "The number of times XOR was successfully interpreted.");
209 STAM_REG_USED(pVM, &pStats->StatRZMonitor, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Monitor", STAMUNIT_OCCURENCES, "The number of times MONITOR was successfully interpreted.");
210 STAM_REG_USED(pVM, &pStats->StatR3Monitor, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Monitor", STAMUNIT_OCCURENCES, "The number of times MONITOR was successfully interpreted.");
211 STAM_REG_USED(pVM, &pStats->StatRZMWait, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/MWait", STAMUNIT_OCCURENCES, "The number of times MWAIT was successfully interpreted.");
212 STAM_REG_USED(pVM, &pStats->StatR3MWait, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/MWait", STAMUNIT_OCCURENCES, "The number of times MWAIT was successfully interpreted.");
213 STAM_REG_USED(pVM, &pStats->StatRZBtr, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Btr", STAMUNIT_OCCURENCES, "The number of times BTR was successfully interpreted.");
214 STAM_REG_USED(pVM, &pStats->StatR3Btr, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Btr", STAMUNIT_OCCURENCES, "The number of times BTR was successfully interpreted.");
215 STAM_REG_USED(pVM, &pStats->StatRZBts, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Bts", STAMUNIT_OCCURENCES, "The number of times BTS was successfully interpreted.");
216 STAM_REG_USED(pVM, &pStats->StatR3Bts, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Bts", STAMUNIT_OCCURENCES, "The number of times BTS was successfully interpreted.");
217 STAM_REG_USED(pVM, &pStats->StatRZBtc, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Btc", STAMUNIT_OCCURENCES, "The number of times BTC was successfully interpreted.");
218 STAM_REG_USED(pVM, &pStats->StatR3Btc, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Btc", STAMUNIT_OCCURENCES, "The number of times BTC was successfully interpreted.");
219 STAM_REG_USED(pVM, &pStats->StatRZCmpXchg, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/CmpXchg", STAMUNIT_OCCURENCES, "The number of times CMPXCHG was successfully interpreted.");
220 STAM_REG_USED(pVM, &pStats->StatR3CmpXchg, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/CmpXchg", STAMUNIT_OCCURENCES, "The number of times CMPXCHG was successfully interpreted.");
221 STAM_REG_USED(pVM, &pStats->StatRZCmpXchg8b, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/CmpXchg8b", STAMUNIT_OCCURENCES, "The number of times CMPXCHG8B was successfully interpreted.");
222 STAM_REG_USED(pVM, &pStats->StatR3CmpXchg8b, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/CmpXchg8b", STAMUNIT_OCCURENCES, "The number of times CMPXCHG8B was successfully interpreted.");
223 STAM_REG_USED(pVM, &pStats->StatRZXAdd, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was successfully interpreted.");
224 STAM_REG_USED(pVM, &pStats->StatR3XAdd, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was successfully interpreted.");
225 STAM_REG_USED(pVM, &pStats->StatR3Rdmsr, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Rdmsr", STAMUNIT_OCCURENCES, "The number of times RDMSR was successfully interpreted.");
226 STAM_REG_USED(pVM, &pStats->StatRZRdmsr, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Rdmsr", STAMUNIT_OCCURENCES, "The number of times RDMSR was successfully interpreted.");
227 STAM_REG_USED(pVM, &pStats->StatR3Wrmsr, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Wrmsr", STAMUNIT_OCCURENCES, "The number of times WRMSR was successfully interpreted.");
228 STAM_REG_USED(pVM, &pStats->StatRZWrmsr, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Wrmsr", STAMUNIT_OCCURENCES, "The number of times WRMSR was successfully interpreted.");
229 STAM_REG_USED(pVM, &pStats->StatR3StosWD, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Stoswd", STAMUNIT_OCCURENCES, "The number of times STOSWD was successfully interpreted.");
230 STAM_REG_USED(pVM, &pStats->StatRZStosWD, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Stoswd", STAMUNIT_OCCURENCES, "The number of times STOSWD was successfully interpreted.");
231 STAM_REG_USED(pVM, &pStats->StatRZWbInvd, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/WbInvd", STAMUNIT_OCCURENCES, "The number of times WBINVD was successfully interpreted.");
232 STAM_REG_USED(pVM, &pStats->StatR3WbInvd, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/WbInvd", STAMUNIT_OCCURENCES, "The number of times WBINVD was successfully interpreted.");
233 STAM_REG_USED(pVM, &pStats->StatRZLmsw, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Success/Lmsw", STAMUNIT_OCCURENCES, "The number of times LMSW was successfully interpreted.");
234 STAM_REG_USED(pVM, &pStats->StatR3Lmsw, STAMTYPE_COUNTER, "/EM/R3/Interpret/Success/Lmsw", STAMUNIT_OCCURENCES, "The number of times LMSW was successfully interpreted.");
235
236 STAM_REG(pVM, &pStats->StatRZInterpretFailed, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed", STAMUNIT_OCCURENCES, "The number of times an instruction was not interpreted.");
237 STAM_REG(pVM, &pStats->StatR3InterpretFailed, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed", STAMUNIT_OCCURENCES, "The number of times an instruction was not interpreted.");
238
239 STAM_REG_USED(pVM, &pStats->StatRZFailedAnd, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/And", STAMUNIT_OCCURENCES, "The number of times AND was not interpreted.");
240 STAM_REG_USED(pVM, &pStats->StatR3FailedAnd, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/And", STAMUNIT_OCCURENCES, "The number of times AND was not interpreted.");
241 STAM_REG_USED(pVM, &pStats->StatRZFailedCpuId, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/CpuId", STAMUNIT_OCCURENCES, "The number of times CPUID was not interpreted.");
242 STAM_REG_USED(pVM, &pStats->StatR3FailedCpuId, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/CpuId", STAMUNIT_OCCURENCES, "The number of times CPUID was not interpreted.");
243 STAM_REG_USED(pVM, &pStats->StatRZFailedDec, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Dec", STAMUNIT_OCCURENCES, "The number of times DEC was not interpreted.");
244 STAM_REG_USED(pVM, &pStats->StatR3FailedDec, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Dec", STAMUNIT_OCCURENCES, "The number of times DEC was not interpreted.");
245 STAM_REG_USED(pVM, &pStats->StatRZFailedHlt, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Hlt", STAMUNIT_OCCURENCES, "The number of times HLT was not interpreted.");
246 STAM_REG_USED(pVM, &pStats->StatR3FailedHlt, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Hlt", STAMUNIT_OCCURENCES, "The number of times HLT was not interpreted.");
247 STAM_REG_USED(pVM, &pStats->StatRZFailedInc, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Inc", STAMUNIT_OCCURENCES, "The number of times INC was not interpreted.");
248 STAM_REG_USED(pVM, &pStats->StatR3FailedInc, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Inc", STAMUNIT_OCCURENCES, "The number of times INC was not interpreted.");
249 STAM_REG_USED(pVM, &pStats->StatRZFailedInvlPg, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/InvlPg", STAMUNIT_OCCURENCES, "The number of times INVLPG was not interpreted.");
250 STAM_REG_USED(pVM, &pStats->StatR3FailedInvlPg, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/InvlPg", STAMUNIT_OCCURENCES, "The number of times INVLPG was not interpreted.");
251 STAM_REG_USED(pVM, &pStats->StatRZFailedIret, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Iret", STAMUNIT_OCCURENCES, "The number of times IRET was not interpreted.");
252 STAM_REG_USED(pVM, &pStats->StatR3FailedIret, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Iret", STAMUNIT_OCCURENCES, "The number of times IRET was not interpreted.");
253 STAM_REG_USED(pVM, &pStats->StatRZFailedLLdt, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/LLdt", STAMUNIT_OCCURENCES, "The number of times LLDT was not interpreted.");
254 STAM_REG_USED(pVM, &pStats->StatR3FailedLLdt, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/LLdt", STAMUNIT_OCCURENCES, "The number of times LLDT was not interpreted.");
255 STAM_REG_USED(pVM, &pStats->StatRZFailedLIdt, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/LIdt", STAMUNIT_OCCURENCES, "The number of times LIDT was not interpreted.");
256 STAM_REG_USED(pVM, &pStats->StatR3FailedLIdt, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/LIdt", STAMUNIT_OCCURENCES, "The number of times LIDT was not interpreted.");
257 STAM_REG_USED(pVM, &pStats->StatRZFailedLGdt, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/LGdt", STAMUNIT_OCCURENCES, "The number of times LGDT was not interpreted.");
258 STAM_REG_USED(pVM, &pStats->StatR3FailedLGdt, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/LGdt", STAMUNIT_OCCURENCES, "The number of times LGDT was not interpreted.");
259 STAM_REG_USED(pVM, &pStats->StatRZFailedMov, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Mov", STAMUNIT_OCCURENCES, "The number of times MOV was not interpreted.");
260 STAM_REG_USED(pVM, &pStats->StatR3FailedMov, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Mov", STAMUNIT_OCCURENCES, "The number of times MOV was not interpreted.");
261 STAM_REG_USED(pVM, &pStats->StatRZFailedMovCRx, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/MovCRx", STAMUNIT_OCCURENCES, "The number of times MOV CRx was not interpreted.");
262 STAM_REG_USED(pVM, &pStats->StatR3FailedMovCRx, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/MovCRx", STAMUNIT_OCCURENCES, "The number of times MOV CRx was not interpreted.");
263 STAM_REG_USED(pVM, &pStats->StatRZFailedMovDRx, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/MovDRx", STAMUNIT_OCCURENCES, "The number of times MOV DRx was not interpreted.");
264 STAM_REG_USED(pVM, &pStats->StatR3FailedMovDRx, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/MovDRx", STAMUNIT_OCCURENCES, "The number of times MOV DRx was not interpreted.");
265 STAM_REG_USED(pVM, &pStats->StatRZFailedOr, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Or", STAMUNIT_OCCURENCES, "The number of times OR was not interpreted.");
266 STAM_REG_USED(pVM, &pStats->StatR3FailedOr, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Or", STAMUNIT_OCCURENCES, "The number of times OR was not interpreted.");
267 STAM_REG_USED(pVM, &pStats->StatRZFailedPop, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Pop", STAMUNIT_OCCURENCES, "The number of times POP was not interpreted.");
268 STAM_REG_USED(pVM, &pStats->StatR3FailedPop, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Pop", STAMUNIT_OCCURENCES, "The number of times POP was not interpreted.");
269 STAM_REG_USED(pVM, &pStats->StatRZFailedSti, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Sti", STAMUNIT_OCCURENCES, "The number of times STI was not interpreted.");
270 STAM_REG_USED(pVM, &pStats->StatR3FailedSti, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Sti", STAMUNIT_OCCURENCES, "The number of times STI was not interpreted.");
271 STAM_REG_USED(pVM, &pStats->StatRZFailedXchg, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Xchg", STAMUNIT_OCCURENCES, "The number of times XCHG was not interpreted.");
272 STAM_REG_USED(pVM, &pStats->StatR3FailedXchg, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Xchg", STAMUNIT_OCCURENCES, "The number of times XCHG was not interpreted.");
273 STAM_REG_USED(pVM, &pStats->StatRZFailedXor, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Xor", STAMUNIT_OCCURENCES, "The number of times XOR was not interpreted.");
274 STAM_REG_USED(pVM, &pStats->StatR3FailedXor, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Xor", STAMUNIT_OCCURENCES, "The number of times XOR was not interpreted.");
275 STAM_REG_USED(pVM, &pStats->StatRZFailedMonitor, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Monitor", STAMUNIT_OCCURENCES, "The number of times MONITOR was not interpreted.");
276 STAM_REG_USED(pVM, &pStats->StatR3FailedMonitor, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Monitor", STAMUNIT_OCCURENCES, "The number of times MONITOR was not interpreted.");
277 STAM_REG_USED(pVM, &pStats->StatRZFailedMWait, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/MWait", STAMUNIT_OCCURENCES, "The number of times MONITOR was not interpreted.");
278 STAM_REG_USED(pVM, &pStats->StatR3FailedMWait, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/MWait", STAMUNIT_OCCURENCES, "The number of times MONITOR was not interpreted.");
279 STAM_REG_USED(pVM, &pStats->StatRZFailedRdtsc, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Rdtsc", STAMUNIT_OCCURENCES, "The number of times RDTSC was not interpreted.");
280 STAM_REG_USED(pVM, &pStats->StatR3FailedRdtsc, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Rdtsc", STAMUNIT_OCCURENCES, "The number of times RDTSC was not interpreted.");
281 STAM_REG_USED(pVM, &pStats->StatRZFailedRdmsr, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Rdmsr", STAMUNIT_OCCURENCES, "The number of times RDMSR was not interpreted.");
282 STAM_REG_USED(pVM, &pStats->StatR3FailedRdmsr, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Rdmsr", STAMUNIT_OCCURENCES, "The number of times RDMSR was not interpreted.");
283 STAM_REG_USED(pVM, &pStats->StatRZFailedWrmsr, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Wrmsr", STAMUNIT_OCCURENCES, "The number of times WRMSR was not interpreted.");
284 STAM_REG_USED(pVM, &pStats->StatR3FailedWrmsr, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Wrmsr", STAMUNIT_OCCURENCES, "The number of times WRMSR was not interpreted.");
285 STAM_REG_USED(pVM, &pStats->StatRZFailedLmsw, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Lmsw", STAMUNIT_OCCURENCES, "The number of times LMSW was not interpreted.");
286 STAM_REG_USED(pVM, &pStats->StatR3FailedLmsw, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Lmsw", STAMUNIT_OCCURENCES, "The number of times LMSW was not interpreted.");
287
288 STAM_REG_USED(pVM, &pStats->StatRZFailedMisc, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Misc", STAMUNIT_OCCURENCES, "The number of times some misc instruction was encountered.");
289 STAM_REG_USED(pVM, &pStats->StatR3FailedMisc, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Misc", STAMUNIT_OCCURENCES, "The number of times some misc instruction was encountered.");
290 STAM_REG_USED(pVM, &pStats->StatRZFailedAdd, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Add", STAMUNIT_OCCURENCES, "The number of times ADD was not interpreted.");
291 STAM_REG_USED(pVM, &pStats->StatR3FailedAdd, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Add", STAMUNIT_OCCURENCES, "The number of times ADD was not interpreted.");
292 STAM_REG_USED(pVM, &pStats->StatRZFailedAdc, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Adc", STAMUNIT_OCCURENCES, "The number of times ADC was not interpreted.");
293 STAM_REG_USED(pVM, &pStats->StatR3FailedAdc, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Adc", STAMUNIT_OCCURENCES, "The number of times ADC was not interpreted.");
294 STAM_REG_USED(pVM, &pStats->StatRZFailedBtr, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Btr", STAMUNIT_OCCURENCES, "The number of times BTR was not interpreted.");
295 STAM_REG_USED(pVM, &pStats->StatR3FailedBtr, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Btr", STAMUNIT_OCCURENCES, "The number of times BTR was not interpreted.");
296 STAM_REG_USED(pVM, &pStats->StatRZFailedBts, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Bts", STAMUNIT_OCCURENCES, "The number of times BTS was not interpreted.");
297 STAM_REG_USED(pVM, &pStats->StatR3FailedBts, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Bts", STAMUNIT_OCCURENCES, "The number of times BTS was not interpreted.");
298 STAM_REG_USED(pVM, &pStats->StatRZFailedBtc, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Btc", STAMUNIT_OCCURENCES, "The number of times BTC was not interpreted.");
299 STAM_REG_USED(pVM, &pStats->StatR3FailedBtc, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Btc", STAMUNIT_OCCURENCES, "The number of times BTC was not interpreted.");
300 STAM_REG_USED(pVM, &pStats->StatRZFailedCli, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Cli", STAMUNIT_OCCURENCES, "The number of times CLI was not interpreted.");
301 STAM_REG_USED(pVM, &pStats->StatR3FailedCli, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Cli", STAMUNIT_OCCURENCES, "The number of times CLI was not interpreted.");
302 STAM_REG_USED(pVM, &pStats->StatRZFailedCmpXchg, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/CmpXchg", STAMUNIT_OCCURENCES, "The number of times CMPXCHG was not interpreted.");
303 STAM_REG_USED(pVM, &pStats->StatR3FailedCmpXchg, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/CmpXchg", STAMUNIT_OCCURENCES, "The number of times CMPXCHG was not interpreted.");
304 STAM_REG_USED(pVM, &pStats->StatRZFailedCmpXchg8b, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/CmpXchg8b", STAMUNIT_OCCURENCES, "The number of times CMPXCHG8B was not interpreted.");
305 STAM_REG_USED(pVM, &pStats->StatR3FailedCmpXchg8b, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/CmpXchg8b", STAMUNIT_OCCURENCES, "The number of times CMPXCHG8B was not interpreted.");
306 STAM_REG_USED(pVM, &pStats->StatRZFailedXAdd, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was not interpreted.");
307 STAM_REG_USED(pVM, &pStats->StatR3FailedXAdd, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/XAdd", STAMUNIT_OCCURENCES, "The number of times XADD was not interpreted.");
308 STAM_REG_USED(pVM, &pStats->StatRZFailedMovNTPS, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/MovNTPS", STAMUNIT_OCCURENCES, "The number of times MOVNTPS was not interpreted.");
309 STAM_REG_USED(pVM, &pStats->StatR3FailedMovNTPS, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/MovNTPS", STAMUNIT_OCCURENCES, "The number of times MOVNTPS was not interpreted.");
310 STAM_REG_USED(pVM, &pStats->StatRZFailedStosWD, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/StosWD", STAMUNIT_OCCURENCES, "The number of times STOSWD was not interpreted.");
311 STAM_REG_USED(pVM, &pStats->StatR3FailedStosWD, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/StosWD", STAMUNIT_OCCURENCES, "The number of times STOSWD was not interpreted.");
312 STAM_REG_USED(pVM, &pStats->StatRZFailedSub, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Sub", STAMUNIT_OCCURENCES, "The number of times SUB was not interpreted.");
313 STAM_REG_USED(pVM, &pStats->StatR3FailedSub, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Sub", STAMUNIT_OCCURENCES, "The number of times SUB was not interpreted.");
314 STAM_REG_USED(pVM, &pStats->StatRZFailedWbInvd, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/WbInvd", STAMUNIT_OCCURENCES, "The number of times WBINVD was not interpreted.");
315 STAM_REG_USED(pVM, &pStats->StatR3FailedWbInvd, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/WbInvd", STAMUNIT_OCCURENCES, "The number of times WBINVD was not interpreted.");
316
317 STAM_REG_USED(pVM, &pStats->StatRZFailedUserMode, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/UserMode", STAMUNIT_OCCURENCES, "The number of rejections because of CPL.");
318 STAM_REG_USED(pVM, &pStats->StatR3FailedUserMode, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/UserMode", STAMUNIT_OCCURENCES, "The number of rejections because of CPL.");
319 STAM_REG_USED(pVM, &pStats->StatRZFailedPrefix, STAMTYPE_COUNTER, "/EM/RZ/Interpret/Failed/Prefix", STAMUNIT_OCCURENCES, "The number of rejections because of prefix .");
320 STAM_REG_USED(pVM, &pStats->StatR3FailedPrefix, STAMTYPE_COUNTER, "/EM/R3/Interpret/Failed/Prefix", STAMUNIT_OCCURENCES, "The number of rejections because of prefix .");
321
322 STAM_REG_USED(pVM, &pStats->StatCli, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Cli", STAMUNIT_OCCURENCES, "Number of cli instructions.");
323 STAM_REG_USED(pVM, &pStats->StatSti, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Sti", STAMUNIT_OCCURENCES, "Number of sli instructions.");
324 STAM_REG_USED(pVM, &pStats->StatIn, STAMTYPE_COUNTER, "/EM/R3/PrivInst/In", STAMUNIT_OCCURENCES, "Number of in instructions.");
325 STAM_REG_USED(pVM, &pStats->StatOut, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Out", STAMUNIT_OCCURENCES, "Number of out instructions.");
326 STAM_REG_USED(pVM, &pStats->StatHlt, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Hlt", STAMUNIT_OCCURENCES, "Number of hlt instructions not handled in GC because of PATM.");
327 STAM_REG_USED(pVM, &pStats->StatInvlpg, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Invlpg", STAMUNIT_OCCURENCES, "Number of invlpg instructions.");
328 STAM_REG_USED(pVM, &pStats->StatMisc, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Misc", STAMUNIT_OCCURENCES, "Number of misc. instructions.");
329 STAM_REG_USED(pVM, &pStats->StatMovWriteCR[0], STAMTYPE_COUNTER, "/EM/R3/PrivInst/Mov CR0, X", STAMUNIT_OCCURENCES, "Number of mov CR0 read instructions.");
330 STAM_REG_USED(pVM, &pStats->StatMovWriteCR[1], STAMTYPE_COUNTER, "/EM/R3/PrivInst/Mov CR1, X", STAMUNIT_OCCURENCES, "Number of mov CR1 read instructions.");
331 STAM_REG_USED(pVM, &pStats->StatMovWriteCR[2], STAMTYPE_COUNTER, "/EM/R3/PrivInst/Mov CR2, X", STAMUNIT_OCCURENCES, "Number of mov CR2 read instructions.");
332 STAM_REG_USED(pVM, &pStats->StatMovWriteCR[3], STAMTYPE_COUNTER, "/EM/R3/PrivInst/Mov CR3, X", STAMUNIT_OCCURENCES, "Number of mov CR3 read instructions.");
333 STAM_REG_USED(pVM, &pStats->StatMovWriteCR[4], STAMTYPE_COUNTER, "/EM/R3/PrivInst/Mov CR4, X", STAMUNIT_OCCURENCES, "Number of mov CR4 read instructions.");
334 STAM_REG_USED(pVM, &pStats->StatMovReadCR[0], STAMTYPE_COUNTER, "/EM/R3/PrivInst/Mov X, CR0", STAMUNIT_OCCURENCES, "Number of mov CR0 write instructions.");
335 STAM_REG_USED(pVM, &pStats->StatMovReadCR[1], STAMTYPE_COUNTER, "/EM/R3/PrivInst/Mov X, CR1", STAMUNIT_OCCURENCES, "Number of mov CR1 write instructions.");
336 STAM_REG_USED(pVM, &pStats->StatMovReadCR[2], STAMTYPE_COUNTER, "/EM/R3/PrivInst/Mov X, CR2", STAMUNIT_OCCURENCES, "Number of mov CR2 write instructions.");
337 STAM_REG_USED(pVM, &pStats->StatMovReadCR[3], STAMTYPE_COUNTER, "/EM/R3/PrivInst/Mov X, CR3", STAMUNIT_OCCURENCES, "Number of mov CR3 write instructions.");
338 STAM_REG_USED(pVM, &pStats->StatMovReadCR[4], STAMTYPE_COUNTER, "/EM/R3/PrivInst/Mov X, CR4", STAMUNIT_OCCURENCES, "Number of mov CR4 write instructions.");
339 STAM_REG_USED(pVM, &pStats->StatMovDRx, STAMTYPE_COUNTER, "/EM/R3/PrivInst/MovDRx", STAMUNIT_OCCURENCES, "Number of mov DRx instructions.");
340 STAM_REG_USED(pVM, &pStats->StatIret, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Iret", STAMUNIT_OCCURENCES, "Number of iret instructions.");
341 STAM_REG_USED(pVM, &pStats->StatMovLgdt, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Lgdt", STAMUNIT_OCCURENCES, "Number of lgdt instructions.");
342 STAM_REG_USED(pVM, &pStats->StatMovLidt, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Lidt", STAMUNIT_OCCURENCES, "Number of lidt instructions.");
343 STAM_REG_USED(pVM, &pStats->StatMovLldt, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Lldt", STAMUNIT_OCCURENCES, "Number of lldt instructions.");
344 STAM_REG_USED(pVM, &pStats->StatSysEnter, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Sysenter", STAMUNIT_OCCURENCES, "Number of sysenter instructions.");
345 STAM_REG_USED(pVM, &pStats->StatSysExit, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Sysexit", STAMUNIT_OCCURENCES, "Number of sysexit instructions.");
346 STAM_REG_USED(pVM, &pStats->StatSysCall, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Syscall", STAMUNIT_OCCURENCES, "Number of syscall instructions.");
347 STAM_REG_USED(pVM, &pStats->StatSysRet, STAMTYPE_COUNTER, "/EM/R3/PrivInst/Sysret", STAMUNIT_OCCURENCES, "Number of sysret instructions.");
348
349 STAM_REG(pVM, &pVM->em.s.StatTotalClis, STAMTYPE_COUNTER, "/EM/Cli/Total", STAMUNIT_OCCURENCES, "Total number of cli instructions executed.");
350 pVM->em.s.pCliStatTree = 0;
351#endif /* VBOX_WITH_STATISTICS */
352
353 /* these should be considered for release statistics. */
354 STAM_REL_REG(pVM, &pVM->em.s.StatForcedActions, STAMTYPE_PROFILE, "/PROF/EM/ForcedActions", STAMUNIT_TICKS_PER_CALL, "Profiling forced action execution.");
355 STAM_REG(pVM, &pVM->em.s.StatIOEmu, STAMTYPE_PROFILE, "/PROF/EM/Emulation/IO", STAMUNIT_TICKS_PER_CALL, "Profiling of emR3RawExecuteIOInstruction.");
356 STAM_REG(pVM, &pVM->em.s.StatPrivEmu, STAMTYPE_PROFILE, "/PROF/EM/Emulation/Priv", STAMUNIT_TICKS_PER_CALL, "Profiling of emR3RawPrivileged.");
357 STAM_REG(pVM, &pVM->em.s.StatMiscEmu, STAMTYPE_PROFILE, "/PROF/EM/Emulation/Misc", STAMUNIT_TICKS_PER_CALL, "Profiling of emR3RawExecuteInstruction.");
358
359 STAM_REL_REG(pVM, &pVM->em.s.StatHalted, STAMTYPE_PROFILE, "/PROF/EM/Halted", STAMUNIT_TICKS_PER_CALL, "Profiling halted state (VMR3WaitHalted).");
360 STAM_REG(pVM, &pVM->em.s.StatHwAccEntry, STAMTYPE_PROFILE, "/PROF/EM/HwAccEnter", STAMUNIT_TICKS_PER_CALL, "Profiling Hardware Accelerated Mode entry overhead.");
361 STAM_REG(pVM, &pVM->em.s.StatHwAccExec, STAMTYPE_PROFILE, "/PROF/EM/HwAccExec", STAMUNIT_TICKS_PER_CALL, "Profiling Hardware Accelerated Mode execution.");
362 STAM_REG(pVM, &pVM->em.s.StatREMEmu, STAMTYPE_PROFILE, "/PROF/EM/REMEmuSingle", STAMUNIT_TICKS_PER_CALL, "Profiling single instruction REM execution.");
363 STAM_REG(pVM, &pVM->em.s.StatREMExec, STAMTYPE_PROFILE, "/PROF/EM/REMExec", STAMUNIT_TICKS_PER_CALL, "Profiling REM execution.");
364 STAM_REG(pVM, &pVM->em.s.StatREMSync, STAMTYPE_PROFILE, "/PROF/EM/REMSync", STAMUNIT_TICKS_PER_CALL, "Profiling REM context syncing.");
365 STAM_REL_REG(pVM, &pVM->em.s.StatREMTotal, STAMTYPE_PROFILE, "/PROF/EM/REMTotal", STAMUNIT_TICKS_PER_CALL, "Profiling emR3RemExecute (excluding FFs).");
366 STAM_REG(pVM, &pVM->em.s.StatRAWEntry, STAMTYPE_PROFILE, "/PROF/EM/RAWEnter", STAMUNIT_TICKS_PER_CALL, "Profiling Raw Mode entry overhead.");
367 STAM_REG(pVM, &pVM->em.s.StatRAWExec, STAMTYPE_PROFILE, "/PROF/EM/RAWExec", STAMUNIT_TICKS_PER_CALL, "Profiling Raw Mode execution.");
368 STAM_REG(pVM, &pVM->em.s.StatRAWTail, STAMTYPE_PROFILE, "/PROF/EM/RAWTail", STAMUNIT_TICKS_PER_CALL, "Profiling Raw Mode tail overhead.");
369 STAM_REL_REG(pVM, &pVM->em.s.StatRAWTotal, STAMTYPE_PROFILE, "/PROF/EM/RAWTotal", STAMUNIT_TICKS_PER_CALL, "Profiling emR3RawExecute (excluding FFs).");
370 STAM_REL_REG(pVM, &pVM->em.s.StatTotal, STAMTYPE_PROFILE_ADV, "/PROF/EM/Total", STAMUNIT_TICKS_PER_CALL, "Profiling EMR3ExecuteVM.");
371
372
373 return VINF_SUCCESS;
374}
375
376
377/**
378 * Initializes the per-VCPU EM.
379 *
380 * @returns VBox status code.
381 * @param pVM The VM to operate on.
382 */
383VMMR3DECL(int) EMR3InitCPU(PVM pVM)
384{
385 LogFlow(("EMR3InitCPU\n"));
386 return VINF_SUCCESS;
387}
388
389
390/**
391 * Applies relocations to data and code managed by this
392 * component. This function will be called at init and
393 * whenever the VMM need to relocate it self inside the GC.
394 *
395 * @param pVM The VM.
396 */
397VMMR3DECL(void) EMR3Relocate(PVM pVM)
398{
399 LogFlow(("EMR3Relocate\n"));
400 if (pVM->em.s.pStatsR3)
401 pVM->em.s.pStatsRC = MMHyperR3ToRC(pVM, pVM->em.s.pStatsR3);
402}
403
404
405/**
406 * Reset notification.
407 *
408 * @param pVM
409 */
410VMMR3DECL(void) EMR3Reset(PVM pVM)
411{
412 LogFlow(("EMR3Reset: \n"));
413 pVM->em.s.fForceRAW = false;
414}
415
416
417/**
418 * Terminates the EM.
419 *
420 * Termination means cleaning up and freeing all resources,
421 * the VM it self is at this point powered off or suspended.
422 *
423 * @returns VBox status code.
424 * @param pVM The VM to operate on.
425 */
426VMMR3DECL(int) EMR3Term(PVM pVM)
427{
428 AssertMsg(pVM->em.s.offVM, ("bad init order!\n"));
429
430 return VINF_SUCCESS;
431}
432
433/**
434 * Terminates the per-VCPU EM.
435 *
436 * Termination means cleaning up and freeing all resources,
437 * the VM it self is at this point powered off or suspended.
438 *
439 * @returns VBox status code.
440 * @param pVM The VM to operate on.
441 */
442VMMR3DECL(int) EMR3TermCPU(PVM pVM)
443{
444 return 0;
445}
446
447/**
448 * Execute state save operation.
449 *
450 * @returns VBox status code.
451 * @param pVM VM Handle.
452 * @param pSSM SSM operation handle.
453 */
454static DECLCALLBACK(int) emR3Save(PVM pVM, PSSMHANDLE pSSM)
455{
456 return SSMR3PutBool(pSSM, pVM->em.s.fForceRAW);
457}
458
459
460/**
461 * Execute state load operation.
462 *
463 * @returns VBox status code.
464 * @param pVM VM Handle.
465 * @param pSSM SSM operation handle.
466 * @param u32Version Data layout version.
467 */
468static DECLCALLBACK(int) emR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version)
469{
470 /*
471 * Validate version.
472 */
473 if (u32Version != EM_SAVED_STATE_VERSION)
474 {
475 AssertMsgFailed(("emR3Load: Invalid version u32Version=%d (current %d)!\n", u32Version, EM_SAVED_STATE_VERSION));
476 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
477 }
478
479 /*
480 * Load the saved state.
481 */
482 int rc = SSMR3GetBool(pSSM, &pVM->em.s.fForceRAW);
483 if (RT_FAILURE(rc))
484 pVM->em.s.fForceRAW = false;
485
486 Assert(!pVM->em.s.pCliStatTree);
487 return rc;
488}
489
490
491/**
492 * Enables or disables a set of raw-mode execution modes.
493 *
494 * @returns VINF_SUCCESS on success.
495 * @returns VINF_RESCHEDULE if a rescheduling might be required.
496 * @returns VERR_INVALID_PARAMETER on an invalid enmMode value.
497 *
498 * @param pVM The VM to operate on.
499 * @param enmMode The execution mode change.
500 * @thread The emulation thread.
501 */
502VMMR3DECL(int) EMR3RawSetMode(PVM pVM, EMRAWMODE enmMode)
503{
504 switch (enmMode)
505 {
506 case EMRAW_NONE:
507 pVM->fRawR3Enabled = false;
508 pVM->fRawR0Enabled = false;
509 break;
510 case EMRAW_RING3_ENABLE:
511 pVM->fRawR3Enabled = true;
512 break;
513 case EMRAW_RING3_DISABLE:
514 pVM->fRawR3Enabled = false;
515 break;
516 case EMRAW_RING0_ENABLE:
517 pVM->fRawR0Enabled = true;
518 break;
519 case EMRAW_RING0_DISABLE:
520 pVM->fRawR0Enabled = false;
521 break;
522 default:
523 AssertMsgFailed(("Invalid enmMode=%d\n", enmMode));
524 return VERR_INVALID_PARAMETER;
525 }
526 Log(("EMR3SetRawMode: fRawR3Enabled=%RTbool fRawR0Enabled=%RTbool\n",
527 pVM->fRawR3Enabled, pVM->fRawR0Enabled));
528 return pVM->em.s.enmState == EMSTATE_RAW ? VINF_EM_RESCHEDULE : VINF_SUCCESS;
529}
530
531
532/**
533 * Raise a fatal error.
534 *
535 * Safely terminate the VM with full state report and stuff. This function
536 * will naturally never return.
537 *
538 * @param pVM VM handle.
539 * @param rc VBox status code.
540 */
541VMMR3DECL(void) EMR3FatalError(PVM pVM, int rc)
542{
543 longjmp(pVM->em.s.u.FatalLongJump, rc);
544 AssertReleaseMsgFailed(("longjmp returned!\n"));
545}
546
547
548/**
549 * Gets the EM state name.
550 *
551 * @returns pointer to read only state name,
552 * @param enmState The state.
553 */
554VMMR3DECL(const char *) EMR3GetStateName(EMSTATE enmState)
555{
556 switch (enmState)
557 {
558 case EMSTATE_NONE: return "EMSTATE_NONE";
559 case EMSTATE_RAW: return "EMSTATE_RAW";
560 case EMSTATE_HWACC: return "EMSTATE_HWACC";
561 case EMSTATE_REM: return "EMSTATE_REM";
562 case EMSTATE_PARAV: return "EMSTATE_PARAV";
563 case EMSTATE_HALTED: return "EMSTATE_HALTED";
564 case EMSTATE_SUSPENDED: return "EMSTATE_SUSPENDED";
565 case EMSTATE_TERMINATING: return "EMSTATE_TERMINATING";
566 case EMSTATE_DEBUG_GUEST_RAW: return "EMSTATE_DEBUG_GUEST_RAW";
567 case EMSTATE_DEBUG_GUEST_REM: return "EMSTATE_DEBUG_GUEST_REM";
568 case EMSTATE_DEBUG_HYPER: return "EMSTATE_DEBUG_HYPER";
569 case EMSTATE_GURU_MEDITATION: return "EMSTATE_GURU_MEDITATION";
570 default: return "Unknown!";
571 }
572}
573
574
575#ifdef VBOX_WITH_STATISTICS
576/**
577 * Just a braindead function to keep track of cli addresses.
578 * @param pVM VM handle.
579 * @param GCPtrInstr The EIP of the cli instruction.
580 */
581static void emR3RecordCli(PVM pVM, RTGCPTR GCPtrInstr)
582{
583 PCLISTAT pRec;
584
585 pRec = (PCLISTAT)RTAvlPVGet(&pVM->em.s.pCliStatTree, (AVLPVKEY)GCPtrInstr);
586 if (!pRec)
587 {
588 /* New cli instruction; insert into the tree. */
589 pRec = (PCLISTAT)MMR3HeapAllocZ(pVM, MM_TAG_EM, sizeof(*pRec));
590 Assert(pRec);
591 if (!pRec)
592 return;
593 pRec->Core.Key = (AVLPVKEY)GCPtrInstr;
594
595 char szCliStatName[32];
596 RTStrPrintf(szCliStatName, sizeof(szCliStatName), "/EM/Cli/0x%RGv", GCPtrInstr);
597 STAM_REG(pVM, &pRec->Counter, STAMTYPE_COUNTER, szCliStatName, STAMUNIT_OCCURENCES, "Number of times cli was executed.");
598
599 bool fRc = RTAvlPVInsert(&pVM->em.s.pCliStatTree, &pRec->Core);
600 Assert(fRc); NOREF(fRc);
601 }
602 STAM_COUNTER_INC(&pRec->Counter);
603 STAM_COUNTER_INC(&pVM->em.s.StatTotalClis);
604}
605#endif /* VBOX_WITH_STATISTICS */
606
607
608/**
609 * Debug loop.
610 *
611 * @returns VBox status code for EM.
612 * @param pVM VM handle.
613 * @param rc Current EM VBox status code..
614 */
615static int emR3Debug(PVM pVM, int rc)
616{
617 for (;;)
618 {
619 Log(("emR3Debug: rc=%Rrc\n", rc));
620 const int rcLast = rc;
621
622 /*
623 * Debug related RC.
624 */
625 switch (rc)
626 {
627 /*
628 * Single step an instruction.
629 */
630 case VINF_EM_DBG_STEP:
631 if ( pVM->em.s.enmState == EMSTATE_DEBUG_GUEST_RAW
632 || pVM->em.s.enmState == EMSTATE_DEBUG_HYPER
633 || pVM->em.s.fForceRAW /* paranoia */)
634 rc = emR3RawStep(pVM);
635 else
636 {
637 Assert(pVM->em.s.enmState == EMSTATE_DEBUG_GUEST_REM);
638 rc = emR3RemStep(pVM);
639 }
640 break;
641
642 /*
643 * Simple events: stepped, breakpoint, stop/assertion.
644 */
645 case VINF_EM_DBG_STEPPED:
646 rc = DBGFR3Event(pVM, DBGFEVENT_STEPPED);
647 break;
648
649 case VINF_EM_DBG_BREAKPOINT:
650 rc = DBGFR3EventBreakpoint(pVM, DBGFEVENT_BREAKPOINT);
651 break;
652
653 case VINF_EM_DBG_STOP:
654 rc = DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, NULL, 0, NULL, NULL);
655 break;
656
657 case VINF_EM_DBG_HYPER_STEPPED:
658 rc = DBGFR3Event(pVM, DBGFEVENT_STEPPED_HYPER);
659 break;
660
661 case VINF_EM_DBG_HYPER_BREAKPOINT:
662 rc = DBGFR3EventBreakpoint(pVM, DBGFEVENT_BREAKPOINT_HYPER);
663 break;
664
665 case VINF_EM_DBG_HYPER_ASSERTION:
666 RTPrintf("\nVINF_EM_DBG_HYPER_ASSERTION:\n%s%s\n", VMMR3GetRZAssertMsg1(pVM), VMMR3GetRZAssertMsg2(pVM));
667 rc = DBGFR3EventAssertion(pVM, DBGFEVENT_ASSERTION_HYPER, VMMR3GetRZAssertMsg1(pVM), VMMR3GetRZAssertMsg2(pVM));
668 break;
669
670 /*
671 * Guru meditation.
672 */
673 case VERR_VMM_RING0_ASSERTION: /** @todo Make a guru meditation event! */
674 rc = DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, "VERR_VMM_RING0_ASSERTION", 0, NULL, NULL);
675 break;
676 case VERR_REM_TOO_MANY_TRAPS: /** @todo Make a guru meditation event! */
677 rc = DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, "VERR_REM_TOO_MANY_TRAPS", 0, NULL, NULL);
678 break;
679
680 default: /** @todo don't use default for guru, but make special errors code! */
681 rc = DBGFR3Event(pVM, DBGFEVENT_FATAL_ERROR);
682 break;
683 }
684
685 /*
686 * Process the result.
687 */
688 do
689 {
690 switch (rc)
691 {
692 /*
693 * Continue the debugging loop.
694 */
695 case VINF_EM_DBG_STEP:
696 case VINF_EM_DBG_STOP:
697 case VINF_EM_DBG_STEPPED:
698 case VINF_EM_DBG_BREAKPOINT:
699 case VINF_EM_DBG_HYPER_STEPPED:
700 case VINF_EM_DBG_HYPER_BREAKPOINT:
701 case VINF_EM_DBG_HYPER_ASSERTION:
702 break;
703
704 /*
705 * Resuming execution (in some form) has to be done here if we got
706 * a hypervisor debug event.
707 */
708 case VINF_SUCCESS:
709 case VINF_EM_RESUME:
710 case VINF_EM_SUSPEND:
711 case VINF_EM_RESCHEDULE:
712 case VINF_EM_RESCHEDULE_RAW:
713 case VINF_EM_RESCHEDULE_REM:
714 case VINF_EM_HALT:
715 if (pVM->em.s.enmState == EMSTATE_DEBUG_HYPER)
716 {
717 rc = emR3RawResumeHyper(pVM);
718 if (rc != VINF_SUCCESS && RT_SUCCESS(rc))
719 continue;
720 }
721 if (rc == VINF_SUCCESS)
722 rc = VINF_EM_RESCHEDULE;
723 return rc;
724
725 /*
726 * The debugger isn't attached.
727 * We'll simply turn the thing off since that's the easiest thing to do.
728 */
729 case VERR_DBGF_NOT_ATTACHED:
730 switch (rcLast)
731 {
732 case VINF_EM_DBG_HYPER_STEPPED:
733 case VINF_EM_DBG_HYPER_BREAKPOINT:
734 case VINF_EM_DBG_HYPER_ASSERTION:
735 case VERR_TRPM_PANIC:
736 case VERR_TRPM_DONT_PANIC:
737 case VERR_VMM_RING0_ASSERTION:
738 return rcLast;
739 }
740 return VINF_EM_OFF;
741
742 /*
743 * Status codes terminating the VM in one or another sense.
744 */
745 case VINF_EM_TERMINATE:
746 case VINF_EM_OFF:
747 case VINF_EM_RESET:
748 case VINF_EM_RAW_STALE_SELECTOR:
749 case VINF_EM_RAW_IRET_TRAP:
750 case VERR_TRPM_PANIC:
751 case VERR_TRPM_DONT_PANIC:
752 case VERR_VMM_RING0_ASSERTION:
753 case VERR_INTERNAL_ERROR:
754 return rc;
755
756 /*
757 * The rest is unexpected, and will keep us here.
758 */
759 default:
760 AssertMsgFailed(("Unxpected rc %Rrc!\n", rc));
761 break;
762 }
763 } while (false);
764 } /* debug for ever */
765}
766
767
768/**
769 * Steps recompiled code.
770 *
771 * @returns VBox status code. The most important ones are: VINF_EM_STEP_EVENT,
772 * VINF_EM_RESCHEDULE, VINF_EM_SUSPEND, VINF_EM_RESET and VINF_EM_TERMINATE.
773 *
774 * @param pVM VM handle.
775 */
776static int emR3RemStep(PVM pVM)
777{
778 LogFlow(("emR3RemStep: cs:eip=%04x:%08x\n", CPUMGetGuestCS(pVM), CPUMGetGuestEIP(pVM)));
779
780 /*
781 * Switch to REM, step instruction, switch back.
782 */
783 int rc = REMR3State(pVM);
784 if (RT_SUCCESS(rc))
785 {
786 rc = REMR3Step(pVM);
787 REMR3StateBack(pVM);
788 }
789 LogFlow(("emR3RemStep: returns %Rrc cs:eip=%04x:%08x\n", rc, CPUMGetGuestCS(pVM), CPUMGetGuestEIP(pVM)));
790 return rc;
791}
792
793
794/**
795 * Executes recompiled code.
796 *
797 * This function contains the recompiler version of the inner
798 * execution loop (the outer loop being in EMR3ExecuteVM()).
799 *
800 * @returns VBox status code. The most important ones are: VINF_EM_RESCHEDULE,
801 * VINF_EM_SUSPEND, VINF_EM_RESET and VINF_EM_TERMINATE.
802 *
803 * @param pVM VM handle.
804 * @param pfFFDone Where to store an indicator telling wheter or not
805 * FFs were done before returning.
806 *
807 */
808static int emR3RemExecute(PVM pVM, bool *pfFFDone)
809{
810#ifdef LOG_ENABLED
811 PCPUMCTX pCtx = pVM->em.s.pCtx;
812 uint32_t cpl = CPUMGetGuestCPL(pVM, CPUMCTX2CORE(pCtx));
813
814 if (pCtx->eflags.Bits.u1VM)
815 Log(("EMV86: %04X:%08X IF=%d\n", pCtx->cs, pCtx->eip, pCtx->eflags.Bits.u1IF));
816 else
817 Log(("EMR%d: %04X:%08X ESP=%08X IF=%d CR0=%x\n", cpl, pCtx->cs, pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, (uint32_t)pCtx->cr0));
818#endif
819 STAM_REL_PROFILE_ADV_START(&pVM->em.s.StatREMTotal, a);
820
821#if defined(VBOX_STRICT) && defined(DEBUG_bird)
822 AssertMsg( VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3|VM_FF_PGM_SYNC_CR3_NON_GLOBAL)
823 || !MMHyperIsInsideArea(pVM, CPUMGetGuestEIP(pVM)), /** @todo #1419 - get flat address. */
824 ("cs:eip=%RX16:%RX32\n", CPUMGetGuestCS(pVM), CPUMGetGuestEIP(pVM)));
825#endif
826
827 /*
828 * Spin till we get a forced action which returns anything but VINF_SUCCESS
829 * or the REM suggests raw-mode execution.
830 */
831 *pfFFDone = false;
832 bool fInREMState = false;
833 int rc = VINF_SUCCESS;
834 for (;;)
835 {
836 /*
837 * Update REM state if not already in sync.
838 */
839 if (!fInREMState)
840 {
841 STAM_PROFILE_START(&pVM->em.s.StatREMSync, b);
842 rc = REMR3State(pVM);
843 STAM_PROFILE_STOP(&pVM->em.s.StatREMSync, b);
844 if (RT_FAILURE(rc))
845 break;
846 fInREMState = true;
847
848 /*
849 * We might have missed the raising of VMREQ, TIMER and some other
850 * imporant FFs while we were busy switching the state. So, check again.
851 */
852 if (VM_FF_ISPENDING(pVM, VM_FF_REQUEST | VM_FF_TIMER | VM_FF_PDM_QUEUES | VM_FF_DBGF | VM_FF_TERMINATE | VM_FF_RESET))
853 {
854 LogFlow(("emR3RemExecute: Skipping run, because FF is set. %#x\n", pVM->fForcedActions));
855 goto l_REMDoForcedActions;
856 }
857 }
858
859
860 /*
861 * Execute REM.
862 */
863 STAM_PROFILE_START(&pVM->em.s.StatREMExec, c);
864 rc = REMR3Run(pVM);
865 STAM_PROFILE_STOP(&pVM->em.s.StatREMExec, c);
866
867
868 /*
869 * Deal with high priority post execution FFs before doing anything else.
870 */
871 if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK))
872 rc = emR3HighPriorityPostForcedActions(pVM, rc);
873
874 /*
875 * Process the returned status code.
876 * (Try keep this short! Call functions!)
877 */
878 if (rc != VINF_SUCCESS)
879 {
880 if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
881 break;
882 if (rc != VINF_REM_INTERRUPED_FF)
883 {
884 /*
885 * Anything which is not known to us means an internal error
886 * and the termination of the VM!
887 */
888 AssertMsg(rc == VERR_REM_TOO_MANY_TRAPS, ("Unknown GC return code: %Rra\n", rc));
889 break;
890 }
891 }
892
893
894 /*
895 * Check and execute forced actions.
896 * Sync back the VM state before calling any of these.
897 */
898#ifdef VBOX_HIGH_RES_TIMERS_HACK
899 TMTimerPoll(pVM);
900#endif
901 if (VM_FF_ISPENDING(pVM, VM_FF_ALL_BUT_RAW_MASK & ~(VM_FF_CSAM_PENDING_ACTION | VM_FF_CSAM_SCAN_PAGE)))
902 {
903l_REMDoForcedActions:
904 if (fInREMState)
905 {
906 STAM_PROFILE_START(&pVM->em.s.StatREMSync, d);
907 REMR3StateBack(pVM);
908 STAM_PROFILE_STOP(&pVM->em.s.StatREMSync, d);
909 fInREMState = false;
910 }
911 STAM_REL_PROFILE_ADV_SUSPEND(&pVM->em.s.StatREMTotal, a);
912 rc = emR3ForcedActions(pVM, rc);
913 STAM_REL_PROFILE_ADV_RESUME(&pVM->em.s.StatREMTotal, a);
914 if ( rc != VINF_SUCCESS
915 && rc != VINF_EM_RESCHEDULE_REM)
916 {
917 *pfFFDone = true;
918 break;
919 }
920 }
921
922 } /* The Inner Loop, recompiled execution mode version. */
923
924
925 /*
926 * Returning. Sync back the VM state if required.
927 */
928 if (fInREMState)
929 {
930 STAM_PROFILE_START(&pVM->em.s.StatREMSync, e);
931 REMR3StateBack(pVM);
932 STAM_PROFILE_STOP(&pVM->em.s.StatREMSync, e);
933 }
934
935 STAM_REL_PROFILE_ADV_STOP(&pVM->em.s.StatREMTotal, a);
936 return rc;
937}
938
939
940/**
941 * Resumes executing hypervisor after a debug event.
942 *
943 * This is kind of special since our current guest state is
944 * potentially out of sync.
945 *
946 * @returns VBox status code.
947 * @param pVM The VM handle.
948 */
949static int emR3RawResumeHyper(PVM pVM)
950{
951 int rc;
952 PCPUMCTX pCtx = pVM->em.s.pCtx;
953 Assert(pVM->em.s.enmState == EMSTATE_DEBUG_HYPER);
954 Log(("emR3RawResumeHyper: cs:eip=%RTsel:%RGr efl=%RGr\n", pCtx->cs, pCtx->eip, pCtx->eflags));
955
956 /*
957 * Resume execution.
958 */
959 CPUMRawEnter(pVM, NULL);
960 CPUMSetHyperEFlags(pVM, CPUMGetHyperEFlags(pVM) | X86_EFL_RF);
961 rc = VMMR3ResumeHyper(pVM);
962 Log(("emR3RawStep: cs:eip=%RTsel:%RGr efl=%RGr - returned from GC with rc=%Rrc\n", pCtx->cs, pCtx->eip, pCtx->eflags, rc));
963 rc = CPUMRawLeave(pVM, NULL, rc);
964 VM_FF_CLEAR(pVM, VM_FF_RESUME_GUEST_MASK);
965
966 /*
967 * Deal with the return code.
968 */
969 rc = emR3HighPriorityPostForcedActions(pVM, rc);
970 rc = emR3RawHandleRC(pVM, pCtx, rc);
971 rc = emR3RawUpdateForceFlag(pVM, pCtx, rc);
972 return rc;
973}
974
975
976/**
977 * Steps rawmode.
978 *
979 * @returns VBox status code.
980 * @param pVM The VM handle.
981 */
982static int emR3RawStep(PVM pVM)
983{
984 Assert( pVM->em.s.enmState == EMSTATE_DEBUG_HYPER
985 || pVM->em.s.enmState == EMSTATE_DEBUG_GUEST_RAW
986 || pVM->em.s.enmState == EMSTATE_DEBUG_GUEST_REM);
987 int rc;
988 PCPUMCTX pCtx = pVM->em.s.pCtx;
989 bool fGuest = pVM->em.s.enmState != EMSTATE_DEBUG_HYPER;
990#ifndef DEBUG_sandervl
991 Log(("emR3RawStep: cs:eip=%RTsel:%RGr efl=%RGr\n", fGuest ? CPUMGetGuestCS(pVM) : CPUMGetHyperCS(pVM),
992 fGuest ? CPUMGetGuestEIP(pVM) : CPUMGetHyperEIP(pVM), fGuest ? CPUMGetGuestEFlags(pVM) : CPUMGetHyperEFlags(pVM)));
993#endif
994 if (fGuest)
995 {
996 /*
997 * Check vital forced actions, but ignore pending interrupts and timers.
998 */
999 if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
1000 {
1001 rc = emR3RawForcedActions(pVM, pCtx);
1002 if (RT_FAILURE(rc))
1003 return rc;
1004 }
1005
1006 /*
1007 * Set flags for single stepping.
1008 */
1009 CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) | X86_EFL_TF | X86_EFL_RF);
1010 }
1011 else
1012 CPUMSetHyperEFlags(pVM, CPUMGetHyperEFlags(pVM) | X86_EFL_TF | X86_EFL_RF);
1013
1014 /*
1015 * Single step.
1016 * We do not start time or anything, if anything we should just do a few nanoseconds.
1017 */
1018 CPUMRawEnter(pVM, NULL);
1019 do
1020 {
1021 if (pVM->em.s.enmState == EMSTATE_DEBUG_HYPER)
1022 rc = VMMR3ResumeHyper(pVM);
1023 else
1024 rc = VMMR3RawRunGC(pVM);
1025#ifndef DEBUG_sandervl
1026 Log(("emR3RawStep: cs:eip=%RTsel:%RGr efl=%RGr - GC rc %Rrc\n", fGuest ? CPUMGetGuestCS(pVM) : CPUMGetHyperCS(pVM),
1027 fGuest ? CPUMGetGuestEIP(pVM) : CPUMGetHyperEIP(pVM), fGuest ? CPUMGetGuestEFlags(pVM) : CPUMGetHyperEFlags(pVM), rc));
1028#endif
1029 } while ( rc == VINF_SUCCESS
1030 || rc == VINF_EM_RAW_INTERRUPT);
1031 rc = CPUMRawLeave(pVM, NULL, rc);
1032 VM_FF_CLEAR(pVM, VM_FF_RESUME_GUEST_MASK);
1033
1034 /*
1035 * Make sure the trap flag is cleared.
1036 * (Too bad if the guest is trying to single step too.)
1037 */
1038 if (fGuest)
1039 CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) & ~X86_EFL_TF);
1040 else
1041 CPUMSetHyperEFlags(pVM, CPUMGetHyperEFlags(pVM) & ~X86_EFL_TF);
1042
1043 /*
1044 * Deal with the return codes.
1045 */
1046 rc = emR3HighPriorityPostForcedActions(pVM, rc);
1047 rc = emR3RawHandleRC(pVM, pCtx, rc);
1048 rc = emR3RawUpdateForceFlag(pVM, pCtx, rc);
1049 return rc;
1050}
1051
1052
1053#ifdef DEBUG
1054
1055/**
1056 * Steps hardware accelerated mode.
1057 *
1058 * @returns VBox status code.
1059 * @param pVM The VM handle.
1060 * @param idCpu VMCPU id.
1061 */
1062static int emR3HwAccStep(PVM pVM, RTCPUID idCpu)
1063{
1064 Assert(pVM->em.s.enmState == EMSTATE_DEBUG_GUEST_HWACC);
1065
1066 int rc;
1067 PCPUMCTX pCtx = pVM->em.s.pCtx;
1068 VM_FF_CLEAR(pVM, (VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS));
1069
1070 /*
1071 * Check vital forced actions, but ignore pending interrupts and timers.
1072 */
1073 if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
1074 {
1075 rc = emR3RawForcedActions(pVM, pCtx);
1076 if (RT_FAILURE(rc))
1077 return rc;
1078 }
1079 /*
1080 * Set flags for single stepping.
1081 */
1082 CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) | X86_EFL_TF | X86_EFL_RF);
1083
1084 /*
1085 * Single step.
1086 * We do not start time or anything, if anything we should just do a few nanoseconds.
1087 */
1088 do
1089 {
1090 rc = VMMR3HwAccRunGC(pVM, idCpu);
1091 } while ( rc == VINF_SUCCESS
1092 || rc == VINF_EM_RAW_INTERRUPT);
1093 VM_FF_CLEAR(pVM, VM_FF_RESUME_GUEST_MASK);
1094
1095 /*
1096 * Make sure the trap flag is cleared.
1097 * (Too bad if the guest is trying to single step too.)
1098 */
1099 CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) & ~X86_EFL_TF);
1100
1101 /*
1102 * Deal with the return codes.
1103 */
1104 rc = emR3HighPriorityPostForcedActions(pVM, rc);
1105 rc = emR3RawHandleRC(pVM, pCtx, rc);
1106 rc = emR3RawUpdateForceFlag(pVM, pCtx, rc);
1107 return rc;
1108}
1109
1110
1111void emR3SingleStepExecRaw(PVM pVM, uint32_t cIterations)
1112{
1113 EMSTATE enmOldState = pVM->em.s.enmState;
1114
1115 pVM->em.s.enmState = EMSTATE_DEBUG_GUEST_RAW;
1116
1117 Log(("Single step BEGIN:\n"));
1118 for (uint32_t i = 0; i < cIterations; i++)
1119 {
1120 DBGFR3PrgStep(pVM);
1121 DBGFR3DisasInstrCurrentLog(pVM, "RSS: ");
1122 emR3RawStep(pVM);
1123 }
1124 Log(("Single step END:\n"));
1125 CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) & ~X86_EFL_TF);
1126 pVM->em.s.enmState = enmOldState;
1127}
1128
1129
1130void emR3SingleStepExecHwAcc(PVM pVM, RTCPUID idCpu, uint32_t cIterations)
1131{
1132 EMSTATE enmOldState = pVM->em.s.enmState;
1133
1134 pVM->em.s.enmState = EMSTATE_DEBUG_GUEST_HWACC;
1135
1136 Log(("Single step BEGIN:\n"));
1137 for (uint32_t i = 0; i < cIterations; i++)
1138 {
1139 DBGFR3PrgStep(pVM);
1140 DBGFR3DisasInstrCurrentLog(pVM, "RSS: ");
1141 emR3HwAccStep(pVM, idCpu);
1142 }
1143 Log(("Single step END:\n"));
1144 CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) & ~X86_EFL_TF);
1145 pVM->em.s.enmState = enmOldState;
1146}
1147
1148
1149void emR3SingleStepExecRem(PVM pVM, uint32_t cIterations)
1150{
1151 EMSTATE enmOldState = pVM->em.s.enmState;
1152
1153 pVM->em.s.enmState = EMSTATE_DEBUG_GUEST_REM;
1154
1155 Log(("Single step BEGIN:\n"));
1156 for (uint32_t i = 0; i < cIterations; i++)
1157 {
1158 DBGFR3PrgStep(pVM);
1159 DBGFR3DisasInstrCurrentLog(pVM, "RSS: ");
1160 emR3RemStep(pVM);
1161 }
1162 Log(("Single step END:\n"));
1163 CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) & ~X86_EFL_TF);
1164 pVM->em.s.enmState = enmOldState;
1165}
1166
1167#endif /* DEBUG */
1168
1169
1170/**
1171 * Executes one (or perhaps a few more) instruction(s).
1172 *
1173 * @returns VBox status code suitable for EM.
1174 *
1175 * @param pVM VM handle.
1176 * @param rcGC GC return code
1177 * @param pszPrefix Disassembly prefix. If not NULL we'll disassemble the
1178 * instruction and prefix the log output with this text.
1179 */
1180#ifdef LOG_ENABLED
1181static int emR3RawExecuteInstructionWorker(PVM pVM, int rcGC, const char *pszPrefix)
1182#else
1183static int emR3RawExecuteInstructionWorker(PVM pVM, int rcGC)
1184#endif
1185{
1186 PCPUMCTX pCtx = pVM->em.s.pCtx;
1187 int rc;
1188
1189 /*
1190 *
1191 * The simple solution is to use the recompiler.
1192 * The better solution is to disassemble the current instruction and
1193 * try handle as many as possible without using REM.
1194 *
1195 */
1196
1197#ifdef LOG_ENABLED
1198 /*
1199 * Disassemble the instruction if requested.
1200 */
1201 if (pszPrefix)
1202 {
1203 DBGFR3InfoLog(pVM, "cpumguest", pszPrefix);
1204 DBGFR3DisasInstrCurrentLog(pVM, pszPrefix);
1205 }
1206#endif /* LOG_ENABLED */
1207
1208 /*
1209 * PATM is making life more interesting.
1210 * We cannot hand anything to REM which has an EIP inside patch code. So, we'll
1211 * tell PATM there is a trap in this code and have it take the appropriate actions
1212 * to allow us execute the code in REM.
1213 */
1214 if (PATMIsPatchGCAddr(pVM, pCtx->eip))
1215 {
1216 Log(("emR3RawExecuteInstruction: In patch block. eip=%RRv\n", (RTRCPTR)pCtx->eip));
1217
1218 RTGCPTR pNewEip;
1219 rc = PATMR3HandleTrap(pVM, pCtx, pCtx->eip, &pNewEip);
1220 switch (rc)
1221 {
1222 /*
1223 * It's not very useful to emulate a single instruction and then go back to raw
1224 * mode; just execute the whole block until IF is set again.
1225 */
1226 case VINF_SUCCESS:
1227 Log(("emR3RawExecuteInstruction: Executing instruction starting at new address %RGv IF=%d VMIF=%x\n",
1228 pNewEip, pCtx->eflags.Bits.u1IF, pVM->em.s.pPatmGCState->uVMFlags));
1229 pCtx->eip = pNewEip;
1230 Assert(pCtx->eip);
1231
1232 if (pCtx->eflags.Bits.u1IF)
1233 {
1234 /*
1235 * The last instruction in the patch block needs to be executed!! (sti/sysexit for example)
1236 */
1237 Log(("PATCH: IF=1 -> emulate last instruction as it can't be interrupted!!\n"));
1238 return emR3RawExecuteInstruction(pVM, "PATCHIR");
1239 }
1240 else if (rcGC == VINF_PATM_PENDING_IRQ_AFTER_IRET)
1241 {
1242 /* special case: iret, that sets IF, detected a pending irq/event */
1243 return emR3RawExecuteInstruction(pVM, "PATCHIRET");
1244 }
1245 return VINF_EM_RESCHEDULE_REM;
1246
1247 /*
1248 * One instruction.
1249 */
1250 case VINF_PATCH_EMULATE_INSTR:
1251 Log(("emR3RawExecuteInstruction: Emulate patched instruction at %RGv IF=%d VMIF=%x\n",
1252 pNewEip, pCtx->eflags.Bits.u1IF, pVM->em.s.pPatmGCState->uVMFlags));
1253 pCtx->eip = pNewEip;
1254 return emR3RawExecuteInstruction(pVM, "PATCHIR");
1255
1256 /*
1257 * The patch was disabled, hand it to the REM.
1258 */
1259 case VERR_PATCH_DISABLED:
1260 Log(("emR3RawExecuteInstruction: Disabled patch -> new eip %RGv IF=%d VMIF=%x\n",
1261 pNewEip, pCtx->eflags.Bits.u1IF, pVM->em.s.pPatmGCState->uVMFlags));
1262 pCtx->eip = pNewEip;
1263 if (pCtx->eflags.Bits.u1IF)
1264 {
1265 /*
1266 * The last instruction in the patch block needs to be executed!! (sti/sysexit for example)
1267 */
1268 Log(("PATCH: IF=1 -> emulate last instruction as it can't be interrupted!!\n"));
1269 return emR3RawExecuteInstruction(pVM, "PATCHIR");
1270 }
1271 return VINF_EM_RESCHEDULE_REM;
1272
1273 /* Force continued patch exection; usually due to write monitored stack. */
1274 case VINF_PATCH_CONTINUE:
1275 return VINF_SUCCESS;
1276
1277 default:
1278 AssertReleaseMsgFailed(("Unknown return code %Rrc from PATMR3HandleTrap\n", rc));
1279 return VERR_INTERNAL_ERROR;
1280 }
1281 }
1282
1283#if 0
1284 /* Try our own instruction emulator before falling back to the recompiler. */
1285 DISCPUSTATE Cpu;
1286 rc = CPUMR3DisasmInstrCPU(pVM, pCtx, pCtx->rip, &Cpu, "GEN EMU");
1287 if (RT_SUCCESS(rc))
1288 {
1289 uint32_t size;
1290
1291 switch (Cpu.pCurInstr->opcode)
1292 {
1293 /* @todo we can do more now */
1294 case OP_MOV:
1295 case OP_AND:
1296 case OP_OR:
1297 case OP_XOR:
1298 case OP_POP:
1299 case OP_INC:
1300 case OP_DEC:
1301 case OP_XCHG:
1302 STAM_PROFILE_START(&pVM->em.s.StatMiscEmu, a);
1303 rc = EMInterpretInstructionCPU(pVM, &Cpu, CPUMCTX2CORE(pCtx), 0, &size);
1304 if (RT_SUCCESS(rc))
1305 {
1306 pCtx->rip += Cpu.opsize;
1307 STAM_PROFILE_STOP(&pVM->em.s.StatMiscEmu, a);
1308 return rc;
1309 }
1310 if (rc != VERR_EM_INTERPRETER)
1311 AssertMsgFailedReturn(("rc=%Rrc\n", rc), rc);
1312 STAM_PROFILE_STOP(&pVM->em.s.StatMiscEmu, a);
1313 break;
1314 }
1315 }
1316#endif /* 0 */
1317 STAM_PROFILE_START(&pVM->em.s.StatREMEmu, a);
1318 rc = REMR3EmulateInstruction(pVM);
1319 STAM_PROFILE_STOP(&pVM->em.s.StatREMEmu, a);
1320
1321 return rc;
1322}
1323
1324
1325/**
1326 * Executes one (or perhaps a few more) instruction(s).
1327 * This is just a wrapper for discarding pszPrefix in non-logging builds.
1328 *
1329 * @returns VBox status code suitable for EM.
1330 * @param pVM VM handle.
1331 * @param pszPrefix Disassembly prefix. If not NULL we'll disassemble the
1332 * instruction and prefix the log output with this text.
1333 * @param rcGC GC return code
1334 */
1335DECLINLINE(int) emR3RawExecuteInstruction(PVM pVM, const char *pszPrefix, int rcGC)
1336{
1337#ifdef LOG_ENABLED
1338 return emR3RawExecuteInstructionWorker(pVM, rcGC, pszPrefix);
1339#else
1340 return emR3RawExecuteInstructionWorker(pVM, rcGC);
1341#endif
1342}
1343
1344/**
1345 * Executes one (or perhaps a few more) IO instruction(s).
1346 *
1347 * @returns VBox status code suitable for EM.
1348 * @param pVM VM handle.
1349 */
1350int emR3RawExecuteIOInstruction(PVM pVM)
1351{
1352 int rc;
1353 PCPUMCTX pCtx = pVM->em.s.pCtx;
1354
1355 STAM_PROFILE_START(&pVM->em.s.StatIOEmu, a);
1356
1357 /** @todo probably we should fall back to the recompiler; otherwise we'll go back and forth between HC & GC
1358 * as io instructions tend to come in packages of more than one
1359 */
1360 DISCPUSTATE Cpu;
1361 rc = CPUMR3DisasmInstrCPU(pVM, pCtx, pCtx->rip, &Cpu, "IO EMU");
1362 if (RT_SUCCESS(rc))
1363 {
1364 rc = VINF_EM_RAW_EMULATE_INSTR;
1365
1366 if (!(Cpu.prefix & (PREFIX_REP | PREFIX_REPNE)))
1367 {
1368 switch (Cpu.pCurInstr->opcode)
1369 {
1370 case OP_IN:
1371 {
1372 STAM_COUNTER_INC(&pVM->em.s.CTX_SUFF(pStats)->StatIn);
1373 rc = IOMInterpretIN(pVM, CPUMCTX2CORE(pCtx), &Cpu);
1374 break;
1375 }
1376
1377 case OP_OUT:
1378 {
1379 STAM_COUNTER_INC(&pVM->em.s.CTX_SUFF(pStats)->StatOut);
1380 rc = IOMInterpretOUT(pVM, CPUMCTX2CORE(pCtx), &Cpu);
1381 break;
1382 }
1383 }
1384 }
1385 else if (Cpu.prefix & PREFIX_REP)
1386 {
1387 switch (Cpu.pCurInstr->opcode)
1388 {
1389 case OP_INSB:
1390 case OP_INSWD:
1391 {
1392 STAM_COUNTER_INC(&pVM->em.s.CTX_SUFF(pStats)->StatIn);
1393 rc = IOMInterpretINS(pVM, CPUMCTX2CORE(pCtx), &Cpu);
1394 break;
1395 }
1396
1397 case OP_OUTSB:
1398 case OP_OUTSWD:
1399 {
1400 STAM_COUNTER_INC(&pVM->em.s.CTX_SUFF(pStats)->StatOut);
1401 rc = IOMInterpretOUTS(pVM, CPUMCTX2CORE(pCtx), &Cpu);
1402 break;
1403 }
1404 }
1405 }
1406
1407 /*
1408 * Handled the I/O return codes.
1409 * (The unhandled cases end up with rc == VINF_EM_RAW_EMULATE_INSTR.)
1410 */
1411 if (IOM_SUCCESS(rc))
1412 {
1413 pCtx->rip += Cpu.opsize;
1414 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
1415 return rc;
1416 }
1417
1418 if (rc == VINF_EM_RAW_GUEST_TRAP)
1419 {
1420 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
1421 rc = emR3RawGuestTrap(pVM);
1422 return rc;
1423 }
1424 AssertMsg(rc != VINF_TRPM_XCPT_DISPATCHED, ("Handle VINF_TRPM_XCPT_DISPATCHED\n"));
1425
1426 if (RT_FAILURE(rc))
1427 {
1428 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
1429 return rc;
1430 }
1431 AssertMsg(rc == VINF_EM_RAW_EMULATE_INSTR || rc == VINF_EM_RESCHEDULE_REM, ("rc=%Rrc\n", rc));
1432 }
1433 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
1434 return emR3RawExecuteInstruction(pVM, "IO: ");
1435}
1436
1437
1438/**
1439 * Handle a guest context trap.
1440 *
1441 * @returns VBox status code suitable for EM.
1442 * @param pVM VM handle.
1443 */
1444static int emR3RawGuestTrap(PVM pVM)
1445{
1446 PCPUMCTX pCtx = pVM->em.s.pCtx;
1447
1448 /*
1449 * Get the trap info.
1450 */
1451 uint8_t u8TrapNo;
1452 TRPMEVENT enmType;
1453 RTGCUINT uErrorCode;
1454 RTGCUINTPTR uCR2;
1455 int rc = TRPMQueryTrapAll(pVM, &u8TrapNo, &enmType, &uErrorCode, &uCR2);
1456 if (RT_FAILURE(rc))
1457 {
1458 AssertReleaseMsgFailed(("No trap! (rc=%Rrc)\n", rc));
1459 return rc;
1460 }
1461
1462 /*
1463 * Traps can be directly forwarded in hardware accelerated mode.
1464 */
1465 if (HWACCMR3IsActive(pVM))
1466 {
1467#ifdef LOGGING_ENABLED
1468 DBGFR3InfoLog(pVM, "cpumguest", "Guest trap");
1469 DBGFR3DisasInstrCurrentLog(pVM, "Guest trap");
1470#endif
1471 return VINF_EM_RESCHEDULE_HWACC;
1472 }
1473
1474#if 1 /* Experimental: Review, disable if it causes trouble. */
1475 /*
1476 * Handle traps in patch code first.
1477 *
1478 * We catch a few of these cases in RC before returning to R3 (#PF, #GP, #BP)
1479 * but several traps isn't handled specially by TRPM in RC and we end up here
1480 * instead. One example is #DE.
1481 */
1482 uint32_t uCpl = CPUMGetGuestCPL(pVM, CPUMCTX2CORE(pCtx));
1483 if ( uCpl == 0
1484 && PATMIsPatchGCAddr(pVM, (RTGCPTR)pCtx->eip))
1485 {
1486 LogFlow(("emR3RawGuestTrap: trap %#x in patch code; eip=%08x\n", u8TrapNo, pCtx->eip));
1487 return emR3PatchTrap(pVM, pCtx, rc);
1488 }
1489#endif
1490
1491 /*
1492 * If the guest gate is marked unpatched, then we will check again if we can patch it.
1493 * (This assumes that we've already tried and failed to dispatch the trap in
1494 * RC for the gates that already has been patched. Which is true for most high
1495 * volume traps, because these are handled specially, but not for odd ones like #DE.)
1496 */
1497 if (TRPMR3GetGuestTrapHandler(pVM, u8TrapNo) == TRPM_INVALID_HANDLER)
1498 {
1499 CSAMR3CheckGates(pVM, u8TrapNo, 1);
1500 Log(("emR3RawHandleRC: recheck gate %x -> valid=%d\n", u8TrapNo, TRPMR3GetGuestTrapHandler(pVM, u8TrapNo) != TRPM_INVALID_HANDLER));
1501
1502 /* If it was successful, then we could go back to raw mode. */
1503 if (TRPMR3GetGuestTrapHandler(pVM, u8TrapNo) != TRPM_INVALID_HANDLER)
1504 {
1505 /* Must check pending forced actions as our IDT or GDT might be out of sync. */
1506 rc = EMR3CheckRawForcedActions(pVM);
1507 AssertRCReturn(rc, rc);
1508
1509 TRPMERRORCODE enmError = uErrorCode != ~0U
1510 ? TRPM_TRAP_HAS_ERRORCODE
1511 : TRPM_TRAP_NO_ERRORCODE;
1512 rc = TRPMForwardTrap(pVM, CPUMCTX2CORE(pCtx), u8TrapNo, uErrorCode, enmError, TRPM_TRAP, -1);
1513 if (rc == VINF_SUCCESS /* Don't use RT_SUCCESS */)
1514 {
1515 TRPMResetTrap(pVM);
1516 return VINF_EM_RESCHEDULE_RAW;
1517 }
1518 AssertMsg(rc == VINF_EM_RAW_GUEST_TRAP, ("%Rrc\n", rc));
1519 }
1520 }
1521
1522 /*
1523 * Scan kernel code that traps; we might not get another chance.
1524 */
1525 /** @todo move this up before the dispatching? */
1526 if ( (pCtx->ss & X86_SEL_RPL) <= 1
1527 && !pCtx->eflags.Bits.u1VM)
1528 {
1529 Assert(!PATMIsPatchGCAddr(pVM, pCtx->eip));
1530 CSAMR3CheckCodeEx(pVM, CPUMCTX2CORE(pCtx), pCtx->eip);
1531 }
1532
1533 /*
1534 * Trap specific handling.
1535 */
1536 if (u8TrapNo == 6) /* (#UD) Invalid opcode. */
1537 {
1538 /*
1539 * If MONITOR & MWAIT are supported, then interpret them here.
1540 */
1541 DISCPUSTATE cpu;
1542 rc = CPUMR3DisasmInstrCPU(pVM, pCtx, pCtx->rip, &cpu, "Guest Trap (#UD): ");
1543 if ( RT_SUCCESS(rc)
1544 && (cpu.pCurInstr->opcode == OP_MONITOR || cpu.pCurInstr->opcode == OP_MWAIT))
1545 {
1546 uint32_t u32Dummy, u32Features, u32ExtFeatures;
1547 CPUMGetGuestCpuId(pVM, 1, &u32Dummy, &u32Dummy, &u32ExtFeatures, &u32Features);
1548 if (u32ExtFeatures & X86_CPUID_FEATURE_ECX_MONITOR)
1549 {
1550 rc = TRPMResetTrap(pVM);
1551 AssertRC(rc);
1552
1553 uint32_t opsize;
1554 rc = EMInterpretInstructionCPU(pVM, &cpu, CPUMCTX2CORE(pCtx), 0, &opsize);
1555 if (RT_SUCCESS(rc))
1556 {
1557 pCtx->rip += cpu.opsize;
1558 return rc;
1559 }
1560 return emR3RawExecuteInstruction(pVM, "Monitor: ");
1561 }
1562 }
1563 }
1564 else if (u8TrapNo == 13) /* (#GP) Privileged exception */
1565 {
1566 /*
1567 * Handle I/O bitmap?
1568 */
1569 /** @todo We're not supposed to be here with a false guest trap concerning
1570 * I/O access. We can easily handle those in RC. */
1571 DISCPUSTATE cpu;
1572 rc = CPUMR3DisasmInstrCPU(pVM, pCtx, pCtx->rip, &cpu, "Guest Trap: ");
1573 if ( RT_SUCCESS(rc)
1574 && (cpu.pCurInstr->optype & OPTYPE_PORTIO))
1575 {
1576 /*
1577 * We should really check the TSS for the IO bitmap, but it's not like this
1578 * lazy approach really makes things worse.
1579 */
1580 rc = TRPMResetTrap(pVM);
1581 AssertRC(rc);
1582 return emR3RawExecuteInstruction(pVM, "IO Guest Trap: ");
1583 }
1584 }
1585
1586#ifdef LOG_ENABLED
1587 DBGFR3InfoLog(pVM, "cpumguest", "Guest trap");
1588 DBGFR3DisasInstrCurrentLog(pVM, "Guest trap");
1589
1590 /* Get guest page information. */
1591 uint64_t fFlags = 0;
1592 RTGCPHYS GCPhys = 0;
1593 int rc2 = PGMGstGetPage(pVM, uCR2, &fFlags, &GCPhys);
1594 Log(("emR3RawGuestTrap: cs:eip=%04x:%08x: trap=%02x err=%08x cr2=%08x cr0=%08x%s: Phys=%RGp fFlags=%08llx %s %s %s%s rc2=%d\n",
1595 pCtx->cs, pCtx->eip, u8TrapNo, uErrorCode, uCR2, (uint32_t)pCtx->cr0, (enmType == TRPM_SOFTWARE_INT) ? " software" : "", GCPhys, fFlags,
1596 fFlags & X86_PTE_P ? "P " : "NP", fFlags & X86_PTE_US ? "U" : "S",
1597 fFlags & X86_PTE_RW ? "RW" : "R0", fFlags & X86_PTE_G ? " G" : "", rc2));
1598#endif
1599
1600 /*
1601 * #PG has CR2.
1602 * (Because of stuff like above we must set CR2 in a delayed fashion.)
1603 */
1604 if (u8TrapNo == 14 /* #PG */)
1605 pCtx->cr2 = uCR2;
1606
1607 return VINF_EM_RESCHEDULE_REM;
1608}
1609
1610
1611/**
1612 * Handle a ring switch trap.
1613 * Need to do statistics and to install patches. The result is going to REM.
1614 *
1615 * @returns VBox status code suitable for EM.
1616 * @param pVM VM handle.
1617 */
1618int emR3RawRingSwitch(PVM pVM)
1619{
1620 int rc;
1621 DISCPUSTATE Cpu;
1622 PCPUMCTX pCtx = pVM->em.s.pCtx;
1623
1624 /*
1625 * sysenter, syscall & callgate
1626 */
1627 rc = CPUMR3DisasmInstrCPU(pVM, pCtx, pCtx->rip, &Cpu, "RSWITCH: ");
1628 if (RT_SUCCESS(rc))
1629 {
1630 if (Cpu.pCurInstr->opcode == OP_SYSENTER)
1631 {
1632 if (pCtx->SysEnter.cs != 0)
1633 {
1634 rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DIS_SELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip),
1635 (SELMGetCpuModeFromSelector(pVM, pCtx->eflags, pCtx->cs, &pCtx->csHid) == CPUMODE_32BIT) ? PATMFL_CODE32 : 0);
1636 if (RT_SUCCESS(rc))
1637 {
1638 DBGFR3DisasInstrCurrentLog(pVM, "Patched sysenter instruction");
1639 return VINF_EM_RESCHEDULE_RAW;
1640 }
1641 }
1642 }
1643
1644#ifdef VBOX_WITH_STATISTICS
1645 switch (Cpu.pCurInstr->opcode)
1646 {
1647 case OP_SYSENTER:
1648 STAM_COUNTER_INC(&pVM->em.s.CTX_SUFF(pStats)->StatSysEnter);
1649 break;
1650 case OP_SYSEXIT:
1651 STAM_COUNTER_INC(&pVM->em.s.CTX_SUFF(pStats)->StatSysExit);
1652 break;
1653 case OP_SYSCALL:
1654 STAM_COUNTER_INC(&pVM->em.s.CTX_SUFF(pStats)->StatSysCall);
1655 break;
1656 case OP_SYSRET:
1657 STAM_COUNTER_INC(&pVM->em.s.CTX_SUFF(pStats)->StatSysRet);
1658 break;
1659 }
1660#endif
1661 }
1662 else
1663 AssertRC(rc);
1664
1665 /* go to the REM to emulate a single instruction */
1666 return emR3RawExecuteInstruction(pVM, "RSWITCH: ");
1667}
1668
1669
1670/**
1671 * Handle a trap (\#PF or \#GP) in patch code
1672 *
1673 * @returns VBox status code suitable for EM.
1674 * @param pVM VM handle.
1675 * @param pCtx CPU context
1676 * @param gcret GC return code
1677 */
1678static int emR3PatchTrap(PVM pVM, PCPUMCTX pCtx, int gcret)
1679{
1680 uint8_t u8TrapNo;
1681 int rc;
1682 TRPMEVENT enmType;
1683 RTGCUINT uErrorCode;
1684 RTGCUINTPTR uCR2;
1685
1686 Assert(PATMIsPatchGCAddr(pVM, pCtx->eip));
1687
1688 if (gcret == VINF_PATM_PATCH_INT3)
1689 {
1690 u8TrapNo = 3;
1691 uCR2 = 0;
1692 uErrorCode = 0;
1693 }
1694 else if (gcret == VINF_PATM_PATCH_TRAP_GP)
1695 {
1696 /* No active trap in this case. Kind of ugly. */
1697 u8TrapNo = X86_XCPT_GP;
1698 uCR2 = 0;
1699 uErrorCode = 0;
1700 }
1701 else
1702 {
1703 rc = TRPMQueryTrapAll(pVM, &u8TrapNo, &enmType, &uErrorCode, &uCR2);
1704 if (RT_FAILURE(rc))
1705 {
1706 AssertReleaseMsgFailed(("emR3PatchTrap: no trap! (rc=%Rrc) gcret=%Rrc\n", rc, gcret));
1707 return rc;
1708 }
1709 /* Reset the trap as we'll execute the original instruction again. */
1710 TRPMResetTrap(pVM);
1711 }
1712
1713 /*
1714 * Deal with traps inside patch code.
1715 * (This code won't run outside GC.)
1716 */
1717 if (u8TrapNo != 1)
1718 {
1719#ifdef LOG_ENABLED
1720 DBGFR3InfoLog(pVM, "cpumguest", "Trap in patch code");
1721 DBGFR3DisasInstrCurrentLog(pVM, "Patch code");
1722
1723 DISCPUSTATE Cpu;
1724 int rc;
1725
1726 rc = CPUMR3DisasmInstrCPU(pVM, pCtx, pCtx->eip, &Cpu, "Patch code: ");
1727 if ( RT_SUCCESS(rc)
1728 && Cpu.pCurInstr->opcode == OP_IRET)
1729 {
1730 uint32_t eip, selCS, uEFlags;
1731
1732 /* Iret crashes are bad as we have already changed the flags on the stack */
1733 rc = PGMPhysSimpleReadGCPtr(pVM, &eip, pCtx->esp, 4);
1734 rc |= PGMPhysSimpleReadGCPtr(pVM, &selCS, pCtx->esp+4, 4);
1735 rc |= PGMPhysSimpleReadGCPtr(pVM, &uEFlags, pCtx->esp+8, 4);
1736 if (rc == VINF_SUCCESS)
1737 {
1738 if ( (uEFlags & X86_EFL_VM)
1739 || (selCS & X86_SEL_RPL) == 3)
1740 {
1741 uint32_t selSS, esp;
1742
1743 rc |= PGMPhysSimpleReadGCPtr(pVM, &esp, pCtx->esp + 12, 4);
1744 rc |= PGMPhysSimpleReadGCPtr(pVM, &selSS, pCtx->esp + 16, 4);
1745
1746 if (uEFlags & X86_EFL_VM)
1747 {
1748 uint32_t selDS, selES, selFS, selGS;
1749 rc = PGMPhysSimpleReadGCPtr(pVM, &selES, pCtx->esp + 20, 4);
1750 rc |= PGMPhysSimpleReadGCPtr(pVM, &selDS, pCtx->esp + 24, 4);
1751 rc |= PGMPhysSimpleReadGCPtr(pVM, &selFS, pCtx->esp + 28, 4);
1752 rc |= PGMPhysSimpleReadGCPtr(pVM, &selGS, pCtx->esp + 32, 4);
1753 if (rc == VINF_SUCCESS)
1754 {
1755 Log(("Patch code: IRET->VM stack frame: return address %04X:%08RX32 eflags=%08x ss:esp=%04X:%08RX32\n", selCS, eip, uEFlags, selSS, esp));
1756 Log(("Patch code: IRET->VM stack frame: DS=%04X ES=%04X FS=%04X GS=%04X\n", selDS, selES, selFS, selGS));
1757 }
1758 }
1759 else
1760 Log(("Patch code: IRET stack frame: return address %04X:%08RX32 eflags=%08x ss:esp=%04X:%08RX32\n", selCS, eip, uEFlags, selSS, esp));
1761 }
1762 else
1763 Log(("Patch code: IRET stack frame: return address %04X:%08RX32 eflags=%08x\n", selCS, eip, uEFlags));
1764 }
1765 }
1766#endif /* LOG_ENABLED */
1767 Log(("emR3PatchTrap: in patch: eip=%08x: trap=%02x err=%08x cr2=%08x cr0=%08x\n",
1768 pCtx->eip, u8TrapNo, uErrorCode, uCR2, (uint32_t)pCtx->cr0));
1769
1770 RTGCPTR pNewEip;
1771 rc = PATMR3HandleTrap(pVM, pCtx, pCtx->eip, &pNewEip);
1772 switch (rc)
1773 {
1774 /*
1775 * Execute the faulting instruction.
1776 */
1777 case VINF_SUCCESS:
1778 {
1779 /** @todo execute a whole block */
1780 Log(("emR3PatchTrap: Executing faulting instruction at new address %RGv\n", pNewEip));
1781 if (!(pVM->em.s.pPatmGCState->uVMFlags & X86_EFL_IF))
1782 Log(("emR3PatchTrap: Virtual IF flag disabled!!\n"));
1783
1784 pCtx->eip = pNewEip;
1785 AssertRelease(pCtx->eip);
1786
1787 if (pCtx->eflags.Bits.u1IF)
1788 {
1789 /* Windows XP lets irets fault intentionally and then takes action based on the opcode; an
1790 * int3 patch overwrites it and leads to blue screens. Remove the patch in this case.
1791 */
1792 if ( u8TrapNo == X86_XCPT_GP
1793 && PATMIsInt3Patch(pVM, pCtx->eip, NULL, NULL))
1794 {
1795 /** @todo move to PATMR3HandleTrap */
1796 Log(("Possible Windows XP iret fault at %08RX32\n", pCtx->eip));
1797 PATMR3RemovePatch(pVM, pCtx->eip);
1798 }
1799
1800 /** @todo Knoppix 5 regression when returning VINF_SUCCESS here and going back to raw mode. */
1801 /* Note: possibly because a reschedule is required (e.g. iret to V86 code) */
1802
1803 return emR3RawExecuteInstruction(pVM, "PATCHIR");
1804 /* Interrupts are enabled; just go back to the original instruction.
1805 return VINF_SUCCESS; */
1806 }
1807 return VINF_EM_RESCHEDULE_REM;
1808 }
1809
1810 /*
1811 * One instruction.
1812 */
1813 case VINF_PATCH_EMULATE_INSTR:
1814 Log(("emR3PatchTrap: Emulate patched instruction at %RGv IF=%d VMIF=%x\n",
1815 pNewEip, pCtx->eflags.Bits.u1IF, pVM->em.s.pPatmGCState->uVMFlags));
1816 pCtx->eip = pNewEip;
1817 AssertRelease(pCtx->eip);
1818 return emR3RawExecuteInstruction(pVM, "PATCHEMUL: ");
1819
1820 /*
1821 * The patch was disabled, hand it to the REM.
1822 */
1823 case VERR_PATCH_DISABLED:
1824 if (!(pVM->em.s.pPatmGCState->uVMFlags & X86_EFL_IF))
1825 Log(("emR3PatchTrap: Virtual IF flag disabled!!\n"));
1826 pCtx->eip = pNewEip;
1827 AssertRelease(pCtx->eip);
1828
1829 if (pCtx->eflags.Bits.u1IF)
1830 {
1831 /*
1832 * The last instruction in the patch block needs to be executed!! (sti/sysexit for example)
1833 */
1834 Log(("PATCH: IF=1 -> emulate last instruction as it can't be interrupted!!\n"));
1835 return emR3RawExecuteInstruction(pVM, "PATCHIR");
1836 }
1837 return VINF_EM_RESCHEDULE_REM;
1838
1839 /* Force continued patch exection; usually due to write monitored stack. */
1840 case VINF_PATCH_CONTINUE:
1841 return VINF_SUCCESS;
1842
1843 /*
1844 * Anything else is *fatal*.
1845 */
1846 default:
1847 AssertReleaseMsgFailed(("Unknown return code %Rrc from PATMR3HandleTrap!\n", rc));
1848 return VERR_INTERNAL_ERROR;
1849 }
1850 }
1851 return VINF_SUCCESS;
1852}
1853
1854
1855/**
1856 * Handle a privileged instruction.
1857 *
1858 * @returns VBox status code suitable for EM.
1859 * @param pVM VM handle.
1860 */
1861int emR3RawPrivileged(PVM pVM)
1862{
1863 STAM_PROFILE_START(&pVM->em.s.StatPrivEmu, a);
1864 PCPUMCTX pCtx = pVM->em.s.pCtx;
1865
1866 Assert(!pCtx->eflags.Bits.u1VM);
1867
1868 if (PATMIsEnabled(pVM))
1869 {
1870 /*
1871 * Check if in patch code.
1872 */
1873 if (PATMR3IsInsidePatchJump(pVM, pCtx->eip, NULL))
1874 {
1875#ifdef LOG_ENABLED
1876 DBGFR3InfoLog(pVM, "cpumguest", "PRIV");
1877#endif
1878 AssertMsgFailed(("FATAL ERROR: executing random instruction inside generated patch jump %08X\n", pCtx->eip));
1879 return VERR_EM_RAW_PATCH_CONFLICT;
1880 }
1881 if ( (pCtx->ss & X86_SEL_RPL) == 0
1882 && !pCtx->eflags.Bits.u1VM
1883 && !PATMIsPatchGCAddr(pVM, pCtx->eip))
1884 {
1885 int rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DIS_SELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip),
1886 (SELMGetCpuModeFromSelector(pVM, pCtx->eflags, pCtx->cs, &pCtx->csHid) == CPUMODE_32BIT) ? PATMFL_CODE32 : 0);
1887 if (RT_SUCCESS(rc))
1888 {
1889#ifdef LOG_ENABLED
1890 DBGFR3InfoLog(pVM, "cpumguest", "PRIV");
1891#endif
1892 DBGFR3DisasInstrCurrentLog(pVM, "Patched privileged instruction");
1893 return VINF_SUCCESS;
1894 }
1895 }
1896 }
1897
1898#ifdef LOG_ENABLED
1899 if (!PATMIsPatchGCAddr(pVM, pCtx->eip))
1900 {
1901 DBGFR3InfoLog(pVM, "cpumguest", "PRIV");
1902 DBGFR3DisasInstrCurrentLog(pVM, "Privileged instr: ");
1903 }
1904#endif
1905
1906 /*
1907 * Instruction statistics and logging.
1908 */
1909 DISCPUSTATE Cpu;
1910 int rc;
1911
1912 rc = CPUMR3DisasmInstrCPU(pVM, pCtx, pCtx->rip, &Cpu, "PRIV: ");
1913 if (RT_SUCCESS(rc))
1914 {
1915#ifdef VBOX_WITH_STATISTICS
1916 PEMSTATS pStats = pVM->em.s.CTX_SUFF(pStats);
1917 switch (Cpu.pCurInstr->opcode)
1918 {
1919 case OP_INVLPG:
1920 STAM_COUNTER_INC(&pStats->StatInvlpg);
1921 break;
1922 case OP_IRET:
1923 STAM_COUNTER_INC(&pStats->StatIret);
1924 break;
1925 case OP_CLI:
1926 STAM_COUNTER_INC(&pStats->StatCli);
1927 emR3RecordCli(pVM, pCtx->rip);
1928 break;
1929 case OP_STI:
1930 STAM_COUNTER_INC(&pStats->StatSti);
1931 break;
1932 case OP_INSB:
1933 case OP_INSWD:
1934 case OP_IN:
1935 case OP_OUTSB:
1936 case OP_OUTSWD:
1937 case OP_OUT:
1938 AssertMsgFailed(("Unexpected privileged exception due to port IO\n"));
1939 break;
1940
1941 case OP_MOV_CR:
1942 if (Cpu.param1.flags & USE_REG_GEN32)
1943 {
1944 //read
1945 Assert(Cpu.param2.flags & USE_REG_CR);
1946 Assert(Cpu.param2.base.reg_ctrl <= USE_REG_CR4);
1947 STAM_COUNTER_INC(&pStats->StatMovReadCR[Cpu.param2.base.reg_ctrl]);
1948 }
1949 else
1950 {
1951 //write
1952 Assert(Cpu.param1.flags & USE_REG_CR);
1953 Assert(Cpu.param1.base.reg_ctrl <= USE_REG_CR4);
1954 STAM_COUNTER_INC(&pStats->StatMovWriteCR[Cpu.param1.base.reg_ctrl]);
1955 }
1956 break;
1957
1958 case OP_MOV_DR:
1959 STAM_COUNTER_INC(&pStats->StatMovDRx);
1960 break;
1961 case OP_LLDT:
1962 STAM_COUNTER_INC(&pStats->StatMovLldt);
1963 break;
1964 case OP_LIDT:
1965 STAM_COUNTER_INC(&pStats->StatMovLidt);
1966 break;
1967 case OP_LGDT:
1968 STAM_COUNTER_INC(&pStats->StatMovLgdt);
1969 break;
1970 case OP_SYSENTER:
1971 STAM_COUNTER_INC(&pStats->StatSysEnter);
1972 break;
1973 case OP_SYSEXIT:
1974 STAM_COUNTER_INC(&pStats->StatSysExit);
1975 break;
1976 case OP_SYSCALL:
1977 STAM_COUNTER_INC(&pStats->StatSysCall);
1978 break;
1979 case OP_SYSRET:
1980 STAM_COUNTER_INC(&pStats->StatSysRet);
1981 break;
1982 case OP_HLT:
1983 STAM_COUNTER_INC(&pStats->StatHlt);
1984 break;
1985 default:
1986 STAM_COUNTER_INC(&pStats->StatMisc);
1987 Log4(("emR3RawPrivileged: opcode=%d\n", Cpu.pCurInstr->opcode));
1988 break;
1989 }
1990#endif /* VBOX_WITH_STATISTICS */
1991 if ( (pCtx->ss & X86_SEL_RPL) == 0
1992 && !pCtx->eflags.Bits.u1VM
1993 && SELMGetCpuModeFromSelector(pVM, pCtx->eflags, pCtx->cs, &pCtx->csHid) == CPUMODE_32BIT)
1994 {
1995 uint32_t size;
1996
1997 STAM_PROFILE_START(&pVM->em.s.StatPrivEmu, a);
1998 switch (Cpu.pCurInstr->opcode)
1999 {
2000 case OP_CLI:
2001 pCtx->eflags.u32 &= ~X86_EFL_IF;
2002 Assert(Cpu.opsize == 1);
2003 pCtx->rip += Cpu.opsize;
2004 STAM_PROFILE_STOP(&pVM->em.s.StatPrivEmu, a);
2005 return VINF_EM_RESCHEDULE_REM; /* must go to the recompiler now! */
2006
2007 case OP_STI:
2008 pCtx->eflags.u32 |= X86_EFL_IF;
2009 EMSetInhibitInterruptsPC(pVM, pCtx->rip + Cpu.opsize);
2010 Assert(Cpu.opsize == 1);
2011 pCtx->rip += Cpu.opsize;
2012 STAM_PROFILE_STOP(&pVM->em.s.StatPrivEmu, a);
2013 return VINF_SUCCESS;
2014
2015 case OP_HLT:
2016 if (PATMIsPatchGCAddr(pVM, (RTGCPTR)pCtx->eip))
2017 {
2018 PATMTRANSSTATE enmState;
2019 RTGCPTR pOrgInstrGC = PATMR3PatchToGCPtr(pVM, pCtx->eip, &enmState);
2020
2021 if (enmState == PATMTRANS_OVERWRITTEN)
2022 {
2023 rc = PATMR3DetectConflict(pVM, pOrgInstrGC, pOrgInstrGC);
2024 Assert(rc == VERR_PATCH_DISABLED);
2025 /* Conflict detected, patch disabled */
2026 Log(("emR3RawPrivileged: detected conflict -> disabled patch at %08RX32\n", pCtx->eip));
2027
2028 enmState = PATMTRANS_SAFE;
2029 }
2030
2031 /* The translation had better be successful. Otherwise we can't recover. */
2032 AssertReleaseMsg(pOrgInstrGC && enmState != PATMTRANS_OVERWRITTEN, ("Unable to translate instruction address at %08RX32\n", pCtx->eip));
2033 if (enmState != PATMTRANS_OVERWRITTEN)
2034 pCtx->eip = pOrgInstrGC;
2035 }
2036 /* no break; we could just return VINF_EM_HALT here */
2037
2038 case OP_MOV_CR:
2039 case OP_MOV_DR:
2040#ifdef LOG_ENABLED
2041 if (PATMIsPatchGCAddr(pVM, pCtx->eip))
2042 {
2043 DBGFR3InfoLog(pVM, "cpumguest", "PRIV");
2044 DBGFR3DisasInstrCurrentLog(pVM, "Privileged instr: ");
2045 }
2046#endif
2047
2048 rc = EMInterpretInstructionCPU(pVM, &Cpu, CPUMCTX2CORE(pCtx), 0, &size);
2049 if (RT_SUCCESS(rc))
2050 {
2051 pCtx->rip += Cpu.opsize;
2052 STAM_PROFILE_STOP(&pVM->em.s.StatPrivEmu, a);
2053
2054 if ( Cpu.pCurInstr->opcode == OP_MOV_CR
2055 && Cpu.param1.flags == USE_REG_CR /* write */
2056 )
2057 {
2058 /* Deal with CR0 updates inside patch code that force
2059 * us to go to the recompiler.
2060 */
2061 if ( PATMIsPatchGCAddr(pVM, pCtx->rip)
2062 && (pCtx->cr0 & (X86_CR0_WP|X86_CR0_PG|X86_CR0_PE)) != (X86_CR0_WP|X86_CR0_PG|X86_CR0_PE))
2063 {
2064 PATMTRANSSTATE enmState;
2065 RTGCPTR pOrgInstrGC = PATMR3PatchToGCPtr(pVM, pCtx->rip, &enmState);
2066
2067 Assert(pCtx->eflags.Bits.u1IF == 0);
2068 Log(("Force recompiler switch due to cr0 (%RGp) update\n", pCtx->cr0));
2069 if (enmState == PATMTRANS_OVERWRITTEN)
2070 {
2071 rc = PATMR3DetectConflict(pVM, pOrgInstrGC, pOrgInstrGC);
2072 Assert(rc == VERR_PATCH_DISABLED);
2073 /* Conflict detected, patch disabled */
2074 Log(("emR3RawPrivileged: detected conflict -> disabled patch at %RGv\n", (RTGCPTR)pCtx->rip));
2075 enmState = PATMTRANS_SAFE;
2076 }
2077 /* The translation had better be successful. Otherwise we can't recover. */
2078 AssertReleaseMsg(pOrgInstrGC && enmState != PATMTRANS_OVERWRITTEN, ("Unable to translate instruction address at %RGv\n", (RTGCPTR)pCtx->rip));
2079 if (enmState != PATMTRANS_OVERWRITTEN)
2080 pCtx->rip = pOrgInstrGC;
2081 }
2082
2083 /* Reschedule is necessary as the execution/paging mode might have changed. */
2084 return VINF_EM_RESCHEDULE;
2085 }
2086 return rc; /* can return VINF_EM_HALT as well. */
2087 }
2088 AssertMsgReturn(rc == VERR_EM_INTERPRETER, ("%Rrc\n", rc), rc);
2089 break; /* fall back to the recompiler */
2090 }
2091 STAM_PROFILE_STOP(&pVM->em.s.StatPrivEmu, a);
2092 }
2093 }
2094
2095 if (PATMIsPatchGCAddr(pVM, pCtx->eip))
2096 return emR3PatchTrap(pVM, pCtx, VINF_PATM_PATCH_TRAP_GP);
2097
2098 return emR3RawExecuteInstruction(pVM, "PRIV");
2099}
2100
2101
2102/**
2103 * Update the forced rawmode execution modifier.
2104 *
2105 * This function is called when we're returning from the raw-mode loop(s). If we're
2106 * in patch code, it will set a flag forcing execution to be resumed in raw-mode,
2107 * if not in patch code, the flag will be cleared.
2108 *
2109 * We should never interrupt patch code while it's being executed. Cli patches can
2110 * contain big code blocks, but they are always executed with IF=0. Other patches
2111 * replace single instructions and should be atomic.
2112 *
2113 * @returns Updated rc.
2114 *
2115 * @param pVM The VM handle.
2116 * @param pCtx The guest CPU context.
2117 * @param rc The result code.
2118 */
2119DECLINLINE(int) emR3RawUpdateForceFlag(PVM pVM, PCPUMCTX pCtx, int rc)
2120{
2121 if (PATMIsPatchGCAddr(pVM, pCtx->eip)) /** @todo check cs selector base/type */
2122 {
2123 /* ignore reschedule attempts. */
2124 switch (rc)
2125 {
2126 case VINF_EM_RESCHEDULE:
2127 case VINF_EM_RESCHEDULE_REM:
2128 rc = VINF_SUCCESS;
2129 break;
2130 }
2131 pVM->em.s.fForceRAW = true;
2132 }
2133 else
2134 pVM->em.s.fForceRAW = false;
2135 return rc;
2136}
2137
2138
2139/**
2140 * Process a subset of the raw-mode return code.
2141 *
2142 * Since we have to share this with raw-mode single stepping, this inline
2143 * function has been created to avoid code duplication.
2144 *
2145 * @returns VINF_SUCCESS if it's ok to continue raw mode.
2146 * @returns VBox status code to return to the EM main loop.
2147 *
2148 * @param pVM The VM handle
2149 * @param rc The return code.
2150 * @param pCtx The guest cpu context.
2151 */
2152DECLINLINE(int) emR3RawHandleRC(PVM pVM, PCPUMCTX pCtx, int rc)
2153{
2154 switch (rc)
2155 {
2156 /*
2157 * Common & simple ones.
2158 */
2159 case VINF_SUCCESS:
2160 break;
2161 case VINF_EM_RESCHEDULE_RAW:
2162 case VINF_EM_RESCHEDULE_HWACC:
2163 case VINF_EM_RAW_INTERRUPT:
2164 case VINF_EM_RAW_TO_R3:
2165 case VINF_EM_RAW_TIMER_PENDING:
2166 case VINF_EM_PENDING_REQUEST:
2167 rc = VINF_SUCCESS;
2168 break;
2169
2170 /*
2171 * Privileged instruction.
2172 */
2173 case VINF_EM_RAW_EXCEPTION_PRIVILEGED:
2174 case VINF_PATM_PATCH_TRAP_GP:
2175 rc = emR3RawPrivileged(pVM);
2176 break;
2177
2178 /*
2179 * Got a trap which needs dispatching.
2180 */
2181 case VINF_EM_RAW_GUEST_TRAP:
2182 if (PATMR3IsInsidePatchJump(pVM, pCtx->eip, NULL))
2183 {
2184 AssertReleaseMsgFailed(("FATAL ERROR: executing random instruction inside generated patch jump %08X\n", CPUMGetGuestEIP(pVM)));
2185 rc = VERR_EM_RAW_PATCH_CONFLICT;
2186 break;
2187 }
2188 rc = emR3RawGuestTrap(pVM);
2189 break;
2190
2191 /*
2192 * Trap in patch code.
2193 */
2194 case VINF_PATM_PATCH_TRAP_PF:
2195 case VINF_PATM_PATCH_INT3:
2196 rc = emR3PatchTrap(pVM, pCtx, rc);
2197 break;
2198
2199 case VINF_PATM_DUPLICATE_FUNCTION:
2200 Assert(PATMIsPatchGCAddr(pVM, (RTGCPTR)pCtx->eip));
2201 rc = PATMR3DuplicateFunctionRequest(pVM, pCtx);
2202 AssertRC(rc);
2203 rc = VINF_SUCCESS;
2204 break;
2205
2206 case VINF_PATM_CHECK_PATCH_PAGE:
2207 rc = PATMR3HandleMonitoredPage(pVM);
2208 AssertRC(rc);
2209 rc = VINF_SUCCESS;
2210 break;
2211
2212 /*
2213 * Patch manager.
2214 */
2215 case VERR_EM_RAW_PATCH_CONFLICT:
2216 AssertReleaseMsgFailed(("%Rrc handling is not yet implemented\n", rc));
2217 break;
2218
2219#ifdef VBOX_WITH_VMI
2220 /*
2221 * PARAV function.
2222 */
2223 case VINF_EM_RESCHEDULE_PARAV:
2224 rc = PARAVCallFunction(pVM);
2225 break;
2226#endif
2227
2228 /*
2229 * Memory mapped I/O access - attempt to patch the instruction
2230 */
2231 case VINF_PATM_HC_MMIO_PATCH_READ:
2232 rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DIS_SELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip),
2233 PATMFL_MMIO_ACCESS | ((SELMGetCpuModeFromSelector(pVM, pCtx->eflags, pCtx->cs, &pCtx->csHid) == CPUMODE_32BIT) ? PATMFL_CODE32 : 0));
2234 if (RT_FAILURE(rc))
2235 rc = emR3RawExecuteInstruction(pVM, "MMIO");
2236 break;
2237
2238 case VINF_PATM_HC_MMIO_PATCH_WRITE:
2239 AssertFailed(); /* not yet implemented. */
2240 rc = emR3RawExecuteInstruction(pVM, "MMIO");
2241 break;
2242
2243 /*
2244 * Conflict or out of page tables.
2245 *
2246 * VM_FF_PGM_SYNC_CR3 is set by the hypervisor and all we need to
2247 * do here is to execute the pending forced actions.
2248 */
2249 case VINF_PGM_SYNC_CR3:
2250 AssertMsg(VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL),
2251 ("VINF_PGM_SYNC_CR3 and no VM_FF_PGM_SYNC_CR3*!\n"));
2252 rc = VINF_SUCCESS;
2253 break;
2254
2255 /*
2256 * Paging mode change.
2257 */
2258 case VINF_PGM_CHANGE_MODE:
2259 rc = PGMChangeMode(pVM, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
2260 if (RT_SUCCESS(rc))
2261 rc = VINF_EM_RESCHEDULE;
2262 break;
2263
2264 /*
2265 * CSAM wants to perform a task in ring-3. It has set an FF action flag.
2266 */
2267 case VINF_CSAM_PENDING_ACTION:
2268 rc = VINF_SUCCESS;
2269 break;
2270
2271 /*
2272 * Invoked Interrupt gate - must directly (!) go to the recompiler.
2273 */
2274 case VINF_EM_RAW_INTERRUPT_PENDING:
2275 case VINF_EM_RAW_RING_SWITCH_INT:
2276 Assert(TRPMHasTrap(pVM));
2277 Assert(!PATMIsPatchGCAddr(pVM, (RTGCPTR)pCtx->eip));
2278
2279 if (TRPMHasTrap(pVM))
2280 {
2281 /* If the guest gate is marked unpatched, then we will check again if we can patch it. */
2282 uint8_t u8Interrupt = TRPMGetTrapNo(pVM);
2283 if (TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) == TRPM_INVALID_HANDLER)
2284 {
2285 CSAMR3CheckGates(pVM, u8Interrupt, 1);
2286 Log(("emR3RawHandleRC: recheck gate %x -> valid=%d\n", u8Interrupt, TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) != TRPM_INVALID_HANDLER));
2287 /* Note: If it was successful, then we could go back to raw mode, but let's keep things simple for now. */
2288 }
2289 }
2290 rc = VINF_EM_RESCHEDULE_REM;
2291 break;
2292
2293 /*
2294 * Other ring switch types.
2295 */
2296 case VINF_EM_RAW_RING_SWITCH:
2297 rc = emR3RawRingSwitch(pVM);
2298 break;
2299
2300 /*
2301 * REMGCNotifyInvalidatePage() failed because of overflow.
2302 */
2303 case VERR_REM_FLUSHED_PAGES_OVERFLOW:
2304 Assert((pCtx->ss & X86_SEL_RPL) != 1);
2305 REMR3ReplayInvalidatedPages(pVM);
2306 rc = VINF_SUCCESS;
2307 break;
2308
2309 /*
2310 * I/O Port access - emulate the instruction.
2311 */
2312 case VINF_IOM_HC_IOPORT_READ:
2313 case VINF_IOM_HC_IOPORT_WRITE:
2314 rc = emR3RawExecuteIOInstruction(pVM);
2315 break;
2316
2317 /*
2318 * Memory mapped I/O access - emulate the instruction.
2319 */
2320 case VINF_IOM_HC_MMIO_READ:
2321 case VINF_IOM_HC_MMIO_WRITE:
2322 case VINF_IOM_HC_MMIO_READ_WRITE:
2323 rc = emR3RawExecuteInstruction(pVM, "MMIO");
2324 break;
2325
2326 /*
2327 * Execute instruction.
2328 */
2329 case VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT:
2330 rc = emR3RawExecuteInstruction(pVM, "LDT FAULT: ");
2331 break;
2332 case VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT:
2333 rc = emR3RawExecuteInstruction(pVM, "GDT FAULT: ");
2334 break;
2335 case VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT:
2336 rc = emR3RawExecuteInstruction(pVM, "IDT FAULT: ");
2337 break;
2338 case VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT:
2339 rc = emR3RawExecuteInstruction(pVM, "TSS FAULT: ");
2340 break;
2341 case VINF_EM_RAW_EMULATE_INSTR_PD_FAULT:
2342 rc = emR3RawExecuteInstruction(pVM, "PD FAULT: ");
2343 break;
2344
2345 case VINF_EM_RAW_EMULATE_INSTR_HLT:
2346 /** @todo skip instruction and go directly to the halt state. (see REM for implementation details) */
2347 rc = emR3RawPrivileged(pVM);
2348 break;
2349
2350 case VINF_PATM_PENDING_IRQ_AFTER_IRET:
2351 rc = emR3RawExecuteInstruction(pVM, "EMUL: ", VINF_PATM_PENDING_IRQ_AFTER_IRET);
2352 break;
2353
2354 case VINF_EM_RAW_EMULATE_INSTR:
2355 case VINF_PATCH_EMULATE_INSTR:
2356 rc = emR3RawExecuteInstruction(pVM, "EMUL: ");
2357 break;
2358
2359 /*
2360 * Stale selector and iret traps => REM.
2361 */
2362 case VINF_EM_RAW_STALE_SELECTOR:
2363 case VINF_EM_RAW_IRET_TRAP:
2364 /* We will not go to the recompiler if EIP points to patch code. */
2365 if (PATMIsPatchGCAddr(pVM, pCtx->eip))
2366 {
2367 pCtx->eip = PATMR3PatchToGCPtr(pVM, (RTGCPTR)pCtx->eip, 0);
2368 }
2369 LogFlow(("emR3RawHandleRC: %Rrc -> %Rrc\n", rc, VINF_EM_RESCHEDULE_REM));
2370 rc = VINF_EM_RESCHEDULE_REM;
2371 break;
2372
2373 /*
2374 * Up a level.
2375 */
2376 case VINF_EM_TERMINATE:
2377 case VINF_EM_OFF:
2378 case VINF_EM_RESET:
2379 case VINF_EM_SUSPEND:
2380 case VINF_EM_HALT:
2381 case VINF_EM_RESUME:
2382 case VINF_EM_RESCHEDULE:
2383 case VINF_EM_RESCHEDULE_REM:
2384 break;
2385
2386 /*
2387 * Up a level and invoke the debugger.
2388 */
2389 case VINF_EM_DBG_STEPPED:
2390 case VINF_EM_DBG_BREAKPOINT:
2391 case VINF_EM_DBG_STEP:
2392 case VINF_EM_DBG_HYPER_BREAKPOINT:
2393 case VINF_EM_DBG_HYPER_STEPPED:
2394 case VINF_EM_DBG_HYPER_ASSERTION:
2395 case VINF_EM_DBG_STOP:
2396 break;
2397
2398 /*
2399 * Up a level, dump and debug.
2400 */
2401 case VERR_TRPM_DONT_PANIC:
2402 case VERR_TRPM_PANIC:
2403 case VERR_VMM_RING0_ASSERTION:
2404 break;
2405
2406 /*
2407 * Up a level, after HwAccM have done some release logging.
2408 */
2409 case VERR_VMX_INVALID_VMCS_FIELD:
2410 case VERR_VMX_INVALID_VMCS_PTR:
2411 case VERR_VMX_INVALID_VMXON_PTR:
2412 case VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_CODE:
2413 case VERR_VMX_UNEXPECTED_EXCEPTION:
2414 case VERR_VMX_UNEXPECTED_EXIT_CODE:
2415 case VERR_VMX_INVALID_GUEST_STATE:
2416 case VERR_VMX_UNABLE_TO_START_VM:
2417 case VERR_VMX_UNABLE_TO_RESUME_VM:
2418 HWACCMR3CheckError(pVM, rc);
2419 break;
2420 /*
2421 * Anything which is not known to us means an internal error
2422 * and the termination of the VM!
2423 */
2424 default:
2425 AssertMsgFailed(("Unknown GC return code: %Rra\n", rc));
2426 break;
2427 }
2428 return rc;
2429}
2430
2431
2432/**
2433 * Check for pending raw actions
2434 *
2435 * @returns VBox status code.
2436 * @param pVM The VM to operate on.
2437 */
2438VMMR3DECL(int) EMR3CheckRawForcedActions(PVM pVM)
2439{
2440 return emR3RawForcedActions(pVM, pVM->em.s.pCtx);
2441}
2442
2443
2444/**
2445 * Process raw-mode specific forced actions.
2446 *
2447 * This function is called when any FFs in the VM_FF_HIGH_PRIORITY_PRE_RAW_MASK is pending.
2448 *
2449 * @returns VBox status code.
2450 * Only the normal success/failure stuff, no VINF_EM_*.
2451 * @param pVM The VM handle.
2452 * @param pCtx The guest CPUM register context.
2453 */
2454static int emR3RawForcedActions(PVM pVM, PCPUMCTX pCtx)
2455{
2456 /*
2457 * Note that the order is *vitally* important!
2458 * Also note that SELMR3UpdateFromCPUM may trigger VM_FF_SELM_SYNC_TSS.
2459 */
2460
2461
2462 /*
2463 * Sync selector tables.
2464 */
2465 if (VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT))
2466 {
2467 int rc = SELMR3UpdateFromCPUM(pVM);
2468 if (RT_FAILURE(rc))
2469 return rc;
2470 }
2471
2472 /*
2473 * Sync IDT.
2474 */
2475 if (VM_FF_ISSET(pVM, VM_FF_TRPM_SYNC_IDT))
2476 {
2477 int rc = TRPMR3SyncIDT(pVM);
2478 if (RT_FAILURE(rc))
2479 return rc;
2480 }
2481
2482 /*
2483 * Sync TSS.
2484 */
2485 if (VM_FF_ISSET(pVM, VM_FF_SELM_SYNC_TSS))
2486 {
2487 int rc = SELMR3SyncTSS(pVM);
2488 if (RT_FAILURE(rc))
2489 return rc;
2490 }
2491
2492 /*
2493 * Sync page directory.
2494 */
2495 if (VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL))
2496 {
2497 int rc = PGMSyncCR3(pVM, pCtx->cr0, pCtx->cr3, pCtx->cr4, VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
2498 if (RT_FAILURE(rc))
2499 return rc;
2500
2501 Assert(!VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT));
2502
2503 /* Prefetch pages for EIP and ESP */
2504 /** @todo This is rather expensive. Should investigate if it really helps at all. */
2505 rc = PGMPrefetchPage(pVM, SELMToFlat(pVM, DIS_SELREG_CS, CPUMCTX2CORE(pCtx), pCtx->rip));
2506 if (rc == VINF_SUCCESS)
2507 rc = PGMPrefetchPage(pVM, SELMToFlat(pVM, DIS_SELREG_SS, CPUMCTX2CORE(pCtx), pCtx->rsp));
2508 if (rc != VINF_SUCCESS)
2509 {
2510 if (rc != VINF_PGM_SYNC_CR3)
2511 return rc;
2512 rc = PGMSyncCR3(pVM, pCtx->cr0, pCtx->cr3, pCtx->cr4, VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
2513 if (RT_FAILURE(rc))
2514 return rc;
2515 }
2516 /** @todo maybe prefetch the supervisor stack page as well */
2517 }
2518
2519 /*
2520 * Allocate handy pages (just in case the above actions have consumed some pages).
2521 */
2522 if (VM_FF_ISSET(pVM, VM_FF_PGM_NEED_HANDY_PAGES))
2523 {
2524 int rc = PGMR3PhysAllocateHandyPages(pVM);
2525 if (RT_FAILURE(rc))
2526 return rc;
2527 }
2528
2529 return VINF_SUCCESS;
2530}
2531
2532
2533/**
2534 * Executes raw code.
2535 *
2536 * This function contains the raw-mode version of the inner
2537 * execution loop (the outer loop being in EMR3ExecuteVM()).
2538 *
2539 * @returns VBox status code. The most important ones are: VINF_EM_RESCHEDULE,
2540 * VINF_EM_RESCHEDULE_REM, VINF_EM_SUSPEND, VINF_EM_RESET and VINF_EM_TERMINATE.
2541 *
2542 * @param pVM VM handle.
2543 * @param pfFFDone Where to store an indicator telling whether or not
2544 * FFs were done before returning.
2545 */
2546static int emR3RawExecute(PVM pVM, bool *pfFFDone)
2547{
2548 STAM_REL_PROFILE_ADV_START(&pVM->em.s.StatRAWTotal, a);
2549
2550 int rc = VERR_INTERNAL_ERROR;
2551 PCPUMCTX pCtx = pVM->em.s.pCtx;
2552 LogFlow(("emR3RawExecute: (cs:eip=%04x:%08x)\n", pCtx->cs, pCtx->eip));
2553 pVM->em.s.fForceRAW = false;
2554 *pfFFDone = false;
2555
2556
2557 /*
2558 *
2559 * Spin till we get a forced action or raw mode status code resulting in
2560 * in anything but VINF_SUCCESS or VINF_EM_RESCHEDULE_RAW.
2561 *
2562 */
2563 for (;;)
2564 {
2565 STAM_PROFILE_ADV_START(&pVM->em.s.StatRAWEntry, b);
2566
2567 /*
2568 * Check various preconditions.
2569 */
2570#ifdef VBOX_STRICT
2571 Assert(REMR3QueryPendingInterrupt(pVM) == REM_NO_PENDING_IRQ);
2572 Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss & X86_SEL_RPL) == 3 || (pCtx->ss & X86_SEL_RPL) == 0);
2573 AssertMsg( (pCtx->eflags.u32 & X86_EFL_IF)
2574 || PATMShouldUseRawMode(pVM, (RTGCPTR)pCtx->eip),
2575 ("Tried to execute code with IF at EIP=%08x!\n", pCtx->eip));
2576 if ( !VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL)
2577 && PGMR3MapHasConflicts(pVM, pCtx->cr3, pVM->fRawR0Enabled))
2578 {
2579 AssertMsgFailed(("We should not get conflicts any longer!!!\n"));
2580 return VERR_INTERNAL_ERROR;
2581 }
2582#endif /* VBOX_STRICT */
2583
2584 /*
2585 * Process high priority pre-execution raw-mode FFs.
2586 */
2587 if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
2588 {
2589 rc = emR3RawForcedActions(pVM, pCtx);
2590 if (RT_FAILURE(rc))
2591 break;
2592 }
2593
2594 /*
2595 * If we're going to execute ring-0 code, the guest state needs to
2596 * be modified a bit and some of the state components (IF, SS/CS RPL,
2597 * and perhaps EIP) needs to be stored with PATM.
2598 */
2599 rc = CPUMRawEnter(pVM, NULL);
2600 if (rc != VINF_SUCCESS)
2601 {
2602 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatRAWEntry, b);
2603 break;
2604 }
2605
2606 /*
2607 * Scan code before executing it. Don't bother with user mode or V86 code
2608 */
2609 if ( (pCtx->ss & X86_SEL_RPL) <= 1
2610 && !pCtx->eflags.Bits.u1VM
2611 && !PATMIsPatchGCAddr(pVM, pCtx->eip))
2612 {
2613 STAM_PROFILE_ADV_SUSPEND(&pVM->em.s.StatRAWEntry, b);
2614 CSAMR3CheckCodeEx(pVM, CPUMCTX2CORE(pCtx), pCtx->eip);
2615 STAM_PROFILE_ADV_RESUME(&pVM->em.s.StatRAWEntry, b);
2616 }
2617
2618#ifdef LOG_ENABLED
2619 /*
2620 * Log important stuff before entering GC.
2621 */
2622 PPATMGCSTATE pGCState = PATMR3QueryGCStateHC(pVM);
2623 if (pCtx->eflags.Bits.u1VM)
2624 Log(("RV86: %04X:%08X IF=%d VMFlags=%x\n", pCtx->cs, pCtx->eip, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags));
2625 else if ((pCtx->ss & X86_SEL_RPL) == 1)
2626 {
2627 bool fCSAMScanned = CSAMIsPageScanned(pVM, (RTGCPTR)pCtx->eip);
2628 Log(("RR0: %08X ESP=%08X IF=%d VMFlags=%x PIF=%d CPL=%d (Scanned=%d)\n", pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags, pGCState->fPIF, (pCtx->ss & X86_SEL_RPL), fCSAMScanned));
2629 }
2630 else if ((pCtx->ss & X86_SEL_RPL) == 3)
2631 Log(("RR3: %08X ESP=%08X IF=%d VMFlags=%x\n", pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags));
2632#endif /* LOG_ENABLED */
2633
2634
2635
2636 /*
2637 * Execute the code.
2638 */
2639 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatRAWEntry, b);
2640 STAM_PROFILE_START(&pVM->em.s.StatRAWExec, c);
2641 VMMR3Unlock(pVM);
2642 rc = VMMR3RawRunGC(pVM);
2643 VMMR3Lock(pVM);
2644 STAM_PROFILE_STOP(&pVM->em.s.StatRAWExec, c);
2645 STAM_PROFILE_ADV_START(&pVM->em.s.StatRAWTail, d);
2646
2647 LogFlow(("RR0-E: %08X ESP=%08X IF=%d VMFlags=%x PIF=%d CPL=%d\n", pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags, pGCState->fPIF, (pCtx->ss & X86_SEL_RPL)));
2648 LogFlow(("VMMR3RawRunGC returned %Rrc\n", rc));
2649
2650
2651
2652 /*
2653 * Restore the real CPU state and deal with high priority post
2654 * execution FFs before doing anything else.
2655 */
2656 rc = CPUMRawLeave(pVM, NULL, rc);
2657 VM_FF_CLEAR(pVM, VM_FF_RESUME_GUEST_MASK);
2658 if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK))
2659 rc = emR3HighPriorityPostForcedActions(pVM, rc);
2660
2661#ifdef VBOX_STRICT
2662 /*
2663 * Assert TSS consistency & rc vs patch code.
2664 */
2665 if ( !VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_TSS | VM_FF_SELM_SYNC_GDT) /* GDT implies TSS at the moment. */
2666 && EMIsRawRing0Enabled(pVM))
2667 SELMR3CheckTSS(pVM);
2668 switch (rc)
2669 {
2670 case VINF_SUCCESS:
2671 case VINF_EM_RAW_INTERRUPT:
2672 case VINF_PATM_PATCH_TRAP_PF:
2673 case VINF_PATM_PATCH_TRAP_GP:
2674 case VINF_PATM_PATCH_INT3:
2675 case VINF_PATM_CHECK_PATCH_PAGE:
2676 case VINF_EM_RAW_EXCEPTION_PRIVILEGED:
2677 case VINF_EM_RAW_GUEST_TRAP:
2678 case VINF_EM_RESCHEDULE_RAW:
2679 break;
2680
2681 default:
2682 if (PATMIsPatchGCAddr(pVM, pCtx->eip) && !(pCtx->eflags.u32 & X86_EFL_TF))
2683 LogIt(NULL, 0, LOG_GROUP_PATM, ("Patch code interrupted at %RRv for reason %Rrc\n", (RTRCPTR)CPUMGetGuestEIP(pVM), rc));
2684 break;
2685 }
2686 /*
2687 * Let's go paranoid!
2688 */
2689 if ( !VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL)
2690 && PGMR3MapHasConflicts(pVM, pCtx->cr3, pVM->fRawR0Enabled))
2691 {
2692 AssertMsgFailed(("We should not get conflicts any longer!!!\n"));
2693 return VERR_INTERNAL_ERROR;
2694 }
2695#endif /* VBOX_STRICT */
2696
2697 /*
2698 * Process the returned status code.
2699 */
2700 if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
2701 {
2702 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatRAWTail, d);
2703 break;
2704 }
2705 rc = emR3RawHandleRC(pVM, pCtx, rc);
2706 if (rc != VINF_SUCCESS)
2707 {
2708 rc = emR3RawUpdateForceFlag(pVM, pCtx, rc);
2709 if (rc != VINF_SUCCESS)
2710 {
2711 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatRAWTail, d);
2712 break;
2713 }
2714 }
2715
2716 /*
2717 * Check and execute forced actions.
2718 */
2719#ifdef VBOX_HIGH_RES_TIMERS_HACK
2720 TMTimerPoll(pVM);
2721#endif
2722 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatRAWTail, d);
2723 if (VM_FF_ISPENDING(pVM, ~VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
2724 {
2725 Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss & X86_SEL_RPL) != 1);
2726
2727 STAM_REL_PROFILE_ADV_SUSPEND(&pVM->em.s.StatRAWTotal, a);
2728 rc = emR3ForcedActions(pVM, rc);
2729 STAM_REL_PROFILE_ADV_RESUME(&pVM->em.s.StatRAWTotal, a);
2730 if ( rc != VINF_SUCCESS
2731 && rc != VINF_EM_RESCHEDULE_RAW)
2732 {
2733 rc = emR3RawUpdateForceFlag(pVM, pCtx, rc);
2734 if (rc != VINF_SUCCESS)
2735 {
2736 *pfFFDone = true;
2737 break;
2738 }
2739 }
2740 }
2741 }
2742
2743 /*
2744 * Return to outer loop.
2745 */
2746#if defined(LOG_ENABLED) && defined(DEBUG)
2747 RTLogFlush(NULL);
2748#endif
2749 STAM_REL_PROFILE_ADV_STOP(&pVM->em.s.StatRAWTotal, a);
2750 return rc;
2751}
2752
2753
2754/**
2755 * Executes hardware accelerated raw code. (Intel VMX & AMD SVM)
2756 *
2757 * This function contains the raw-mode version of the inner
2758 * execution loop (the outer loop being in EMR3ExecuteVM()).
2759 *
2760 * @returns VBox status code. The most important ones are: VINF_EM_RESCHEDULE, VINF_EM_RESCHEDULE_RAW,
2761 * VINF_EM_RESCHEDULE_REM, VINF_EM_SUSPEND, VINF_EM_RESET and VINF_EM_TERMINATE.
2762 *
2763 * @param pVM VM handle.
2764 * @param idCpu VMCPU id.
2765 * @param pfFFDone Where to store an indicator telling whether or not
2766 * FFs were done before returning.
2767 */
2768static int emR3HwAccExecute(PVM pVM, RTCPUID idCpu, bool *pfFFDone)
2769{
2770 int rc = VERR_INTERNAL_ERROR;
2771 PCPUMCTX pCtx = pVM->em.s.pCtx;
2772
2773 LogFlow(("emR3HwAccExecute%d: (cs:eip=%04x:%RGv)\n", idCpu, pCtx->cs, (RTGCPTR)pCtx->rip));
2774 *pfFFDone = false;
2775
2776 STAM_COUNTER_INC(&pVM->em.s.StatHwAccExecuteEntry);
2777
2778 /*
2779 * Spin till we get a forced action which returns anything but VINF_SUCCESS.
2780 */
2781 for (;;)
2782 {
2783 STAM_PROFILE_ADV_START(&pVM->em.s.StatHwAccEntry, a);
2784
2785 /*
2786 * Check various preconditions.
2787 */
2788 VM_FF_CLEAR(pVM, (VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS));
2789
2790 /*
2791 * Process high priority pre-execution raw-mode FFs.
2792 */
2793 if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
2794 {
2795 rc = emR3RawForcedActions(pVM, pCtx);
2796 if (RT_FAILURE(rc))
2797 break;
2798 }
2799
2800#ifdef LOG_ENABLED
2801 /*
2802 * Log important stuff before entering GC.
2803 */
2804 if (TRPMHasTrap(pVM))
2805 Log(("Pending hardware interrupt=0x%x cs:rip=%04X:%RGv\n", TRPMGetTrapNo(pVM), pCtx->cs, (RTGCPTR)pCtx->rip));
2806
2807 uint32_t cpl = CPUMGetGuestCPL(pVM, CPUMCTX2CORE(pCtx));
2808 if (pCtx->eflags.Bits.u1VM)
2809 Log(("HWV86: %08X IF=%d\n", pCtx->eip, pCtx->eflags.Bits.u1IF));
2810 else if (CPUMIsGuestIn64BitCode(pVM, CPUMCTX2CORE(pCtx)))
2811 Log(("HWR%d: %04X:%RGv ESP=%RGv IF=%d CR0=%x CR4=%x EFER=%x\n", cpl, pCtx->cs, (RTGCPTR)pCtx->rip, pCtx->rsp, pCtx->eflags.Bits.u1IF, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER));
2812 else
2813 Log(("HWR%d: %04X:%08X ESP=%08X IF=%d CR0=%x CR4=%x EFER=%x\n", cpl, pCtx->cs, pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER));
2814#endif /* LOG_ENABLED */
2815
2816 /*
2817 * Execute the code.
2818 */
2819 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatHwAccEntry, a);
2820 STAM_PROFILE_START(&pVM->em.s.StatHwAccExec, x);
2821 VMMR3Unlock(pVM);
2822 rc = VMMR3HwAccRunGC(pVM, idCpu);
2823 VMMR3Lock(pVM);
2824 STAM_PROFILE_STOP(&pVM->em.s.StatHwAccExec, x);
2825
2826 /*
2827 * Deal with high priority post execution FFs before doing anything else.
2828 */
2829 VM_FF_CLEAR(pVM, VM_FF_RESUME_GUEST_MASK);
2830 if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK))
2831 rc = emR3HighPriorityPostForcedActions(pVM, rc);
2832
2833 /*
2834 * Process the returned status code.
2835 */
2836 if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
2837 break;
2838
2839 rc = emR3RawHandleRC(pVM, pCtx, rc);
2840 if (rc != VINF_SUCCESS)
2841 break;
2842
2843 /*
2844 * Check and execute forced actions.
2845 */
2846#ifdef VBOX_HIGH_RES_TIMERS_HACK
2847 TMTimerPoll(pVM);
2848#endif
2849 if (VM_FF_ISPENDING(pVM, VM_FF_ALL_MASK))
2850 {
2851 rc = emR3ForcedActions(pVM, rc);
2852 if ( rc != VINF_SUCCESS
2853 && rc != VINF_EM_RESCHEDULE_HWACC)
2854 {
2855 *pfFFDone = true;
2856 break;
2857 }
2858 }
2859 }
2860 /*
2861 * Return to outer loop.
2862 */
2863#if defined(LOG_ENABLED) && defined(DEBUG)
2864 RTLogFlush(NULL);
2865#endif
2866 return rc;
2867}
2868
2869
2870/**
2871 * Decides whether to execute RAW, HWACC or REM.
2872 *
2873 * @returns new EM state
2874 * @param pVM The VM.
2875 * @param pCtx The CPU context.
2876 */
2877DECLINLINE(EMSTATE) emR3Reschedule(PVM pVM, PCPUMCTX pCtx)
2878{
2879 /*
2880 * When forcing raw-mode execution, things are simple.
2881 */
2882 if (pVM->em.s.fForceRAW)
2883 return EMSTATE_RAW;
2884
2885 /* !!! THIS MUST BE IN SYNC WITH remR3CanExecuteRaw !!! */
2886 /* !!! THIS MUST BE IN SYNC WITH remR3CanExecuteRaw !!! */
2887 /* !!! THIS MUST BE IN SYNC WITH remR3CanExecuteRaw !!! */
2888
2889 X86EFLAGS EFlags = pCtx->eflags;
2890 if (HWACCMIsEnabled(pVM))
2891 {
2892 /* Hardware accelerated raw-mode:
2893 *
2894 * Typically only 32-bits protected mode, with paging enabled, code is allowed here.
2895 */
2896 if (HWACCMR3CanExecuteGuest(pVM, pCtx) == true)
2897 return EMSTATE_HWACC;
2898
2899 /* Note: Raw mode and hw accelerated mode are incompatible. The latter turns
2900 * off monitoring features essential for raw mode! */
2901 return EMSTATE_REM;
2902 }
2903
2904 /*
2905 * Standard raw-mode:
2906 *
2907 * Here we only support 16 & 32 bits protected mode ring 3 code that has no IO privileges
2908 * or 32 bits protected mode ring 0 code
2909 *
2910 * The tests are ordered by the likelyhood of being true during normal execution.
2911 */
2912 if (EFlags.u32 & (X86_EFL_TF /* | HF_INHIBIT_IRQ_MASK*/))
2913 {
2914 Log2(("raw mode refused: EFlags=%#x\n", EFlags.u32));
2915 return EMSTATE_REM;
2916 }
2917
2918#ifndef VBOX_RAW_V86
2919 if (EFlags.u32 & X86_EFL_VM) {
2920 Log2(("raw mode refused: VM_MASK\n"));
2921 return EMSTATE_REM;
2922 }
2923#endif
2924
2925 /** @todo check up the X86_CR0_AM flag in respect to raw mode!!! We're probably not emulating it right! */
2926 uint32_t u32CR0 = pCtx->cr0;
2927 if ((u32CR0 & (X86_CR0_PG | X86_CR0_PE)) != (X86_CR0_PG | X86_CR0_PE))
2928 {
2929 //Log2(("raw mode refused: %s%s%s\n", (u32CR0 & X86_CR0_PG) ? "" : " !PG", (u32CR0 & X86_CR0_PE) ? "" : " !PE", (u32CR0 & X86_CR0_AM) ? "" : " !AM"));
2930 return EMSTATE_REM;
2931 }
2932
2933 if (pCtx->cr4 & X86_CR4_PAE)
2934 {
2935 uint32_t u32Dummy, u32Features;
2936
2937 CPUMGetGuestCpuId(pVM, 1, &u32Dummy, &u32Dummy, &u32Dummy, &u32Features);
2938 if (!(u32Features & X86_CPUID_FEATURE_EDX_PAE))
2939 return EMSTATE_REM;
2940 }
2941
2942 unsigned uSS = pCtx->ss;
2943 if ( pCtx->eflags.Bits.u1VM
2944 || (uSS & X86_SEL_RPL) == 3)
2945 {
2946 if (!EMIsRawRing3Enabled(pVM))
2947 return EMSTATE_REM;
2948
2949 if (!(EFlags.u32 & X86_EFL_IF))
2950 {
2951 Log2(("raw mode refused: IF (RawR3)\n"));
2952 return EMSTATE_REM;
2953 }
2954
2955 if (!(u32CR0 & X86_CR0_WP) && EMIsRawRing0Enabled(pVM))
2956 {
2957 Log2(("raw mode refused: CR0.WP + RawR0\n"));
2958 return EMSTATE_REM;
2959 }
2960 }
2961 else
2962 {
2963 if (!EMIsRawRing0Enabled(pVM))
2964 return EMSTATE_REM;
2965
2966 /* Only ring 0 supervisor code. */
2967 if ((uSS & X86_SEL_RPL) != 0)
2968 {
2969 Log2(("raw r0 mode refused: CPL %d\n", uSS & X86_SEL_RPL));
2970 return EMSTATE_REM;
2971 }
2972
2973 // Let's start with pure 32 bits ring 0 code first
2974 /** @todo What's pure 32-bit mode? flat? */
2975 if ( !(pCtx->ssHid.Attr.n.u1DefBig)
2976 || !(pCtx->csHid.Attr.n.u1DefBig))
2977 {
2978 Log2(("raw r0 mode refused: SS/CS not 32bit\n"));
2979 return EMSTATE_REM;
2980 }
2981
2982 /* Write protection must be turned on, or else the guest can overwrite our hypervisor code and data. */
2983 if (!(u32CR0 & X86_CR0_WP))
2984 {
2985 Log2(("raw r0 mode refused: CR0.WP=0!\n"));
2986 return EMSTATE_REM;
2987 }
2988
2989 if (PATMShouldUseRawMode(pVM, (RTGCPTR)pCtx->eip))
2990 {
2991 Log2(("raw r0 mode forced: patch code\n"));
2992 return EMSTATE_RAW;
2993 }
2994
2995#if !defined(VBOX_ALLOW_IF0) && !defined(VBOX_RUN_INTERRUPT_GATE_HANDLERS)
2996 if (!(EFlags.u32 & X86_EFL_IF))
2997 {
2998 ////Log2(("R0: IF=0 VIF=%d %08X\n", eip, pVMeflags));
2999 //Log2(("RR0: Interrupts turned off; fall back to emulation\n"));
3000 return EMSTATE_REM;
3001 }
3002#endif
3003
3004 /** @todo still necessary??? */
3005 if (EFlags.Bits.u2IOPL != 0)
3006 {
3007 Log2(("raw r0 mode refused: IOPL %d\n", EFlags.Bits.u2IOPL));
3008 return EMSTATE_REM;
3009 }
3010 }
3011
3012 Assert(PGMPhysIsA20Enabled(pVM));
3013 return EMSTATE_RAW;
3014}
3015
3016
3017/**
3018 * Executes all high priority post execution force actions.
3019 *
3020 * @returns rc or a fatal status code.
3021 *
3022 * @param pVM VM handle.
3023 * @param rc The current rc.
3024 */
3025static int emR3HighPriorityPostForcedActions(PVM pVM, int rc)
3026{
3027 if (VM_FF_ISSET(pVM, VM_FF_PDM_CRITSECT))
3028 PDMR3CritSectFF(pVM);
3029
3030 if (VM_FF_ISSET(pVM, VM_FF_CSAM_PENDING_ACTION))
3031 CSAMR3DoPendingAction(pVM);
3032
3033 return rc;
3034}
3035
3036
3037/**
3038 * Executes all pending forced actions.
3039 *
3040 * Forced actions can cause execution delays and execution
3041 * rescheduling. The first we deal with using action priority, so
3042 * that for instance pending timers aren't scheduled and ran until
3043 * right before execution. The rescheduling we deal with using
3044 * return codes. The same goes for VM termination, only in that case
3045 * we exit everything.
3046 *
3047 * @returns VBox status code of equal or greater importance/severity than rc.
3048 * The most important ones are: VINF_EM_RESCHEDULE,
3049 * VINF_EM_SUSPEND, VINF_EM_RESET and VINF_EM_TERMINATE.
3050 *
3051 * @param pVM VM handle.
3052 * @param rc The current rc.
3053 *
3054 */
3055static int emR3ForcedActions(PVM pVM, int rc)
3056{
3057 STAM_REL_PROFILE_START(&pVM->em.s.StatForcedActions, a);
3058#ifdef VBOX_STRICT
3059 int rcIrq = VINF_SUCCESS;
3060#endif
3061 int rc2;
3062#define UPDATE_RC() \
3063 do { \
3064 AssertMsg(rc2 <= 0 || (rc2 >= VINF_EM_FIRST && rc2 <= VINF_EM_LAST), ("Invalid FF return code: %Rra\n", rc2)); \
3065 if (rc2 == VINF_SUCCESS || rc < VINF_SUCCESS) \
3066 break; \
3067 if (!rc || rc2 < rc) \
3068 rc = rc2; \
3069 } while (0)
3070
3071 /*
3072 * Post execution chunk first.
3073 */
3074 if (VM_FF_ISPENDING(pVM, VM_FF_NORMAL_PRIORITY_POST_MASK))
3075 {
3076 /*
3077 * Termination request.
3078 */
3079 if (VM_FF_ISSET(pVM, VM_FF_TERMINATE))
3080 {
3081 Log2(("emR3ForcedActions: returns VINF_EM_TERMINATE\n"));
3082 STAM_REL_PROFILE_STOP(&pVM->em.s.StatForcedActions, a);
3083 return VINF_EM_TERMINATE;
3084 }
3085
3086 /*
3087 * Debugger Facility polling.
3088 */
3089 if (VM_FF_ISSET(pVM, VM_FF_DBGF))
3090 {
3091 rc2 = DBGFR3VMMForcedAction(pVM);
3092 UPDATE_RC();
3093 }
3094
3095 /*
3096 * Postponed reset request.
3097 */
3098 if (VM_FF_ISSET(pVM, VM_FF_RESET))
3099 {
3100 rc2 = VMR3Reset(pVM);
3101 UPDATE_RC();
3102 VM_FF_CLEAR(pVM, VM_FF_RESET);
3103 }
3104
3105 /*
3106 * CSAM page scanning.
3107 */
3108 if (VM_FF_ISSET(pVM, VM_FF_CSAM_SCAN_PAGE))
3109 {
3110 PCPUMCTX pCtx = pVM->em.s.pCtx;
3111
3112 /** @todo: check for 16 or 32 bits code! (D bit in the code selector) */
3113 Log(("Forced action VM_FF_CSAM_SCAN_PAGE\n"));
3114
3115 CSAMR3CheckCodeEx(pVM, CPUMCTX2CORE(pCtx), pCtx->eip);
3116 VM_FF_CLEAR(pVM, VM_FF_CSAM_SCAN_PAGE);
3117 }
3118
3119 /* check that we got them all */
3120 Assert(!(VM_FF_NORMAL_PRIORITY_POST_MASK & ~(VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_CSAM_SCAN_PAGE)));
3121 }
3122
3123 /*
3124 * Normal priority then.
3125 * (Executed in no particular order.)
3126 */
3127 if (VM_FF_ISPENDING(pVM, VM_FF_NORMAL_PRIORITY_MASK))
3128 {
3129 /*
3130 * PDM Queues are pending.
3131 */
3132 if (VM_FF_ISSET(pVM, VM_FF_PDM_QUEUES))
3133 PDMR3QueueFlushAll(pVM);
3134
3135 /*
3136 * PDM DMA transfers are pending.
3137 */
3138 if (VM_FF_ISSET(pVM, VM_FF_PDM_DMA))
3139 PDMR3DmaRun(pVM);
3140
3141 /*
3142 * Requests from other threads.
3143 */
3144 if (VM_FF_ISSET(pVM, VM_FF_REQUEST))
3145 {
3146 rc2 = VMR3ReqProcessU(pVM->pUVM, VMREQDEST_ANY);
3147 if (rc2 == VINF_EM_OFF || rc2 == VINF_EM_TERMINATE)
3148 {
3149 Log2(("emR3ForcedActions: returns %Rrc\n", rc2));
3150 STAM_REL_PROFILE_STOP(&pVM->em.s.StatForcedActions, a);
3151 return rc2;
3152 }
3153 UPDATE_RC();
3154 }
3155
3156 /* Replay the handler notification changes. */
3157 if (VM_FF_ISSET(pVM, VM_FF_REM_HANDLER_NOTIFY))
3158 REMR3ReplayHandlerNotifications(pVM);
3159
3160 /* check that we got them all */
3161 Assert(!(VM_FF_NORMAL_PRIORITY_MASK & ~(VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_REM_HANDLER_NOTIFY)));
3162 }
3163
3164 /*
3165 * Execute polling function ever so often.
3166 * THIS IS A HACK, IT WILL BE *REPLACED* BY PROPER ASYNC NETWORKING "SOON"!
3167 */
3168 static unsigned cLast = 0;
3169 if (!((++cLast) % 4))
3170 PDMR3Poll(pVM);
3171
3172 /*
3173 * High priority pre execution chunk last.
3174 * (Executed in ascending priority order.)
3175 */
3176 if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_MASK))
3177 {
3178 /*
3179 * Timers before interrupts.
3180 */
3181 if (VM_FF_ISSET(pVM, VM_FF_TIMER))
3182 TMR3TimerQueuesDo(pVM);
3183
3184 /*
3185 * The instruction following an emulated STI should *always* be executed!
3186 */
3187 if (VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS))
3188 {
3189 Log(("VM_FF_EMULATED_STI at %RGv successor %RGv\n", (RTGCPTR)CPUMGetGuestRIP(pVM), EMGetInhibitInterruptsPC(pVM)));
3190 if (CPUMGetGuestEIP(pVM) != EMGetInhibitInterruptsPC(pVM))
3191 {
3192 /* Note: we intentionally don't clear VM_FF_INHIBIT_INTERRUPTS here if the eip is the same as the inhibited instr address.
3193 * Before we are able to execute this instruction in raw mode (iret to guest code) an external interrupt might
3194 * force a world switch again. Possibly allowing a guest interrupt to be dispatched in the process. This could
3195 * break the guest. Sounds very unlikely, but such timing sensitive problem are not as rare as you might think.
3196 */
3197 VM_FF_CLEAR(pVM, VM_FF_INHIBIT_INTERRUPTS);
3198 }
3199 if (HWACCMR3IsActive(pVM))
3200 rc2 = VINF_EM_RESCHEDULE_HWACC;
3201 else
3202 rc2 = PATMAreInterruptsEnabled(pVM) ? VINF_EM_RESCHEDULE_RAW : VINF_EM_RESCHEDULE_REM;
3203
3204 UPDATE_RC();
3205 }
3206
3207 /*
3208 * Interrupts.
3209 */
3210 if ( !VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS)
3211 && (!rc || rc >= VINF_EM_RESCHEDULE_RAW)
3212 && !TRPMHasTrap(pVM) /* an interrupt could already be scheduled for dispatching in the recompiler. */
3213 && PATMAreInterruptsEnabled(pVM)
3214 && !HWACCMR3IsEventPending(pVM))
3215 {
3216 if (VM_FF_ISPENDING(pVM, VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC))
3217 {
3218 /* Note: it's important to make sure the return code from TRPMR3InjectEvent isn't ignored! */
3219 /** @todo this really isn't nice, should properly handle this */
3220 rc2 = TRPMR3InjectEvent(pVM, TRPM_HARDWARE_INT);
3221#ifdef VBOX_STRICT
3222 rcIrq = rc2;
3223#endif
3224 UPDATE_RC();
3225 }
3226 /** @todo really ugly; if we entered the hlt state when exiting the recompiler and an interrupt was pending, we previously got stuck in the halted state. */
3227 else if (REMR3QueryPendingInterrupt(pVM) != REM_NO_PENDING_IRQ)
3228 {
3229 rc2 = VINF_EM_RESCHEDULE_REM;
3230 UPDATE_RC();
3231 }
3232 }
3233
3234 /*
3235 * Allocate handy pages.
3236 */
3237 if (VM_FF_ISSET(pVM, VM_FF_PGM_NEED_HANDY_PAGES))
3238 {
3239 rc2 = PGMR3PhysAllocateHandyPages(pVM);
3240 UPDATE_RC();
3241 }
3242
3243 /*
3244 * Debugger Facility request.
3245 */
3246 if (VM_FF_ISSET(pVM, VM_FF_DBGF))
3247 {
3248 rc2 = DBGFR3VMMForcedAction(pVM);
3249 UPDATE_RC();
3250 }
3251
3252 /*
3253 * Termination request.
3254 */
3255 if (VM_FF_ISSET(pVM, VM_FF_TERMINATE))
3256 {
3257 Log2(("emR3ForcedActions: returns VINF_EM_TERMINATE\n"));
3258 STAM_REL_PROFILE_STOP(&pVM->em.s.StatForcedActions, a);
3259 return VINF_EM_TERMINATE;
3260 }
3261
3262#ifdef DEBUG
3263 /*
3264 * Debug, pause the VM.
3265 */
3266 if (VM_FF_ISSET(pVM, VM_FF_DEBUG_SUSPEND))
3267 {
3268 VM_FF_CLEAR(pVM, VM_FF_DEBUG_SUSPEND);
3269 Log(("emR3ForcedActions: returns VINF_EM_SUSPEND\n"));
3270 return VINF_EM_SUSPEND;
3271 }
3272
3273#endif
3274 /* check that we got them all */
3275 Assert(!(VM_FF_HIGH_PRIORITY_PRE_MASK & ~(VM_FF_TIMER | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_DBGF | VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TERMINATE | VM_FF_DEBUG_SUSPEND | VM_FF_INHIBIT_INTERRUPTS | VM_FF_PGM_NEED_HANDY_PAGES)));
3276 }
3277
3278#undef UPDATE_RC
3279 Log2(("emR3ForcedActions: returns %Rrc\n", rc));
3280 STAM_REL_PROFILE_STOP(&pVM->em.s.StatForcedActions, a);
3281 Assert(rcIrq == VINF_SUCCESS || rcIrq == rc);
3282 return rc;
3283}
3284
3285
3286/**
3287 * Execute VM.
3288 *
3289 * This function is the main loop of the VM. The emulation thread
3290 * calls this function when the VM has been successfully constructed
3291 * and we're ready for executing the VM.
3292 *
3293 * Returning from this function means that the VM is turned off or
3294 * suspended (state already saved) and deconstruction in next in line.
3295 *
3296 * All interaction from other thread are done using forced actions
3297 * and signaling of the wait object.
3298 *
3299 * @returns VBox status code, informational status codes may indicate failure.
3300 * @param pVM The VM to operate on.
3301 * @param idCpu VMCPU id.
3302 */
3303VMMR3DECL(int) EMR3ExecuteVM(PVM pVM, RTCPUID idCpu)
3304{
3305 LogFlow(("EMR3ExecuteVM: pVM=%p enmVMState=%d enmState=%d (%s) fForceRAW=%d\n", pVM, pVM->enmVMState,
3306 pVM->em.s.enmState, EMR3GetStateName(pVM->em.s.enmState), pVM->em.s.fForceRAW));
3307 VM_ASSERT_EMT(pVM);
3308 Assert(pVM->em.s.enmState == EMSTATE_NONE || pVM->em.s.enmState == EMSTATE_SUSPENDED);
3309
3310 VMMR3Lock(pVM);
3311
3312 int rc = setjmp(pVM->em.s.u.FatalLongJump);
3313 if (rc == 0)
3314 {
3315 /*
3316 * Start the virtual time.
3317 */
3318 rc = TMVirtualResume(pVM);
3319 Assert(rc == VINF_SUCCESS);
3320 rc = TMCpuTickResume(pVM);
3321 Assert(rc == VINF_SUCCESS);
3322
3323 /*
3324 * The Outer Main Loop.
3325 */
3326 bool fFFDone = false;
3327
3328 /* Reschedule right away to start in the right state. */
3329 rc = VINF_SUCCESS;
3330 pVM->em.s.enmState = emR3Reschedule(pVM, pVM->em.s.pCtx);
3331
3332 STAM_REL_PROFILE_ADV_START(&pVM->em.s.StatTotal, x);
3333 for (;;)
3334 {
3335 /*
3336 * Before we can schedule anything (we're here because
3337 * scheduling is required) we must service any pending
3338 * forced actions to avoid any pending action causing
3339 * immediate rescheduling upon entering an inner loop
3340 *
3341 * Do forced actions.
3342 */
3343 if ( !fFFDone
3344 && rc != VINF_EM_TERMINATE
3345 && rc != VINF_EM_OFF
3346 && VM_FF_ISPENDING(pVM, VM_FF_ALL_BUT_RAW_MASK))
3347 {
3348 rc = emR3ForcedActions(pVM, rc);
3349 if ( ( rc == VINF_EM_RESCHEDULE_REM
3350 || rc == VINF_EM_RESCHEDULE_HWACC)
3351 && pVM->em.s.fForceRAW)
3352 rc = VINF_EM_RESCHEDULE_RAW;
3353 }
3354 else if (fFFDone)
3355 fFFDone = false;
3356
3357 /*
3358 * Now what to do?
3359 */
3360 Log2(("EMR3ExecuteVM: rc=%Rrc\n", rc));
3361 switch (rc)
3362 {
3363 /*
3364 * Keep doing what we're currently doing.
3365 */
3366 case VINF_SUCCESS:
3367 break;
3368
3369 /*
3370 * Reschedule - to raw-mode execution.
3371 */
3372 case VINF_EM_RESCHEDULE_RAW:
3373 Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_RAW: %d -> %d (EMSTATE_RAW)\n", pVM->em.s.enmState, EMSTATE_RAW));
3374 pVM->em.s.enmState = EMSTATE_RAW;
3375 break;
3376
3377 /*
3378 * Reschedule - to hardware accelerated raw-mode execution.
3379 */
3380 case VINF_EM_RESCHEDULE_HWACC:
3381 Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_HWACC: %d -> %d (EMSTATE_HWACC)\n", pVM->em.s.enmState, EMSTATE_HWACC));
3382 Assert(!pVM->em.s.fForceRAW);
3383 pVM->em.s.enmState = EMSTATE_HWACC;
3384 break;
3385
3386 /*
3387 * Reschedule - to recompiled execution.
3388 */
3389 case VINF_EM_RESCHEDULE_REM:
3390 Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_REM: %d -> %d (EMSTATE_REM)\n", pVM->em.s.enmState, EMSTATE_REM));
3391 pVM->em.s.enmState = EMSTATE_REM;
3392 break;
3393
3394#ifdef VBOX_WITH_VMI
3395 /*
3396 * Reschedule - parav call.
3397 */
3398 case VINF_EM_RESCHEDULE_PARAV:
3399 Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_PARAV: %d -> %d (EMSTATE_PARAV)\n", pVM->em.s.enmState, EMSTATE_PARAV));
3400 pVM->em.s.enmState = EMSTATE_PARAV;
3401 break;
3402#endif
3403
3404 /*
3405 * Resume.
3406 */
3407 case VINF_EM_RESUME:
3408 Log2(("EMR3ExecuteVM: VINF_EM_RESUME: %d -> VINF_EM_RESCHEDULE\n", pVM->em.s.enmState));
3409 /* fall through and get scheduled. */
3410
3411 /*
3412 * Reschedule.
3413 */
3414 case VINF_EM_RESCHEDULE:
3415 {
3416 EMSTATE enmState = emR3Reschedule(pVM, pVM->em.s.pCtx);
3417 Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE: %d -> %d (%s)\n", pVM->em.s.enmState, enmState, EMR3GetStateName(enmState)));
3418 pVM->em.s.enmState = enmState;
3419 break;
3420 }
3421
3422 /*
3423 * Halted.
3424 */
3425 case VINF_EM_HALT:
3426 Log2(("EMR3ExecuteVM: VINF_EM_HALT: %d -> %d\n", pVM->em.s.enmState, EMSTATE_HALTED));
3427 pVM->em.s.enmState = EMSTATE_HALTED;
3428 break;
3429
3430 /*
3431 * Suspend.
3432 */
3433 case VINF_EM_SUSPEND:
3434 Log2(("EMR3ExecuteVM: VINF_EM_SUSPEND: %d -> %d\n", pVM->em.s.enmState, EMSTATE_SUSPENDED));
3435 pVM->em.s.enmState = EMSTATE_SUSPENDED;
3436 break;
3437
3438 /*
3439 * Reset.
3440 * We might end up doing a double reset for now, we'll have to clean up the mess later.
3441 */
3442 case VINF_EM_RESET:
3443 {
3444 EMSTATE enmState = emR3Reschedule(pVM, pVM->em.s.pCtx);
3445 Log2(("EMR3ExecuteVM: VINF_EM_RESET: %d -> %d (%s)\n", pVM->em.s.enmState, enmState, EMR3GetStateName(enmState)));
3446 pVM->em.s.enmState = enmState;
3447 break;
3448 }
3449
3450 /*
3451 * Power Off.
3452 */
3453 case VINF_EM_OFF:
3454 pVM->em.s.enmState = EMSTATE_TERMINATING;
3455 Log2(("EMR3ExecuteVM: returns VINF_EM_OFF (%d -> %d)\n", pVM->em.s.enmState, EMSTATE_TERMINATING));
3456 TMVirtualPause(pVM);
3457 TMCpuTickPause(pVM);
3458 VMMR3Unlock(pVM);
3459 STAM_REL_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x);
3460 return rc;
3461
3462 /*
3463 * Terminate the VM.
3464 */
3465 case VINF_EM_TERMINATE:
3466 pVM->em.s.enmState = EMSTATE_TERMINATING;
3467 Log(("EMR3ExecuteVM returns VINF_EM_TERMINATE (%d -> %d)\n", pVM->em.s.enmState, EMSTATE_TERMINATING));
3468 TMVirtualPause(pVM);
3469 TMCpuTickPause(pVM);
3470 STAM_REL_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x);
3471 return rc;
3472
3473 /*
3474 * Guest debug events.
3475 */
3476 case VINF_EM_DBG_STEPPED:
3477 AssertMsgFailed(("VINF_EM_DBG_STEPPED cannot be here!"));
3478 case VINF_EM_DBG_STOP:
3479 case VINF_EM_DBG_BREAKPOINT:
3480 case VINF_EM_DBG_STEP:
3481 if (pVM->em.s.enmState == EMSTATE_RAW)
3482 {
3483 Log2(("EMR3ExecuteVM: %Rrc: %d -> %d\n", rc, pVM->em.s.enmState, EMSTATE_DEBUG_GUEST_RAW));
3484 pVM->em.s.enmState = EMSTATE_DEBUG_GUEST_RAW;
3485 }
3486 else
3487 {
3488 Log2(("EMR3ExecuteVM: %Rrc: %d -> %d\n", rc, pVM->em.s.enmState, EMSTATE_DEBUG_GUEST_REM));
3489 pVM->em.s.enmState = EMSTATE_DEBUG_GUEST_REM;
3490 }
3491 break;
3492
3493 /*
3494 * Hypervisor debug events.
3495 */
3496 case VINF_EM_DBG_HYPER_STEPPED:
3497 case VINF_EM_DBG_HYPER_BREAKPOINT:
3498 case VINF_EM_DBG_HYPER_ASSERTION:
3499 Log2(("EMR3ExecuteVM: %Rrc: %d -> %d\n", rc, pVM->em.s.enmState, EMSTATE_DEBUG_HYPER));
3500 pVM->em.s.enmState = EMSTATE_DEBUG_HYPER;
3501 break;
3502
3503 /*
3504 * Guru mediations.
3505 */
3506 case VERR_VMM_RING0_ASSERTION:
3507 Log(("EMR3ExecuteVM: %Rrc: %d -> %d (EMSTATE_GURU_MEDITATION)\n", rc, pVM->em.s.enmState, EMSTATE_GURU_MEDITATION));
3508 pVM->em.s.enmState = EMSTATE_GURU_MEDITATION;
3509 break;
3510
3511 /*
3512 * Any error code showing up here other than the ones we
3513 * know and process above are considered to be FATAL.
3514 *
3515 * Unknown warnings and informational status codes are also
3516 * included in this.
3517 */
3518 default:
3519 if (RT_SUCCESS(rc))
3520 {
3521 AssertMsgFailed(("Unexpected warning or informational status code %Rra!\n", rc));
3522 rc = VERR_EM_INTERNAL_ERROR;
3523 }
3524 pVM->em.s.enmState = EMSTATE_GURU_MEDITATION;
3525 Log(("EMR3ExecuteVM returns %d\n", rc));
3526 break;
3527 }
3528
3529
3530 /*
3531 * Any waiters can now be woken up
3532 */
3533 VMMR3Unlock(pVM);
3534 VMMR3Lock(pVM);
3535
3536 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x); /* (skip this in release) */
3537 STAM_PROFILE_ADV_START(&pVM->em.s.StatTotal, x);
3538
3539 /*
3540 * Act on the state.
3541 */
3542 switch (pVM->em.s.enmState)
3543 {
3544 /*
3545 * Execute raw.
3546 */
3547 case EMSTATE_RAW:
3548 rc = emR3RawExecute(pVM, &fFFDone);
3549 break;
3550
3551 /*
3552 * Execute hardware accelerated raw.
3553 */
3554 case EMSTATE_HWACC:
3555 rc = emR3HwAccExecute(pVM, idCpu, &fFFDone);
3556 break;
3557
3558 /*
3559 * Execute recompiled.
3560 */
3561 case EMSTATE_REM:
3562 rc = emR3RemExecute(pVM, &fFFDone);
3563 Log2(("EMR3ExecuteVM: emR3RemExecute -> %Rrc\n", rc));
3564 break;
3565
3566#ifdef VBOX_WITH_VMI
3567 /*
3568 * Execute PARAV function.
3569 */
3570 case EMSTATE_PARAV:
3571 rc = PARAVCallFunction(pVM);
3572 pVM->em.s.enmState = EMSTATE_REM;
3573 break;
3574#endif
3575
3576 /*
3577 * hlt - execution halted until interrupt.
3578 */
3579 case EMSTATE_HALTED:
3580 {
3581 STAM_REL_PROFILE_START(&pVM->em.s.StatHalted, y);
3582 rc = VMR3WaitHalted(pVM, !(CPUMGetGuestEFlags(pVM) & X86_EFL_IF));
3583 STAM_REL_PROFILE_STOP(&pVM->em.s.StatHalted, y);
3584 break;
3585 }
3586
3587 /*
3588 * Suspended - return to VM.cpp.
3589 */
3590 case EMSTATE_SUSPENDED:
3591 TMVirtualPause(pVM);
3592 TMCpuTickPause(pVM);
3593 VMMR3Unlock(pVM);
3594 STAM_REL_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x);
3595 return VINF_EM_SUSPEND;
3596
3597 /*
3598 * Debugging in the guest.
3599 */
3600 case EMSTATE_DEBUG_GUEST_REM:
3601 case EMSTATE_DEBUG_GUEST_RAW:
3602 TMVirtualPause(pVM);
3603 TMCpuTickPause(pVM);
3604 rc = emR3Debug(pVM, rc);
3605 TMVirtualResume(pVM);
3606 TMCpuTickResume(pVM);
3607 Log2(("EMR3ExecuteVM: enmr3Debug -> %Rrc (state %d)\n", rc, pVM->em.s.enmState));
3608 break;
3609
3610 /*
3611 * Debugging in the hypervisor.
3612 */
3613 case EMSTATE_DEBUG_HYPER:
3614 {
3615 TMVirtualPause(pVM);
3616 TMCpuTickPause(pVM);
3617 STAM_REL_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x);
3618
3619 rc = emR3Debug(pVM, rc);
3620 Log2(("EMR3ExecuteVM: enmr3Debug -> %Rrc (state %d)\n", rc, pVM->em.s.enmState));
3621 if (rc != VINF_SUCCESS)
3622 {
3623 /* switch to guru meditation mode */
3624 pVM->em.s.enmState = EMSTATE_GURU_MEDITATION;
3625 VMMR3FatalDump(pVM, rc);
3626 return rc;
3627 }
3628
3629 STAM_REL_PROFILE_ADV_START(&pVM->em.s.StatTotal, x);
3630 TMVirtualResume(pVM);
3631 TMCpuTickResume(pVM);
3632 break;
3633 }
3634
3635 /*
3636 * Guru meditation takes place in the debugger.
3637 */
3638 case EMSTATE_GURU_MEDITATION:
3639 {
3640 TMVirtualPause(pVM);
3641 TMCpuTickPause(pVM);
3642 VMMR3FatalDump(pVM, rc);
3643 emR3Debug(pVM, rc);
3644 VMMR3Unlock(pVM);
3645 STAM_REL_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x);
3646 return rc;
3647 }
3648
3649 /*
3650 * The states we don't expect here.
3651 */
3652 case EMSTATE_NONE:
3653 case EMSTATE_TERMINATING:
3654 default:
3655 AssertMsgFailed(("EMR3ExecuteVM: Invalid state %d!\n", pVM->em.s.enmState));
3656 pVM->em.s.enmState = EMSTATE_GURU_MEDITATION;
3657 TMVirtualPause(pVM);
3658 TMCpuTickPause(pVM);
3659 VMMR3Unlock(pVM);
3660 STAM_REL_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x);
3661 return VERR_EM_INTERNAL_ERROR;
3662 }
3663 } /* The Outer Main Loop */
3664 }
3665 else
3666 {
3667 /*
3668 * Fatal error.
3669 */
3670 LogFlow(("EMR3ExecuteVM: returns %Rrc (longjmp / fatal error)\n", rc));
3671 TMVirtualPause(pVM);
3672 TMCpuTickPause(pVM);
3673 VMMR3FatalDump(pVM, rc);
3674 emR3Debug(pVM, rc);
3675 VMMR3Unlock(pVM);
3676 STAM_REL_PROFILE_ADV_STOP(&pVM->em.s.StatTotal, x);
3677 /** @todo change the VM state! */
3678 return rc;
3679 }
3680
3681 /* (won't ever get here). */
3682 AssertFailed();
3683}
3684
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