VirtualBox

source: vbox/trunk/include/VBox/vmm/iem.h@ 73606

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

VMM: Nested VMX: bugref:9180 Various bits:

  • IEM: Started VMXON, VMXOFF implementation, use IEM_OPCODE_GET_NEXT_RM.
  • IEM: Fixed INVPCID C impl, removed unused IEMExecDecodedInvpcid.
  • IEM: Updated iemCImpl_load_CrX to check for CR0/CR4 fixed bits in VMX.
  • IEM: Update offModRm to reset/re-initialize where needed.
  • CPUM: Added VMX root, non-root mode and other bits and updated a few places where they're used.
  • HM: Started adding fine-grained VMX instruction failure diagnostics.
  • HM: Made VM instruction error an enum.
  • HM: Added HMVMXAll.cpp for all context VMX code.
  • Ensure building with VBOX_WITH_NESTED_HWVIRT_[SVM|VMX] does the right thing based on host CPU.
  • CPUM: Added dumping of nested-VMX CPUMCTX state.
  • HMVMXR0: Added memory operand decoding.
  • HMVMXR0: VMX instr. privilege checks (CR0/CR4 read shadows are not consulted, so we need to do them)
  • HM: Added some more bit-field representaions.
  • Recompiler: Refuse to run when in nested-VMX guest code.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.0 KB
