VirtualBox

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

Last change on this file since 55034 was 55034, checked in by vboxsync, 10 years ago

VMM: Added VMCPU_FF_UNHALT force-flag.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 122.7 KB
Line 
1/* $Id: EM.cpp 55034 2015-03-31 13:41:56Z vboxsync $ */
2/** @file
3 * EM - Execution Monitor / Manager.
4 */
5
6/*
7 * Copyright (C) 2006-2015 Oracle Corporation
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
18/** @page pg_em EM - The Execution Monitor / Manager
19 *
20 * The Execution Monitor/Manager is responsible for running the VM, scheduling
21 * the right kind of execution (Raw-mode, Hardware Assisted, Recompiled or
22 * Interpreted), and keeping the CPU states in sync. The function
23 * EMR3ExecuteVM() is the 'main-loop' of the VM, while each of the execution
24 * modes has different inner loops (emR3RawExecute, emR3HmExecute, and
25 * emR3RemExecute).
26 *
27 * The interpreted execution is only used to avoid switching between
28 * raw-mode/hm and the recompiler when fielding virtualization traps/faults.
29 * The interpretation is thus implemented as part of EM.
30 *
31 * @see grp_em
32 */
33
34/*******************************************************************************
35* Header Files *
36*******************************************************************************/
37#define LOG_GROUP LOG_GROUP_EM
38#include <VBox/vmm/em.h>
39#include <VBox/vmm/vmm.h>
40#include <VBox/vmm/patm.h>
41#include <VBox/vmm/csam.h>
42#include <VBox/vmm/selm.h>
43#include <VBox/vmm/trpm.h>
44#include <VBox/vmm/iem.h>
45#include <VBox/vmm/iom.h>
46#include <VBox/vmm/dbgf.h>
47#include <VBox/vmm/pgm.h>
48#ifdef VBOX_WITH_REM
49# include <VBox/vmm/rem.h>
50#endif
51#include <VBox/vmm/tm.h>
52#include <VBox/vmm/mm.h>
53#include <VBox/vmm/ssm.h>
54#include <VBox/vmm/pdmapi.h>
55#include <VBox/vmm/pdmcritsect.h>
56#include <VBox/vmm/pdmqueue.h>
57#include <VBox/vmm/hm.h>
58#include <VBox/vmm/patm.h>
59#include "EMInternal.h"
60#include <VBox/vmm/vm.h>
61#include <VBox/vmm/uvm.h>
62#include <VBox/vmm/cpumdis.h>
63#include <VBox/dis.h>
64#include <VBox/disopcode.h>
65#include "VMMTracing.h"
66
67#include <iprt/asm.h>
68#include <iprt/string.h>
69#include <iprt/stream.h>
70#include <iprt/thread.h>
71
72
73/*******************************************************************************
74* Defined Constants And Macros *
75*******************************************************************************/
76#if 0 /* Disabled till after 2.1.0 when we've time to test it. */
77#define EM_NOTIFY_HM
78#endif
79
80
81/*******************************************************************************
82* Internal Functions *
83*******************************************************************************/
84static DECLCALLBACK(int) emR3Save(PVM pVM, PSSMHANDLE pSSM);
85static DECLCALLBACK(int) emR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
86#if defined(LOG_ENABLED) || defined(VBOX_STRICT)
87static const char *emR3GetStateName(EMSTATE enmState);
88#endif
89static VBOXSTRICTRC emR3Debug(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc);
90static int emR3RemStep(PVM pVM, PVMCPU pVCpu);
91static int emR3RemExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone);
92int emR3HighPriorityPostForcedActions(PVM pVM, PVMCPU pVCpu, int rc);
93
94
95/**
96 * Initializes the EM.
97 *
98 * @returns VBox status code.
99 * @param pVM Pointer to the VM.
100 */
101VMMR3_INT_DECL(int) EMR3Init(PVM pVM)
102{
103 LogFlow(("EMR3Init\n"));
104 /*
105 * Assert alignment and sizes.
106 */
107 AssertCompileMemberAlignment(VM, em.s, 32);
108 AssertCompile(sizeof(pVM->em.s) <= sizeof(pVM->em.padding));
109 AssertCompile(sizeof(pVM->aCpus[0].em.s.u.FatalLongJump) <= sizeof(pVM->aCpus[0].em.s.u.achPaddingFatalLongJump));
110
111 /*
112 * Init the structure.
113 */
114 pVM->em.s.offVM = RT_OFFSETOF(VM, em.s);
115 PCFGMNODE pCfgRoot = CFGMR3GetRoot(pVM);
116 PCFGMNODE pCfgEM = CFGMR3GetChild(pCfgRoot, "EM");
117
118 bool fEnabled;
119 int rc = CFGMR3QueryBoolDef(pCfgRoot, "RawR3Enabled", &fEnabled, true);
120 AssertLogRelRCReturn(rc, rc);
121 pVM->fRecompileUser = !fEnabled;
122
123 rc = CFGMR3QueryBoolDef(pCfgRoot, "RawR0Enabled", &fEnabled, true);
124 AssertLogRelRCReturn(rc, rc);
125 pVM->fRecompileSupervisor = !fEnabled;
126
127#ifdef VBOX_WITH_RAW_RING1
128 rc = CFGMR3QueryBoolDef(pCfgRoot, "RawR1Enabled", &pVM->fRawRing1Enabled, false);
129 AssertLogRelRCReturn(rc, rc);
130#else
131 pVM->fRawRing1Enabled = false; /* Disabled by default. */
132#endif
133
134 rc = CFGMR3QueryBoolDef(pCfgEM, "IemExecutesAll", &pVM->em.s.fIemExecutesAll, false);
135 AssertLogRelRCReturn(rc, rc);
136
137 rc = CFGMR3QueryBoolDef(pCfgEM, "TripleFaultReset", &fEnabled, false);
138 AssertLogRelRCReturn(rc, rc);
139 pVM->em.s.fGuruOnTripleFault = !fEnabled;
140 if (!pVM->em.s.fGuruOnTripleFault && pVM->cCpus > 1)
141 {
142 LogRel(("EM: Overriding /EM/TripleFaultReset, must be false on SMP.\n"));
143 pVM->em.s.fGuruOnTripleFault = true;
144 }
145
146 Log(("EMR3Init: fRecompileUser=%RTbool fRecompileSupervisor=%RTbool fRawRing1Enabled=%RTbool fIemExecutesAll=%RTbool fGuruOnTripleFault=%RTbool\n",
147 pVM->fRecompileUser, pVM->fRecompileSupervisor, pVM->fRawRing1Enabled, pVM->em.s.fIemExecutesAll, pVM->em.s.fGuruOnTripleFault));
148
149#ifdef VBOX_WITH_REM
150 /*
151 * Initialize the REM critical section.
152 */
153 AssertCompileMemberAlignment(EM, CritSectREM, sizeof(uintptr_t));
154 rc = PDMR3CritSectInit(pVM, &pVM->em.s.CritSectREM, RT_SRC_POS, "EM-REM");
155 AssertRCReturn(rc, rc);
156#endif
157
158 /*
159 * Saved state.
160 */
161 rc = SSMR3RegisterInternal(pVM, "em", 0, EM_SAVED_STATE_VERSION, 16,
162 NULL, NULL, NULL,
163 NULL, emR3Save, NULL,
164 NULL, emR3Load, NULL);
165 if (RT_FAILURE(rc))
166 return rc;
167
168 for (VMCPUID i = 0; i < pVM->cCpus; i++)
169 {
170 PVMCPU pVCpu = &pVM->aCpus[i];
171
172 pVCpu->em.s.enmState = (i == 0) ? EMSTATE_NONE : EMSTATE_WAIT_SIPI;
173 pVCpu->em.s.enmPrevState = EMSTATE_NONE;
174 pVCpu->em.s.fForceRAW = false;
175
176 pVCpu->em.s.pCtx = CPUMQueryGuestCtxPtr(pVCpu);
177#ifdef VBOX_WITH_RAW_MODE
178 if (!HMIsEnabled(pVM))
179 {
180 pVCpu->em.s.pPatmGCState = PATMR3QueryGCStateHC(pVM);
181 AssertMsg(pVCpu->em.s.pPatmGCState, ("PATMR3QueryGCStateHC failed!\n"));
182 }
183#endif
184
185 /* Force reset of the time slice. */
186 pVCpu->em.s.u64TimeSliceStart = 0;
187
188# define EM_REG_COUNTER(a, b, c) \
189 rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, c, b, i); \
190 AssertRC(rc);
191
192# define EM_REG_COUNTER_USED(a, b, c) \
193 rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, c, b, i); \
194 AssertRC(rc);
195
196# define EM_REG_PROFILE(a, b, c) \
197 rc = STAMR3RegisterF(pVM, a, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, c, b, i); \
198 AssertRC(rc);
199
200# define EM_REG_PROFILE_ADV(a, b, c) \
201 rc = STAMR3RegisterF(pVM, a, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, c, b, i); \
202 AssertRC(rc);
203
204 /*
205 * Statistics.
206 */
207#ifdef VBOX_WITH_STATISTICS
208 PEMSTATS pStats;
209 rc = MMHyperAlloc(pVM, sizeof(*pStats), 0, MM_TAG_EM, (void **)&pStats);
210 if (RT_FAILURE(rc))
211 return rc;
212
213 pVCpu->em.s.pStatsR3 = pStats;
214 pVCpu->em.s.pStatsR0 = MMHyperR3ToR0(pVM, pStats);
215 pVCpu->em.s.pStatsRC = MMHyperR3ToRC(pVM, pStats);
216
217 EM_REG_PROFILE(&pStats->StatRZEmulate, "/EM/CPU%d/RZ/Interpret", "Profiling of EMInterpretInstruction.");
218 EM_REG_PROFILE(&pStats->StatR3Emulate, "/EM/CPU%d/R3/Interpret", "Profiling of EMInterpretInstruction.");
219
220 EM_REG_PROFILE(&pStats->StatRZInterpretSucceeded, "/EM/CPU%d/RZ/Interpret/Success", "The number of times an instruction was successfully interpreted.");
221 EM_REG_PROFILE(&pStats->StatR3InterpretSucceeded, "/EM/CPU%d/R3/Interpret/Success", "The number of times an instruction was successfully interpreted.");
222
223 EM_REG_COUNTER_USED(&pStats->StatRZAnd, "/EM/CPU%d/RZ/Interpret/Success/And", "The number of times AND was successfully interpreted.");
224 EM_REG_COUNTER_USED(&pStats->StatR3And, "/EM/CPU%d/R3/Interpret/Success/And", "The number of times AND was successfully interpreted.");
225 EM_REG_COUNTER_USED(&pStats->StatRZAdd, "/EM/CPU%d/RZ/Interpret/Success/Add", "The number of times ADD was successfully interpreted.");
226 EM_REG_COUNTER_USED(&pStats->StatR3Add, "/EM/CPU%d/R3/Interpret/Success/Add", "The number of times ADD was successfully interpreted.");
227 EM_REG_COUNTER_USED(&pStats->StatRZAdc, "/EM/CPU%d/RZ/Interpret/Success/Adc", "The number of times ADC was successfully interpreted.");
228 EM_REG_COUNTER_USED(&pStats->StatR3Adc, "/EM/CPU%d/R3/Interpret/Success/Adc", "The number of times ADC was successfully interpreted.");
229 EM_REG_COUNTER_USED(&pStats->StatRZSub, "/EM/CPU%d/RZ/Interpret/Success/Sub", "The number of times SUB was successfully interpreted.");
230 EM_REG_COUNTER_USED(&pStats->StatR3Sub, "/EM/CPU%d/R3/Interpret/Success/Sub", "The number of times SUB was successfully interpreted.");
231 EM_REG_COUNTER_USED(&pStats->StatRZCpuId, "/EM/CPU%d/RZ/Interpret/Success/CpuId", "The number of times CPUID was successfully interpreted.");
232 EM_REG_COUNTER_USED(&pStats->StatR3CpuId, "/EM/CPU%d/R3/Interpret/Success/CpuId", "The number of times CPUID was successfully interpreted.");
233 EM_REG_COUNTER_USED(&pStats->StatRZDec, "/EM/CPU%d/RZ/Interpret/Success/Dec", "The number of times DEC was successfully interpreted.");
234 EM_REG_COUNTER_USED(&pStats->StatR3Dec, "/EM/CPU%d/R3/Interpret/Success/Dec", "The number of times DEC was successfully interpreted.");
235 EM_REG_COUNTER_USED(&pStats->StatRZHlt, "/EM/CPU%d/RZ/Interpret/Success/Hlt", "The number of times HLT was successfully interpreted.");
236 EM_REG_COUNTER_USED(&pStats->StatR3Hlt, "/EM/CPU%d/R3/Interpret/Success/Hlt", "The number of times HLT was successfully interpreted.");
237 EM_REG_COUNTER_USED(&pStats->StatRZInc, "/EM/CPU%d/RZ/Interpret/Success/Inc", "The number of times INC was successfully interpreted.");
238 EM_REG_COUNTER_USED(&pStats->StatR3Inc, "/EM/CPU%d/R3/Interpret/Success/Inc", "The number of times INC was successfully interpreted.");
239 EM_REG_COUNTER_USED(&pStats->StatRZInvlPg, "/EM/CPU%d/RZ/Interpret/Success/Invlpg", "The number of times INVLPG was successfully interpreted.");
240 EM_REG_COUNTER_USED(&pStats->StatR3InvlPg, "/EM/CPU%d/R3/Interpret/Success/Invlpg", "The number of times INVLPG was successfully interpreted.");
241 EM_REG_COUNTER_USED(&pStats->StatRZIret, "/EM/CPU%d/RZ/Interpret/Success/Iret", "The number of times IRET was successfully interpreted.");
242 EM_REG_COUNTER_USED(&pStats->StatR3Iret, "/EM/CPU%d/R3/Interpret/Success/Iret", "The number of times IRET was successfully interpreted.");
243 EM_REG_COUNTER_USED(&pStats->StatRZLLdt, "/EM/CPU%d/RZ/Interpret/Success/LLdt", "The number of times LLDT was successfully interpreted.");
244 EM_REG_COUNTER_USED(&pStats->StatR3LLdt, "/EM/CPU%d/R3/Interpret/Success/LLdt", "The number of times LLDT was successfully interpreted.");
245 EM_REG_COUNTER_USED(&pStats->StatRZLIdt, "/EM/CPU%d/RZ/Interpret/Success/LIdt", "The number of times LIDT was successfully interpreted.");
246 EM_REG_COUNTER_USED(&pStats->StatR3LIdt, "/EM/CPU%d/R3/Interpret/Success/LIdt", "The number of times LIDT was successfully interpreted.");
247 EM_REG_COUNTER_USED(&pStats->StatRZLGdt, "/EM/CPU%d/RZ/Interpret/Success/LGdt", "The number of times LGDT was successfully interpreted.");
248 EM_REG_COUNTER_USED(&pStats->StatR3LGdt, "/EM/CPU%d/R3/Interpret/Success/LGdt", "The number of times LGDT was successfully interpreted.");
249 EM_REG_COUNTER_USED(&pStats->StatRZMov, "/EM/CPU%d/RZ/Interpret/Success/Mov", "The number of times MOV was successfully interpreted.");
250 EM_REG_COUNTER_USED(&pStats->StatR3Mov, "/EM/CPU%d/R3/Interpret/Success/Mov", "The number of times MOV was successfully interpreted.");
251 EM_REG_COUNTER_USED(&pStats->StatRZMovCRx, "/EM/CPU%d/RZ/Interpret/Success/MovCRx", "The number of times MOV CRx was successfully interpreted.");
252 EM_REG_COUNTER_USED(&pStats->StatR3MovCRx, "/EM/CPU%d/R3/Interpret/Success/MovCRx", "The number of times MOV CRx was successfully interpreted.");
253 EM_REG_COUNTER_USED(&pStats->StatRZMovDRx, "/EM/CPU%d/RZ/Interpret/Success/MovDRx", "The number of times MOV DRx was successfully interpreted.");
254 EM_REG_COUNTER_USED(&pStats->StatR3MovDRx, "/EM/CPU%d/R3/Interpret/Success/MovDRx", "The number of times MOV DRx was successfully interpreted.");
255 EM_REG_COUNTER_USED(&pStats->StatRZOr, "/EM/CPU%d/RZ/Interpret/Success/Or", "The number of times OR was successfully interpreted.");
256 EM_REG_COUNTER_USED(&pStats->StatR3Or, "/EM/CPU%d/R3/Interpret/Success/Or", "The number of times OR was successfully interpreted.");
257 EM_REG_COUNTER_USED(&pStats->StatRZPop, "/EM/CPU%d/RZ/Interpret/Success/Pop", "The number of times POP was successfully interpreted.");
258 EM_REG_COUNTER_USED(&pStats->StatR3Pop, "/EM/CPU%d/R3/Interpret/Success/Pop", "The number of times POP was successfully interpreted.");
259 EM_REG_COUNTER_USED(&pStats->StatRZRdtsc, "/EM/CPU%d/RZ/Interpret/Success/Rdtsc", "The number of times RDTSC was successfully interpreted.");
260 EM_REG_COUNTER_USED(&pStats->StatR3Rdtsc, "/EM/CPU%d/R3/Interpret/Success/Rdtsc", "The number of times RDTSC was successfully interpreted.");
261 EM_REG_COUNTER_USED(&pStats->StatRZRdpmc, "/EM/CPU%d/RZ/Interpret/Success/Rdpmc", "The number of times RDPMC was successfully interpreted.");
262 EM_REG_COUNTER_USED(&pStats->StatR3Rdpmc, "/EM/CPU%d/R3/Interpret/Success/Rdpmc", "The number of times RDPMC was successfully interpreted.");
263 EM_REG_COUNTER_USED(&pStats->StatRZSti, "/EM/CPU%d/RZ/Interpret/Success/Sti", "The number of times STI was successfully interpreted.");
264 EM_REG_COUNTER_USED(&pStats->StatR3Sti, "/EM/CPU%d/R3/Interpret/Success/Sti", "The number of times STI was successfully interpreted.");
265 EM_REG_COUNTER_USED(&pStats->StatRZXchg, "/EM/CPU%d/RZ/Interpret/Success/Xchg", "The number of times XCHG was successfully interpreted.");
266 EM_REG_COUNTER_USED(&pStats->StatR3Xchg, "/EM/CPU%d/R3/Interpret/Success/Xchg", "The number of times XCHG was successfully interpreted.");
267 EM_REG_COUNTER_USED(&pStats->StatRZXor, "/EM/CPU%d/RZ/Interpret/Success/Xor", "The number of times XOR was successfully interpreted.");
268 EM_REG_COUNTER_USED(&pStats->StatR3Xor, "/EM/CPU%d/R3/Interpret/Success/Xor", "The number of times XOR was successfully interpreted.");
269 EM_REG_COUNTER_USED(&pStats->StatRZMonitor, "/EM/CPU%d/RZ/Interpret/Success/Monitor", "The number of times MONITOR was successfully interpreted.");
270 EM_REG_COUNTER_USED(&pStats->StatR3Monitor, "/EM/CPU%d/R3/Interpret/Success/Monitor", "The number of times MONITOR was successfully interpreted.");
271 EM_REG_COUNTER_USED(&pStats->StatRZMWait, "/EM/CPU%d/RZ/Interpret/Success/MWait", "The number of times MWAIT was successfully interpreted.");
272 EM_REG_COUNTER_USED(&pStats->StatR3MWait, "/EM/CPU%d/R3/Interpret/Success/MWait", "The number of times MWAIT was successfully interpreted.");
273 EM_REG_COUNTER_USED(&pStats->StatRZBtr, "/EM/CPU%d/RZ/Interpret/Success/Btr", "The number of times BTR was successfully interpreted.");
274 EM_REG_COUNTER_USED(&pStats->StatR3Btr, "/EM/CPU%d/R3/Interpret/Success/Btr", "The number of times BTR was successfully interpreted.");
275 EM_REG_COUNTER_USED(&pStats->StatRZBts, "/EM/CPU%d/RZ/Interpret/Success/Bts", "The number of times BTS was successfully interpreted.");
276 EM_REG_COUNTER_USED(&pStats->StatR3Bts, "/EM/CPU%d/R3/Interpret/Success/Bts", "The number of times BTS was successfully interpreted.");
277 EM_REG_COUNTER_USED(&pStats->StatRZBtc, "/EM/CPU%d/RZ/Interpret/Success/Btc", "The number of times BTC was successfully interpreted.");
278 EM_REG_COUNTER_USED(&pStats->StatR3Btc, "/EM/CPU%d/R3/Interpret/Success/Btc", "The number of times BTC was successfully interpreted.");
279 EM_REG_COUNTER_USED(&pStats->StatRZCmpXchg, "/EM/CPU%d/RZ/Interpret/Success/CmpXchg", "The number of times CMPXCHG was successfully interpreted.");
280 EM_REG_COUNTER_USED(&pStats->StatR3CmpXchg, "/EM/CPU%d/R3/Interpret/Success/CmpXchg", "The number of times CMPXCHG was successfully interpreted.");
281 EM_REG_COUNTER_USED(&pStats->StatRZCmpXchg8b, "/EM/CPU%d/RZ/Interpret/Success/CmpXchg8b", "The number of times CMPXCHG8B was successfully interpreted.");
282 EM_REG_COUNTER_USED(&pStats->StatR3CmpXchg8b, "/EM/CPU%d/R3/Interpret/Success/CmpXchg8b", "The number of times CMPXCHG8B was successfully interpreted.");
283 EM_REG_COUNTER_USED(&pStats->StatRZXAdd, "/EM/CPU%d/RZ/Interpret/Success/XAdd", "The number of times XADD was successfully interpreted.");
284 EM_REG_COUNTER_USED(&pStats->StatR3XAdd, "/EM/CPU%d/R3/Interpret/Success/XAdd", "The number of times XADD was successfully interpreted.");
285 EM_REG_COUNTER_USED(&pStats->StatR3Rdmsr, "/EM/CPU%d/R3/Interpret/Success/Rdmsr", "The number of times RDMSR was successfully interpreted.");
286 EM_REG_COUNTER_USED(&pStats->StatRZRdmsr, "/EM/CPU%d/RZ/Interpret/Success/Rdmsr", "The number of times RDMSR was successfully interpreted.");
287 EM_REG_COUNTER_USED(&pStats->StatR3Wrmsr, "/EM/CPU%d/R3/Interpret/Success/Wrmsr", "The number of times WRMSR was successfully interpreted.");
288 EM_REG_COUNTER_USED(&pStats->StatRZWrmsr, "/EM/CPU%d/RZ/Interpret/Success/Wrmsr", "The number of times WRMSR was successfully interpreted.");
289 EM_REG_COUNTER_USED(&pStats->StatR3StosWD, "/EM/CPU%d/R3/Interpret/Success/Stoswd", "The number of times STOSWD was successfully interpreted.");
290 EM_REG_COUNTER_USED(&pStats->StatRZStosWD, "/EM/CPU%d/RZ/Interpret/Success/Stoswd", "The number of times STOSWD was successfully interpreted.");
291 EM_REG_COUNTER_USED(&pStats->StatRZWbInvd, "/EM/CPU%d/RZ/Interpret/Success/WbInvd", "The number of times WBINVD was successfully interpreted.");
292 EM_REG_COUNTER_USED(&pStats->StatR3WbInvd, "/EM/CPU%d/R3/Interpret/Success/WbInvd", "The number of times WBINVD was successfully interpreted.");
293 EM_REG_COUNTER_USED(&pStats->StatRZLmsw, "/EM/CPU%d/RZ/Interpret/Success/Lmsw", "The number of times LMSW was successfully interpreted.");
294 EM_REG_COUNTER_USED(&pStats->StatR3Lmsw, "/EM/CPU%d/R3/Interpret/Success/Lmsw", "The number of times LMSW was successfully interpreted.");
295 EM_REG_COUNTER_USED(&pStats->StatRZSmsw, "/EM/CPU%d/RZ/Interpret/Success/Smsw", "The number of times SMSW was successfully interpreted.");
296 EM_REG_COUNTER_USED(&pStats->StatR3Smsw, "/EM/CPU%d/R3/Interpret/Success/Smsw", "The number of times SMSW was successfully interpreted.");
297
298 EM_REG_COUNTER(&pStats->StatRZInterpretFailed, "/EM/CPU%d/RZ/Interpret/Failed", "The number of times an instruction was not interpreted.");
299 EM_REG_COUNTER(&pStats->StatR3InterpretFailed, "/EM/CPU%d/R3/Interpret/Failed", "The number of times an instruction was not interpreted.");
300
301 EM_REG_COUNTER_USED(&pStats->StatRZFailedAnd, "/EM/CPU%d/RZ/Interpret/Failed/And", "The number of times AND was not interpreted.");
302 EM_REG_COUNTER_USED(&pStats->StatR3FailedAnd, "/EM/CPU%d/R3/Interpret/Failed/And", "The number of times AND was not interpreted.");
303 EM_REG_COUNTER_USED(&pStats->StatRZFailedCpuId, "/EM/CPU%d/RZ/Interpret/Failed/CpuId", "The number of times CPUID was not interpreted.");
304 EM_REG_COUNTER_USED(&pStats->StatR3FailedCpuId, "/EM/CPU%d/R3/Interpret/Failed/CpuId", "The number of times CPUID was not interpreted.");
305 EM_REG_COUNTER_USED(&pStats->StatRZFailedDec, "/EM/CPU%d/RZ/Interpret/Failed/Dec", "The number of times DEC was not interpreted.");
306 EM_REG_COUNTER_USED(&pStats->StatR3FailedDec, "/EM/CPU%d/R3/Interpret/Failed/Dec", "The number of times DEC was not interpreted.");
307 EM_REG_COUNTER_USED(&pStats->StatRZFailedHlt, "/EM/CPU%d/RZ/Interpret/Failed/Hlt", "The number of times HLT was not interpreted.");
308 EM_REG_COUNTER_USED(&pStats->StatR3FailedHlt, "/EM/CPU%d/R3/Interpret/Failed/Hlt", "The number of times HLT was not interpreted.");
309 EM_REG_COUNTER_USED(&pStats->StatRZFailedInc, "/EM/CPU%d/RZ/Interpret/Failed/Inc", "The number of times INC was not interpreted.");
310 EM_REG_COUNTER_USED(&pStats->StatR3FailedInc, "/EM/CPU%d/R3/Interpret/Failed/Inc", "The number of times INC was not interpreted.");
311 EM_REG_COUNTER_USED(&pStats->StatRZFailedInvlPg, "/EM/CPU%d/RZ/Interpret/Failed/InvlPg", "The number of times INVLPG was not interpreted.");
312 EM_REG_COUNTER_USED(&pStats->StatR3FailedInvlPg, "/EM/CPU%d/R3/Interpret/Failed/InvlPg", "The number of times INVLPG was not interpreted.");
313 EM_REG_COUNTER_USED(&pStats->StatRZFailedIret, "/EM/CPU%d/RZ/Interpret/Failed/Iret", "The number of times IRET was not interpreted.");
314 EM_REG_COUNTER_USED(&pStats->StatR3FailedIret, "/EM/CPU%d/R3/Interpret/Failed/Iret", "The number of times IRET was not interpreted.");
315 EM_REG_COUNTER_USED(&pStats->StatRZFailedLLdt, "/EM/CPU%d/RZ/Interpret/Failed/LLdt", "The number of times LLDT was not interpreted.");
316 EM_REG_COUNTER_USED(&pStats->StatR3FailedLLdt, "/EM/CPU%d/R3/Interpret/Failed/LLdt", "The number of times LLDT was not interpreted.");
317 EM_REG_COUNTER_USED(&pStats->StatRZFailedLIdt, "/EM/CPU%d/RZ/Interpret/Failed/LIdt", "The number of times LIDT was not interpreted.");
318 EM_REG_COUNTER_USED(&pStats->StatR3FailedLIdt, "/EM/CPU%d/R3/Interpret/Failed/LIdt", "The number of times LIDT was not interpreted.");
319 EM_REG_COUNTER_USED(&pStats->StatRZFailedLGdt, "/EM/CPU%d/RZ/Interpret/Failed/LGdt", "The number of times LGDT was not interpreted.");
320 EM_REG_COUNTER_USED(&pStats->StatR3FailedLGdt, "/EM/CPU%d/R3/Interpret/Failed/LGdt", "The number of times LGDT was not interpreted.");
321 EM_REG_COUNTER_USED(&pStats->StatRZFailedMov, "/EM/CPU%d/RZ/Interpret/Failed/Mov", "The number of times MOV was not interpreted.");
322 EM_REG_COUNTER_USED(&pStats->StatR3FailedMov, "/EM/CPU%d/R3/Interpret/Failed/Mov", "The number of times MOV was not interpreted.");
323 EM_REG_COUNTER_USED(&pStats->StatRZFailedMovCRx, "/EM/CPU%d/RZ/Interpret/Failed/MovCRx", "The number of times MOV CRx was not interpreted.");
324 EM_REG_COUNTER_USED(&pStats->StatR3FailedMovCRx, "/EM/CPU%d/R3/Interpret/Failed/MovCRx", "The number of times MOV CRx was not interpreted.");
325 EM_REG_COUNTER_USED(&pStats->StatRZFailedMovDRx, "/EM/CPU%d/RZ/Interpret/Failed/MovDRx", "The number of times MOV DRx was not interpreted.");
326 EM_REG_COUNTER_USED(&pStats->StatR3FailedMovDRx, "/EM/CPU%d/R3/Interpret/Failed/MovDRx", "The number of times MOV DRx was not interpreted.");
327 EM_REG_COUNTER_USED(&pStats->StatRZFailedOr, "/EM/CPU%d/RZ/Interpret/Failed/Or", "The number of times OR was not interpreted.");
328 EM_REG_COUNTER_USED(&pStats->StatR3FailedOr, "/EM/CPU%d/R3/Interpret/Failed/Or", "The number of times OR was not interpreted.");
329 EM_REG_COUNTER_USED(&pStats->StatRZFailedPop, "/EM/CPU%d/RZ/Interpret/Failed/Pop", "The number of times POP was not interpreted.");
330 EM_REG_COUNTER_USED(&pStats->StatR3FailedPop, "/EM/CPU%d/R3/Interpret/Failed/Pop", "The number of times POP was not interpreted.");
331 EM_REG_COUNTER_USED(&pStats->StatRZFailedSti, "/EM/CPU%d/RZ/Interpret/Failed/Sti", "The number of times STI was not interpreted.");
332 EM_REG_COUNTER_USED(&pStats->StatR3FailedSti, "/EM/CPU%d/R3/Interpret/Failed/Sti", "The number of times STI was not interpreted.");
333 EM_REG_COUNTER_USED(&pStats->StatRZFailedXchg, "/EM/CPU%d/RZ/Interpret/Failed/Xchg", "The number of times XCHG was not interpreted.");
334 EM_REG_COUNTER_USED(&pStats->StatR3FailedXchg, "/EM/CPU%d/R3/Interpret/Failed/Xchg", "The number of times XCHG was not interpreted.");
335 EM_REG_COUNTER_USED(&pStats->StatRZFailedXor, "/EM/CPU%d/RZ/Interpret/Failed/Xor", "The number of times XOR was not interpreted.");
336 EM_REG_COUNTER_USED(&pStats->StatR3FailedXor, "/EM/CPU%d/R3/Interpret/Failed/Xor", "The number of times XOR was not interpreted.");
337 EM_REG_COUNTER_USED(&pStats->StatRZFailedMonitor, "/EM/CPU%d/RZ/Interpret/Failed/Monitor", "The number of times MONITOR was not interpreted.");
338 EM_REG_COUNTER_USED(&pStats->StatR3FailedMonitor, "/EM/CPU%d/R3/Interpret/Failed/Monitor", "The number of times MONITOR was not interpreted.");
339 EM_REG_COUNTER_USED(&pStats->StatRZFailedMWait, "/EM/CPU%d/RZ/Interpret/Failed/MWait", "The number of times MWAIT was not interpreted.");
340 EM_REG_COUNTER_USED(&pStats->StatR3FailedMWait, "/EM/CPU%d/R3/Interpret/Failed/MWait", "The number of times MWAIT was not interpreted.");
341 EM_REG_COUNTER_USED(&pStats->StatRZFailedRdtsc, "/EM/CPU%d/RZ/Interpret/Failed/Rdtsc", "The number of times RDTSC was not interpreted.");
342 EM_REG_COUNTER_USED(&pStats->StatR3FailedRdtsc, "/EM/CPU%d/R3/Interpret/Failed/Rdtsc", "The number of times RDTSC was not interpreted.");
343 EM_REG_COUNTER_USED(&pStats->StatRZFailedRdpmc, "/EM/CPU%d/RZ/Interpret/Failed/Rdpmc", "The number of times RDPMC was not interpreted.");
344 EM_REG_COUNTER_USED(&pStats->StatR3FailedRdpmc, "/EM/CPU%d/R3/Interpret/Failed/Rdpmc", "The number of times RDPMC was not interpreted.");
345 EM_REG_COUNTER_USED(&pStats->StatRZFailedRdmsr, "/EM/CPU%d/RZ/Interpret/Failed/Rdmsr", "The number of times RDMSR was not interpreted.");
346 EM_REG_COUNTER_USED(&pStats->StatR3FailedRdmsr, "/EM/CPU%d/R3/Interpret/Failed/Rdmsr", "The number of times RDMSR was not interpreted.");
347 EM_REG_COUNTER_USED(&pStats->StatRZFailedWrmsr, "/EM/CPU%d/RZ/Interpret/Failed/Wrmsr", "The number of times WRMSR was not interpreted.");
348 EM_REG_COUNTER_USED(&pStats->StatR3FailedWrmsr, "/EM/CPU%d/R3/Interpret/Failed/Wrmsr", "The number of times WRMSR was not interpreted.");
349 EM_REG_COUNTER_USED(&pStats->StatRZFailedLmsw, "/EM/CPU%d/RZ/Interpret/Failed/Lmsw", "The number of times LMSW was not interpreted.");
350 EM_REG_COUNTER_USED(&pStats->StatR3FailedLmsw, "/EM/CPU%d/R3/Interpret/Failed/Lmsw", "The number of times LMSW was not interpreted.");
351 EM_REG_COUNTER_USED(&pStats->StatRZFailedSmsw, "/EM/CPU%d/RZ/Interpret/Failed/Smsw", "The number of times SMSW was not interpreted.");
352 EM_REG_COUNTER_USED(&pStats->StatR3FailedSmsw, "/EM/CPU%d/R3/Interpret/Failed/Smsw", "The number of times SMSW was not interpreted.");
353
354 EM_REG_COUNTER_USED(&pStats->StatRZFailedMisc, "/EM/CPU%d/RZ/Interpret/Failed/Misc", "The number of times some misc instruction was encountered.");
355 EM_REG_COUNTER_USED(&pStats->StatR3FailedMisc, "/EM/CPU%d/R3/Interpret/Failed/Misc", "The number of times some misc instruction was encountered.");
356 EM_REG_COUNTER_USED(&pStats->StatRZFailedAdd, "/EM/CPU%d/RZ/Interpret/Failed/Add", "The number of times ADD was not interpreted.");
357 EM_REG_COUNTER_USED(&pStats->StatR3FailedAdd, "/EM/CPU%d/R3/Interpret/Failed/Add", "The number of times ADD was not interpreted.");
358 EM_REG_COUNTER_USED(&pStats->StatRZFailedAdc, "/EM/CPU%d/RZ/Interpret/Failed/Adc", "The number of times ADC was not interpreted.");
359 EM_REG_COUNTER_USED(&pStats->StatR3FailedAdc, "/EM/CPU%d/R3/Interpret/Failed/Adc", "The number of times ADC was not interpreted.");
360 EM_REG_COUNTER_USED(&pStats->StatRZFailedBtr, "/EM/CPU%d/RZ/Interpret/Failed/Btr", "The number of times BTR was not interpreted.");
361 EM_REG_COUNTER_USED(&pStats->StatR3FailedBtr, "/EM/CPU%d/R3/Interpret/Failed/Btr", "The number of times BTR was not interpreted.");
362 EM_REG_COUNTER_USED(&pStats->StatRZFailedBts, "/EM/CPU%d/RZ/Interpret/Failed/Bts", "The number of times BTS was not interpreted.");
363 EM_REG_COUNTER_USED(&pStats->StatR3FailedBts, "/EM/CPU%d/R3/Interpret/Failed/Bts", "The number of times BTS was not interpreted.");
364 EM_REG_COUNTER_USED(&pStats->StatRZFailedBtc, "/EM/CPU%d/RZ/Interpret/Failed/Btc", "The number of times BTC was not interpreted.");
365 EM_REG_COUNTER_USED(&pStats->StatR3FailedBtc, "/EM/CPU%d/R3/Interpret/Failed/Btc", "The number of times BTC was not interpreted.");
366 EM_REG_COUNTER_USED(&pStats->StatRZFailedCli, "/EM/CPU%d/RZ/Interpret/Failed/Cli", "The number of times CLI was not interpreted.");
367 EM_REG_COUNTER_USED(&pStats->StatR3FailedCli, "/EM/CPU%d/R3/Interpret/Failed/Cli", "The number of times CLI was not interpreted.");
368 EM_REG_COUNTER_USED(&pStats->StatRZFailedCmpXchg, "/EM/CPU%d/RZ/Interpret/Failed/CmpXchg", "The number of times CMPXCHG was not interpreted.");
369 EM_REG_COUNTER_USED(&pStats->StatR3FailedCmpXchg, "/EM/CPU%d/R3/Interpret/Failed/CmpXchg", "The number of times CMPXCHG was not interpreted.");
370 EM_REG_COUNTER_USED(&pStats->StatRZFailedCmpXchg8b, "/EM/CPU%d/RZ/Interpret/Failed/CmpXchg8b", "The number of times CMPXCHG8B was not interpreted.");
371 EM_REG_COUNTER_USED(&pStats->StatR3FailedCmpXchg8b, "/EM/CPU%d/R3/Interpret/Failed/CmpXchg8b", "The number of times CMPXCHG8B was not interpreted.");
372 EM_REG_COUNTER_USED(&pStats->StatRZFailedXAdd, "/EM/CPU%d/RZ/Interpret/Failed/XAdd", "The number of times XADD was not interpreted.");
373 EM_REG_COUNTER_USED(&pStats->StatR3FailedXAdd, "/EM/CPU%d/R3/Interpret/Failed/XAdd", "The number of times XADD was not interpreted.");
374 EM_REG_COUNTER_USED(&pStats->StatRZFailedMovNTPS, "/EM/CPU%d/RZ/Interpret/Failed/MovNTPS", "The number of times MOVNTPS was not interpreted.");
375 EM_REG_COUNTER_USED(&pStats->StatR3FailedMovNTPS, "/EM/CPU%d/R3/Interpret/Failed/MovNTPS", "The number of times MOVNTPS was not interpreted.");
376 EM_REG_COUNTER_USED(&pStats->StatRZFailedStosWD, "/EM/CPU%d/RZ/Interpret/Failed/StosWD", "The number of times STOSWD was not interpreted.");
377 EM_REG_COUNTER_USED(&pStats->StatR3FailedStosWD, "/EM/CPU%d/R3/Interpret/Failed/StosWD", "The number of times STOSWD was not interpreted.");
378 EM_REG_COUNTER_USED(&pStats->StatRZFailedSub, "/EM/CPU%d/RZ/Interpret/Failed/Sub", "The number of times SUB was not interpreted.");
379 EM_REG_COUNTER_USED(&pStats->StatR3FailedSub, "/EM/CPU%d/R3/Interpret/Failed/Sub", "The number of times SUB was not interpreted.");
380 EM_REG_COUNTER_USED(&pStats->StatRZFailedWbInvd, "/EM/CPU%d/RZ/Interpret/Failed/WbInvd", "The number of times WBINVD was not interpreted.");
381 EM_REG_COUNTER_USED(&pStats->StatR3FailedWbInvd, "/EM/CPU%d/R3/Interpret/Failed/WbInvd", "The number of times WBINVD was not interpreted.");
382
383 EM_REG_COUNTER_USED(&pStats->StatRZFailedUserMode, "/EM/CPU%d/RZ/Interpret/Failed/UserMode", "The number of rejections because of CPL.");
384 EM_REG_COUNTER_USED(&pStats->StatR3FailedUserMode, "/EM/CPU%d/R3/Interpret/Failed/UserMode", "The number of rejections because of CPL.");
385 EM_REG_COUNTER_USED(&pStats->StatRZFailedPrefix, "/EM/CPU%d/RZ/Interpret/Failed/Prefix", "The number of rejections because of prefix .");
386 EM_REG_COUNTER_USED(&pStats->StatR3FailedPrefix, "/EM/CPU%d/R3/Interpret/Failed/Prefix", "The number of rejections because of prefix .");
387
388 EM_REG_COUNTER_USED(&pStats->StatIoRestarted, "/EM/CPU%d/R3/PrivInst/IoRestarted", "I/O instructions restarted in ring-3.");
389# ifdef VBOX_WITH_FIRST_IEM_STEP
390 EM_REG_COUNTER_USED(&pStats->StatIoIem, "/EM/CPU%d/R3/PrivInst/IoIem", "I/O instructions end to IEM in ring-3.");
391# else
392 EM_REG_COUNTER_USED(&pStats->StatIn, "/EM/CPU%d/R3/PrivInst/In", "Number of in instructions.");
393 EM_REG_COUNTER_USED(&pStats->StatOut, "/EM/CPU%d/R3/PrivInst/Out", "Number of out instructions.");
394# endif
395 EM_REG_COUNTER_USED(&pStats->StatCli, "/EM/CPU%d/R3/PrivInst/Cli", "Number of cli instructions.");
396 EM_REG_COUNTER_USED(&pStats->StatSti, "/EM/CPU%d/R3/PrivInst/Sti", "Number of sli instructions.");
397 EM_REG_COUNTER_USED(&pStats->StatHlt, "/EM/CPU%d/R3/PrivInst/Hlt", "Number of hlt instructions not handled in GC because of PATM.");
398 EM_REG_COUNTER_USED(&pStats->StatInvlpg, "/EM/CPU%d/R3/PrivInst/Invlpg", "Number of invlpg instructions.");
399 EM_REG_COUNTER_USED(&pStats->StatMisc, "/EM/CPU%d/R3/PrivInst/Misc", "Number of misc. instructions.");
400 EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[0], "/EM/CPU%d/R3/PrivInst/Mov CR0, X", "Number of mov CR0 write instructions.");
401 EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[1], "/EM/CPU%d/R3/PrivInst/Mov CR1, X", "Number of mov CR1 write instructions.");
402 EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[2], "/EM/CPU%d/R3/PrivInst/Mov CR2, X", "Number of mov CR2 write instructions.");
403 EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[3], "/EM/CPU%d/R3/PrivInst/Mov CR3, X", "Number of mov CR3 write instructions.");
404 EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[4], "/EM/CPU%d/R3/PrivInst/Mov CR4, X", "Number of mov CR4 write instructions.");
405 EM_REG_COUNTER_USED(&pStats->StatMovReadCR[0], "/EM/CPU%d/R3/PrivInst/Mov X, CR0", "Number of mov CR0 read instructions.");
406 EM_REG_COUNTER_USED(&pStats->StatMovReadCR[1], "/EM/CPU%d/R3/PrivInst/Mov X, CR1", "Number of mov CR1 read instructions.");
407 EM_REG_COUNTER_USED(&pStats->StatMovReadCR[2], "/EM/CPU%d/R3/PrivInst/Mov X, CR2", "Number of mov CR2 read instructions.");
408 EM_REG_COUNTER_USED(&pStats->StatMovReadCR[3], "/EM/CPU%d/R3/PrivInst/Mov X, CR3", "Number of mov CR3 read instructions.");
409 EM_REG_COUNTER_USED(&pStats->StatMovReadCR[4], "/EM/CPU%d/R3/PrivInst/Mov X, CR4", "Number of mov CR4 read instructions.");
410 EM_REG_COUNTER_USED(&pStats->StatMovDRx, "/EM/CPU%d/R3/PrivInst/MovDRx", "Number of mov DRx instructions.");
411 EM_REG_COUNTER_USED(&pStats->StatIret, "/EM/CPU%d/R3/PrivInst/Iret", "Number of iret instructions.");
412 EM_REG_COUNTER_USED(&pStats->StatMovLgdt, "/EM/CPU%d/R3/PrivInst/Lgdt", "Number of lgdt instructions.");
413 EM_REG_COUNTER_USED(&pStats->StatMovLidt, "/EM/CPU%d/R3/PrivInst/Lidt", "Number of lidt instructions.");
414 EM_REG_COUNTER_USED(&pStats->StatMovLldt, "/EM/CPU%d/R3/PrivInst/Lldt", "Number of lldt instructions.");
415 EM_REG_COUNTER_USED(&pStats->StatSysEnter, "/EM/CPU%d/R3/PrivInst/Sysenter", "Number of sysenter instructions.");
416 EM_REG_COUNTER_USED(&pStats->StatSysExit, "/EM/CPU%d/R3/PrivInst/Sysexit", "Number of sysexit instructions.");
417 EM_REG_COUNTER_USED(&pStats->StatSysCall, "/EM/CPU%d/R3/PrivInst/Syscall", "Number of syscall instructions.");
418 EM_REG_COUNTER_USED(&pStats->StatSysRet, "/EM/CPU%d/R3/PrivInst/Sysret", "Number of sysret instructions.");
419
420 EM_REG_COUNTER(&pVCpu->em.s.StatTotalClis, "/EM/CPU%d/Cli/Total", "Total number of cli instructions executed.");
421 pVCpu->em.s.pCliStatTree = 0;
422
423 /* these should be considered for release statistics. */
424 EM_REG_COUNTER(&pVCpu->em.s.StatIOEmu, "/PROF/CPU%d/EM/Emulation/IO", "Profiling of emR3RawExecuteIOInstruction.");
425 EM_REG_COUNTER(&pVCpu->em.s.StatPrivEmu, "/PROF/CPU%d/EM/Emulation/Priv", "Profiling of emR3RawPrivileged.");
426 EM_REG_PROFILE(&pVCpu->em.s.StatHmEntry, "/PROF/CPU%d/EM/HmEnter", "Profiling Hardware Accelerated Mode entry overhead.");
427 EM_REG_PROFILE(&pVCpu->em.s.StatHmExec, "/PROF/CPU%d/EM/HmExec", "Profiling Hardware Accelerated Mode execution.");
428 EM_REG_PROFILE(&pVCpu->em.s.StatIEMEmu, "/PROF/CPU%d/EM/IEMEmuSingle", "Profiling single instruction IEM execution.");
429 EM_REG_PROFILE(&pVCpu->em.s.StatIEMThenREM, "/PROF/CPU%d/EM/IEMThenRem", "Profiling IEM-then-REM instruction execution (by IEM).");
430 EM_REG_PROFILE(&pVCpu->em.s.StatREMEmu, "/PROF/CPU%d/EM/REMEmuSingle", "Profiling single instruction REM execution.");
431 EM_REG_PROFILE(&pVCpu->em.s.StatREMExec, "/PROF/CPU%d/EM/REMExec", "Profiling REM execution.");
432 EM_REG_PROFILE(&pVCpu->em.s.StatREMSync, "/PROF/CPU%d/EM/REMSync", "Profiling REM context syncing.");
433 EM_REG_PROFILE(&pVCpu->em.s.StatRAWEntry, "/PROF/CPU%d/EM/RAWEnter", "Profiling Raw Mode entry overhead.");
434 EM_REG_PROFILE(&pVCpu->em.s.StatRAWExec, "/PROF/CPU%d/EM/RAWExec", "Profiling Raw Mode execution.");
435 EM_REG_PROFILE(&pVCpu->em.s.StatRAWTail, "/PROF/CPU%d/EM/RAWTail", "Profiling Raw Mode tail overhead.");
436
437#endif /* VBOX_WITH_STATISTICS */
438
439 EM_REG_COUNTER(&pVCpu->em.s.StatForcedActions, "/PROF/CPU%d/EM/ForcedActions", "Profiling forced action execution.");
440 EM_REG_COUNTER(&pVCpu->em.s.StatHalted, "/PROF/CPU%d/EM/Halted", "Profiling halted state (VMR3WaitHalted).");
441 EM_REG_PROFILE_ADV(&pVCpu->em.s.StatCapped, "/PROF/CPU%d/EM/Capped", "Profiling capped state (sleep).");
442 EM_REG_COUNTER(&pVCpu->em.s.StatREMTotal, "/PROF/CPU%d/EM/REMTotal", "Profiling emR3RemExecute (excluding FFs).");
443 EM_REG_COUNTER(&pVCpu->em.s.StatRAWTotal, "/PROF/CPU%d/EM/RAWTotal", "Profiling emR3RawExecute (excluding FFs).");
444
445 EM_REG_PROFILE_ADV(&pVCpu->em.s.StatTotal, "/PROF/CPU%d/EM/Total", "Profiling EMR3ExecuteVM.");
446 }
447
448 emR3InitDbg(pVM);
449 return VINF_SUCCESS;
450}
451
452
453/**
454 * Applies relocations to data and code managed by this
455 * component. This function will be called at init and
456 * whenever the VMM need to relocate it self inside the GC.
457 *
458 * @param pVM Pointer to the VM.
459 */
460VMMR3_INT_DECL(void) EMR3Relocate(PVM pVM)
461{
462 LogFlow(("EMR3Relocate\n"));
463 for (VMCPUID i = 0; i < pVM->cCpus; i++)
464 {
465 PVMCPU pVCpu = &pVM->aCpus[i];
466 if (pVCpu->em.s.pStatsR3)
467 pVCpu->em.s.pStatsRC = MMHyperR3ToRC(pVM, pVCpu->em.s.pStatsR3);
468 }
469}
470
471
472/**
473 * Reset the EM state for a CPU.
474 *
475 * Called by EMR3Reset and hot plugging.
476 *
477 * @param pVCpu Pointer to the VMCPU.
478 */
479VMMR3_INT_DECL(void) EMR3ResetCpu(PVMCPU pVCpu)
480{
481 pVCpu->em.s.fForceRAW = false;
482
483 /* VMR3Reset may return VINF_EM_RESET or VINF_EM_SUSPEND, so transition
484 out of the HALTED state here so that enmPrevState doesn't end up as
485 HALTED when EMR3Execute returns. */
486 if (pVCpu->em.s.enmState == EMSTATE_HALTED)
487 {
488 Log(("EMR3ResetCpu: Cpu#%u %s -> %s\n", pVCpu->idCpu, emR3GetStateName(pVCpu->em.s.enmState), pVCpu->idCpu == 0 ? "EMSTATE_NONE" : "EMSTATE_WAIT_SIPI"));
489 pVCpu->em.s.enmState = pVCpu->idCpu == 0 ? EMSTATE_NONE : EMSTATE_WAIT_SIPI;
490 }
491}
492
493
494/**
495 * Reset notification.
496 *
497 * @param pVM Pointer to the VM.
498 */
499VMMR3_INT_DECL(void) EMR3Reset(PVM pVM)
500{
501 Log(("EMR3Reset: \n"));
502 for (VMCPUID i = 0; i < pVM->cCpus; i++)
503 EMR3ResetCpu(&pVM->aCpus[i]);
504}
505
506
507/**
508 * Terminates the EM.
509 *
510 * Termination means cleaning up and freeing all resources,
511 * the VM it self is at this point powered off or suspended.
512 *
513 * @returns VBox status code.
514 * @param pVM Pointer to the VM.
515 */
516VMMR3_INT_DECL(int) EMR3Term(PVM pVM)
517{
518 AssertMsg(pVM->em.s.offVM, ("bad init order!\n"));
519
520#ifdef VBOX_WITH_REM
521 PDMR3CritSectDelete(&pVM->em.s.CritSectREM);
522#endif
523 return VINF_SUCCESS;
524}
525
526
527/**
528 * Execute state save operation.
529 *
530 * @returns VBox status code.
531 * @param pVM Pointer to the VM.
532 * @param pSSM SSM operation handle.
533 */
534static DECLCALLBACK(int) emR3Save(PVM pVM, PSSMHANDLE pSSM)
535{
536 for (VMCPUID i = 0; i < pVM->cCpus; i++)
537 {
538 PVMCPU pVCpu = &pVM->aCpus[i];
539
540 int rc = SSMR3PutBool(pSSM, pVCpu->em.s.fForceRAW);
541 AssertRCReturn(rc, rc);
542
543 Assert(pVCpu->em.s.enmState == EMSTATE_SUSPENDED);
544 Assert(pVCpu->em.s.enmPrevState != EMSTATE_SUSPENDED);
545 rc = SSMR3PutU32(pSSM, pVCpu->em.s.enmPrevState);
546 AssertRCReturn(rc, rc);
547
548 /* Save mwait state. */
549 rc = SSMR3PutU32(pSSM, pVCpu->em.s.MWait.fWait);
550 AssertRCReturn(rc, rc);
551 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s.MWait.uMWaitRAX);
552 AssertRCReturn(rc, rc);
553 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s.MWait.uMWaitRCX);
554 AssertRCReturn(rc, rc);
555 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s.MWait.uMonitorRAX);
556 AssertRCReturn(rc, rc);
557 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s.MWait.uMonitorRCX);
558 AssertRCReturn(rc, rc);
559 rc = SSMR3PutGCPtr(pSSM, pVCpu->em.s.MWait.uMonitorRDX);
560 AssertRCReturn(rc, rc);
561 }
562 return VINF_SUCCESS;
563}
564
565
566/**
567 * Execute state load operation.
568 *
569 * @returns VBox status code.
570 * @param pVM Pointer to the VM.
571 * @param pSSM SSM operation handle.
572 * @param uVersion Data layout version.
573 * @param uPass The data pass.
574 */
575static DECLCALLBACK(int) emR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
576{
577 /*
578 * Validate version.
579 */
580 if ( uVersion > EM_SAVED_STATE_VERSION
581 || uVersion < EM_SAVED_STATE_VERSION_PRE_SMP)
582 {
583 AssertMsgFailed(("emR3Load: Invalid version uVersion=%d (current %d)!\n", uVersion, EM_SAVED_STATE_VERSION));
584 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
585 }
586 Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
587
588 /*
589 * Load the saved state.
590 */
591 for (VMCPUID i = 0; i < pVM->cCpus; i++)
592 {
593 PVMCPU pVCpu = &pVM->aCpus[i];
594
595 int rc = SSMR3GetBool(pSSM, &pVCpu->em.s.fForceRAW);
596 if (RT_FAILURE(rc))
597 pVCpu->em.s.fForceRAW = false;
598 AssertRCReturn(rc, rc);
599
600 if (uVersion > EM_SAVED_STATE_VERSION_PRE_SMP)
601 {
602 AssertCompile(sizeof(pVCpu->em.s.enmPrevState) == sizeof(uint32_t));
603 rc = SSMR3GetU32(pSSM, (uint32_t *)&pVCpu->em.s.enmPrevState);
604 AssertRCReturn(rc, rc);
605 Assert(pVCpu->em.s.enmPrevState != EMSTATE_SUSPENDED);
606
607 pVCpu->em.s.enmState = EMSTATE_SUSPENDED;
608 }
609 if (uVersion > EM_SAVED_STATE_VERSION_PRE_MWAIT)
610 {
611 /* Load mwait state. */
612 rc = SSMR3GetU32(pSSM, &pVCpu->em.s.MWait.fWait);
613 AssertRCReturn(rc, rc);
614 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s.MWait.uMWaitRAX);
615 AssertRCReturn(rc, rc);
616 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s.MWait.uMWaitRCX);
617 AssertRCReturn(rc, rc);
618 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s.MWait.uMonitorRAX);
619 AssertRCReturn(rc, rc);
620 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s.MWait.uMonitorRCX);
621 AssertRCReturn(rc, rc);
622 rc = SSMR3GetGCPtr(pSSM, &pVCpu->em.s.MWait.uMonitorRDX);
623 AssertRCReturn(rc, rc);
624 }
625
626 Assert(!pVCpu->em.s.pCliStatTree);
627 }
628 return VINF_SUCCESS;
629}
630
631
632/**
633 * Argument packet for emR3SetExecutionPolicy.
634 */
635struct EMR3SETEXECPOLICYARGS
636{
637 EMEXECPOLICY enmPolicy;
638 bool fEnforce;
639};
640
641
642/**
643 * @callback_method_impl{FNVMMEMTRENDEZVOUS, Rendezvous callback for EMR3SetExecutionPolicy.}
644 */
645static DECLCALLBACK(VBOXSTRICTRC) emR3SetExecutionPolicy(PVM pVM, PVMCPU pVCpu, void *pvUser)
646{
647 /*
648 * Only the first CPU changes the variables.
649 */
650 if (pVCpu->idCpu == 0)
651 {
652 struct EMR3SETEXECPOLICYARGS *pArgs = (struct EMR3SETEXECPOLICYARGS *)pvUser;
653 switch (pArgs->enmPolicy)
654 {
655 case EMEXECPOLICY_RECOMPILE_RING0:
656 pVM->fRecompileSupervisor = pArgs->fEnforce;
657 break;
658 case EMEXECPOLICY_RECOMPILE_RING3:
659 pVM->fRecompileUser = pArgs->fEnforce;
660 break;
661 case EMEXECPOLICY_IEM_ALL:
662 pVM->em.s.fIemExecutesAll = pArgs->fEnforce;
663 break;
664 default:
665 AssertFailedReturn(VERR_INVALID_PARAMETER);
666 }
667 Log(("emR3SetExecutionPolicy: fRecompileUser=%RTbool fRecompileSupervisor=%RTbool fIemExecutesAll=%RTbool\n",
668 pVM->fRecompileUser, pVM->fRecompileSupervisor, pVM->em.s.fIemExecutesAll));
669 }
670
671 /*
672 * Force rescheduling if in RAW, HM, IEM, or REM.
673 */
674 return pVCpu->em.s.enmState == EMSTATE_RAW
675 || pVCpu->em.s.enmState == EMSTATE_HM
676 || pVCpu->em.s.enmState == EMSTATE_IEM
677 || pVCpu->em.s.enmState == EMSTATE_REM
678 || pVCpu->em.s.enmState == EMSTATE_IEM_THEN_REM
679 ? VINF_EM_RESCHEDULE
680 : VINF_SUCCESS;
681}
682
683
684/**
685 * Changes an execution scheduling policy parameter.
686 *
687 * This is used to enable or disable raw-mode / hardware-virtualization
688 * execution of user and supervisor code.
689 *
690 * @returns VINF_SUCCESS on success.
691 * @returns VINF_RESCHEDULE if a rescheduling might be required.
692 * @returns VERR_INVALID_PARAMETER on an invalid enmMode value.
693 *
694 * @param pUVM The user mode VM handle.
695 * @param enmPolicy The scheduling policy to change.
696 * @param fEnforce Whether to enforce the policy or not.
697 */
698VMMR3DECL(int) EMR3SetExecutionPolicy(PUVM pUVM, EMEXECPOLICY enmPolicy, bool fEnforce)
699{
700 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
701 VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, VERR_INVALID_VM_HANDLE);
702 AssertReturn(enmPolicy > EMEXECPOLICY_INVALID && enmPolicy < EMEXECPOLICY_END, VERR_INVALID_PARAMETER);
703
704 struct EMR3SETEXECPOLICYARGS Args = { enmPolicy, fEnforce };
705 return VMMR3EmtRendezvous(pUVM->pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING, emR3SetExecutionPolicy, &Args);
706}
707
708
709/**
710 * Queries an execution scheduling policy parameter.
711 *
712 * @returns VBox status code
713 * @param pUVM The user mode VM handle.
714 * @param enmPolicy The scheduling policy to query.
715 * @param pfEnforced Where to return the current value.
716 */
717VMMR3DECL(int) EMR3QueryExecutionPolicy(PUVM pUVM, EMEXECPOLICY enmPolicy, bool *pfEnforced)
718{
719 AssertReturn(enmPolicy > EMEXECPOLICY_INVALID && enmPolicy < EMEXECPOLICY_END, VERR_INVALID_PARAMETER);
720 AssertPtrReturn(pfEnforced, VERR_INVALID_POINTER);
721 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
722 PVM pVM = pUVM->pVM;
723 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
724
725 /* No need to bother EMTs with a query. */
726 switch (enmPolicy)
727 {
728 case EMEXECPOLICY_RECOMPILE_RING0:
729 *pfEnforced = pVM->fRecompileSupervisor;
730 break;
731 case EMEXECPOLICY_RECOMPILE_RING3:
732 *pfEnforced = pVM->fRecompileUser;
733 break;
734 case EMEXECPOLICY_IEM_ALL:
735 *pfEnforced = pVM->em.s.fIemExecutesAll;
736 break;
737 default:
738 AssertFailedReturn(VERR_INTERNAL_ERROR_2);
739 }
740
741 return VINF_SUCCESS;
742}
743
744
745/**
746 * Raise a fatal error.
747 *
748 * Safely terminate the VM with full state report and stuff. This function
749 * will naturally never return.
750 *
751 * @param pVCpu Pointer to the VMCPU.
752 * @param rc VBox status code.
753 */
754VMMR3DECL(void) EMR3FatalError(PVMCPU pVCpu, int rc)
755{
756 pVCpu->em.s.enmState = EMSTATE_GURU_MEDITATION;
757 longjmp(pVCpu->em.s.u.FatalLongJump, rc);
758 AssertReleaseMsgFailed(("longjmp returned!\n"));
759}
760
761
762#if defined(LOG_ENABLED) || defined(VBOX_STRICT)
763/**
764 * Gets the EM state name.
765 *
766 * @returns pointer to read only state name,
767 * @param enmState The state.
768 */
769static const char *emR3GetStateName(EMSTATE enmState)
770{
771 switch (enmState)
772 {
773 case EMSTATE_NONE: return "EMSTATE_NONE";
774 case EMSTATE_RAW: return "EMSTATE_RAW";
775 case EMSTATE_HM: return "EMSTATE_HM";
776 case EMSTATE_IEM: return "EMSTATE_IEM";
777 case EMSTATE_REM: return "EMSTATE_REM";
778 case EMSTATE_HALTED: return "EMSTATE_HALTED";
779 case EMSTATE_WAIT_SIPI: return "EMSTATE_WAIT_SIPI";
780 case EMSTATE_SUSPENDED: return "EMSTATE_SUSPENDED";
781 case EMSTATE_TERMINATING: return "EMSTATE_TERMINATING";
782 case EMSTATE_DEBUG_GUEST_RAW: return "EMSTATE_DEBUG_GUEST_RAW";
783 case EMSTATE_DEBUG_GUEST_HM: return "EMSTATE_DEBUG_GUEST_HM";
784 case EMSTATE_DEBUG_GUEST_IEM: return "EMSTATE_DEBUG_GUEST_IEM";
785 case EMSTATE_DEBUG_GUEST_REM: return "EMSTATE_DEBUG_GUEST_REM";
786 case EMSTATE_DEBUG_HYPER: return "EMSTATE_DEBUG_HYPER";
787 case EMSTATE_GURU_MEDITATION: return "EMSTATE_GURU_MEDITATION";
788 case EMSTATE_IEM_THEN_REM: return "EMSTATE_IEM_THEN_REM";
789 default: return "Unknown!";
790 }
791}
792#endif /* LOG_ENABLED || VBOX_STRICT */
793
794
795/**
796 * Debug loop.
797 *
798 * @returns VBox status code for EM.
799 * @param pVM Pointer to the VM.
800 * @param pVCpu Pointer to the VMCPU.
801 * @param rc Current EM VBox status code.
802 */
803static VBOXSTRICTRC emR3Debug(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc)
804{
805 for (;;)
806 {
807 Log(("emR3Debug: rc=%Rrc\n", VBOXSTRICTRC_VAL(rc)));
808 const VBOXSTRICTRC rcLast = rc;
809
810 /*
811 * Debug related RC.
812 */
813 switch (VBOXSTRICTRC_VAL(rc))
814 {
815 /*
816 * Single step an instruction.
817 */
818 case VINF_EM_DBG_STEP:
819 if ( pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_RAW
820 || pVCpu->em.s.enmState == EMSTATE_DEBUG_HYPER
821 || pVCpu->em.s.fForceRAW /* paranoia */)
822#ifdef VBOX_WITH_RAW_MODE
823 rc = emR3RawStep(pVM, pVCpu);
824#else
825 AssertLogRelMsgFailedStmt(("Bad EM state."), VERR_EM_INTERNAL_ERROR);
826#endif
827 else if (pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_HM)
828 rc = EMR3HmSingleInstruction(pVM, pVCpu, 0 /*fFlags*/);
829#ifdef VBOX_WITH_REM
830 else if (pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_REM)
831 rc = emR3RemStep(pVM, pVCpu);
832#endif
833 else
834 {
835 rc = IEMExecOne(pVCpu); /** @todo add dedicated interface... */
836 if (rc == VINF_SUCCESS || rc == VINF_EM_RESCHEDULE)
837 rc = VINF_EM_DBG_STEPPED;
838 }
839 break;
840
841 /*
842 * Simple events: stepped, breakpoint, stop/assertion.
843 */
844 case VINF_EM_DBG_STEPPED:
845 rc = DBGFR3Event(pVM, DBGFEVENT_STEPPED);
846 break;
847
848 case VINF_EM_DBG_BREAKPOINT:
849 rc = DBGFR3EventBreakpoint(pVM, DBGFEVENT_BREAKPOINT);
850 break;
851
852 case VINF_EM_DBG_STOP:
853 rc = DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, NULL, 0, NULL, NULL);
854 break;
855
856 case VINF_EM_DBG_HYPER_STEPPED:
857 rc = DBGFR3Event(pVM, DBGFEVENT_STEPPED_HYPER);
858 break;
859
860 case VINF_EM_DBG_HYPER_BREAKPOINT:
861 rc = DBGFR3EventBreakpoint(pVM, DBGFEVENT_BREAKPOINT_HYPER);
862 break;
863
864 case VINF_EM_DBG_HYPER_ASSERTION:
865 RTPrintf("\nVINF_EM_DBG_HYPER_ASSERTION:\n%s%s\n", VMMR3GetRZAssertMsg1(pVM), VMMR3GetRZAssertMsg2(pVM));
866 RTLogFlush(NULL);
867 rc = DBGFR3EventAssertion(pVM, DBGFEVENT_ASSERTION_HYPER, VMMR3GetRZAssertMsg1(pVM), VMMR3GetRZAssertMsg2(pVM));
868 break;
869
870 /*
871 * Guru meditation.
872 */
873 case VERR_VMM_RING0_ASSERTION: /** @todo Make a guru meditation event! */
874 rc = DBGFR3EventSrc(pVM, DBGFEVENT_FATAL_ERROR, "VERR_VMM_RING0_ASSERTION", 0, NULL, NULL);
875 break;
876 case VERR_REM_TOO_MANY_TRAPS: /** @todo Make a guru meditation event! */
877 rc = DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, "VERR_REM_TOO_MANY_TRAPS", 0, NULL, NULL);
878 break;
879
880 default: /** @todo don't use default for guru, but make special errors code! */
881 {
882 LogRel(("emR3Debug: rc=%Rrc\n", VBOXSTRICTRC_VAL(rc)));
883 rc = DBGFR3Event(pVM, DBGFEVENT_FATAL_ERROR);
884 break;
885 }
886 }
887
888 /*
889 * Process the result.
890 */
891 do
892 {
893 switch (VBOXSTRICTRC_VAL(rc))
894 {
895 /*
896 * Continue the debugging loop.
897 */
898 case VINF_EM_DBG_STEP:
899 case VINF_EM_DBG_STOP:
900 case VINF_EM_DBG_STEPPED:
901 case VINF_EM_DBG_BREAKPOINT:
902 case VINF_EM_DBG_HYPER_STEPPED:
903 case VINF_EM_DBG_HYPER_BREAKPOINT:
904 case VINF_EM_DBG_HYPER_ASSERTION:
905 break;
906
907 /*
908 * Resuming execution (in some form) has to be done here if we got
909 * a hypervisor debug event.
910 */
911 case VINF_SUCCESS:
912 case VINF_EM_RESUME:
913 case VINF_EM_SUSPEND:
914 case VINF_EM_RESCHEDULE:
915 case VINF_EM_RESCHEDULE_RAW:
916 case VINF_EM_RESCHEDULE_REM:
917 case VINF_EM_HALT:
918 if (pVCpu->em.s.enmState == EMSTATE_DEBUG_HYPER)
919 {
920#ifdef VBOX_WITH_RAW_MODE
921 rc = emR3RawResumeHyper(pVM, pVCpu);
922 if (rc != VINF_SUCCESS && RT_SUCCESS(rc))
923 continue;
924#else
925 AssertLogRelMsgFailedReturn(("Not implemented\n"), VERR_EM_INTERNAL_ERROR);
926#endif
927 }
928 if (rc == VINF_SUCCESS)
929 rc = VINF_EM_RESCHEDULE;
930 return rc;
931
932 /*
933 * The debugger isn't attached.
934 * We'll simply turn the thing off since that's the easiest thing to do.
935 */
936 case VERR_DBGF_NOT_ATTACHED:
937 switch (VBOXSTRICTRC_VAL(rcLast))
938 {
939 case VINF_EM_DBG_HYPER_STEPPED:
940 case VINF_EM_DBG_HYPER_BREAKPOINT:
941 case VINF_EM_DBG_HYPER_ASSERTION:
942 case VERR_TRPM_PANIC:
943 case VERR_TRPM_DONT_PANIC:
944 case VERR_VMM_RING0_ASSERTION:
945 case VERR_VMM_HYPER_CR3_MISMATCH:
946 case VERR_VMM_RING3_CALL_DISABLED:
947 return rcLast;
948 }
949 return VINF_EM_OFF;
950
951 /*
952 * Status codes terminating the VM in one or another sense.
953 */
954 case VINF_EM_TERMINATE:
955 case VINF_EM_OFF:
956 case VINF_EM_RESET:
957 case VINF_EM_NO_MEMORY:
958 case VINF_EM_RAW_STALE_SELECTOR:
959 case VINF_EM_RAW_IRET_TRAP:
960 case VERR_TRPM_PANIC:
961 case VERR_TRPM_DONT_PANIC:
962 case VERR_IEM_INSTR_NOT_IMPLEMENTED:
963 case VERR_IEM_ASPECT_NOT_IMPLEMENTED:
964 case VERR_VMM_RING0_ASSERTION:
965 case VERR_VMM_HYPER_CR3_MISMATCH:
966 case VERR_VMM_RING3_CALL_DISABLED:
967 case VERR_INTERNAL_ERROR:
968 case VERR_INTERNAL_ERROR_2:
969 case VERR_INTERNAL_ERROR_3:
970 case VERR_INTERNAL_ERROR_4:
971 case VERR_INTERNAL_ERROR_5:
972 case VERR_IPE_UNEXPECTED_STATUS:
973 case VERR_IPE_UNEXPECTED_INFO_STATUS:
974 case VERR_IPE_UNEXPECTED_ERROR_STATUS:
975 return rc;
976
977 /*
978 * The rest is unexpected, and will keep us here.
979 */
980 default:
981 AssertMsgFailed(("Unexpected rc %Rrc!\n", VBOXSTRICTRC_VAL(rc)));
982 break;
983 }
984 } while (false);
985 } /* debug for ever */
986}
987
988
989/**
990 * Steps recompiled code.
991 *
992 * @returns VBox status code. The most important ones are: VINF_EM_STEP_EVENT,
993 * VINF_EM_RESCHEDULE, VINF_EM_SUSPEND, VINF_EM_RESET and VINF_EM_TERMINATE.
994 *
995 * @param pVM Pointer to the VM.
996 * @param pVCpu Pointer to the VMCPU.
997 */
998static int emR3RemStep(PVM pVM, PVMCPU pVCpu)
999{
1000 Log3(("emR3RemStep: cs:eip=%04x:%08x\n", CPUMGetGuestCS(pVCpu), CPUMGetGuestEIP(pVCpu)));
1001
1002#ifdef VBOX_WITH_REM
1003 EMRemLock(pVM);
1004
1005 /*
1006 * Switch to REM, step instruction, switch back.
1007 */
1008 int rc = REMR3State(pVM, pVCpu);
1009 if (RT_SUCCESS(rc))
1010 {
1011 rc = REMR3Step(pVM, pVCpu);
1012 REMR3StateBack(pVM, pVCpu);
1013 }
1014 EMRemUnlock(pVM);
1015
1016#else
1017 int rc = VBOXSTRICTRC_TODO(IEMExecOne(pVCpu)); NOREF(pVM);
1018#endif
1019
1020 Log3(("emR3RemStep: returns %Rrc cs:eip=%04x:%08x\n", rc, CPUMGetGuestCS(pVCpu), CPUMGetGuestEIP(pVCpu)));
1021 return rc;
1022}
1023
1024
1025/**
1026 * emR3RemExecute helper that syncs the state back from REM and leave the REM
1027 * critical section.
1028 *
1029 * @returns false - new fInREMState value.
1030 * @param pVM Pointer to the VM.
1031 * @param pVCpu Pointer to the VMCPU.
1032 */
1033DECLINLINE(bool) emR3RemExecuteSyncBack(PVM pVM, PVMCPU pVCpu)
1034{
1035#ifdef VBOX_WITH_REM
1036 STAM_PROFILE_START(&pVCpu->em.s.StatREMSync, a);
1037 REMR3StateBack(pVM, pVCpu);
1038 STAM_PROFILE_STOP(&pVCpu->em.s.StatREMSync, a);
1039
1040 EMRemUnlock(pVM);
1041#endif
1042 return false;
1043}
1044
1045
1046/**
1047 * Executes recompiled code.
1048 *
1049 * This function contains the recompiler version of the inner
1050 * execution loop (the outer loop being in EMR3ExecuteVM()).
1051 *
1052 * @returns VBox status code. The most important ones are: VINF_EM_RESCHEDULE,
1053 * VINF_EM_SUSPEND, VINF_EM_RESET and VINF_EM_TERMINATE.
1054 *
1055 * @param pVM Pointer to the VM.
1056 * @param pVCpu Pointer to the VMCPU.
1057 * @param pfFFDone Where to store an indicator telling whether or not
1058 * FFs were done before returning.
1059 *
1060 */
1061static int emR3RemExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone)
1062{
1063#ifdef LOG_ENABLED
1064 PCPUMCTX pCtx = pVCpu->em.s.pCtx;
1065 uint32_t cpl = CPUMGetGuestCPL(pVCpu);
1066
1067 if (pCtx->eflags.Bits.u1VM)
1068 Log(("EMV86: %04X:%08X IF=%d\n", pCtx->cs.Sel, pCtx->eip, pCtx->eflags.Bits.u1IF));
1069 else
1070 Log(("EMR%d: %04X:%08X ESP=%08X IF=%d CR0=%x eflags=%x\n", cpl, pCtx->cs.Sel, pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, (uint32_t)pCtx->cr0, pCtx->eflags.u));
1071#endif
1072 STAM_REL_PROFILE_ADV_START(&pVCpu->em.s.StatREMTotal, a);
1073
1074#if defined(VBOX_STRICT) && defined(DEBUG_bird)
1075 AssertMsg( VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL)
1076 || !MMHyperIsInsideArea(pVM, CPUMGetGuestEIP(pVCpu)), /** @todo @bugref{1419} - get flat address. */
1077 ("cs:eip=%RX16:%RX32\n", CPUMGetGuestCS(pVCpu), CPUMGetGuestEIP(pVCpu)));
1078#endif
1079
1080 /*
1081 * Spin till we get a forced action which returns anything but VINF_SUCCESS
1082 * or the REM suggests raw-mode execution.
1083 */
1084 *pfFFDone = false;
1085#ifdef VBOX_WITH_REM
1086 bool fInREMState = false;
1087#endif
1088 int rc = VINF_SUCCESS;
1089 for (;;)
1090 {
1091#ifdef VBOX_WITH_REM
1092 /*
1093 * Lock REM and update the state if not already in sync.
1094 *
1095 * Note! Big lock, but you are not supposed to own any lock when
1096 * coming in here.
1097 */
1098 if (!fInREMState)
1099 {
1100 EMRemLock(pVM);
1101 STAM_PROFILE_START(&pVCpu->em.s.StatREMSync, b);
1102
1103 /* Flush the recompiler translation blocks if the VCPU has changed,
1104 also force a full CPU state resync. */
1105 if (pVM->em.s.idLastRemCpu != pVCpu->idCpu)
1106 {
1107 REMFlushTBs(pVM);
1108 CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_ALL);
1109 }
1110 pVM->em.s.idLastRemCpu = pVCpu->idCpu;
1111
1112 rc = REMR3State(pVM, pVCpu);
1113
1114 STAM_PROFILE_STOP(&pVCpu->em.s.StatREMSync, b);
1115 if (RT_FAILURE(rc))
1116 break;
1117 fInREMState = true;
1118
1119 /*
1120 * We might have missed the raising of VMREQ, TIMER and some other
1121 * important FFs while we were busy switching the state. So, check again.
1122 */
1123 if ( VM_FF_IS_PENDING(pVM, VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_DBGF | VM_FF_CHECK_VM_STATE | VM_FF_RESET)
1124 || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_TIMER | VMCPU_FF_REQUEST))
1125 {
1126 LogFlow(("emR3RemExecute: Skipping run, because FF is set. %#x\n", pVM->fGlobalForcedActions));
1127 goto l_REMDoForcedActions;
1128 }
1129 }
1130#endif
1131
1132 /*
1133 * Execute REM.
1134 */
1135 if (RT_LIKELY(emR3IsExecutionAllowed(pVM, pVCpu)))
1136 {
1137 STAM_PROFILE_START(&pVCpu->em.s.StatREMExec, c);
1138#ifdef VBOX_WITH_REM
1139 rc = REMR3Run(pVM, pVCpu);
1140#else
1141 rc = VBOXSTRICTRC_TODO(IEMExecLots(pVCpu));
1142#endif
1143 STAM_PROFILE_STOP(&pVCpu->em.s.StatREMExec, c);
1144 }
1145 else
1146 {
1147 /* Give up this time slice; virtual time continues */
1148 STAM_REL_PROFILE_ADV_START(&pVCpu->em.s.StatCapped, u);
1149 RTThreadSleep(5);
1150 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatCapped, u);
1151 rc = VINF_SUCCESS;
1152 }
1153
1154 /*
1155 * Deal with high priority post execution FFs before doing anything
1156 * else. Sync back the state and leave the lock to be on the safe side.
1157 */
1158 if ( VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK)
1159 || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
1160 {
1161#ifdef VBOX_WITH_REM
1162 fInREMState = emR3RemExecuteSyncBack(pVM, pVCpu);
1163#endif
1164 rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
1165 }
1166
1167 /*
1168 * Process the returned status code.
1169 */
1170 if (rc != VINF_SUCCESS)
1171 {
1172 if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
1173 break;
1174 if (rc != VINF_REM_INTERRUPED_FF)
1175 {
1176 /*
1177 * Anything which is not known to us means an internal error
1178 * and the termination of the VM!
1179 */
1180 AssertMsg(rc == VERR_REM_TOO_MANY_TRAPS, ("Unknown GC return code: %Rra\n", rc));
1181 break;
1182 }
1183 }
1184
1185
1186 /*
1187 * Check and execute forced actions.
1188 *
1189 * Sync back the VM state and leave the lock before calling any of
1190 * these, you never know what's going to happen here.
1191 */
1192#ifdef VBOX_HIGH_RES_TIMERS_HACK
1193 TMTimerPollVoid(pVM, pVCpu);
1194#endif
1195 AssertCompile(VMCPU_FF_ALL_REM_MASK & VMCPU_FF_TIMER);
1196 if ( VM_FF_IS_PENDING(pVM, VM_FF_ALL_REM_MASK)
1197 || VMCPU_FF_IS_PENDING(pVCpu,
1198 VMCPU_FF_ALL_REM_MASK
1199 & VM_WHEN_RAW_MODE(~(VMCPU_FF_CSAM_PENDING_ACTION | VMCPU_FF_CSAM_SCAN_PAGE), UINT32_MAX)) )
1200 {
1201l_REMDoForcedActions:
1202#ifdef VBOX_WITH_REM
1203 if (fInREMState)
1204 fInREMState = emR3RemExecuteSyncBack(pVM, pVCpu);
1205#endif
1206 STAM_REL_PROFILE_ADV_SUSPEND(&pVCpu->em.s.StatREMTotal, a);
1207 rc = emR3ForcedActions(pVM, pVCpu, rc);
1208 VBOXVMM_EM_FF_ALL_RET(pVCpu, rc);
1209 STAM_REL_PROFILE_ADV_RESUME(&pVCpu->em.s.StatREMTotal, a);
1210 if ( rc != VINF_SUCCESS
1211 && rc != VINF_EM_RESCHEDULE_REM)
1212 {
1213 *pfFFDone = true;
1214 break;
1215 }
1216 }
1217
1218 } /* The Inner Loop, recompiled execution mode version. */
1219
1220
1221#ifdef VBOX_WITH_REM
1222 /*
1223 * Returning. Sync back the VM state if required.
1224 */
1225 if (fInREMState)
1226 fInREMState = emR3RemExecuteSyncBack(pVM, pVCpu);
1227#endif
1228
1229 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatREMTotal, a);
1230 return rc;
1231}
1232
1233
1234#ifdef DEBUG
1235
1236int emR3SingleStepExecRem(PVM pVM, PVMCPU pVCpu, uint32_t cIterations)
1237{
1238 EMSTATE enmOldState = pVCpu->em.s.enmState;
1239
1240 pVCpu->em.s.enmState = EMSTATE_DEBUG_GUEST_REM;
1241
1242 Log(("Single step BEGIN:\n"));
1243 for (uint32_t i = 0; i < cIterations; i++)
1244 {
1245 DBGFR3PrgStep(pVCpu);
1246 DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS");
1247 emR3RemStep(pVM, pVCpu);
1248 if (emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx) != EMSTATE_REM)
1249 break;
1250 }
1251 Log(("Single step END:\n"));
1252 CPUMSetGuestEFlags(pVCpu, CPUMGetGuestEFlags(pVCpu) & ~X86_EFL_TF);
1253 pVCpu->em.s.enmState = enmOldState;
1254 return VINF_EM_RESCHEDULE;
1255}
1256
1257#endif /* DEBUG */
1258
1259
1260/**
1261 * Try execute the problematic code in IEM first, then fall back on REM if there
1262 * is too much of it or if IEM doesn't implement something.
1263 *
1264 * @returns Strict VBox status code from IEMExecLots.
1265 * @param pVM The cross context VM structure.
1266 * @param pVCpu The cross context CPU structure for the calling EMT.
1267 * @param pfFFDone Force flags done indicator.
1268 *
1269 * @thread EMT(pVCpu)
1270 */
1271static VBOXSTRICTRC emR3ExecuteIemThenRem(PVM pVM, PVMCPU pVCpu, bool *pfFFDone)
1272{
1273 LogFlow(("emR3ExecuteIemThenRem: %04x:%RGv\n", CPUMGetGuestCS(pVCpu), CPUMGetGuestRIP(pVCpu)));
1274 *pfFFDone = false;
1275
1276 /*
1277 * Execute in IEM for a while.
1278 */
1279 while (pVCpu->em.s.cIemThenRemInstructions < 1024)
1280 {
1281 VBOXSTRICTRC rcStrict = IEMExecLots(pVCpu);
1282 if (rcStrict != VINF_SUCCESS)
1283 {
1284 if ( rcStrict == VERR_IEM_ASPECT_NOT_IMPLEMENTED
1285 || rcStrict == VERR_IEM_INSTR_NOT_IMPLEMENTED)
1286 break;
1287
1288 pVCpu->em.s.cIemThenRemInstructions++;
1289 Log(("emR3ExecuteIemThenRem: returns %Rrc after %u instructions\n",
1290 VBOXSTRICTRC_VAL(rcStrict), pVCpu->em.s.cIemThenRemInstructions));
1291 return rcStrict;
1292 }
1293 pVCpu->em.s.cIemThenRemInstructions++;
1294
1295 EMSTATE enmNewState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
1296 if (enmNewState != EMSTATE_REM && enmNewState != EMSTATE_IEM_THEN_REM)
1297 {
1298 LogFlow(("emR3ExecuteIemThenRem: -> %d (%s) after %u instructions\n",
1299 enmNewState, emR3GetStateName(enmNewState), pVCpu->em.s.cIemThenRemInstructions));
1300 pVCpu->em.s.enmPrevState = pVCpu->em.s.enmState;
1301 pVCpu->em.s.enmState = enmNewState;
1302 return VINF_SUCCESS;
1303 }
1304
1305 /*
1306 * Check for pending actions.
1307 */
1308 if ( VM_FF_IS_PENDING(pVM, VM_FF_ALL_REM_MASK)
1309 || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_ALL_REM_MASK))
1310 return VINF_SUCCESS;
1311 }
1312
1313 /*
1314 * Switch to REM.
1315 */
1316 Log(("emR3ExecuteIemThenRem: -> EMSTATE_REM (after %u instructions)\n", pVCpu->em.s.cIemThenRemInstructions));
1317 pVCpu->em.s.enmState = EMSTATE_REM;
1318 return VINF_SUCCESS;
1319}
1320
1321
1322/**
1323 * Decides whether to execute RAW, HWACC or REM.
1324 *
1325 * @returns new EM state
1326 * @param pVM Pointer to the VM.
1327 * @param pVCpu Pointer to the VMCPU.
1328 * @param pCtx Pointer to the guest CPU context.
1329 */
1330EMSTATE emR3Reschedule(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
1331{
1332 /*
1333 * When forcing raw-mode execution, things are simple.
1334 */
1335 if (pVCpu->em.s.fForceRAW)
1336 return EMSTATE_RAW;
1337
1338 /*
1339 * We stay in the wait for SIPI state unless explicitly told otherwise.
1340 */
1341 if (pVCpu->em.s.enmState == EMSTATE_WAIT_SIPI)
1342 return EMSTATE_WAIT_SIPI;
1343
1344 /*
1345 * Execute everything in IEM?
1346 */
1347 if (pVM->em.s.fIemExecutesAll)
1348 return EMSTATE_IEM;
1349
1350 /* !!! THIS MUST BE IN SYNC WITH remR3CanExecuteRaw !!! */
1351 /* !!! THIS MUST BE IN SYNC WITH remR3CanExecuteRaw !!! */
1352 /* !!! THIS MUST BE IN SYNC WITH remR3CanExecuteRaw !!! */
1353
1354 X86EFLAGS EFlags = pCtx->eflags;
1355 if (HMIsEnabled(pVM))
1356 {
1357 /*
1358 * Hardware accelerated raw-mode:
1359 */
1360 if ( EMIsHwVirtExecutionEnabled(pVM)
1361 && HMR3CanExecuteGuest(pVM, pCtx))
1362 return EMSTATE_HM;
1363
1364 /*
1365 * Note! Raw mode and hw accelerated mode are incompatible. The latter
1366 * turns off monitoring features essential for raw mode!
1367 */
1368#ifdef VBOX_WITH_FIRST_IEM_STEP
1369 return EMSTATE_IEM_THEN_REM;
1370#else
1371 return EMSTATE_REM;
1372#endif
1373 }
1374
1375 /*
1376 * Standard raw-mode:
1377 *
1378 * Here we only support 16 & 32 bits protected mode ring 3 code that has no IO privileges
1379 * or 32 bits protected mode ring 0 code
1380 *
1381 * The tests are ordered by the likelihood of being true during normal execution.
1382 */
1383 if (EFlags.u32 & (X86_EFL_TF /* | HF_INHIBIT_IRQ_MASK*/))
1384 {
1385 Log2(("raw mode refused: EFlags=%#x\n", EFlags.u32));
1386 return EMSTATE_REM;
1387 }
1388
1389# ifndef VBOX_RAW_V86
1390 if (EFlags.u32 & X86_EFL_VM) {
1391 Log2(("raw mode refused: VM_MASK\n"));
1392 return EMSTATE_REM;
1393 }
1394# endif
1395
1396 /** @todo check up the X86_CR0_AM flag in respect to raw mode!!! We're probably not emulating it right! */
1397 uint32_t u32CR0 = pCtx->cr0;
1398 if ((u32CR0 & (X86_CR0_PG | X86_CR0_PE)) != (X86_CR0_PG | X86_CR0_PE))
1399 {
1400 //Log2(("raw mode refused: %s%s%s\n", (u32CR0 & X86_CR0_PG) ? "" : " !PG", (u32CR0 & X86_CR0_PE) ? "" : " !PE", (u32CR0 & X86_CR0_AM) ? "" : " !AM"));
1401 return EMSTATE_REM;
1402 }
1403
1404 if (pCtx->cr4 & X86_CR4_PAE)
1405 {
1406 uint32_t u32Dummy, u32Features;
1407
1408 CPUMGetGuestCpuId(pVCpu, 1, 0, &u32Dummy, &u32Dummy, &u32Dummy, &u32Features);
1409 if (!(u32Features & X86_CPUID_FEATURE_EDX_PAE))
1410 return EMSTATE_REM;
1411 }
1412
1413 unsigned uSS = pCtx->ss.Sel;
1414 if ( pCtx->eflags.Bits.u1VM
1415 || (uSS & X86_SEL_RPL) == 3)
1416 {
1417 if (!EMIsRawRing3Enabled(pVM))
1418 return EMSTATE_REM;
1419
1420 if (!(EFlags.u32 & X86_EFL_IF))
1421 {
1422 Log2(("raw mode refused: IF (RawR3)\n"));
1423 return EMSTATE_REM;
1424 }
1425
1426 if (!(u32CR0 & X86_CR0_WP) && EMIsRawRing0Enabled(pVM))
1427 {
1428 Log2(("raw mode refused: CR0.WP + RawR0\n"));
1429 return EMSTATE_REM;
1430 }
1431 }
1432 else
1433 {
1434 if (!EMIsRawRing0Enabled(pVM))
1435 return EMSTATE_REM;
1436
1437 if (EMIsRawRing1Enabled(pVM))
1438 {
1439 /* Only ring 0 and 1 supervisor code. */
1440 if ((uSS & X86_SEL_RPL) == 2) /* ring 1 code is moved into ring 2, so we can't support ring-2 in that case. */
1441 {
1442 Log2(("raw r0 mode refused: CPL %d\n", uSS & X86_SEL_RPL));
1443 return EMSTATE_REM;
1444 }
1445 }
1446 /* Only ring 0 supervisor code. */
1447 else if ((uSS & X86_SEL_RPL) != 0)
1448 {
1449 Log2(("raw r0 mode refused: CPL %d\n", uSS & X86_SEL_RPL));
1450 return EMSTATE_REM;
1451 }
1452
1453 // Let's start with pure 32 bits ring 0 code first
1454 /** @todo What's pure 32-bit mode? flat? */
1455 if ( !(pCtx->ss.Attr.n.u1DefBig)
1456 || !(pCtx->cs.Attr.n.u1DefBig))
1457 {
1458 Log2(("raw r0 mode refused: SS/CS not 32bit\n"));
1459 return EMSTATE_REM;
1460 }
1461
1462 /* Write protection must be turned on, or else the guest can overwrite our hypervisor code and data. */
1463 if (!(u32CR0 & X86_CR0_WP))
1464 {
1465 Log2(("raw r0 mode refused: CR0.WP=0!\n"));
1466 return EMSTATE_REM;
1467 }
1468
1469# ifdef VBOX_WITH_RAW_MODE
1470 if (PATMShouldUseRawMode(pVM, (RTGCPTR)pCtx->eip))
1471 {
1472 Log2(("raw r0 mode forced: patch code\n"));
1473# ifdef VBOX_WITH_SAFE_STR
1474 Assert(pCtx->tr.Sel);
1475# endif
1476 return EMSTATE_RAW;
1477 }
1478# endif /* VBOX_WITH_RAW_MODE */
1479
1480# if !defined(VBOX_ALLOW_IF0) && !defined(VBOX_RUN_INTERRUPT_GATE_HANDLERS)
1481 if (!(EFlags.u32 & X86_EFL_IF))
1482 {
1483 ////Log2(("R0: IF=0 VIF=%d %08X\n", eip, pVMeflags));
1484 //Log2(("RR0: Interrupts turned off; fall back to emulation\n"));
1485 return EMSTATE_REM;
1486 }
1487# endif
1488
1489# ifndef VBOX_WITH_RAW_RING1
1490 /** @todo still necessary??? */
1491 if (EFlags.Bits.u2IOPL != 0)
1492 {
1493 Log2(("raw r0 mode refused: IOPL %d\n", EFlags.Bits.u2IOPL));
1494 return EMSTATE_REM;
1495 }
1496# endif
1497 }
1498
1499 /*
1500 * Stale hidden selectors means raw-mode is unsafe (being very careful).
1501 */
1502 if (pCtx->cs.fFlags & CPUMSELREG_FLAGS_STALE)
1503 {
1504 Log2(("raw mode refused: stale CS\n"));
1505 return EMSTATE_REM;
1506 }
1507 if (pCtx->ss.fFlags & CPUMSELREG_FLAGS_STALE)
1508 {
1509 Log2(("raw mode refused: stale SS\n"));
1510 return EMSTATE_REM;
1511 }
1512 if (pCtx->ds.fFlags & CPUMSELREG_FLAGS_STALE)
1513 {
1514 Log2(("raw mode refused: stale DS\n"));
1515 return EMSTATE_REM;
1516 }
1517 if (pCtx->es.fFlags & CPUMSELREG_FLAGS_STALE)
1518 {
1519 Log2(("raw mode refused: stale ES\n"));
1520 return EMSTATE_REM;
1521 }
1522 if (pCtx->fs.fFlags & CPUMSELREG_FLAGS_STALE)
1523 {
1524 Log2(("raw mode refused: stale FS\n"));
1525 return EMSTATE_REM;
1526 }
1527 if (pCtx->gs.fFlags & CPUMSELREG_FLAGS_STALE)
1528 {
1529 Log2(("raw mode refused: stale GS\n"));
1530 return EMSTATE_REM;
1531 }
1532
1533# ifdef VBOX_WITH_SAFE_STR
1534 if (pCtx->tr.Sel == 0)
1535 {
1536 Log(("Raw mode refused -> TR=0\n"));
1537 return EMSTATE_REM;
1538 }
1539# endif
1540
1541 /*Assert(PGMPhysIsA20Enabled(pVCpu));*/
1542 return EMSTATE_RAW;
1543}
1544
1545
1546/**
1547 * Executes all high priority post execution force actions.
1548 *
1549 * @returns rc or a fatal status code.
1550 *
1551 * @param pVM Pointer to the VM.
1552 * @param pVCpu Pointer to the VMCPU.
1553 * @param rc The current rc.
1554 */
1555int emR3HighPriorityPostForcedActions(PVM pVM, PVMCPU pVCpu, int rc)
1556{
1557 VBOXVMM_EM_FF_HIGH(pVCpu, pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions, rc);
1558
1559 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_PDM_CRITSECT))
1560 PDMCritSectBothFF(pVCpu);
1561
1562 /* Update CR3 (Nested Paging case for HM). */
1563 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_CR3))
1564 {
1565 int rc2 = PGMUpdateCR3(pVCpu, CPUMGetGuestCR3(pVCpu));
1566 if (RT_FAILURE(rc2))
1567 return rc2;
1568 Assert(!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_CR3));
1569 }
1570
1571 /* Update PAE PDPEs. This must be done *after* PGMUpdateCR3() and used only by the Nested Paging case for HM. */
1572 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES))
1573 {
1574 if (CPUMIsGuestInPAEMode(pVCpu))
1575 {
1576 PX86PDPE pPdpes = HMGetPaePdpes(pVCpu);
1577 AssertPtr(pPdpes);
1578
1579 PGMGstUpdatePaePdpes(pVCpu, pPdpes);
1580 Assert(!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES));
1581 }
1582 else
1583 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES);
1584 }
1585
1586#ifdef VBOX_WITH_RAW_MODE
1587 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_CSAM_PENDING_ACTION))
1588 CSAMR3DoPendingAction(pVM, pVCpu);
1589#endif
1590
1591 if (VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY))
1592 {
1593 if ( rc > VINF_EM_NO_MEMORY
1594 && rc <= VINF_EM_LAST)
1595 rc = VINF_EM_NO_MEMORY;
1596 }
1597
1598 return rc;
1599}
1600
1601
1602/**
1603 * Executes all pending forced actions.
1604 *
1605 * Forced actions can cause execution delays and execution
1606 * rescheduling. The first we deal with using action priority, so
1607 * that for instance pending timers aren't scheduled and ran until
1608 * right before execution. The rescheduling we deal with using
1609 * return codes. The same goes for VM termination, only in that case
1610 * we exit everything.
1611 *
1612 * @returns VBox status code of equal or greater importance/severity than rc.
1613 * The most important ones are: VINF_EM_RESCHEDULE,
1614 * VINF_EM_SUSPEND, VINF_EM_RESET and VINF_EM_TERMINATE.
1615 *
1616 * @param pVM Pointer to the VM.
1617 * @param pVCpu Pointer to the VMCPU.
1618 * @param rc The current rc.
1619 *
1620 */
1621int emR3ForcedActions(PVM pVM, PVMCPU pVCpu, int rc)
1622{
1623 STAM_REL_PROFILE_START(&pVCpu->em.s.StatForcedActions, a);
1624#ifdef VBOX_STRICT
1625 int rcIrq = VINF_SUCCESS;
1626#endif
1627 int rc2;
1628#define UPDATE_RC() \
1629 do { \
1630 AssertMsg(rc2 <= 0 || (rc2 >= VINF_EM_FIRST && rc2 <= VINF_EM_LAST), ("Invalid FF return code: %Rra\n", rc2)); \
1631 if (rc2 == VINF_SUCCESS || rc < VINF_SUCCESS) \
1632 break; \
1633 if (!rc || rc2 < rc) \
1634 rc = rc2; \
1635 } while (0)
1636 VBOXVMM_EM_FF_ALL(pVCpu, pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions, rc);
1637
1638 /*
1639 * Post execution chunk first.
1640 */
1641 if ( VM_FF_IS_PENDING(pVM, VM_FF_NORMAL_PRIORITY_POST_MASK)
1642 || (VMCPU_FF_NORMAL_PRIORITY_POST_MASK && VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_NORMAL_PRIORITY_POST_MASK)) )
1643 {
1644 /*
1645 * EMT Rendezvous (must be serviced before termination).
1646 */
1647 if (VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS))
1648 {
1649 rc2 = VMMR3EmtRendezvousFF(pVM, pVCpu);
1650 UPDATE_RC();
1651 /** @todo HACK ALERT! The following test is to make sure EM+TM
1652 * thinks the VM is stopped/reset before the next VM state change
1653 * is made. We need a better solution for this, or at least make it
1654 * possible to do: (rc >= VINF_EM_FIRST && rc <=
1655 * VINF_EM_SUSPEND). */
1656 if (RT_UNLIKELY(rc == VINF_EM_SUSPEND || rc == VINF_EM_RESET || rc == VINF_EM_OFF))
1657 {
1658 Log2(("emR3ForcedActions: returns %Rrc\n", rc));
1659 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
1660 return rc;
1661 }
1662 }
1663
1664 /*
1665 * State change request (cleared by vmR3SetStateLocked).
1666 */
1667 if (VM_FF_IS_PENDING(pVM, VM_FF_CHECK_VM_STATE))
1668 {
1669 VMSTATE enmState = VMR3GetState(pVM);
1670 switch (enmState)
1671 {
1672 case VMSTATE_FATAL_ERROR:
1673 case VMSTATE_FATAL_ERROR_LS:
1674 Log2(("emR3ForcedActions: %s -> VINF_EM_SUSPEND\n", VMGetStateName(enmState) ));
1675 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
1676 return VINF_EM_SUSPEND;
1677
1678 case VMSTATE_DESTROYING:
1679 Log2(("emR3ForcedActions: %s -> VINF_EM_TERMINATE\n", VMGetStateName(enmState) ));
1680 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
1681 return VINF_EM_TERMINATE;
1682
1683 default:
1684 AssertMsgFailed(("%s\n", VMGetStateName(enmState)));
1685 }
1686 }
1687
1688 /*
1689 * Debugger Facility polling.
1690 */
1691 if (VM_FF_IS_PENDING(pVM, VM_FF_DBGF))
1692 {
1693 rc2 = DBGFR3VMMForcedAction(pVM);
1694 UPDATE_RC();
1695 }
1696
1697 /*
1698 * Postponed reset request.
1699 */
1700 if (VM_FF_TEST_AND_CLEAR(pVM, VM_FF_RESET))
1701 {
1702 rc2 = VMR3Reset(pVM->pUVM);
1703 UPDATE_RC();
1704 }
1705
1706#ifdef VBOX_WITH_RAW_MODE
1707 /*
1708 * CSAM page scanning.
1709 */
1710 if ( !VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY)
1711 && VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_CSAM_SCAN_PAGE))
1712 {
1713 PCPUMCTX pCtx = pVCpu->em.s.pCtx;
1714
1715 /** @todo: check for 16 or 32 bits code! (D bit in the code selector) */
1716 Log(("Forced action VMCPU_FF_CSAM_SCAN_PAGE\n"));
1717
1718 CSAMR3CheckCodeEx(pVM, pCtx, pCtx->eip);
1719 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_CSAM_SCAN_PAGE);
1720 }
1721#endif
1722
1723 /*
1724 * Out of memory? Putting this after CSAM as it may in theory cause us to run out of memory.
1725 */
1726 if (VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY))
1727 {
1728 rc2 = PGMR3PhysAllocateHandyPages(pVM);
1729 UPDATE_RC();
1730 if (rc == VINF_EM_NO_MEMORY)
1731 return rc;
1732 }
1733
1734 /* check that we got them all */
1735 AssertCompile(VM_FF_NORMAL_PRIORITY_POST_MASK == (VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS));
1736 AssertCompile(VMCPU_FF_NORMAL_PRIORITY_POST_MASK == VM_WHEN_RAW_MODE(VMCPU_FF_CSAM_SCAN_PAGE, 0));
1737 }
1738
1739 /*
1740 * Normal priority then.
1741 * (Executed in no particular order.)
1742 */
1743 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_NORMAL_PRIORITY_MASK, VM_FF_PGM_NO_MEMORY))
1744 {
1745 /*
1746 * PDM Queues are pending.
1747 */
1748 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_PDM_QUEUES, VM_FF_PGM_NO_MEMORY))
1749 PDMR3QueueFlushAll(pVM);
1750
1751 /*
1752 * PDM DMA transfers are pending.
1753 */
1754 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_PDM_DMA, VM_FF_PGM_NO_MEMORY))
1755 PDMR3DmaRun(pVM);
1756
1757 /*
1758 * EMT Rendezvous (make sure they are handled before the requests).
1759 */
1760 if (VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS))
1761 {
1762 rc2 = VMMR3EmtRendezvousFF(pVM, pVCpu);
1763 UPDATE_RC();
1764 /** @todo HACK ALERT! The following test is to make sure EM+TM
1765 * thinks the VM is stopped/reset before the next VM state change
1766 * is made. We need a better solution for this, or at least make it
1767 * possible to do: (rc >= VINF_EM_FIRST && rc <=
1768 * VINF_EM_SUSPEND). */
1769 if (RT_UNLIKELY(rc == VINF_EM_SUSPEND || rc == VINF_EM_RESET || rc == VINF_EM_OFF))
1770 {
1771 Log2(("emR3ForcedActions: returns %Rrc\n", rc));
1772 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
1773 return rc;
1774 }
1775 }
1776
1777 /*
1778 * Requests from other threads.
1779 */
1780 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_REQUEST, VM_FF_PGM_NO_MEMORY))
1781 {
1782 rc2 = VMR3ReqProcessU(pVM->pUVM, VMCPUID_ANY, false /*fPriorityOnly*/);
1783 if (rc2 == VINF_EM_OFF || rc2 == VINF_EM_TERMINATE) /** @todo this shouldn't be necessary */
1784 {
1785 Log2(("emR3ForcedActions: returns %Rrc\n", rc2));
1786 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
1787 return rc2;
1788 }
1789 UPDATE_RC();
1790 /** @todo HACK ALERT! The following test is to make sure EM+TM
1791 * thinks the VM is stopped/reset before the next VM state change
1792 * is made. We need a better solution for this, or at least make it
1793 * possible to do: (rc >= VINF_EM_FIRST && rc <=
1794 * VINF_EM_SUSPEND). */
1795 if (RT_UNLIKELY(rc == VINF_EM_SUSPEND || rc == VINF_EM_RESET || rc == VINF_EM_OFF))
1796 {
1797 Log2(("emR3ForcedActions: returns %Rrc\n", rc));
1798 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
1799 return rc;
1800 }
1801 }
1802
1803#ifdef VBOX_WITH_REM
1804 /* Replay the handler notification changes. */
1805 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_REM_HANDLER_NOTIFY, VM_FF_PGM_NO_MEMORY))
1806 {
1807 /* Try not to cause deadlocks. */
1808 if ( pVM->cCpus == 1
1809 || ( !PGMIsLockOwner(pVM)
1810 && !IOMIsLockWriteOwner(pVM))
1811 )
1812 {
1813 EMRemLock(pVM);
1814 REMR3ReplayHandlerNotifications(pVM);
1815 EMRemUnlock(pVM);
1816 }
1817 }
1818#endif
1819
1820 /* check that we got them all */
1821 AssertCompile(VM_FF_NORMAL_PRIORITY_MASK == (VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_REM_HANDLER_NOTIFY | VM_FF_EMT_RENDEZVOUS));
1822 }
1823
1824 /*
1825 * Normal priority then. (per-VCPU)
1826 * (Executed in no particular order.)
1827 */
1828 if ( !VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY)
1829 && VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_NORMAL_PRIORITY_MASK))
1830 {
1831 /*
1832 * Requests from other threads.
1833 */
1834 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_REQUEST))
1835 {
1836 rc2 = VMR3ReqProcessU(pVM->pUVM, pVCpu->idCpu, false /*fPriorityOnly*/);
1837 if (rc2 == VINF_EM_OFF || rc2 == VINF_EM_TERMINATE || rc2 == VINF_EM_RESET)
1838 {
1839 Log2(("emR3ForcedActions: returns %Rrc\n", rc2));
1840 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
1841 return rc2;
1842 }
1843 UPDATE_RC();
1844 /** @todo HACK ALERT! The following test is to make sure EM+TM
1845 * thinks the VM is stopped/reset before the next VM state change
1846 * is made. We need a better solution for this, or at least make it
1847 * possible to do: (rc >= VINF_EM_FIRST && rc <=
1848 * VINF_EM_SUSPEND). */
1849 if (RT_UNLIKELY(rc == VINF_EM_SUSPEND || rc == VINF_EM_RESET || rc == VINF_EM_OFF))
1850 {
1851 Log2(("emR3ForcedActions: returns %Rrc\n", rc));
1852 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
1853 return rc;
1854 }
1855 }
1856
1857 /*
1858 * Forced unhalting of EMT.
1859 */
1860 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_UNHALT))
1861 {
1862 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_UNHALT);
1863 if (rc == VINF_EM_HALT)
1864 {
1865 rc2 = VINF_EM_RESCHEDULE;
1866 UPDATE_RC();
1867 }
1868 }
1869
1870 /* check that we got them all */
1871 Assert(!(VMCPU_FF_NORMAL_PRIORITY_MASK & ~(VMCPU_FF_REQUEST | VMCPU_FF_UNHALT)));
1872 }
1873
1874 /*
1875 * High priority pre execution chunk last.
1876 * (Executed in ascending priority order.)
1877 */
1878 if ( VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_MASK)
1879 || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_MASK))
1880 {
1881 /*
1882 * Timers before interrupts.
1883 */
1884 if ( VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_TIMER)
1885 && !VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY))
1886 TMR3TimerQueuesDo(pVM);
1887
1888 /*
1889 * The instruction following an emulated STI should *always* be executed!
1890 *
1891 * Note! We intentionally don't clear VM_FF_INHIBIT_INTERRUPTS here if
1892 * the eip is the same as the inhibited instr address. Before we
1893 * are able to execute this instruction in raw mode (iret to
1894 * guest code) an external interrupt might force a world switch
1895 * again. Possibly allowing a guest interrupt to be dispatched
1896 * in the process. This could break the guest. Sounds very
1897 * unlikely, but such timing sensitive problem are not as rare as
1898 * you might think.
1899 */
1900 if ( VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
1901 && !VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY))
1902 {
1903 if (CPUMGetGuestRIP(pVCpu) != EMGetInhibitInterruptsPC(pVCpu))
1904 {
1905 Log(("Clearing VMCPU_FF_INHIBIT_INTERRUPTS at %RGv - successor %RGv\n", (RTGCPTR)CPUMGetGuestRIP(pVCpu), EMGetInhibitInterruptsPC(pVCpu)));
1906 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
1907 }
1908 else
1909 Log(("Leaving VMCPU_FF_INHIBIT_INTERRUPTS set at %RGv\n", (RTGCPTR)CPUMGetGuestRIP(pVCpu)));
1910 }
1911
1912 /*
1913 * Interrupts.
1914 */
1915 bool fWakeupPending = false;
1916 if ( !VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY)
1917 && !VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
1918 && (!rc || rc >= VINF_EM_RESCHEDULE_HM)
1919 && !TRPMHasTrap(pVCpu) /* an interrupt could already be scheduled for dispatching in the recompiler. */
1920#ifdef VBOX_WITH_RAW_MODE
1921 && PATMAreInterruptsEnabled(pVM)
1922#else
1923 && (pVCpu->em.s.pCtx->eflags.u32 & X86_EFL_IF)
1924#endif
1925 && !HMR3IsEventPending(pVCpu))
1926 {
1927 Assert(pVCpu->em.s.enmState != EMSTATE_WAIT_SIPI);
1928 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
1929 {
1930 /* Note: it's important to make sure the return code from TRPMR3InjectEvent isn't ignored! */
1931 /** @todo this really isn't nice, should properly handle this */
1932 rc2 = TRPMR3InjectEvent(pVM, pVCpu, TRPM_HARDWARE_INT);
1933 if (pVM->em.s.fIemExecutesAll && (rc2 == VINF_EM_RESCHEDULE_REM || rc2 == VINF_EM_RESCHEDULE_HM || rc2 == VINF_EM_RESCHEDULE_RAW))
1934 rc2 = VINF_EM_RESCHEDULE;
1935#ifdef VBOX_STRICT
1936 rcIrq = rc2;
1937#endif
1938 UPDATE_RC();
1939 /* Reschedule required: We must not miss the wakeup below! */
1940 fWakeupPending = true;
1941 }
1942#ifdef VBOX_WITH_REM
1943 /** @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. */
1944 else if (REMR3QueryPendingInterrupt(pVM, pVCpu) != REM_NO_PENDING_IRQ)
1945 {
1946 Log2(("REMR3QueryPendingInterrupt -> %#x\n", REMR3QueryPendingInterrupt(pVM, pVCpu)));
1947 rc2 = VINF_EM_RESCHEDULE_REM;
1948 UPDATE_RC();
1949 }
1950#endif
1951 }
1952
1953 /*
1954 * Allocate handy pages.
1955 */
1956 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_PGM_NEED_HANDY_PAGES, VM_FF_PGM_NO_MEMORY))
1957 {
1958 rc2 = PGMR3PhysAllocateHandyPages(pVM);
1959 UPDATE_RC();
1960 }
1961
1962 /*
1963 * Debugger Facility request.
1964 */
1965 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_DBGF, VM_FF_PGM_NO_MEMORY))
1966 {
1967 rc2 = DBGFR3VMMForcedAction(pVM);
1968 UPDATE_RC();
1969 }
1970
1971 /*
1972 * EMT Rendezvous (must be serviced before termination).
1973 */
1974 if ( !fWakeupPending /* don't miss the wakeup from EMSTATE_HALTED! */
1975 && VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS))
1976 {
1977 rc2 = VMMR3EmtRendezvousFF(pVM, pVCpu);
1978 UPDATE_RC();
1979 /** @todo HACK ALERT! The following test is to make sure EM+TM thinks the VM is
1980 * stopped/reset before the next VM state change is made. We need a better
1981 * solution for this, or at least make it possible to do: (rc >= VINF_EM_FIRST
1982 * && rc >= VINF_EM_SUSPEND). */
1983 if (RT_UNLIKELY(rc == VINF_EM_SUSPEND || rc == VINF_EM_RESET || rc == VINF_EM_OFF))
1984 {
1985 Log2(("emR3ForcedActions: returns %Rrc\n", rc));
1986 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
1987 return rc;
1988 }
1989 }
1990
1991 /*
1992 * State change request (cleared by vmR3SetStateLocked).
1993 */
1994 if ( !fWakeupPending /* don't miss the wakeup from EMSTATE_HALTED! */
1995 && VM_FF_IS_PENDING(pVM, VM_FF_CHECK_VM_STATE))
1996 {
1997 VMSTATE enmState = VMR3GetState(pVM);
1998 switch (enmState)
1999 {
2000 case VMSTATE_FATAL_ERROR:
2001 case VMSTATE_FATAL_ERROR_LS:
2002 Log2(("emR3ForcedActions: %s -> VINF_EM_SUSPEND\n", VMGetStateName(enmState) ));
2003 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
2004 return VINF_EM_SUSPEND;
2005
2006 case VMSTATE_DESTROYING:
2007 Log2(("emR3ForcedActions: %s -> VINF_EM_TERMINATE\n", VMGetStateName(enmState) ));
2008 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
2009 return VINF_EM_TERMINATE;
2010
2011 default:
2012 AssertMsgFailed(("%s\n", VMGetStateName(enmState)));
2013 }
2014 }
2015
2016 /*
2017 * Out of memory? Since most of our fellow high priority actions may cause us
2018 * to run out of memory, we're employing VM_FF_IS_PENDING_EXCEPT and putting this
2019 * at the end rather than the start. Also, VM_FF_TERMINATE has higher priority
2020 * than us since we can terminate without allocating more memory.
2021 */
2022 if (VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY))
2023 {
2024 rc2 = PGMR3PhysAllocateHandyPages(pVM);
2025 UPDATE_RC();
2026 if (rc == VINF_EM_NO_MEMORY)
2027 return rc;
2028 }
2029
2030 /*
2031 * If the virtual sync clock is still stopped, make TM restart it.
2032 */
2033 if (VM_FF_IS_PENDING(pVM, VM_FF_TM_VIRTUAL_SYNC))
2034 TMR3VirtualSyncFF(pVM, pVCpu);
2035
2036#ifdef DEBUG
2037 /*
2038 * Debug, pause the VM.
2039 */
2040 if (VM_FF_IS_PENDING(pVM, VM_FF_DEBUG_SUSPEND))
2041 {
2042 VM_FF_CLEAR(pVM, VM_FF_DEBUG_SUSPEND);
2043 Log(("emR3ForcedActions: returns VINF_EM_SUSPEND\n"));
2044 return VINF_EM_SUSPEND;
2045 }
2046#endif
2047
2048 /* check that we got them all */
2049 AssertCompile(VM_FF_HIGH_PRIORITY_PRE_MASK == (VM_FF_TM_VIRTUAL_SYNC | VM_FF_DBGF | VM_FF_CHECK_VM_STATE | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS));
2050 AssertCompile(VMCPU_FF_HIGH_PRIORITY_PRE_MASK == (VMCPU_FF_TIMER | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_INHIBIT_INTERRUPTS | VM_WHEN_RAW_MODE(VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT, 0)));
2051 }
2052
2053#undef UPDATE_RC
2054 Log2(("emR3ForcedActions: returns %Rrc\n", rc));
2055 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a);
2056 Assert(rcIrq == VINF_SUCCESS || rcIrq == rc);
2057 return rc;
2058}
2059
2060
2061/**
2062 * Check if the preset execution time cap restricts guest execution scheduling.
2063 *
2064 * @returns true if allowed, false otherwise
2065 * @param pVM Pointer to the VM.
2066 * @param pVCpu Pointer to the VMCPU.
2067 */
2068bool emR3IsExecutionAllowed(PVM pVM, PVMCPU pVCpu)
2069{
2070 uint64_t u64UserTime, u64KernelTime;
2071
2072 if ( pVM->uCpuExecutionCap != 100
2073 && RT_SUCCESS(RTThreadGetExecutionTimeMilli(&u64KernelTime, &u64UserTime)))
2074 {
2075 uint64_t u64TimeNow = RTTimeMilliTS();
2076 if (pVCpu->em.s.u64TimeSliceStart + EM_TIME_SLICE < u64TimeNow)
2077 {
2078 /* New time slice. */
2079 pVCpu->em.s.u64TimeSliceStart = u64TimeNow;
2080 pVCpu->em.s.u64TimeSliceStartExec = u64KernelTime + u64UserTime;
2081 pVCpu->em.s.u64TimeSliceExec = 0;
2082 }
2083 pVCpu->em.s.u64TimeSliceExec = u64KernelTime + u64UserTime - pVCpu->em.s.u64TimeSliceStartExec;
2084
2085 Log2(("emR3IsExecutionAllowed: start=%RX64 startexec=%RX64 exec=%RX64 (cap=%x)\n", pVCpu->em.s.u64TimeSliceStart, pVCpu->em.s.u64TimeSliceStartExec, pVCpu->em.s.u64TimeSliceExec, (EM_TIME_SLICE * pVM->uCpuExecutionCap) / 100));
2086 if (pVCpu->em.s.u64TimeSliceExec >= (EM_TIME_SLICE * pVM->uCpuExecutionCap) / 100)
2087 return false;
2088 }
2089 return true;
2090}
2091
2092
2093/**
2094 * Execute VM.
2095 *
2096 * This function is the main loop of the VM. The emulation thread
2097 * calls this function when the VM has been successfully constructed
2098 * and we're ready for executing the VM.
2099 *
2100 * Returning from this function means that the VM is turned off or
2101 * suspended (state already saved) and deconstruction is next in line.
2102 *
2103 * All interaction from other thread are done using forced actions
2104 * and signaling of the wait object.
2105 *
2106 * @returns VBox status code, informational status codes may indicate failure.
2107 * @param pVM Pointer to the VM.
2108 * @param pVCpu Pointer to the VMCPU.
2109 */
2110VMMR3_INT_DECL(int) EMR3ExecuteVM(PVM pVM, PVMCPU pVCpu)
2111{
2112 Log(("EMR3ExecuteVM: pVM=%p enmVMState=%d (%s) enmState=%d (%s) enmPrevState=%d (%s) fForceRAW=%RTbool\n",
2113 pVM,
2114 pVM->enmVMState, VMR3GetStateName(pVM->enmVMState),
2115 pVCpu->em.s.enmState, emR3GetStateName(pVCpu->em.s.enmState),
2116 pVCpu->em.s.enmPrevState, emR3GetStateName(pVCpu->em.s.enmPrevState),
2117 pVCpu->em.s.fForceRAW));
2118 VM_ASSERT_EMT(pVM);
2119 AssertMsg( pVCpu->em.s.enmState == EMSTATE_NONE
2120 || pVCpu->em.s.enmState == EMSTATE_WAIT_SIPI
2121 || pVCpu->em.s.enmState == EMSTATE_SUSPENDED,
2122 ("%s\n", emR3GetStateName(pVCpu->em.s.enmState)));
2123
2124 int rc = setjmp(pVCpu->em.s.u.FatalLongJump);
2125 if (rc == 0)
2126 {
2127 /*
2128 * Start the virtual time.
2129 */
2130 TMR3NotifyResume(pVM, pVCpu);
2131
2132 /*
2133 * The Outer Main Loop.
2134 */
2135 bool fFFDone = false;
2136
2137 /* Reschedule right away to start in the right state. */
2138 rc = VINF_SUCCESS;
2139
2140 /* If resuming after a pause or a state load, restore the previous
2141 state or else we'll start executing code. Else, just reschedule. */
2142 if ( pVCpu->em.s.enmState == EMSTATE_SUSPENDED
2143 && ( pVCpu->em.s.enmPrevState == EMSTATE_WAIT_SIPI
2144 || pVCpu->em.s.enmPrevState == EMSTATE_HALTED))
2145 pVCpu->em.s.enmState = pVCpu->em.s.enmPrevState;
2146 else
2147 pVCpu->em.s.enmState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
2148 pVCpu->em.s.cIemThenRemInstructions = 0;
2149 Log(("EMR3ExecuteVM: enmState=%s\n", emR3GetStateName(pVCpu->em.s.enmState)));
2150
2151 STAM_REL_PROFILE_ADV_START(&pVCpu->em.s.StatTotal, x);
2152 for (;;)
2153 {
2154 /*
2155 * Before we can schedule anything (we're here because
2156 * scheduling is required) we must service any pending
2157 * forced actions to avoid any pending action causing
2158 * immediate rescheduling upon entering an inner loop
2159 *
2160 * Do forced actions.
2161 */
2162 if ( !fFFDone
2163 && RT_SUCCESS(rc)
2164 && rc != VINF_EM_TERMINATE
2165 && rc != VINF_EM_OFF
2166 && ( VM_FF_IS_PENDING(pVM, VM_FF_ALL_REM_MASK)
2167 || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_ALL_REM_MASK)))
2168 {
2169 rc = emR3ForcedActions(pVM, pVCpu, rc);
2170 VBOXVMM_EM_FF_ALL_RET(pVCpu, rc);
2171 if ( ( rc == VINF_EM_RESCHEDULE_REM
2172 || rc == VINF_EM_RESCHEDULE_HM)
2173 && pVCpu->em.s.fForceRAW)
2174 rc = VINF_EM_RESCHEDULE_RAW;
2175 }
2176 else if (fFFDone)
2177 fFFDone = false;
2178
2179 /*
2180 * Now what to do?
2181 */
2182 Log2(("EMR3ExecuteVM: rc=%Rrc\n", rc));
2183 EMSTATE const enmOldState = pVCpu->em.s.enmState;
2184 switch (rc)
2185 {
2186 /*
2187 * Keep doing what we're currently doing.
2188 */
2189 case VINF_SUCCESS:
2190 break;
2191
2192 /*
2193 * Reschedule - to raw-mode execution.
2194 */
2195 case VINF_EM_RESCHEDULE_RAW:
2196 Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_RAW: %d -> %d (EMSTATE_RAW)\n", enmOldState, EMSTATE_RAW));
2197 Assert(!pVM->em.s.fIemExecutesAll || pVCpu->em.s.enmState != EMSTATE_IEM);
2198 pVCpu->em.s.enmState = EMSTATE_RAW;
2199 break;
2200
2201 /*
2202 * Reschedule - to hardware accelerated raw-mode execution.
2203 */
2204 case VINF_EM_RESCHEDULE_HM:
2205 Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_HM: %d -> %d (EMSTATE_HM)\n", enmOldState, EMSTATE_HM));
2206 Assert(!pVM->em.s.fIemExecutesAll || pVCpu->em.s.enmState != EMSTATE_IEM);
2207 Assert(!pVCpu->em.s.fForceRAW);
2208 pVCpu->em.s.enmState = EMSTATE_HM;
2209 break;
2210
2211 /*
2212 * Reschedule - to recompiled execution.
2213 */
2214 case VINF_EM_RESCHEDULE_REM:
2215#ifdef VBOX_WITH_FIRST_IEM_STEP
2216 Assert(!pVM->em.s.fIemExecutesAll || pVCpu->em.s.enmState != EMSTATE_IEM);
2217 if (HMIsEnabled(pVM))
2218 {
2219 Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_REM: %d -> %d (EMSTATE_IEM_THEN_REM)\n",
2220 enmOldState, EMSTATE_IEM_THEN_REM));
2221 if (pVCpu->em.s.enmState != EMSTATE_IEM_THEN_REM)
2222 {
2223 pVCpu->em.s.enmState = EMSTATE_IEM_THEN_REM;
2224 pVCpu->em.s.cIemThenRemInstructions = 0;
2225 }
2226 }
2227 else
2228 {
2229 Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_REM: %d -> %d (EMSTATE_REM)\n", enmOldState, EMSTATE_REM));
2230 pVCpu->em.s.enmState = EMSTATE_REM;
2231 }
2232#else
2233 Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_REM: %d -> %d (EMSTATE_REM)\n", enmOldState, EMSTATE_REM));
2234 Assert(!pVM->em.s.fIemExecutesAll || pVCpu->em.s.enmState != EMSTATE_IEM);
2235 pVCpu->em.s.enmState = EMSTATE_REM;
2236#endif
2237 break;
2238
2239 /*
2240 * Resume.
2241 */
2242 case VINF_EM_RESUME:
2243 Log2(("EMR3ExecuteVM: VINF_EM_RESUME: %d -> VINF_EM_RESCHEDULE\n", enmOldState));
2244 /* Don't reschedule in the halted or wait for SIPI case. */
2245 if ( pVCpu->em.s.enmPrevState == EMSTATE_WAIT_SIPI
2246 || pVCpu->em.s.enmPrevState == EMSTATE_HALTED)
2247 {
2248 pVCpu->em.s.enmState = pVCpu->em.s.enmPrevState;
2249 break;
2250 }
2251 /* fall through and get scheduled. */
2252
2253 /*
2254 * Reschedule.
2255 */
2256 case VINF_EM_RESCHEDULE:
2257 {
2258 EMSTATE enmState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
2259 Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE: %d -> %d (%s)\n", enmOldState, enmState, emR3GetStateName(enmState)));
2260 if (pVCpu->em.s.enmState != enmState && enmState == EMSTATE_IEM_THEN_REM)
2261 pVCpu->em.s.cIemThenRemInstructions = 0;
2262 pVCpu->em.s.enmState = enmState;
2263 break;
2264 }
2265
2266 /*
2267 * Halted.
2268 */
2269 case VINF_EM_HALT:
2270 Log2(("EMR3ExecuteVM: VINF_EM_HALT: %d -> %d\n", enmOldState, EMSTATE_HALTED));
2271 pVCpu->em.s.enmState = EMSTATE_HALTED;
2272 break;
2273
2274 /*
2275 * Switch to the wait for SIPI state (application processor only)
2276 */
2277 case VINF_EM_WAIT_SIPI:
2278 Assert(pVCpu->idCpu != 0);
2279 Log2(("EMR3ExecuteVM: VINF_EM_WAIT_SIPI: %d -> %d\n", enmOldState, EMSTATE_WAIT_SIPI));
2280 pVCpu->em.s.enmState = EMSTATE_WAIT_SIPI;
2281 break;
2282
2283
2284 /*
2285 * Suspend.
2286 */
2287 case VINF_EM_SUSPEND:
2288 Log2(("EMR3ExecuteVM: VINF_EM_SUSPEND: %d -> %d\n", enmOldState, EMSTATE_SUSPENDED));
2289 Assert(enmOldState != EMSTATE_SUSPENDED);
2290 pVCpu->em.s.enmPrevState = enmOldState;
2291 pVCpu->em.s.enmState = EMSTATE_SUSPENDED;
2292 break;
2293
2294 /*
2295 * Reset.
2296 * We might end up doing a double reset for now, we'll have to clean up the mess later.
2297 */
2298 case VINF_EM_RESET:
2299 {
2300 if (pVCpu->idCpu == 0)
2301 {
2302 EMSTATE enmState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
2303 Log2(("EMR3ExecuteVM: VINF_EM_RESET: %d -> %d (%s)\n", enmOldState, enmState, emR3GetStateName(enmState)));
2304 if (pVCpu->em.s.enmState != enmState && enmState == EMSTATE_IEM_THEN_REM)
2305 pVCpu->em.s.cIemThenRemInstructions = 0;
2306 pVCpu->em.s.enmState = enmState;
2307 }
2308 else
2309 {
2310 /* All other VCPUs go into the wait for SIPI state. */
2311 pVCpu->em.s.enmState = EMSTATE_WAIT_SIPI;
2312 }
2313 break;
2314 }
2315
2316 /*
2317 * Power Off.
2318 */
2319 case VINF_EM_OFF:
2320 pVCpu->em.s.enmState = EMSTATE_TERMINATING;
2321 Log2(("EMR3ExecuteVM: returns VINF_EM_OFF (%d -> %d)\n", enmOldState, EMSTATE_TERMINATING));
2322 TMR3NotifySuspend(pVM, pVCpu);
2323 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
2324 return rc;
2325
2326 /*
2327 * Terminate the VM.
2328 */
2329 case VINF_EM_TERMINATE:
2330 pVCpu->em.s.enmState = EMSTATE_TERMINATING;
2331 Log(("EMR3ExecuteVM returns VINF_EM_TERMINATE (%d -> %d)\n", enmOldState, EMSTATE_TERMINATING));
2332 if (pVM->enmVMState < VMSTATE_DESTROYING) /* ugly */
2333 TMR3NotifySuspend(pVM, pVCpu);
2334 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
2335 return rc;
2336
2337
2338 /*
2339 * Out of memory, suspend the VM and stuff.
2340 */
2341 case VINF_EM_NO_MEMORY:
2342 Log2(("EMR3ExecuteVM: VINF_EM_NO_MEMORY: %d -> %d\n", enmOldState, EMSTATE_SUSPENDED));
2343 Assert(enmOldState != EMSTATE_SUSPENDED);
2344 pVCpu->em.s.enmPrevState = enmOldState;
2345 pVCpu->em.s.enmState = EMSTATE_SUSPENDED;
2346 TMR3NotifySuspend(pVM, pVCpu);
2347 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
2348
2349 rc = VMSetRuntimeError(pVM, VMSETRTERR_FLAGS_SUSPEND, "HostMemoryLow",
2350 N_("Unable to allocate and lock memory. The virtual machine will be paused. Please close applications to free up memory or close the VM"));
2351 if (rc != VINF_EM_SUSPEND)
2352 {
2353 if (RT_SUCCESS_NP(rc))
2354 {
2355 AssertLogRelMsgFailed(("%Rrc\n", rc));
2356 rc = VERR_EM_INTERNAL_ERROR;
2357 }
2358 pVCpu->em.s.enmState = EMSTATE_GURU_MEDITATION;
2359 }
2360 return rc;
2361
2362 /*
2363 * Guest debug events.
2364 */
2365 case VINF_EM_DBG_STEPPED:
2366 case VINF_EM_DBG_STOP:
2367 case VINF_EM_DBG_BREAKPOINT:
2368 case VINF_EM_DBG_STEP:
2369 if (enmOldState == EMSTATE_RAW)
2370 {
2371 Log2(("EMR3ExecuteVM: %Rrc: %d -> %d\n", rc, enmOldState, EMSTATE_DEBUG_GUEST_RAW));
2372 pVCpu->em.s.enmState = EMSTATE_DEBUG_GUEST_RAW;
2373 }
2374 else if (enmOldState == EMSTATE_HM)
2375 {
2376 Log2(("EMR3ExecuteVM: %Rrc: %d -> %d\n", rc, enmOldState, EMSTATE_DEBUG_GUEST_HM));
2377 pVCpu->em.s.enmState = EMSTATE_DEBUG_GUEST_HM;
2378 }
2379 else if (enmOldState == EMSTATE_REM)
2380 {
2381 Log2(("EMR3ExecuteVM: %Rrc: %d -> %d\n", rc, enmOldState, EMSTATE_DEBUG_GUEST_REM));
2382 pVCpu->em.s.enmState = EMSTATE_DEBUG_GUEST_REM;
2383 }
2384 else
2385 {
2386 Log2(("EMR3ExecuteVM: %Rrc: %d -> %d\n", rc, enmOldState, EMSTATE_DEBUG_GUEST_IEM));
2387 pVCpu->em.s.enmState = EMSTATE_DEBUG_GUEST_IEM;
2388 }
2389 break;
2390
2391 /*
2392 * Hypervisor debug events.
2393 */
2394 case VINF_EM_DBG_HYPER_STEPPED:
2395 case VINF_EM_DBG_HYPER_BREAKPOINT:
2396 case VINF_EM_DBG_HYPER_ASSERTION:
2397 Log2(("EMR3ExecuteVM: %Rrc: %d -> %d\n", rc, enmOldState, EMSTATE_DEBUG_HYPER));
2398 pVCpu->em.s.enmState = EMSTATE_DEBUG_HYPER;
2399 break;
2400
2401 /*
2402 * Triple fault.
2403 */
2404 case VINF_EM_TRIPLE_FAULT:
2405 if (!pVM->em.s.fGuruOnTripleFault)
2406 {
2407 Log(("EMR3ExecuteVM: VINF_EM_TRIPLE_FAULT: CPU reset...\n"));
2408 Assert(pVM->cCpus == 1);
2409 REMR3Reset(pVM);
2410 PGMR3ResetCpu(pVM, pVCpu);
2411 TRPMR3ResetCpu(pVCpu);
2412 CPUMR3ResetCpu(pVM, pVCpu);
2413 EMR3ResetCpu(pVCpu);
2414 HMR3ResetCpu(pVCpu);
2415 pVCpu->em.s.enmState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
2416 Log2(("EMR3ExecuteVM: VINF_EM_TRIPLE_FAULT: %d -> %d\n", rc, enmOldState, pVCpu->em.s.enmState));
2417 break;
2418 }
2419 /* Else fall through and trigger a guru. */
2420 case VERR_VMM_RING0_ASSERTION:
2421 Log(("EMR3ExecuteVM: %Rrc: %d -> %d (EMSTATE_GURU_MEDITATION)\n", rc, enmOldState, EMSTATE_GURU_MEDITATION));
2422 pVCpu->em.s.enmState = EMSTATE_GURU_MEDITATION;
2423 break;
2424
2425 /*
2426 * Any error code showing up here other than the ones we
2427 * know and process above are considered to be FATAL.
2428 *
2429 * Unknown warnings and informational status codes are also
2430 * included in this.
2431 */
2432 default:
2433 if (RT_SUCCESS_NP(rc))
2434 {
2435 AssertMsgFailed(("Unexpected warning or informational status code %Rra!\n", rc));
2436 rc = VERR_EM_INTERNAL_ERROR;
2437 }
2438 Log(("EMR3ExecuteVM: %Rrc: %d -> %d (EMSTATE_GURU_MEDITATION)\n", rc, enmOldState, EMSTATE_GURU_MEDITATION));
2439 pVCpu->em.s.enmState = EMSTATE_GURU_MEDITATION;
2440 break;
2441 }
2442
2443 /*
2444 * Act on state transition.
2445 */
2446 EMSTATE const enmNewState = pVCpu->em.s.enmState;
2447 if (enmOldState != enmNewState)
2448 {
2449 VBOXVMM_EM_STATE_CHANGED(pVCpu, enmOldState, enmNewState, rc);
2450
2451 /* Clear MWait flags. */
2452 if ( enmOldState == EMSTATE_HALTED
2453 && (pVCpu->em.s.MWait.fWait & EMMWAIT_FLAG_ACTIVE)
2454 && ( enmNewState == EMSTATE_RAW
2455 || enmNewState == EMSTATE_HM
2456 || enmNewState == EMSTATE_REM
2457 || enmNewState == EMSTATE_IEM_THEN_REM
2458 || enmNewState == EMSTATE_DEBUG_GUEST_RAW
2459 || enmNewState == EMSTATE_DEBUG_GUEST_HM
2460 || enmNewState == EMSTATE_DEBUG_GUEST_IEM
2461 || enmNewState == EMSTATE_DEBUG_GUEST_REM) )
2462 {
2463 LogFlow(("EMR3ExecuteVM: Clearing MWAIT\n"));
2464 pVCpu->em.s.MWait.fWait &= ~(EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0);
2465 }
2466 }
2467 else
2468 VBOXVMM_EM_STATE_UNCHANGED(pVCpu, enmNewState, rc);
2469
2470 STAM_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x); /* (skip this in release) */
2471 STAM_PROFILE_ADV_START(&pVCpu->em.s.StatTotal, x);
2472
2473 /*
2474 * Act on the new state.
2475 */
2476 switch (enmNewState)
2477 {
2478 /*
2479 * Execute raw.
2480 */
2481 case EMSTATE_RAW:
2482#ifdef VBOX_WITH_RAW_MODE
2483 rc = emR3RawExecute(pVM, pVCpu, &fFFDone);
2484#else
2485 AssertLogRelMsgFailed(("%Rrc\n", rc));
2486 rc = VERR_EM_INTERNAL_ERROR;
2487#endif
2488 break;
2489
2490 /*
2491 * Execute hardware accelerated raw.
2492 */
2493 case EMSTATE_HM:
2494 rc = emR3HmExecute(pVM, pVCpu, &fFFDone);
2495 break;
2496
2497 /*
2498 * Execute recompiled.
2499 */
2500 case EMSTATE_REM:
2501 rc = emR3RemExecute(pVM, pVCpu, &fFFDone);
2502 Log2(("EMR3ExecuteVM: emR3RemExecute -> %Rrc\n", rc));
2503 break;
2504
2505 /*
2506 * Execute in the interpreter.
2507 */
2508 case EMSTATE_IEM:
2509 {
2510#if 0 /* For testing purposes. */
2511 STAM_PROFILE_START(&pVCpu->em.s.StatHmExec, x1);
2512 rc = VBOXSTRICTRC_TODO(EMR3HmSingleInstruction(pVM, pVCpu, EM_ONE_INS_FLAGS_RIP_CHANGE));
2513 STAM_PROFILE_STOP(&pVCpu->em.s.StatHmExec, x1);
2514 if (rc == VINF_EM_DBG_STEPPED || rc == VINF_EM_RESCHEDULE_HM || rc == VINF_EM_RESCHEDULE_REM || rc == VINF_EM_RESCHEDULE_RAW)
2515 rc = VINF_SUCCESS;
2516 else if (rc == VERR_EM_CANNOT_EXEC_GUEST)
2517#endif
2518 rc = VBOXSTRICTRC_TODO(IEMExecLots(pVCpu));
2519 if (pVM->em.s.fIemExecutesAll)
2520 {
2521 Assert(rc != VINF_EM_RESCHEDULE_REM);
2522 Assert(rc != VINF_EM_RESCHEDULE_RAW);
2523 Assert(rc != VINF_EM_RESCHEDULE_HM);
2524 }
2525 fFFDone = false;
2526 break;
2527 }
2528
2529 /*
2530 * Execute in IEM, hoping we can quickly switch aback to HM
2531 * or RAW execution. If our hopes fail, we go to REM.
2532 */
2533 case EMSTATE_IEM_THEN_REM:
2534 {
2535 STAM_PROFILE_START(&pVCpu->em.s.StatIEMThenREM, pIemThenRem);
2536 rc = VBOXSTRICTRC_TODO(emR3ExecuteIemThenRem(pVM, pVCpu, &fFFDone));
2537 STAM_PROFILE_STOP(&pVCpu->em.s.StatIEMThenREM, pIemThenRem);
2538 break;
2539 }
2540
2541 /*
2542 * Application processor execution halted until SIPI.
2543 */
2544 case EMSTATE_WAIT_SIPI:
2545 /* no break */
2546 /*
2547 * hlt - execution halted until interrupt.
2548 */
2549 case EMSTATE_HALTED:
2550 {
2551 STAM_REL_PROFILE_START(&pVCpu->em.s.StatHalted, y);
2552 /* If HM (or someone else) store a pending interrupt in
2553 TRPM, it must be dispatched ASAP without any halting.
2554 Anything pending in TRPM has been accepted and the CPU
2555 should already be the right state to receive it. */
2556 if (TRPMHasTrap(pVCpu))
2557 rc = VINF_EM_RESCHEDULE;
2558 /* MWAIT has a special extension where it's woken up when
2559 an interrupt is pending even when IF=0. */
2560 else if ( (pVCpu->em.s.MWait.fWait & (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0))
2561 == (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0))
2562 {
2563 rc = VMR3WaitHalted(pVM, pVCpu, false /*fIgnoreInterrupts*/);
2564 if ( rc == VINF_SUCCESS
2565 && VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC
2566 | VMCPU_FF_INTERRUPT_NMI | VMCPU_FF_INTERRUPT_SMI | VMCPU_FF_UNHALT))
2567 {
2568 Log(("EMR3ExecuteVM: Triggering reschedule on pending IRQ after MWAIT\n"));
2569 rc = VINF_EM_RESCHEDULE;
2570 }
2571 }
2572 else
2573 {
2574 rc = VMR3WaitHalted(pVM, pVCpu, !(CPUMGetGuestEFlags(pVCpu) & X86_EFL_IF));
2575 if ( rc == VINF_SUCCESS
2576 && VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_NMI | VMCPU_FF_INTERRUPT_SMI | VMCPU_FF_UNHALT))
2577 {
2578 Log(("EMR3ExecuteVM: Triggering reschedule on pending NMI/SMI/UNHALT after HLT\n"));
2579 rc = VINF_EM_RESCHEDULE;
2580 }
2581 }
2582
2583 STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatHalted, y);
2584 break;
2585 }
2586
2587 /*
2588 * Suspended - return to VM.cpp.
2589 */
2590 case EMSTATE_SUSPENDED:
2591 TMR3NotifySuspend(pVM, pVCpu);
2592 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
2593 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName(enmOldState)));
2594 return VINF_EM_SUSPEND;
2595
2596 /*
2597 * Debugging in the guest.
2598 */
2599 case EMSTATE_DEBUG_GUEST_RAW:
2600 case EMSTATE_DEBUG_GUEST_HM:
2601 case EMSTATE_DEBUG_GUEST_IEM:
2602 case EMSTATE_DEBUG_GUEST_REM:
2603 TMR3NotifySuspend(pVM, pVCpu);
2604 rc = VBOXSTRICTRC_TODO(emR3Debug(pVM, pVCpu, rc));
2605 TMR3NotifyResume(pVM, pVCpu);
2606 Log2(("EMR3ExecuteVM: emR3Debug -> %Rrc (state %d)\n", rc, pVCpu->em.s.enmState));
2607 break;
2608
2609 /*
2610 * Debugging in the hypervisor.
2611 */
2612 case EMSTATE_DEBUG_HYPER:
2613 {
2614 TMR3NotifySuspend(pVM, pVCpu);
2615 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
2616
2617 rc = VBOXSTRICTRC_TODO(emR3Debug(pVM, pVCpu, rc));
2618 Log2(("EMR3ExecuteVM: emR3Debug -> %Rrc (state %d)\n", rc, pVCpu->em.s.enmState));
2619 if (rc != VINF_SUCCESS)
2620 {
2621 if (rc == VINF_EM_OFF || rc == VINF_EM_TERMINATE)
2622 pVCpu->em.s.enmState = EMSTATE_TERMINATING;
2623 else
2624 {
2625 /* switch to guru meditation mode */
2626 pVCpu->em.s.enmState = EMSTATE_GURU_MEDITATION;
2627 VMMR3FatalDump(pVM, pVCpu, rc);
2628 }
2629 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName(enmOldState)));
2630 return rc;
2631 }
2632
2633 STAM_REL_PROFILE_ADV_START(&pVCpu->em.s.StatTotal, x);
2634 TMR3NotifyResume(pVM, pVCpu);
2635 break;
2636 }
2637
2638 /*
2639 * Guru meditation takes place in the debugger.
2640 */
2641 case EMSTATE_GURU_MEDITATION:
2642 {
2643 TMR3NotifySuspend(pVM, pVCpu);
2644 VMMR3FatalDump(pVM, pVCpu, rc);
2645 emR3Debug(pVM, pVCpu, rc);
2646 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
2647 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName(enmOldState)));
2648 return rc;
2649 }
2650
2651 /*
2652 * The states we don't expect here.
2653 */
2654 case EMSTATE_NONE:
2655 case EMSTATE_TERMINATING:
2656 default:
2657 AssertMsgFailed(("EMR3ExecuteVM: Invalid state %d!\n", pVCpu->em.s.enmState));
2658 pVCpu->em.s.enmState = EMSTATE_GURU_MEDITATION;
2659 TMR3NotifySuspend(pVM, pVCpu);
2660 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
2661 Log(("EMR3ExecuteVM: actually returns %Rrc (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName(enmOldState)));
2662 return VERR_EM_INTERNAL_ERROR;
2663 }
2664 } /* The Outer Main Loop */
2665 }
2666 else
2667 {
2668 /*
2669 * Fatal error.
2670 */
2671 Log(("EMR3ExecuteVM: returns %Rrc because of longjmp / fatal error; (state %s / %s)\n", rc, emR3GetStateName(pVCpu->em.s.enmState), emR3GetStateName(pVCpu->em.s.enmPrevState)));
2672 TMR3NotifySuspend(pVM, pVCpu);
2673 VMMR3FatalDump(pVM, pVCpu, rc);
2674 emR3Debug(pVM, pVCpu, rc);
2675 STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatTotal, x);
2676 /** @todo change the VM state! */
2677 return rc;
2678 }
2679
2680 /* (won't ever get here). */
2681 AssertFailed();
2682}
2683
2684/**
2685 * Notify EM of a state change (used by FTM)
2686 *
2687 * @param pVM Pointer to the VM.
2688 */
2689VMMR3_INT_DECL(int) EMR3NotifySuspend(PVM pVM)
2690{
2691 PVMCPU pVCpu = VMMGetCpu(pVM);
2692
2693 TMR3NotifySuspend(pVM, pVCpu); /* Stop the virtual time. */
2694 pVCpu->em.s.enmPrevState = pVCpu->em.s.enmState;
2695 pVCpu->em.s.enmState = EMSTATE_SUSPENDED;
2696 return VINF_SUCCESS;
2697}
2698
2699/**
2700 * Notify EM of a state change (used by FTM)
2701 *
2702 * @param pVM Pointer to the VM.
2703 */
2704VMMR3_INT_DECL(int) EMR3NotifyResume(PVM pVM)
2705{
2706 PVMCPU pVCpu = VMMGetCpu(pVM);
2707 EMSTATE enmCurState = pVCpu->em.s.enmState;
2708
2709 TMR3NotifyResume(pVM, pVCpu); /* Resume the virtual time. */
2710 pVCpu->em.s.enmState = pVCpu->em.s.enmPrevState;
2711 pVCpu->em.s.enmPrevState = enmCurState;
2712 return VINF_SUCCESS;
2713}
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