VirtualBox

source: vbox/trunk/src/VBox/VMM/include/EMInternal.h@ 77922

Last change on this file since 77922 was 76585, checked in by vboxsync, 6 years ago

*: scm --fix-header-guard-endif

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.4 KB
Line 
1/* $Id: EMInternal.h 76585 2019-01-01 06:31:29Z vboxsync $ */
2/** @file
3 * EM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2019 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#ifndef VMM_INCLUDED_SRC_include_EMInternal_h
19#define VMM_INCLUDED_SRC_include_EMInternal_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <VBox/cdefs.h>
25#include <VBox/types.h>
26#include <VBox/vmm/em.h>
27#include <VBox/vmm/stam.h>
28#include <VBox/vmm/patm.h>
29#include <VBox/dis.h>
30#include <VBox/vmm/pdmcritsect.h>
31#include <iprt/avl.h>
32#include <setjmp.h>
33
34RT_C_DECLS_BEGIN
35
36
37/** @defgroup grp_em_int Internal
38 * @ingroup grp_em
39 * @internal
40 * @{
41 */
42
43/** The saved state version. */
44#define EM_SAVED_STATE_VERSION 5
45#define EM_SAVED_STATE_VERSION_PRE_IEM 4
46#define EM_SAVED_STATE_VERSION_PRE_MWAIT 3
47#define EM_SAVED_STATE_VERSION_PRE_SMP 2
48
49
50/** @name MWait state flags.
51 * @{
52 */
53/** MWait activated. */
54#define EMMWAIT_FLAG_ACTIVE RT_BIT(0)
55/** MWait will continue when an interrupt is pending even when IF=0. */
56#define EMMWAIT_FLAG_BREAKIRQIF0 RT_BIT(1)
57/** Monitor instruction was executed previously. */
58#define EMMWAIT_FLAG_MONITOR_ACTIVE RT_BIT(2)
59/** @} */
60
61/** EM time slice in ms; used for capping execution time. */
62#define EM_TIME_SLICE 100
63
64/**
65 * Cli node structure
66 */
67typedef struct CLISTAT
68{
69 /** The key is the cli address. */
70 AVLGCPTRNODECORE Core;
71#if HC_ARCH_BITS == 32 && !defined(RT_OS_WINDOWS)
72 /** Padding. */
73 uint32_t u32Padding;
74#endif
75 /** Occurrences. */
76 STAMCOUNTER Counter;
77} CLISTAT, *PCLISTAT;
78#ifdef IN_RING3
79AssertCompileMemberAlignment(CLISTAT, Counter, 8);
80#endif
81
82
83/**
84 * Excessive (used to be) EM statistics.
85 */
86typedef struct EMSTATS
87{
88#if 1 /* rawmode only? */
89 /** @name Privileged Instructions Ending Up In HC.
90 * @{ */
91 STAMCOUNTER StatIoRestarted;
92 STAMCOUNTER StatIoIem;
93 STAMCOUNTER StatCli;
94 STAMCOUNTER StatSti;
95 STAMCOUNTER StatInvlpg;
96 STAMCOUNTER StatHlt;
97 STAMCOUNTER StatMovReadCR[DISCREG_CR4 + 1];
98 STAMCOUNTER StatMovWriteCR[DISCREG_CR4 + 1];
99 STAMCOUNTER StatMovDRx;
100 STAMCOUNTER StatIret;
101 STAMCOUNTER StatMovLgdt;
102 STAMCOUNTER StatMovLldt;
103 STAMCOUNTER StatMovLidt;
104 STAMCOUNTER StatMisc;
105 STAMCOUNTER StatSysEnter;
106 STAMCOUNTER StatSysExit;
107 STAMCOUNTER StatSysCall;
108 STAMCOUNTER StatSysRet;
109 /** @} */
110#endif
111} EMSTATS;
112/** Pointer to the excessive EM statistics. */
113typedef EMSTATS *PEMSTATS;
114
115
116/**
117 * Exit history entry.
118 *
119 * @remarks We could perhaps trim this down a little bit by assuming uFlatPC
120 * only needs 48 bits (currently true but will change) and stuffing
121 * the flags+type in the available 16 bits made available. The
122 * timestamp could likewise be shortened to accomodate the index, or
123 * we might skip the index entirely. However, since we will have to
124 * deal with 56-bit wide PC address before long, there's not point.
125 *
126 * On the upside, there are unused bits in both uFlagsAndType and the
127 * idxSlot fields if needed for anything.
128 */
129typedef struct EMEXITENTRY
130{
131 /** The flat PC (CS:EIP/RIP) address of the exit.
132 * UINT64_MAX if not available. */
133 uint64_t uFlatPC;
134 /** The EMEXIT_MAKE_FLAGS_AND_TYPE */
135 uint32_t uFlagsAndType;
136 /** The index into the exit slot hash table.
137 * UINT32_MAX if too many collisions and not entered into it. */
138 uint32_t idxSlot;
139 /** The TSC timestamp of the exit.
140 * This is 0 if not timestamped. */
141 uint64_t uTimestamp;
142} EMEXITENTRY;
143/** Pointer to an exit history entry. */
144typedef EMEXITENTRY *PEMEXITENTRY;
145/** Pointer to a const exit history entry. */
146typedef EMEXITENTRY const *PCEMEXITENTRY;
147
148
149/**
150 * Converts a EM pointer into a VM pointer.
151 * @returns Pointer to the VM structure the EM is part of.
152 * @param pEM Pointer to EM instance data.
153 */
154#define EM2VM(pEM) ( (PVM)((char*)pEM - pEM->offVM) )
155
156/**
157 * EM VM Instance data.
158 * Changes to this must checked against the padding of the cfgm union in VM!
159 */
160typedef struct EM
161{
162 /** Offset to the VM structure.
163 * See EM2VM(). */
164 RTUINT offVM;
165
166 /** Whether IEM executes everything. */
167 bool fIemExecutesAll;
168 /** Whether a triple fault triggers a guru. */
169 bool fGuruOnTripleFault;
170 /** Alignment padding. */
171 bool afPadding[6];
172
173 /** Id of the VCPU that last executed code in the recompiler. */
174 VMCPUID idLastRemCpu;
175
176#ifdef VBOX_WITH_REM
177 /** REM critical section.
178 * This protects recompiler usage
179 */
180 PDMCRITSECT CritSectREM;
181#endif
182} EM;
183/** Pointer to EM VM instance data. */
184typedef EM *PEM;
185
186
187/**
188 * EM VMCPU Instance data.
189 */
190typedef struct EMCPU
191{
192 /** Execution Manager State. */
193 EMSTATE volatile enmState;
194
195 /** The state prior to the suspending of the VM. */
196 EMSTATE enmPrevState;
197
198 /** Force raw-mode execution.
199 * This is used to prevent REM from trying to execute patch code.
200 * The flag is cleared upon entering emR3RawExecute() and updated in certain return paths. */
201 bool fForceRAW;
202
203 /** Set if hypercall instruction VMMCALL (AMD) & VMCALL (Intel) are enabled.
204 * GIM sets this and the execution managers queries it. Not saved, as GIM
205 * takes care of that bit too. */
206 bool fHypercallEnabled;
207
208 /** Explicit padding. */
209 uint8_t abPadding[2];
210
211 /** The number of instructions we've executed in IEM since switching to the
212 * EMSTATE_IEM_THEN_REM state. */
213 uint32_t cIemThenRemInstructions;
214
215 /** Inhibit interrupts for this instruction. Valid only when VM_FF_INHIBIT_INTERRUPTS is set. */
216 RTGCUINTPTR GCPtrInhibitInterrupts;
217
218#ifdef VBOX_WITH_RAW_MODE
219 /** Pointer to the PATM status structure. (R3 Ptr) */
220 R3PTRTYPE(PPATMGCSTATE) pPatmGCState;
221#else
222 RTR3PTR R3PtrPaddingNoRaw;
223#endif
224 RTR3PTR R3PtrNullPadding; /**< Used to be pCtx. */
225#if GC_ARCH_BITS == 64
226 RTGCPTR aPadding1;
227#endif
228
229 /** Start of the current time slice in ms. */
230 uint64_t u64TimeSliceStart;
231 /** Start of the current time slice in thread execution time (ms). */
232 uint64_t u64TimeSliceStartExec;
233 /** Current time slice value. */
234 uint64_t u64TimeSliceExec;
235
236 /** Pending ring-3 I/O port access (VINF_EM_PENDING_R3_IOPORT_READ / VINF_EM_PENDING_R3_IOPORT_WRITE). */
237 struct
238 {
239 RTIOPORT uPort; /**< The I/O port number.*/
240 uint8_t cbValue; /**< The value size in bytes. Zero when not pending. */
241 uint8_t cbInstr; /**< The instruction length. */
242 uint32_t uValue; /**< The value to write. */
243 } PendingIoPortAccess;
244
245 /** MWait halt state. */
246 struct
247 {
248 uint32_t fWait; /**< Type of mwait; see EMMWAIT_FLAG_*. */
249 uint32_t u32Padding;
250 RTGCPTR uMWaitRAX; /**< MWAIT hints. */
251 RTGCPTR uMWaitRCX; /**< MWAIT extensions. */
252 RTGCPTR uMonitorRAX; /**< Monitored address. */
253 RTGCPTR uMonitorRCX; /**< Monitor extension. */
254 RTGCPTR uMonitorRDX; /**< Monitor hint. */
255 } MWait;
256
257 union
258 {
259 /** Padding used in the other rings.
260 * This must be larger than jmp_buf on any supported platform. */
261 char achPaddingFatalLongJump[HC_ARCH_BITS == 32 ? 176 : 256];
262#ifdef IN_RING3
263 /** Long buffer jump for fatal VM errors.
264 * It will jump to before the outer EM loop is entered. */
265 jmp_buf FatalLongJump;
266#endif
267 } u;
268
269 /** For saving stack space, the disassembler state is allocated here instead of
270 * on the stack. */
271 DISCPUSTATE DisState;
272
273 /** @name Execution profiling.
274 * @{ */
275 STAMPROFILE StatForcedActions;
276 STAMPROFILE StatHalted;
277 STAMPROFILEADV StatCapped;
278 STAMPROFILEADV StatHMEntry;
279 STAMPROFILE StatHMExec;
280 STAMPROFILE StatIEMEmu;
281 STAMPROFILE StatIEMThenREM;
282 STAMPROFILEADV StatNEMEntry;
283 STAMPROFILE StatNEMExec;
284 STAMPROFILE StatREMEmu;
285 STAMPROFILE StatREMExec;
286 STAMPROFILE StatREMSync;
287 STAMPROFILEADV StatREMTotal;
288 STAMPROFILE StatRAWExec;
289 STAMPROFILEADV StatRAWEntry;
290 STAMPROFILEADV StatRAWTail;
291 STAMPROFILEADV StatRAWTotal;
292 STAMPROFILEADV StatTotal;
293 /** @} */
294
295 /** R3: Profiling of emR3RawExecuteIOInstruction. */
296 STAMPROFILE StatIOEmu;
297 /** R3: Profiling of emR3RawPrivileged. */
298 STAMPROFILE StatPrivEmu;
299 /** R3: Number of times emR3HmExecute is called. */
300 STAMCOUNTER StatHMExecuteCalled;
301 /** R3: Number of times emR3NEMExecute is called. */
302 STAMCOUNTER StatNEMExecuteCalled;
303
304 /** More statistics (R3). */
305 R3PTRTYPE(PEMSTATS) pStatsR3;
306 /** More statistics (R0). */
307 R0PTRTYPE(PEMSTATS) pStatsR0;
308 /** More statistics (RC). */
309 RCPTRTYPE(PEMSTATS) pStatsRC;
310#if HC_ARCH_BITS == 64
311 RTRCPTR padding0;
312#endif
313
314 /** Tree for keeping track of cli occurrences (debug only). */
315 R3PTRTYPE(PAVLGCPTRNODECORE) pCliStatTree;
316 STAMCOUNTER StatTotalClis;
317#if HC_ARCH_BITS == 32
318 uint64_t padding1;
319#endif
320
321 /** Exit history table (6KB). */
322 EMEXITENTRY aExitHistory[256];
323 /** Where to store the next exit history entry.
324 * Since aExitHistory is 256 items longs, we'll just increment this and
325 * mask it when using it. That help the readers detect whether we've
326 * wrapped around or not. */
327 uint64_t iNextExit;
328
329 /** Index into aExitRecords set by EMHistoryExec when returning to ring-3.
330 * This is UINT16_MAX if not armed. */
331 uint16_t volatile idxContinueExitRec;
332 /** Whether exit optimizations are enabled or not (in general). */
333 bool fExitOptimizationEnabled : 1;
334 /** Whether exit optimizations are enabled for ring-0 (in general). */
335 bool fExitOptimizationEnabledR0 : 1;
336 /** Whether exit optimizations are enabled for ring-0 when preemption is disabled. */
337 bool fExitOptimizationEnabledR0PreemptDisabled : 1;
338 /** Explicit padding. */
339 bool fPadding2;
340 /** Max number of instructions to execute. */
341 uint16_t cHistoryExecMaxInstructions;
342 /** Min number of instructions to execute while probing. */
343 uint16_t cHistoryProbeMinInstructions;
344 /** Max number of instructions to execute without an exit before giving up probe. */
345 uint16_t cHistoryProbeMaxInstructionsWithoutExit;
346 uint16_t uPadding3;
347 /** Number of exit records in use. */
348 uint32_t cExitRecordUsed;
349 /** Profiling the EMHistoryExec when executing (not probing). */
350 STAMPROFILE StatHistoryExec;
351 /** Number of saved exits. */
352 STAMCOUNTER StatHistoryExecSavedExits;
353 /** Number of instructions executed by EMHistoryExec. */
354 STAMCOUNTER StatHistoryExecInstructions;
355 uint64_t uPadding4;
356 /** Number of instructions executed by EMHistoryExec when probing. */
357 STAMCOUNTER StatHistoryProbeInstructions;
358 /** Number of times probing resulted in EMEXITACTION_NORMAL_PROBED. */
359 STAMCOUNTER StatHistoryProbedNormal;
360 /** Number of times probing resulted in EMEXITACTION_EXEC_WITH_MAX. */
361 STAMCOUNTER StatHistoryProbedExecWithMax;
362 /** Number of times probing resulted in ring-3 continuation. */
363 STAMCOUNTER StatHistoryProbedToRing3;
364 /** Profiling the EMHistoryExec when probing.*/
365 STAMPROFILE StatHistoryProbe;
366 /** Hit statistics for each lookup step. */
367 STAMCOUNTER aStatHistoryRecHits[16];
368 /** Type change statistics for each lookup step. */
369 STAMCOUNTER aStatHistoryRecTypeChanged[16];
370 /** Replacement statistics for each lookup step. */
371 STAMCOUNTER aStatHistoryRecReplaced[16];
372 /** New record statistics for each lookup step. */
373 STAMCOUNTER aStatHistoryRecNew[16];
374
375 /** Exit records (32KB). (Aligned on 32 byte boundrary.) */
376 EMEXITREC aExitRecords[1024];
377} EMCPU;
378/** Pointer to EM VM instance data. */
379typedef EMCPU *PEMCPU;
380
381/** @} */
382
383int emR3InitDbg(PVM pVM);
384
385int emR3HmExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone);
386VBOXSTRICTRC emR3NemExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone);
387int emR3RawExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone);
388
389EMSTATE emR3Reschedule(PVM pVM, PVMCPU pVCpu);
390int emR3ForcedActions(PVM pVM, PVMCPU pVCpu, int rc);
391VBOXSTRICTRC emR3HighPriorityPostForcedActions(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc);
392
393int emR3RawResumeHyper(PVM pVM, PVMCPU pVCpu);
394int emR3RawStep(PVM pVM, PVMCPU pVCpu);
395
396VBOXSTRICTRC emR3NemSingleInstruction(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
397
398int emR3SingleStepExecRem(PVM pVM, PVMCPU pVCpu, uint32_t cIterations);
399
400bool emR3IsExecutionAllowed(PVM pVM, PVMCPU pVCpu);
401
402VBOXSTRICTRC emR3ExecutePendingIoPortWrite(PVM pVM, PVMCPU pVCpu);
403VBOXSTRICTRC emR3ExecutePendingIoPortRead(PVM pVM, PVMCPU pVCpu);
404
405RT_C_DECLS_END
406
407#endif /* !VMM_INCLUDED_SRC_include_EMInternal_h */
408
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