Line 
1/** @file
2 * IEM - Interpreted Execution Manager.
3 */
4
5/*
6 * Copyright (C) 2011-2017 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___VBox_vmm_iem_h
27#define ___VBox_vmm_iem_h
28
29#include <VBox/types.h>
30#include <VBox/vmm/trpm.h>
31#include <iprt/assert.h>
32
33
34RT_C_DECLS_BEGIN
35
36/** @defgroup grp_iem The Interpreted Execution Manager API.
37 * @ingroup grp_vmm
38 * @{
39 */
40
41/** @name IEMXCPTRAISEINFO_XXX - Extra info. on a recursive exception situation.
42 *
43 * This is primarily used by HM for working around a PGM limitation (see
44 * @bugref{6607}) and special NMI/IRET handling. In the future, this may be
45 * used for diagnostics.
46 *
47 * @{
48 */
49typedef uint32_t IEMXCPTRAISEINFO;
50/** Pointer to a IEMXCPTINFO type. */
51typedef IEMXCPTRAISEINFO *PIEMXCPTRAISEINFO;
52/** No addition info. available. */
53#define IEMXCPTRAISEINFO_NONE RT_BIT_32(0)
54/** Delivery of a \#AC caused another \#AC. */
55#define IEMXCPTRAISEINFO_AC_AC RT_BIT_32(1)
56/** Delivery of a \#PF caused another \#PF. */
57#define IEMXCPTRAISEINFO_PF_PF RT_BIT_32(2)
58/** Delivery of a \#PF caused some contributory exception. */
59#define IEMXCPTRAISEINFO_PF_CONTRIBUTORY_XCPT RT_BIT_32(3)
60/** Delivery of an external interrupt caused an exception. */
61#define IEMXCPTRAISEINFO_EXT_INT_XCPT RT_BIT_32(4)
62/** Delivery of an external interrupt caused an \#PF. */
63#define IEMXCPTRAISEINFO_EXT_INT_PF RT_BIT_32(5)
64/** Delivery of a software interrupt caused an exception. */
65#define IEMXCPTRAISEINFO_SOFT_INT_XCPT RT_BIT_32(6)
66/** Delivery of an NMI caused an exception. */
67#define IEMXCPTRAISEINFO_NMI_XCPT RT_BIT_32(7)
68/** Delivery of an NMI caused a \#PF. */
69#define IEMXCPTRAISEINFO_NMI_PF RT_BIT_32(8)
70/** Can re-execute the instruction at CS:RIP. */
71#define IEMXCPTRAISEINFO_CAN_REEXEC_INSTR RT_BIT_32(9)
72/** @} */
73
74
75/** @name IEMXCPTRAISE_XXX - Ways to handle a recursive exception condition.
76 * @{ */
77typedef enum IEMXCPTRAISE
78{
79 /** Raise the current (second) exception. */
80 IEMXCPTRAISE_CURRENT_XCPT = 0,
81 /** Re-raise the previous (first) event (for HM, unused by IEM). */
82 IEMXCPTRAISE_PREV_EVENT,
83 /** Re-execute instruction at CS:RIP (for HM, unused by IEM). */
84 IEMXCPTRAISE_REEXEC_INSTR,
85 /** Raise a \#DF exception. */
86 IEMXCPTRAISE_DOUBLE_FAULT,
87 /** Raise a triple fault. */
88 IEMXCPTRAISE_TRIPLE_FAULT,
89 /** Cause a CPU hang. */
90 IEMXCPTRAISE_CPU_HANG,
91 /** Invalid sequence of events. */
92 IEMXCPTRAISE_INVALID = 0x7fffffff
93} IEMXCPTRAISE;
94/** Pointer to a IEMXCPTRAISE type. */
95typedef IEMXCPTRAISE *PIEMXCPTRAISE;
96/** @} */
97
98
99/** @name Operand or addressing mode.
100 * @{ */
101typedef uint8_t IEMMODE;
102#define IEMMODE_16BIT 0
103#define IEMMODE_32BIT 1
104#define IEMMODE_64BIT 2
105/** @} */
106
107
108/** @name IEM_XCPT_FLAGS_XXX - flags for iemRaiseXcptOrInt.
109 * @{ */
110/** CPU exception. */
111#define IEM_XCPT_FLAGS_T_CPU_XCPT RT_BIT_32(0)
112/** External interrupt (from PIC, APIC, whatever). */
113#define IEM_XCPT_FLAGS_T_EXT_INT RT_BIT_32(1)
114/** Software interrupt (int or into, not bound).
115 * Returns to the following instruction */
116#define IEM_XCPT_FLAGS_T_SOFT_INT RT_BIT_32(2)
117/** Takes an error code. */
118#define IEM_XCPT_FLAGS_ERR RT_BIT_32(3)
119/** Takes a CR2. */
120#define IEM_XCPT_FLAGS_CR2 RT_BIT_32(4)
121/** Generated by the breakpoint instruction. */
122#define IEM_XCPT_FLAGS_BP_INSTR RT_BIT_32(5)
123/** Generated by a DRx instruction breakpoint and RF should be cleared. */
124#define IEM_XCPT_FLAGS_DRx_INSTR_BP RT_BIT_32(6)
125/** Generated by the icebp instruction. */
126#define IEM_XCPT_FLAGS_ICEBP_INSTR RT_BIT_32(7)
127/** Generated by the overflow instruction. */
128#define IEM_XCPT_FLAGS_OF_INSTR RT_BIT_32(8)
129/** @} */
130
131
132/** @name IEMTARGETCPU_XXX - IEM target CPU specification.
133 *
134 * This is a gross simpliciation of CPUMMICROARCH for dealing with really old
135 * CPUs which didn't have much in the way of hinting at supported instructions
136 * and features. This slowly changes with the introduction of CPUID with the
137 * Intel Pentium.
138 *
139 * @{
140 */
141/** The dynamic target CPU mode is for getting thru the BIOS and then use
142 * the debugger or modifying instruction behaviour (e.g. HLT) to switch to a
143 * different target CPU. */
144#define IEMTARGETCPU_DYNAMIC UINT32_C(0)
145/** Intel 8086/8088. */
146#define IEMTARGETCPU_8086 UINT32_C(1)
147/** NEC V20/V30.
148 * @remarks must be between 8086 and 80186. */
149#define IEMTARGETCPU_V20 UINT32_C(2)
150/** Intel 80186/80188. */
151#define IEMTARGETCPU_186 UINT32_C(3)
152/** Intel 80286. */
153#define IEMTARGETCPU_286 UINT32_C(4)
154/** Intel 80386. */
155#define IEMTARGETCPU_386 UINT32_C(5)
156/** Intel 80486. */
157#define IEMTARGETCPU_486 UINT32_C(6)
158/** Intel Pentium . */
159#define IEMTARGETCPU_PENTIUM UINT32_C(7)
160/** Intel PentiumPro. */
161#define IEMTARGETCPU_PPRO UINT32_C(8)
162/** A reasonably current CPU, probably newer than the pentium pro when it comes
163 * to the feature set and behaviour. Generally the CPUID info and CPU vendor
164 * dicates the behaviour here. */
165#define IEMTARGETCPU_CURRENT UINT32_C(9)
166/** @} */
167
168
169/** @name IEM status codes.
170 *
171 * Not quite sure how this will play out in the end, just aliasing safe status
172 * codes for now.
173 *
174 * @{ */
175#define VINF_IEM_RAISED_XCPT VINF_EM_RESCHEDULE
176/** @} */
177
178
179/** The CPUMCTX_EXTRN_XXX mask required to be cleared when interpreting anything.
180 * IEM will ASSUME the caller of IEM APIs has ensured these are already present. */
181#define IEM_CPUMCTX_EXTRN_MUST_MASK ( CPUMCTX_EXTRN_GPRS_MASK \
182 | CPUMCTX_EXTRN_RIP \
183 | CPUMCTX_EXTRN_RFLAGS \
184 | CPUMCTX_EXTRN_SS \
185 | CPUMCTX_EXTRN_CS \
186 | CPUMCTX_EXTRN_CR0 \
187 | CPUMCTX_EXTRN_CR3 \
188 | CPUMCTX_EXTRN_CR4 \
189 | CPUMCTX_EXTRN_APIC_TPR \
190 | CPUMCTX_EXTRN_EFER \
191 | CPUMCTX_EXTRN_DR7 )
192/** The CPUMCTX_EXTRN_XXX mask needed when injecting an exception/interrupt.
193 * IEM will import missing bits, callers are encouraged to make these registers
194 * available prior to injection calls if fetching state anyway. */
195#define IEM_CPUMCTX_EXTRN_XCPT_MASK ( IEM_CPUMCTX_EXTRN_MUST_MASK \
196 | CPUMCTX_EXTRN_CR2 \
197 | CPUMCTX_EXTRN_SREG_MASK \
198 | CPUMCTX_EXTRN_TABLE_MASK )
199/** The CPUMCTX_EXTRN_XXX mask required to be cleared when calling any
200 * IEMExecDecoded API not using memory. IEM will ASSUME the caller of IEM
201 * APIs has ensured these are already present.
202 * @note ASSUMES execution engine has checked for instruction breakpoints
203 * during decoding. */
204#define IEM_CPUMCTX_EXTRN_EXEC_DECODED_NO_MEM_MASK ( CPUMCTX_EXTRN_RIP \
205 | CPUMCTX_EXTRN_RFLAGS \
206 | CPUMCTX_EXTRN_SS /* for CPL */ \
207 | CPUMCTX_EXTRN_CS /* for mode */ \
208 | CPUMCTX_EXTRN_CR0 /* for mode */ \
209 | CPUMCTX_EXTRN_EFER /* for mode */ )
210/** The CPUMCTX_EXTRN_XXX mask required to be cleared when calling any
211 * IEMExecDecoded API using memory. IEM will ASSUME the caller of IEM
212 * APIs has ensured these are already present.
213 * @note ASSUMES execution engine has checked for instruction breakpoints
214 * during decoding. */
215#define IEM_CPUMCTX_EXTRN_EXEC_DECODED_MEM_MASK ( IEM_CPUMCTX_EXTRN_EXEC_DECODED_NO_MEM_MASK \
216 | CPUMCTX_EXTRN_CR3 /* for page tables */ \
217 | CPUMCTX_EXTRN_CR4 /* for mode paging mode */ \
218 | CPUMCTX_EXTRN_DR7 /* for memory breakpoints */ )
219
220#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
221/** The CPUMCTX_EXTRN_XXX mask needed when calling IEMExecSvmVmexit().
222 * IEM will ASSUME the caller has ensured these are already present. */
223# define IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK ( CPUMCTX_EXTRN_RSP \
224 | CPUMCTX_EXTRN_RAX \
225 | CPUMCTX_EXTRN_RIP \
226 | CPUMCTX_EXTRN_RFLAGS \
227 | CPUMCTX_EXTRN_CS \
228 | CPUMCTX_EXTRN_SS \
229 | CPUMCTX_EXTRN_DS \
230 | CPUMCTX_EXTRN_ES \
231 | CPUMCTX_EXTRN_GDTR \
232 | CPUMCTX_EXTRN_IDTR \
233 | CPUMCTX_EXTRN_CR_MASK \
234 | CPUMCTX_EXTRN_EFER \
235 | CPUMCTX_EXTRN_DR6 \
236 | CPUMCTX_EXTRN_DR7 \
237 | CPUMCTX_EXTRN_OTHER_MSRS \
238 | CPUMCTX_EXTRN_HWVIRT \
239 | CPUMCTX_EXTRN_APIC_TPR \
240 | CPUMCTX_EXTRN_HM_SVM_HWVIRT_VIRQ)
241
242/** The CPUMCTX_EXTRN_XXX mask needed when calling IEMExecDecodedVmrun().
243 * IEM will ASSUME the caller has ensured these are already present. */
244# define IEM_CPUMCTX_EXTRN_SVM_VMRUN_MASK IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK
245#endif
246
247VMMDECL(VBOXSTRICTRC) IEMExecOne(PVMCPU pVCpu);
248VMMDECL(VBOXSTRICTRC) IEMExecOneEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten);
249VMMDECL(VBOXSTRICTRC) IEMExecOneWithPrefetchedByPC(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint64_t OpcodeBytesPC,
250 const void *pvOpcodeBytes, size_t cbOpcodeBytes);
251VMMDECL(VBOXSTRICTRC) IEMExecOneBypassEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten);
252VMMDECL(VBOXSTRICTRC) IEMExecOneBypassWithPrefetchedByPC(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint64_t OpcodeBytesPC,
253 const void *pvOpcodeBytes, size_t cbOpcodeBytes);
254VMMDECL(VBOXSTRICTRC) IEMExecOneBypassWithPrefetchedByPCWritten(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint64_t OpcodeBytesPC,
255 const void *pvOpcodeBytes, size_t cbOpcodeBytes,
256 uint32_t *pcbWritten);
257VMMDECL(VBOXSTRICTRC) IEMExecLots(PVMCPU pVCpu, uint32_t *pcInstructions);
258/** Statistics returned by IEMExecForExits. */
259typedef struct IEMEXECFOREXITSTATS
260{
261 uint32_t cInstructions;
262 uint32_t cExits;
263 uint32_t cMaxExitDistance;
264 uint32_t cReserved;
265} IEMEXECFOREXITSTATS;
266/** Pointer to statistics returned by IEMExecForExits. */
267typedef IEMEXECFOREXITSTATS *PIEMEXECFOREXITSTATS;
268VMMDECL(VBOXSTRICTRC) IEMExecForExits(PVMCPU pVCpu, uint32_t fWillExit, uint32_t cMinInstructions, uint32_t cMaxInstructions,
269 uint32_t cMaxInstructionsWithoutExits, PIEMEXECFOREXITSTATS pStats);
270VMMDECL(VBOXSTRICTRC) IEMInjectTrpmEvent(PVMCPU pVCpu);
271VMM_INT_DECL(VBOXSTRICTRC) IEMInjectTrap(PVMCPU pVCpu, uint8_t u8TrapNo, TRPMEVENT enmType, uint16_t uErrCode, RTGCPTR uCr2,
272 uint8_t cbInstr);
273
274VMM_INT_DECL(int) IEMBreakpointSet(PVM pVM, RTGCPTR GCPtrBp);
275VMM_INT_DECL(int) IEMBreakpointClear(PVM pVM, RTGCPTR GCPtrBp);
276
277VMM_INT_DECL(void) IEMTlbInvalidateAll(PVMCPU pVCpu, bool fVmm);
278VMM_INT_DECL(void) IEMTlbInvalidatePage(PVMCPU pVCpu, RTGCPTR GCPtr);
279VMM_INT_DECL(void) IEMTlbInvalidateAllPhysical(PVMCPU pVCpu);
280VMM_INT_DECL(bool) IEMGetCurrentXcpt(PVMCPU pVCpu, uint8_t *puVector, uint32_t *pfFlags, uint32_t *puErr,
281 uint64_t *puCr2);
282VMM_INT_DECL(IEMXCPTRAISE) IEMEvaluateRecursiveXcpt(PVMCPU pVCpu, uint32_t fPrevFlags, uint8_t uPrevVector, uint32_t fCurFlags,
283 uint8_t uCurVector, PIEMXCPTRAISEINFO pXcptRaiseInfo);
284
285/** @name Given Instruction Interpreters
286 * @{ */
287VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoWrite(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode,
288 bool fRepPrefix, uint8_t cbInstr, uint8_t iEffSeg, bool fIoChecked);
289VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoRead(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode,
290 bool fRepPrefix, uint8_t cbInstr, bool fIoChecked);
291VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedOut(PVMCPU pVCpu, uint8_t cbInstr, uint16_t u16Port, uint8_t cbReg);
292VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedIn(PVMCPU pVCpu, uint8_t cbInstr, uint16_t u16Port, uint8_t cbReg);
293VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedMovCRxWrite(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iCrReg, uint8_t iGReg);
294VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedMovCRxRead(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iGReg, uint8_t iCrReg);
295VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedClts(PVMCPU pVCpu, uint8_t cbInstr);
296VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedLmsw(PVMCPU pVCpu, uint8_t cbInstr, uint16_t uValue);
297VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedXsetbv(PVMCPU pVCpu, uint8_t cbInstr);
298VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedWbinvd(PVMCPU pVCpu, uint8_t cbInstr);
299VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedInvd(PVMCPU pVCpu, uint8_t cbInstr);
300VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedInvlpg(PVMCPU pVCpu, uint8_t cbInstr, RTGCPTR GCPtrPage);
301VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedCpuid(PVMCPU pVCpu, uint8_t cbInstr);
302VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedRdpmc(PVMCPU pVCpu, uint8_t cbInstr);
303VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedRdtsc(PVMCPU pVCpu, uint8_t cbInstr);
304VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedRdtscp(PVMCPU pVCpu, uint8_t cbInstr);
305VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedRdmsr(PVMCPU pVCpu, uint8_t cbInstr);
306VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedWrmsr(PVMCPU pVCpu, uint8_t cbInstr);
307VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedMonitor(PVMCPU pVCpu, uint8_t cbInstr);
308VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedMwait(PVMCPU pVCpu, uint8_t cbInstr);
309VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedHlt(PVMCPU pVCpu, uint8_t cbInstr);
310
311#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
312VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedClgi(PVMCPU pVCpu, uint8_t cbInstr);
313VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedStgi(PVMCPU pVCpu, uint8_t cbInstr);
314VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedVmload(PVMCPU pVCpu, uint8_t cbInstr);
315VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedVmsave(PVMCPU pVCpu, uint8_t cbInstr);
316VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedInvlpga(PVMCPU pVCpu, uint8_t cbInstr);
317VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedVmrun(PVMCPU pVCpu, uint8_t cbInstr);
318VMM_INT_DECL(VBOXSTRICTRC) IEMExecSvmVmexit(PVMCPU pVCpu, uint64_t uExitCode, uint64_t uExitInfo1, uint64_t uExitInfo2);
319#endif
320
321#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
322VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedVmxoff(PVMCPU pVCpu, uint8_t cbInstr);
323VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedVmxon(PVMCPU pVCpu, uint8_t cbInstr, RTGCPTR GCPtrVmxon, uint32_t uExitInstrInfo,
324 RTGCPTR GCPtrDisp);
325#endif
326/** @} */
327
328
329/** @defgroup grp_iem_r3 The IEM Host Context Ring-3 API.
330 * @{
331 */
332VMMR3DECL(int) IEMR3Init(PVM pVM);
333VMMR3DECL(int) IEMR3Term(PVM pVM);
334VMMR3DECL(void) IEMR3Relocate(PVM pVM);
335VMMR3_INT_DECL(VBOXSTRICTRC) IEMR3ProcessForceFlag(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rcStrict);
336/** @} */
337
338/** @} */
339
340RT_C_DECLS_END
341
342#endif
343
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