summaryrefslogtreecommitdiff
path: root/include/VBox/vmm
diff options
context:
space:
mode:
Diffstat (limited to 'include/VBox/vmm')
-rw-r--r--include/VBox/vmm/cfgm.h14
-rw-r--r--include/VBox/vmm/cpum.h354
-rw-r--r--include/VBox/vmm/cpum.mac6
-rw-r--r--include/VBox/vmm/cpumctx.h12
-rw-r--r--include/VBox/vmm/cpumdis.h2
-rw-r--r--include/VBox/vmm/csam.h264
-rw-r--r--include/VBox/vmm/dbgf.h423
-rw-r--r--include/VBox/vmm/dbgfsel.h2
-rw-r--r--include/VBox/vmm/em.h151
-rw-r--r--include/VBox/vmm/ftm.h19
-rw-r--r--include/VBox/vmm/gmm.h2
-rw-r--r--include/VBox/vmm/gvm.h2
-rw-r--r--include/VBox/vmm/gvmm.h2
-rw-r--r--include/VBox/vmm/hm.h265
-rw-r--r--include/VBox/vmm/hm_svm.h (renamed from include/VBox/vmm/hwacc_svm.h)221
-rw-r--r--include/VBox/vmm/hm_vmx.h2343
-rw-r--r--include/VBox/vmm/hm_vmx.mac (renamed from include/VBox/vmm/hwacc_vmx.mac)79
-rw-r--r--include/VBox/vmm/hwacc_vmx.h1708
-rw-r--r--include/VBox/vmm/hwaccm.h154
-rw-r--r--include/VBox/vmm/iem.h19
-rw-r--r--include/VBox/vmm/iom.h73
-rw-r--r--include/VBox/vmm/mm.h7
-rw-r--r--include/VBox/vmm/patm.h616
-rw-r--r--include/VBox/vmm/pdm.h3
-rw-r--r--include/VBox/vmm/pdmapi.h160
-rw-r--r--include/VBox/vmm/pdmasynccompletion.h232
-rw-r--r--include/VBox/vmm/pdmblkcache.h2
-rw-r--r--include/VBox/vmm/pdmcardreaderinfs.h91
-rw-r--r--include/VBox/vmm/pdmcommon.h4
-rw-r--r--include/VBox/vmm/pdmcritsect.h25
-rw-r--r--include/VBox/vmm/pdmcritsectrw.h97
-rw-r--r--include/VBox/vmm/pdmdev.h416
-rw-r--r--include/VBox/vmm/pdmdrv.h52
-rw-r--r--include/VBox/vmm/pdmifs.h145
-rw-r--r--include/VBox/vmm/pdmnetinline.h2
-rw-r--r--include/VBox/vmm/pdmnetshaper.h91
-rw-r--r--include/VBox/vmm/pdmnetshaperint.h94
-rw-r--r--include/VBox/vmm/pdmnvram.h78
-rw-r--r--include/VBox/vmm/pdmqueue.h13
-rw-r--r--include/VBox/vmm/pdmusb.h55
-rw-r--r--include/VBox/vmm/pdmwebcaminfs.h133
-rw-r--r--include/VBox/vmm/pgm.h39
-rw-r--r--include/VBox/vmm/rem.h2
-rw-r--r--include/VBox/vmm/selm.h8
-rw-r--r--include/VBox/vmm/ssm.h57
-rw-r--r--include/VBox/vmm/stam.h48
-rw-r--r--include/VBox/vmm/tm.h6
-rw-r--r--include/VBox/vmm/trpm.h22
-rw-r--r--include/VBox/vmm/uvm.h25
-rw-r--r--include/VBox/vmm/vm.h251
-rw-r--r--include/VBox/vmm/vm.mac16
-rw-r--r--include/VBox/vmm/vmapi.h233
-rw-r--r--include/VBox/vmm/vmm.h137
53 files changed, 5189 insertions, 4086 deletions
diff --git a/include/VBox/vmm/cfgm.h b/include/VBox/vmm/cfgm.h
index 9b4e47ab..dbc8e527 100644
--- a/include/VBox/vmm/cfgm.h
+++ b/include/VBox/vmm/cfgm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -74,19 +74,20 @@ typedef enum CFGMCONFIGTYPE
* can make any necessary per-thread initializations at this point.
*
* @returns VBox status code.
- * @param pVM VM handle.
+ * @param pUVM The user mode VM handle.
+ * @param pVM The shared VM handle.
* @param pvUser The argument supplied to VMR3Create().
*/
-typedef DECLCALLBACK(int) FNCFGMCONSTRUCTOR(PVM pVM, void *pvUser);
+typedef DECLCALLBACK(int) FNCFGMCONSTRUCTOR(PUVM pUVM, PVM pVM, void *pvUser);
/** Pointer to a FNCFGMCONSTRUCTOR(). */
typedef FNCFGMCONSTRUCTOR *PFNCFGMCONSTRUCTOR;
VMMR3DECL(int) CFGMR3Init(PVM pVM, PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUser);
VMMR3DECL(int) CFGMR3Term(PVM pVM);
-
-
-VMMR3DECL(PCFGMNODE) CFGMR3CreateTree(PVM pVM);
VMMR3DECL(int) CFGMR3ConstructDefaultTree(PVM pVM);
+
+VMMR3DECL(PCFGMNODE) CFGMR3CreateTree(PUVM pUVM);
+VMMR3DECL(int) CFGMR3DestroyTree(PCFGMNODE pRoot);
VMMR3DECL(void) CFGMR3Dump(PCFGMNODE pRoot);
VMMR3DECL(int) CFGMR3DuplicateSubTree(PCFGMNODE pRoot, PCFGMNODE *ppCopy);
VMMR3DECL(int) CFGMR3ReplaceSubTree(PCFGMNODE pRoot, PCFGMNODE pNewRoot);
@@ -185,6 +186,7 @@ VMMR3DECL(int) CFGMR3QueryStringAllocDef(PCFGMNODE pNode, const char *p
* @{
*/
VMMR3DECL(PCFGMNODE) CFGMR3GetRoot(PVM pVM);
+VMMR3DECL(PCFGMNODE) CFGMR3GetRootU(PUVM pUVM);
VMMR3DECL(PCFGMNODE) CFGMR3GetParent(PCFGMNODE pNode);
VMMR3DECL(PCFGMNODE) CFGMR3GetParentEx(PVM pVM, PCFGMNODE pNode);
VMMR3DECL(PCFGMNODE) CFGMR3GetChild(PCFGMNODE pNode, const char *pszPath);
diff --git a/include/VBox/vmm/cpum.h b/include/VBox/vmm/cpum.h
index 0b4abf33..d3ca4c02 100644
--- a/include/VBox/vmm/cpum.h
+++ b/include/VBox/vmm/cpum.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -77,13 +77,259 @@ typedef enum CPUMCPUVENDOR
CPUMCPUVENDOR_INTEL,
CPUMCPUVENDOR_AMD,
CPUMCPUVENDOR_VIA,
+ CPUMCPUVENDOR_CYRIX,
CPUMCPUVENDOR_UNKNOWN,
- CPUMCPUVENDOR_SYNTHETIC,
/** 32bit hackishness. */
CPUMCPUVENDOR_32BIT_HACK = 0x7fffffff
} CPUMCPUVENDOR;
+/**
+ * X86 and AMD64 CPU microarchitectures and in processor generations.
+ *
+ * @remarks The separation here is sometimes a little bit too finely grained,
+ * and the differences is more like processor generation than micro
+ * arch. This can be useful, so we'll provide functions for getting at
+ * more coarse grained info.
+ */
+typedef enum CPUMMICROARCH
+{
+ kCpumMicroarch_Invalid = 0,
+
+ kCpumMicroarch_Intel_First,
+
+ kCpumMicroarch_Intel_8086 = kCpumMicroarch_Intel_First,
+ kCpumMicroarch_Intel_80186,
+ kCpumMicroarch_Intel_80286,
+ kCpumMicroarch_Intel_80386,
+ kCpumMicroarch_Intel_80486,
+ kCpumMicroarch_Intel_P5,
+
+ kCpumMicroarch_Intel_P6_Core_Atom_First,
+ kCpumMicroarch_Intel_P6 = kCpumMicroarch_Intel_P6_Core_Atom_First,
+ kCpumMicroarch_Intel_P6_II,
+ kCpumMicroarch_Intel_P6_III,
+
+ kCpumMicroarch_Intel_P6_M_Banias,
+ kCpumMicroarch_Intel_P6_M_Dothan,
+ kCpumMicroarch_Intel_Core_Yonah, /**< Core, also known as Enhanced Pentium M. */
+
+ kCpumMicroarch_Intel_Core2_First,
+ kCpumMicroarch_Intel_Core2_Merom = kCpumMicroarch_Intel_Core2_First,
+ kCpumMicroarch_Intel_Core2_Penryn,
+
+ kCpumMicroarch_Intel_Core7_First,
+ kCpumMicroarch_Intel_Core7_Nehalem = kCpumMicroarch_Intel_Core7_First,
+ kCpumMicroarch_Intel_Core7_Westmere,
+ kCpumMicroarch_Intel_Core7_SandyBridge,
+ kCpumMicroarch_Intel_Core7_IvyBridge,
+ kCpumMicroarch_Intel_Core7_Haswell,
+ kCpumMicroarch_Intel_Core7_Broadwell,
+ kCpumMicroarch_Intel_Core7_Skylake,
+ kCpumMicroarch_Intel_Core7_Cannonlake,
+ kCpumMicroarch_Intel_Core7_End,
+
+ kCpumMicroarch_Intel_Atom_First,
+ kCpumMicroarch_Intel_Atom_Bonnell = kCpumMicroarch_Intel_Atom_First,
+ kCpumMicroarch_Intel_Atom_Lincroft, /**< Second generation bonnell (44nm). */
+ kCpumMicroarch_Intel_Atom_Saltwell, /**< 32nm shrink of Bonnell. */
+ kCpumMicroarch_Intel_Atom_Silvermont, /**< 22nm */
+ kCpumMicroarch_Intel_Atom_Airmount, /**< 14nm */
+ kCpumMicroarch_Intel_Atom_Goldmont, /**< 14nm */
+ kCpumMicroarch_Intel_Atom_Unknown,
+ kCpumMicroarch_Intel_Atom_End,
+
+ kCpumMicroarch_Intel_P6_Core_Atom_End,
+
+ kCpumMicroarch_Intel_NB_First,
+ kCpumMicroarch_Intel_NB_Willamette = kCpumMicroarch_Intel_NB_First, /**< 180nm */
+ kCpumMicroarch_Intel_NB_Northwood, /**< 130nm */
+ kCpumMicroarch_Intel_NB_Prescott, /**< 90nm */
+ kCpumMicroarch_Intel_NB_Prescott2M, /**< 90nm */
+ kCpumMicroarch_Intel_NB_CedarMill, /**< 65nm */
+ kCpumMicroarch_Intel_NB_Gallatin, /**< 90nm Xeon, Pentium 4 Extreme Edition ("Emergency Edition"). */
+ kCpumMicroarch_Intel_NB_Unknown,
+ kCpumMicroarch_Intel_NB_End,
+
+ kCpumMicroarch_Intel_Unknown,
+ kCpumMicroarch_Intel_End,
+
+ kCpumMicroarch_AMD_First,
+ kCpumMicroarch_AMD_Am286 = kCpumMicroarch_AMD_First,
+ kCpumMicroarch_AMD_Am386,
+ kCpumMicroarch_AMD_Am486,
+ kCpumMicroarch_AMD_Am486Enh, /**< Covers Am5x86 as well. */
+ kCpumMicroarch_AMD_K5,
+ kCpumMicroarch_AMD_K6,
+
+ kCpumMicroarch_AMD_K7_First,
+ kCpumMicroarch_AMD_K7_Palomino = kCpumMicroarch_AMD_K7_First,
+ kCpumMicroarch_AMD_K7_Spitfire,
+ kCpumMicroarch_AMD_K7_Thunderbird,
+ kCpumMicroarch_AMD_K7_Morgan,
+ kCpumMicroarch_AMD_K7_Thoroughbred,
+ kCpumMicroarch_AMD_K7_Barton,
+ kCpumMicroarch_AMD_K7_Unknown,
+ kCpumMicroarch_AMD_K7_End,
+
+ kCpumMicroarch_AMD_K8_First,
+ kCpumMicroarch_AMD_K8_130nm = kCpumMicroarch_AMD_K8_First, /**< 130nm Clawhammer, Sledgehammer, Newcastle, Paris, Odessa, Dublin */
+ kCpumMicroarch_AMD_K8_90nm, /**< 90nm shrink */
+ kCpumMicroarch_AMD_K8_90nm_DualCore, /**< 90nm with two cores. */
+ kCpumMicroarch_AMD_K8_90nm_AMDV, /**< 90nm with AMD-V (usually) and two cores (usually). */
+ kCpumMicroarch_AMD_K8_65nm, /**< 65nm shrink. */
+ kCpumMicroarch_AMD_K8_End,
+
+ kCpumMicroarch_AMD_K10,
+ kCpumMicroarch_AMD_K10_Lion,
+ kCpumMicroarch_AMD_K10_Llano,
+ kCpumMicroarch_AMD_Bobcat,
+ kCpumMicroarch_AMD_Jaguar,
+
+ kCpumMicroarch_AMD_15h_First,
+ kCpumMicroarch_AMD_15h_Bulldozer = kCpumMicroarch_AMD_15h_First,
+ kCpumMicroarch_AMD_15h_Piledriver,
+ kCpumMicroarch_AMD_15h_Steamroller, /**< Yet to be released, might have different family. */
+ kCpumMicroarch_AMD_15h_Excavator, /**< Yet to be released, might have different family. */
+ kCpumMicroarch_AMD_15h_Unknown,
+ kCpumMicroarch_AMD_15h_End,
+
+ kCpumMicroarch_AMD_16h_First,
+ kCpumMicroarch_AMD_16h_End,
+
+ kCpumMicroarch_AMD_Unknown,
+ kCpumMicroarch_AMD_End,
+
+ kCpumMicroarch_VIA_First,
+ kCpumMicroarch_Centaur_C6 = kCpumMicroarch_VIA_First,
+ kCpumMicroarch_Centaur_C2,
+ kCpumMicroarch_Centaur_C3,
+ kCpumMicroarch_VIA_C3_M2,
+ kCpumMicroarch_VIA_C3_C5A, /**< 180nm Samuel - Cyrix III, C3, 1GigaPro. */
+ kCpumMicroarch_VIA_C3_C5B, /**< 150nm Samuel 2 - Cyrix III, C3, 1GigaPro, Eden ESP, XP 2000+. */
+ kCpumMicroarch_VIA_C3_C5C, /**< 130nm Ezra - C3, Eden ESP. */
+ kCpumMicroarch_VIA_C3_C5N, /**< 130nm Ezra-T - C3. */
+ kCpumMicroarch_VIA_C3_C5XL, /**< 130nm Nehemiah - C3, Eden ESP, Eden-N. */
+ kCpumMicroarch_VIA_C3_C5P, /**< 130nm Nehemiah+ - C3. */
+ kCpumMicroarch_VIA_C7_C5J, /**< 90nm Esther - C7, C7-D, C7-M, Eden, Eden ULV. */
+ kCpumMicroarch_VIA_Isaiah,
+ kCpumMicroarch_VIA_Unknown,
+ kCpumMicroarch_VIA_End,
+
+ kCpumMicroarch_Cyrix_First,
+ kCpumMicroarch_Cyrix_5x86 = kCpumMicroarch_Cyrix_First,
+ kCpumMicroarch_Cyrix_M1,
+ kCpumMicroarch_Cyrix_MediaGX,
+ kCpumMicroarch_Cyrix_MediaGXm,
+ kCpumMicroarch_Cyrix_M2,
+ kCpumMicroarch_Cyrix_Unknown,
+ kCpumMicroarch_Cyrix_End,
+
+ kCpumMicroarch_Unknown,
+
+ kCpumMicroarch_32BitHack = 0x7fffffff
+} CPUMMICROARCH;
+
+
+/** Predicate macro for catching netburst CPUs. */
+#define CPUMMICROARCH_IS_INTEL_NETBURST(a_enmMicroarch) \
+ ((a_enmMicroarch) >= kCpumMicroarch_Intel_NB_First && (a_enmMicroarch) <= kCpumMicroarch_Intel_NB_End)
+
+/** Predicate macro for catching Core7 CPUs. */
+#define CPUMMICROARCH_IS_INTEL_CORE7(a_enmMicroarch) \
+ ((a_enmMicroarch) >= kCpumMicroarch_Intel_Core7_First && (a_enmMicroarch) <= kCpumMicroarch_Intel_Core7_End)
+
+/** Predicate macro for catching AMD Family OFh CPUs (aka K8). */
+#define CPUMMICROARCH_IS_AMD_FAM_0FH(a_enmMicroarch) \
+ ((a_enmMicroarch) >= kCpumMicroarch_AMD_K8_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_K8_End)
+
+/** Predicate macro for catching AMD Family 10H CPUs (aka K10). */
+#define CPUMMICROARCH_IS_AMD_FAM_10H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10)
+
+/** Predicate macro for catching AMD Family 11H CPUs (aka Lion). */
+#define CPUMMICROARCH_IS_AMD_FAM_11H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10_Lion)
+
+/** Predicate macro for catching AMD Family 12H CPUs (aka Llano). */
+#define CPUMMICROARCH_IS_AMD_FAM_12H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10_Llano)
+
+/** Predicate macro for catching AMD Family 14H CPUs (aka Bobcat). */
+#define CPUMMICROARCH_IS_AMD_FAM_14H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_Bobcat)
+
+/** Predicate macro for catching AMD Family 15H CPUs (bulldozer and it's
+ * decendants). */
+#define CPUMMICROARCH_IS_AMD_FAM_15H(a_enmMicroarch) \
+ ((a_enmMicroarch) >= kCpumMicroarch_AMD_15h_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_15h_End)
+
+/** Predicate macro for catching AMD Family 16H CPUs. */
+#define CPUMMICROARCH_IS_AMD_FAM_16H(a_enmMicroarch) \
+ ((a_enmMicroarch) >= kCpumMicroarch_AMD_16h_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_16h_End)
+
+
+
+/**
+ * CPUID leaf.
+ */
+typedef struct CPUMCPUIDLEAF
+{
+ /** The leaf number. */
+ uint32_t uLeaf;
+ /** The sub-leaf number. */
+ uint32_t uSubLeaf;
+ /** Sub-leaf mask. This is 0 when sub-leaves aren't used. */
+ uint32_t fSubLeafMask;
+
+ /** The EAX value. */
+ uint32_t uEax;
+ /** The EBX value. */
+ uint32_t uEbx;
+ /** The ECX value. */
+ uint32_t uEcx;
+ /** The EDX value. */
+ uint32_t uEdx;
+
+ /** Flags. */
+ uint32_t fFlags;
+} CPUMCPUIDLEAF;
+/** Pointer to a CPUID leaf. */
+typedef CPUMCPUIDLEAF *PCPUMCPUIDLEAF;
+/** Pointer to a const CPUID leaf. */
+typedef CPUMCPUIDLEAF const *PCCPUMCPUIDLEAF;
+
+/** @name CPUMCPUIDLEAF::fFlags
+ * @{ */
+/** Indicates that ECX (the sub-leaf indicator) doesn't change when
+ * requesting the final leaf and all undefined leaves that follows it.
+ * Observed for 0x0000000b on Intel. */
+#define CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED RT_BIT_32(0)
+/** @} */
+
+/**
+ * Method used to deal with unknown CPUID leafs.
+ */
+typedef enum CPUMUKNOWNCPUID
+{
+ /** Invalid zero value. */
+ CPUMUKNOWNCPUID_INVALID = 0,
+ /** Use given default values (DefCpuId). */
+ CPUMUKNOWNCPUID_DEFAULTS,
+ /** Return the last standard leaf.
+ * Intel Sandy Bridge has been observed doing this. */
+ CPUMUKNOWNCPUID_LAST_STD_LEAF,
+ /** Return the last standard leaf, with ecx observed.
+ * Intel Sandy Bridge has been observed doing this. */
+ CPUMUKNOWNCPUID_LAST_STD_LEAF_WITH_ECX,
+ /** The register values are passed thru unmodified. */
+ CPUMUKNOWNCPUID_PASSTHRU,
+ /** End of valid value. */
+ CPUMUKNOWNCPUID_END,
+ /** Ensure 32-bit type. */
+ CPUMUKNOWNCPUID_32BIT_HACK = 0x7fffffff
+} CPUMUKNOWNCPUID;
+/** Pointer to unknown CPUID leaf method. */
+typedef CPUMUKNOWNCPUID *PCPUMUKNOWNCPUID;
+
+
+
/** @name Guest Register Getters.
* @{ */
VMMDECL(void) CPUMGetGuestGDTR(PVMCPU pVCpu, PVBOXGDTR pGDTR);
@@ -172,6 +418,8 @@ VMMDECL(bool) CPUMGetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeatur
VMMDECL(void) CPUMSetGuestCtx(PVMCPU pVCpu, const PCPUMCTX pCtx);
VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenCsAndSs(PVMCPU pVCpu);
VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenSelectorReg(PVMCPU pVCpu, PCPUMSELREG pSReg);
+VMMR0_INT_DECL(void) CPUMR0SetGuestTscAux(PVMCPU pVCpu, uint64_t uValue);
+VMMR0_INT_DECL(uint64_t) CPUMR0GetGuestTscAux(PVMCPU pVCpu);
/** @} */
@@ -215,7 +463,18 @@ DECLINLINE(bool) CPUMIsGuestInRealModeEx(PCPUMCTX pCtx)
DECLINLINE(bool) CPUMIsGuestInRealOrV86ModeEx(PCPUMCTX pCtx)
{
return !(pCtx->cr0 & X86_CR0_PE)
- || pCtx->eflags.Bits.u1VM; /** @todo verify that this cannot be set in long mode. */
+ || pCtx->eflags.Bits.u1VM; /* Cannot be set in long mode. Intel spec 2.3.1 "System Flags and Fields in IA-32e Mode". */
+}
+
+/**
+ * Tests if the guest is running in virtual 8086 mode.
+ *
+ * @returns @c true if it is, @c false if not.
+ * @param pCtx Current CPU context
+ */
+DECLINLINE(bool) CPUMIsGuestInV86ModeEx(PCPUMCTX pCtx)
+{
+ return (pCtx->eflags.Bits.u1VM == 1);
}
/**
@@ -259,6 +518,17 @@ DECLINLINE(bool) CPUMIsGuestIn64BitCodeEx(PCPUMCTX pCtx)
}
/**
+ * Tests if the guest has paging enabled or not.
+ *
+ * @returns true if paging is enabled, otherwise false.
+ * @param pCtx Current CPU context
+ */
+DECLINLINE(bool) CPUMIsGuestPagingEnabledEx(PCPUMCTX pCtx)
+{
+ return !!(pCtx->cr0 & X86_CR0_PG);
+}
+
+/**
* Tests if the guest is running in PAE mode or not.
*
* @returns true if in PAE mode, otherwise false.
@@ -266,9 +536,11 @@ DECLINLINE(bool) CPUMIsGuestIn64BitCodeEx(PCPUMCTX pCtx)
*/
DECLINLINE(bool) CPUMIsGuestInPAEModeEx(PCPUMCTX pCtx)
{
- return ( (pCtx->cr4 & X86_CR4_PAE)
- && CPUMIsGuestInPagedProtectedModeEx(pCtx)
- && !CPUMIsGuestInLongModeEx(pCtx));
+ /* Intel mentions EFER.LMA and EFER.LME in different parts of their spec. We shall use EFER.LMA rather
+ than EFER.LME as it reflects if the CPU has entered paging with EFER.LME set. */
+ return ( (pCtx->cr4 & X86_CR4_PAE)
+ && CPUMIsGuestPagingEnabledEx(pCtx)
+ && !(pCtx->msrEFER & MSR_K6_EFER_LMA));
}
#endif /* VBOX_WITHOUT_UNNAMED_UNIONS */
@@ -341,7 +613,7 @@ VMMDECL(void) CPUMSetHyperDR3(PVMCPU pVCpu, RTGCUINTREG uDr3);
VMMDECL(void) CPUMSetHyperDR6(PVMCPU pVCpu, RTGCUINTREG uDr6);
VMMDECL(void) CPUMSetHyperDR7(PVMCPU pVCpu, RTGCUINTREG uDr7);
VMMDECL(void) CPUMSetHyperCtx(PVMCPU pVCpu, const PCPUMCTX pCtx);
-VMMDECL(int) CPUMRecalcHyperDRx(PVMCPU pVCpu);
+VMMDECL(int) CPUMRecalcHyperDRx(PVMCPU pVCpu, uint8_t iGstReg, bool fForceHyper);
/** @} */
VMMDECL(void) CPUMPushHyper(PVMCPU pVCpu, uint32_t u32);
@@ -350,11 +622,10 @@ VMMDECL(PCPUMCTX) CPUMGetHyperCtxPtr(PVMCPU pVCpu);
VMMDECL(PCCPUMCTXCORE) CPUMGetHyperCtxCore(PVMCPU pVCpu);
VMMDECL(PCPUMCTX) CPUMQueryGuestCtxPtr(PVMCPU pVCpu);
VMMDECL(PCCPUMCTXCORE) CPUMGetGuestCtxCore(PVMCPU pVCpu);
-VMMR3DECL(int) CPUMR3RawEnter(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
-VMMR3DECL(int) CPUMR3RawLeave(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, int rc);
+VMM_INT_DECL(int) CPUMRawEnter(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
+VMM_INT_DECL(int) CPUMRawLeave(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, int rc);
VMMDECL(uint32_t) CPUMRawGetEFlags(PVMCPU pVCpu);
VMMDECL(void) CPUMRawSetEFlags(PVMCPU pVCpu, uint32_t fEfl);
-VMMDECL(int) CPUMHandleLazyFPU(PVMCPU pVCpu);
/** @name Changed flags.
* These flags are used to keep track of which important register that
@@ -394,16 +665,32 @@ VMMR3DECL(void) CPUMR3RemLeave(PVMCPU pVCpu, bool fNoOutOfSyncSels);
VMMDECL(bool) CPUMSupportsFXSR(PVM pVM);
VMMDECL(bool) CPUMIsHostUsingSysEnter(PVM pVM);
VMMDECL(bool) CPUMIsHostUsingSysCall(PVM pVM);
-VMMDECL(bool) CPUMIsGuestFPUStateActive(PVMCPU pVCPU);
+VMMDECL(bool) CPUMIsGuestFPUStateActive(PVMCPU pVCpu);
VMMDECL(void) CPUMDeactivateGuestFPUState(PVMCPU pVCpu);
VMMDECL(bool) CPUMIsGuestDebugStateActive(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestDebugStateActivePending(PVMCPU pVCpu);
VMMDECL(void) CPUMDeactivateGuestDebugState(PVMCPU pVCpu);
VMMDECL(bool) CPUMIsHyperDebugStateActive(PVMCPU pVCpu);
-VMMDECL(void) CPUMDeactivateHyperDebugState(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsHyperDebugStateActivePending(PVMCPU pVCpu);
VMMDECL(uint32_t) CPUMGetGuestCPL(PVMCPU pVCpu);
VMMDECL(CPUMMODE) CPUMGetGuestMode(PVMCPU pVCpu);
VMMDECL(uint32_t) CPUMGetGuestCodeBits(PVMCPU pVCpu);
VMMDECL(DISCPUMODE) CPUMGetGuestDisMode(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestScalableBusFrequency(PVM pVM);
+
+/** @name Typical scalable bus frequency values.
+ * @{ */
+/** Special internal value indicating that we don't know the frequency.
+ * @internal */
+#define CPUM_SBUSFREQ_UNKNOWN UINT64_C(1)
+#define CPUM_SBUSFREQ_100MHZ UINT64_C(100000000)
+#define CPUM_SBUSFREQ_133MHZ UINT64_C(133333333)
+#define CPUM_SBUSFREQ_167MHZ UINT64_C(166666666)
+#define CPUM_SBUSFREQ_200MHZ UINT64_C(200000000)
+#define CPUM_SBUSFREQ_267MHZ UINT64_C(266666666)
+#define CPUM_SBUSFREQ_333MHZ UINT64_C(333333333)
+#define CPUM_SBUSFREQ_400MHZ UINT64_C(400000000)
+/** @} */
#ifdef IN_RING3
@@ -413,10 +700,12 @@ VMMDECL(DISCPUMODE) CPUMGetGuestDisMode(PVMCPU pVCpu);
*/
VMMR3DECL(int) CPUMR3Init(PVM pVM);
+VMMR3DECL(int) CPUMR3InitCompleted(PVM pVM);
+VMMR3DECL(void) CPUMR3LogCpuIds(PVM pVM);
VMMR3DECL(void) CPUMR3Relocate(PVM pVM);
VMMR3DECL(int) CPUMR3Term(PVM pVM);
VMMR3DECL(void) CPUMR3Reset(PVM pVM);
-VMMR3DECL(void) CPUMR3ResetCpu(PVMCPU pVCpu);
+VMMR3DECL(void) CPUMR3ResetCpu(PVM pVM, PVMCPU pVCpu);
VMMDECL(bool) CPUMR3IsStateRestorePending(PVM pVM);
VMMR3DECL(void) CPUMR3SetHWVirtEx(PVM pVM, bool fHWVirtExEnabled);
VMMR3DECL(int) CPUMR3SetCR4Feature(PVM pVM, RTHCUINTREG fOr, RTHCUINTREG fAnd);
@@ -425,6 +714,15 @@ VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdExtRCPtr(PVM pVM);
VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdCentaurRCPtr(PVM pVM);
VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdDefRCPtr(PVM pVM);
+VMMR3DECL(CPUMMICROARCH) CPUMR3CpuIdDetermineMicroarchEx(CPUMCPUVENDOR enmVendor, uint8_t bFamily,
+ uint8_t bModel, uint8_t bStepping);
+VMMR3DECL(const char *) CPUMR3MicroarchName(CPUMMICROARCH enmMicroarch);
+VMMR3DECL(int) CPUMR3CpuIdCollectLeaves(PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves);
+VMMR3DECL(int) CPUMR3CpuIdDetectUnknownLeafMethod(PCPUMUKNOWNCPUID penmUnknownMethod, PCPUMCPUID pDefUnknown);
+VMMR3DECL(const char *) CPUMR3CpuIdUnknownLeafMethodName(CPUMUKNOWNCPUID enmUnknownMethod);
+VMMR3DECL(CPUMCPUVENDOR) CPUMR3CpuIdDetectVendorEx(uint32_t uEAX, uint32_t uEBX, uint32_t uECX, uint32_t uEDX);
+VMMR3DECL(const char *) CPUMR3CpuVendorName(CPUMCPUVENDOR enmVendor);
+
/** @} */
#endif /* IN_RING3 */
@@ -459,6 +757,12 @@ DECLASM(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint3
*/
DECLASM(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame);
+VMMDECL(int) CPUMHandleLazyFPU(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+#ifdef VBOX_WITH_RAW_RING1
+VMMDECL(void) CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
+#endif
+
/** @} */
#endif /* IN_RC */
@@ -467,18 +771,20 @@ DECLASM(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame);
* @ingroup grp_cpum
* @{
*/
-VMMR0DECL(int) CPUMR0ModuleInit(void);
-VMMR0DECL(int) CPUMR0ModuleTerm(void);
-VMMR0DECL(int) CPUMR0Init(PVM pVM);
-VMMR0DECL(int) CPUMR0LoadGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-VMMR0DECL(int) CPUMR0SaveGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-VMMR0DECL(int) CPUMR0SaveGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6);
-VMMR0DECL(int) CPUMR0LoadGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6);
-VMMR0DECL(int) CPUMR0LoadHostDebugState(PVM pVM, PVMCPU pVCpu);
-VMMR0DECL(int) CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu);
-VMMR0DECL(int) CPUMR0LoadHyperDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6);
+VMMR0_INT_DECL(int) CPUMR0ModuleInit(void);
+VMMR0_INT_DECL(int) CPUMR0ModuleTerm(void);
+VMMR0_INT_DECL(int) CPUMR0InitVM(PVM pVM);
+VMMR0_INT_DECL(int) CPUMR0Trap07Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR0_INT_DECL(int) CPUMR0LoadGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR0_INT_DECL(int) CPUMR0SaveGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR0_INT_DECL(int) CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu);
+VMMR0_INT_DECL(bool) CPUMR0DebugStateMaybeSaveGuestAndRestoreHost(PVMCPU pVCpu, bool fDr6);
+VMMR0_INT_DECL(bool) CPUMR0DebugStateMaybeSaveGuest(PVMCPU pVCpu, bool fDr6);
+
+VMMR0_INT_DECL(void) CPUMR0LoadGuestDebugState(PVMCPU pVCpu, bool fDr6);
+VMMR0_INT_DECL(void) CPUMR0LoadHyperDebugState(PVMCPU pVCpu, bool fDr6);
#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
-VMMR0DECL(void) CPUMR0SetLApic(PVM pVM, RTCPUID idHostCpu);
+VMMR0_INT_DECL(void) CPUMR0SetLApic(PVMCPU pVCpu, RTCPUID idHostCpu);
#endif
/** @} */
diff --git a/include/VBox/vmm/cpum.mac b/include/VBox/vmm/cpum.mac
index 8f906d06..48d3eb70 100644
--- a/include/VBox/vmm/cpum.mac
+++ b/include/VBox/vmm/cpum.mac
@@ -3,7 +3,7 @@
;
;
-; Copyright (C) 2006-2010 Oracle Corporation
+; Copyright (C) 2006-2012 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
@@ -193,7 +193,8 @@ struc CPUMCTX
.msrCSTAR resb 8
.msrSFMASK resb 8
.msrKERNELGSBASE resb 8
- .au32SizePadding resb 32
+ .msrApicBase resb 8
+ .au32SizePadding resb 24
endstruc
@@ -205,3 +206,4 @@ endstruc
%endif
+
diff --git a/include/VBox/vmm/cpumctx.h b/include/VBox/vmm/cpumctx.h
index 35861823..c4c9df3b 100644
--- a/include/VBox/vmm/cpumctx.h
+++ b/include/VBox/vmm/cpumctx.h
@@ -135,7 +135,8 @@ typedef struct CPUMSYSENTER
/**
* CPU context core.
*
- * @todo eliminate this structure!
+ * @todo Eliminate this structure!
+ * @deprecated We don't push any context cores any more in TRPM.
*/
#pragma pack(1)
typedef struct CPUMCTXCORE
@@ -399,10 +400,11 @@ typedef struct CPUMCTX
uint64_t msrCSTAR; /**< Compatibility mode syscall rip. */
uint64_t msrSFMASK; /**< syscall flag mask. */
uint64_t msrKERNELGSBASE; /**< swapgs exchange value. */
+ uint64_t msrApicBase; /**< The local APIC base (IA32_APIC_BASE MSR). */
/** @} */
/** Size padding. */
- uint32_t au32SizePadding[8];
+ uint32_t au32SizePadding[6];
} CPUMCTX;
#pragma pack()
@@ -414,6 +416,11 @@ typedef struct CPUMCTX
# define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->rax)
/**
+ * Gets the CPUMCTXCORE part of a CPUMCTX.
+ */
+# define CPUMCTX_FROM_CORE(a_pCtxCore) RT_FROM_MEMBER(a_pCtxCore, CPUMCTX, rax)
+
+/**
* Gets the first selector register of a CPUMCTX.
*
* Use this with X86_SREG_COUNT to loop thru the selector registers.
@@ -446,6 +453,7 @@ typedef union CPUMCTXMSRS
uint64_t MtrrFix4K_E8000; /**< IA32_MTRR_FIX4K_E8000 */
uint64_t MtrrFix4K_F0000; /**< IA32_MTRR_FIX4K_F0000 */
uint64_t MtrrFix4K_F8000; /**< IA32_MTRR_FIX4K_F8000 */
+ uint64_t PkgCStateCfgCtrl; /**< MSR_PKG_CST_CONFIG_CONTROL */
} msr;
uint64_t au64[64];
} CPUMCTXMSRS;
diff --git a/include/VBox/vmm/cpumdis.h b/include/VBox/vmm/cpumdis.h
index 9aa509a3..dab556a8 100644
--- a/include/VBox/vmm/cpumdis.h
+++ b/include/VBox/vmm/cpumdis.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/include/VBox/vmm/csam.h b/include/VBox/vmm/csam.h
index 675cac7f..99a68563 100644
--- a/include/VBox/vmm/csam.h
+++ b/include/VBox/vmm/csam.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -28,13 +28,14 @@
#include <VBox/types.h>
+#if defined(VBOX_WITH_RAW_MODE) || defined(DOXYGEN_RUNNING)
/** @defgroup grp_csam The Code Scanning and Analysis API
* @{
*/
/**
- * CSAM monitoring tag
+ * CSAM monitoring tag.
* For use with CSAMR3MonitorPage
*/
typedef enum CSAMTAG
@@ -51,98 +52,22 @@ RT_C_DECLS_BEGIN
/**
- * Check if this page needs to be analysed by CSAM.
- *
- * This function should only be called for supervisor pages and
- * only when CSAM is enabled. Leaving these selection criteria
- * to the caller simplifies the interface (PTE passing).
- *
- * Note the the page has not yet been synced, so the TLB trick
- * (which wasn't ever active anyway) cannot be applied.
- *
- * @returns true if the page should be marked not present because
- * CSAM want need to scan it.
- * @returns false if the page was already scanned.
- * @param pVM The VM to operate on.
- * @param GCPtr GC pointer of page table entry
- */
-VMMDECL(bool) CSAMDoesPageNeedScanning(PVM pVM, RTRCUINTPTR GCPtr);
-
-/**
- * Check if this page was previously scanned by CSAM
- *
- * @returns true -> scanned, false -> not scanned
- * @param pVM The VM to operate on.
- * @param pPage GC page address
- */
-VMMDECL(bool) CSAMIsPageScanned(PVM pVM, RTRCPTR pPage);
-
-/**
- * Mark a page as scanned/not scanned
- *
- * @note: we always mark it as scanned, even if we haven't completely done so
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pPage GC page address (not necessarily aligned)
- * @param fScanned Mark as scanned or not scanned
- *
- */
-VMMDECL(int) CSAMMarkPage(PVM pVM, RTRCUINTPTR pPage, bool fScanned);
-
-
-/**
- * Remember a possible code page for later inspection
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param GCPtr GC pointer of page
- */
-VMMDECL(void) CSAMMarkPossibleCodePage(PVM pVM, RTRCPTR GCPtr);
-
-/**
* Query CSAM state (enabled/disabled)
*
- * @returns 0 - disabled, 1 - enabled
- * @param pVM The VM to operate on.
- */
-#define CSAMIsEnabled(pVM) (pVM->fCSAMEnabled && EMIsRawRing0Enabled(pVM))
-
-/**
- * Turn on code scanning
- *
- * @returns VBox status code. (trap handled or not)
- * @param pVM The VM to operate on.
+ * @returns true / false.
+ * @param a_pVM The shared VM handle.
+ * @internal
*/
-VMMDECL(int) CSAMEnableScanning(PVM pVM);
-
-/**
- * Turn off code scanning
- *
- * @returns VBox status code. (trap handled or not)
- * @param pVM The VM to operate on.
- */
-VMMDECL(int) CSAMDisableScanning(PVM pVM);
+#define CSAMIsEnabled(a_pVM) ((a_pVM)->fCSAMEnabled && EMIsRawRing0Enabled(a_pVM))
-
-/**
- * Check if this page needs to be analysed by CSAM
- *
- * @returns 0 - disabled, 1 - enabled
- * @param pVM The VM to operate on.
- * @param pvFault Fault address
- */
-VMMDECL(int) CSAMExecFault(PVM pVM, RTRCPTR pvFault);
-
-/**
- * Check if we've scanned this instruction before. If true, then we can emulate
- * it instead of returning to ring 3.
- *
- * @returns boolean
- * @param pVM The VM to operate on.
- * @param GCPtr GC pointer of page table entry
- */
-VMMDECL(bool) CSAMIsKnownDangerousInstr(PVM pVM, RTRCUINTPTR GCPtr);
+VMM_INT_DECL(bool) CSAMDoesPageNeedScanning(PVM pVM, RTRCUINTPTR GCPtr);
+VMM_INT_DECL(bool) CSAMIsPageScanned(PVM pVM, RTRCPTR pPage);
+VMM_INT_DECL(int) CSAMMarkPage(PVM pVM, RTRCUINTPTR pPage, bool fScanned);
+VMM_INT_DECL(void) CSAMMarkPossibleCodePage(PVM pVM, RTRCPTR GCPtr);
+VMM_INT_DECL(int) CSAMEnableScanning(PVM pVM);
+VMM_INT_DECL(int) CSAMDisableScanning(PVM pVM);
+VMM_INT_DECL(int) CSAMExecFault(PVM pVM, RTRCPTR pvFault);
+VMM_INT_DECL(bool) CSAMIsKnownDangerousInstr(PVM pVM, RTRCUINTPTR GCPtr);
#ifdef IN_RING3
@@ -151,149 +76,25 @@ VMMDECL(bool) CSAMIsKnownDangerousInstr(PVM pVM, RTRCUINTPTR GCPtr);
* @{
*/
-/**
- * Query CSAM state (enabled/disabled)
- *
- * @returns 0 - disabled, 1 - enabled
- * @param pVM The VM to operate on.
- */
-VMMR3DECL(int) CSAMR3IsEnabled(PVM pVM);
+VMMR3DECL(bool) CSAMR3IsEnabled(PUVM pUVM);
+VMMR3DECL(int) CSAMR3SetScanningEnabled(PUVM pUVM, bool fEnabled);
-/**
- * Initializes the csam.
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- */
-VMMR3DECL(int) CSAMR3Init(PVM pVM);
+VMMR3_INT_DECL(int) CSAMR3Init(PVM pVM);
+VMMR3_INT_DECL(void) CSAMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+VMMR3_INT_DECL(int) CSAMR3Term(PVM pVM);
+VMMR3_INT_DECL(int) CSAMR3Reset(PVM pVM);
-/**
- * Applies relocations to data and code managed by this
- * component. This function will be called at init and
- * whenever the VMM need to relocate it self inside the GC.
- *
- * The csam will update the addresses used by the switcher.
- *
- * @param pVM The VM.
- * @param offDelta Relocation delta.
- */
-VMMR3DECL(void) CSAMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
-
-/**
- * Terminates the csam.
- *
- * Termination means cleaning up and freeing all resources,
- * the VM it self is at this point powered off or suspended.
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- */
-VMMR3DECL(int) CSAMR3Term(PVM pVM);
-
-/**
- * CSAM reset callback.
- *
- * @returns VBox status code.
- * @param pVM The VM which is reset.
- */
-VMMR3DECL(int) CSAMR3Reset(PVM pVM);
+VMMR3_INT_DECL(int) CSAMR3FlushPage(PVM pVM, RTRCPTR addr);
+VMMR3_INT_DECL(int) CSAMR3RemovePage(PVM pVM, RTRCPTR addr);
+VMMR3_INT_DECL(int) CSAMR3CheckCode(PVM pVM, RTRCPTR pInstrGC);
+VMMR3_INT_DECL(int) CSAMR3CheckCodeEx(PVM pVM, PCPUMCTXCORE pCtxCore, RTRCPTR pInstrGC);
+VMMR3_INT_DECL(int) CSAMR3MarkCode(PVM pVM, RTRCPTR pInstr, uint32_t cbInstr, bool fScanned);
+VMMR3_INT_DECL(int) CSAMR3DoPendingAction(PVM pVM, PVMCPU pVCpu);
+VMMR3_INT_DECL(int) CSAMR3CheckGates(PVM pVM, uint32_t iGate, uint32_t cGates);
-
-/**
- * Notify CSAM of a page flush
- *
- * @returns VBox status code
- * @param pVM The VM to operate on.
- * @param addr GC address of the page to flush
- */
-VMMR3DECL(int) CSAMR3FlushPage(PVM pVM, RTRCPTR addr);
-
-/**
- * Remove a CSAM monitored page. Use with care!
- *
- * @returns VBox status code
- * @param pVM The VM to operate on.
- * @param addr GC address of the page to flush
- */
-VMMR3DECL(int) CSAMR3RemovePage(PVM pVM, RTRCPTR addr);
-
-/**
- * Scan and analyse code
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pCtxCore CPU context
- * @param pInstrGC Instruction pointer
- */
-VMMR3DECL(int) CSAMR3CheckCodeEx(PVM pVM, PCPUMCTXCORE pCtxCore, RTRCPTR pInstrGC);
-
-/**
- * Scan and analyse code
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pInstrGC Instruction pointer (0:32 virtual address)
- */
-VMMR3DECL(int) CSAMR3CheckCode(PVM pVM, RTRCPTR pInstrGC);
-
-/**
- * Mark an instruction in a page as scanned/not scanned
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pInstr Instruction pointer
- * @param cbInstr Instruction size
- * @param fScanned Mark as scanned or not
- */
-VMMR3DECL(int) CSAMR3MarkCode(PVM pVM, RTRCPTR pInstr, uint32_t cbInstr, bool fScanned);
-
-/**
- * Perform any pending actions
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pVCpu The VMCPU to operate on.
- */
-VMMR3DECL(int) CSAMR3DoPendingAction(PVM pVM, PVMCPU pVCpu);
-
-/**
- * Monitors a code page (if not already monitored)
- *
- * @returns VBox status code
- * @param pVM The VM to operate on.
- * @param pPageAddrGC The page to monitor
- * @param enmTag Monitor tag
- */
-VMMR3DECL(int) CSAMR3MonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag);
-
-/**
- * Unmonitors a code page
- *
- * @returns VBox status code
- * @param pVM The VM to operate on.
- * @param pPageAddrGC The page to monitor
- * @param enmTag Monitor tag
- */
-VMMR3DECL(int) CSAMR3UnmonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag);
-
-/**
- * Analyse interrupt and trap gates
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param iGate Start gate
- * @param cGates Number of gates to check
- */
-VMMR3DECL(int) CSAMR3CheckGates(PVM pVM, uint32_t iGate, uint32_t cGates);
-
-/**
- * Record previous call instruction addresses
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param GCPtrCall Call address
- */
-VMMR3DECL(int) CSAMR3RecordCallAddress(PVM pVM, RTRCPTR GCPtrCall);
+VMMR3DECL(int) CSAMR3MonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag);
+VMMR3DECL(int) CSAMR3UnmonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag);
+VMMR3DECL(int) CSAMR3RecordCallAddress(PVM pVM, RTRCPTR GCPtrCall);
/** @} */
#endif
@@ -302,4 +103,7 @@ VMMR3DECL(int) CSAMR3RecordCallAddress(PVM pVM, RTRCPTR GCPtrCall);
/** @} */
RT_C_DECLS_END
+#endif /* VBOX_WITH_RAW_MODE */
+
#endif
+
diff --git a/include/VBox/vmm/dbgf.h b/include/VBox/vmm/dbgf.h
index 65bb94c7..9aa4be5b 100644
--- a/include/VBox/vmm/dbgf.h
+++ b/include/VBox/vmm/dbgf.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -46,8 +46,8 @@ RT_C_DECLS_BEGIN
* @ingroup grp_dbgf
* @{
*/
-VMMRZDECL(int) DBGFRZTrap01Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6);
-VMMRZDECL(int) DBGFRZTrap03Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMMRZ_INT_DECL(int) DBGFRZTrap01Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6, bool fAltStepping);
+VMMRZ_INT_DECL(int) DBGFRZTrap03Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
/** @} */
#endif
@@ -114,14 +114,14 @@ typedef const DBGFADDRESS *PCDBGFADDRESS;
#define DBGFADDRESS_IS_HMA(pAddress) ( !!((pAddress)->fFlags & DBGFADDRESS_FLAGS_HMA) )
/** @} */
-VMMR3DECL(int) DBGFR3AddrFromSelOff(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off);
-VMMR3DECL(int) DBGFR3AddrFromSelInfoOff(PVM pVM, PDBGFADDRESS pAddress, PCDBGFSELINFO pSelInfo, RTUINTPTR off);
-VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromFlat(PVM pVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr);
-VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PVM pVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr);
-VMMR3DECL(bool) DBGFR3AddrIsValid(PVM pVM, PCDBGFADDRESS pAddress);
-VMMR3DECL(int) DBGFR3AddrToPhys(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys);
-VMMR3DECL(int) DBGFR3AddrToHostPhys(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys);
-VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr);
+VMMR3DECL(int) DBGFR3AddrFromSelOff(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off);
+VMMR3DECL(int) DBGFR3AddrFromSelInfoOff(PUVM pUVM, PDBGFADDRESS pAddress, PCDBGFSELINFO pSelInfo, RTUINTPTR off);
+VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromFlat(PUVM pUVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr);
+VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PUVM pUVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr);
+VMMR3DECL(bool) DBGFR3AddrIsValid(PUVM pUVM, PCDBGFADDRESS pAddress);
+VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys);
+VMMR3DECL(int) DBGFR3AddrToHostPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys);
+VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr);
VMMR3DECL(PDBGFADDRESS) DBGFR3AddrAdd(PDBGFADDRESS pAddress, RTGCUINTPTR uAddend);
VMMR3DECL(PDBGFADDRESS) DBGFR3AddrSub(PDBGFADDRESS pAddress, RTGCUINTPTR uSubtrahend);
@@ -179,10 +179,10 @@ typedef enum DBGFEVENTTYPE
* to bring up the debugger at a specific place.
*/
DBGFEVENT_DEV_STOP,
- /** The VM is terminating.
+ /** The VM is powering off.
* When this notification is received, the debugger thread should detach ASAP.
*/
- DBGFEVENT_TERMINATING,
+ DBGFEVENT_POWERING_OFF,
/** The usual 32-bit hack. */
DBGFEVENT_32BIT_HACK = 0x7fffffff
@@ -201,7 +201,7 @@ typedef enum DBGFEVENTCTX
/** Recompiled mode. */
DBGFEVENTCTX_REM,
/** VMX / AVT mode. */
- DBGFEVENTCTX_HWACCL,
+ DBGFEVENTCTX_HM,
/** Hypervisor context. */
DBGFEVENTCTX_HYPER,
/** Other mode */
@@ -281,24 +281,29 @@ typedef const DBGFEVENT *PCDBGFEVENT;
# define DBGFSTOP(pVM) VINF_SUCCESS
# endif
-VMMR3DECL(int) DBGFR3Init(PVM pVM);
-VMMR3DECL(int) DBGFR3Term(PVM pVM);
-VMMR3DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta);
-VMMR3DECL(int) DBGFR3VMMForcedAction(PVM pVM);
-VMMR3DECL(int) DBGFR3Event(PVM pVM, DBGFEVENTTYPE enmEvent);
-VMMR3DECL(int) DBGFR3EventSrc(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, const char *pszFunction, const char *pszFormat, ...);
-VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, const char *pszFunction, const char *pszFormat, va_list args);
-VMMR3DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2);
-VMMR3DECL(int) DBGFR3EventBreakpoint(PVM pVM, DBGFEVENTTYPE enmEvent);
-VMMR3DECL(int) DBGFR3Attach(PVM pVM);
-VMMR3DECL(int) DBGFR3Detach(PVM pVM);
-VMMR3DECL(int) DBGFR3EventWait(PVM pVM, RTMSINTERVAL cMillies, PCDBGFEVENT *ppEvent);
-VMMR3DECL(int) DBGFR3Halt(PVM pVM);
-VMMR3DECL(bool) DBGFR3IsHalted(PVM pVM);
-VMMR3DECL(bool) DBGFR3CanWait(PVM pVM);
-VMMR3DECL(int) DBGFR3Resume(PVM pVM);
-VMMR3DECL(int) DBGFR3Step(PVM pVM, VMCPUID idCpu);
-VMMR3DECL(int) DBGFR3PrgStep(PVMCPU pVCpu);
+VMMR3_INT_DECL(int) DBGFR3Init(PVM pVM);
+VMMR3_INT_DECL(int) DBGFR3Term(PVM pVM);
+VMMR3_INT_DECL(void) DBGFR3PowerOff(PVM pVM);
+VMMR3_INT_DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+VMMR3_INT_DECL(int) DBGFR3VMMForcedAction(PVM pVM);
+VMMR3DECL(int) DBGFR3Event(PVM pVM, DBGFEVENTTYPE enmEvent);
+VMMR3DECL(int) DBGFR3EventSrc(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine,
+ const char *pszFunction, const char *pszFormat, ...);
+VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine,
+ const char *pszFunction, const char *pszFormat, va_list args);
+VMMR3_INT_DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2);
+VMMR3_INT_DECL(int) DBGFR3EventBreakpoint(PVM pVM, DBGFEVENTTYPE enmEvent);
+VMMR3_INT_DECL(int) DBGFR3PrgStep(PVMCPU pVCpu);
+
+VMMR3DECL(int) DBGFR3Attach(PUVM pUVM);
+VMMR3DECL(int) DBGFR3Detach(PUVM pUVM);
+VMMR3DECL(int) DBGFR3EventWait(PUVM pUVM, RTMSINTERVAL cMillies, PCDBGFEVENT *ppEvent);
+VMMR3DECL(int) DBGFR3Halt(PUVM pUVM);
+VMMR3DECL(bool) DBGFR3IsHalted(PUVM pUVM);
+VMMR3DECL(int) DBGFR3QueryWaitable(PUVM pUVM);
+VMMR3DECL(int) DBGFR3Resume(PUVM pUVM);
+VMMR3DECL(int) DBGFR3Step(PUVM pUVM, VMCPUID idCpu);
+VMMR3DECL(int) DBGFR3InjectNMI(PUVM pUVM, VMCPUID idCpu);
#endif /* IN_RING3 */
@@ -384,39 +389,44 @@ typedef DBGFBP *PDBGFBP;
typedef const DBGFBP *PCDBGFBP;
#ifdef IN_RING3 /* The breakpoint management API is only available in ring-3. */
-VMMR3DECL(int) DBGFR3BpSet(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
-VMMR3DECL(int) DBGFR3BpSetReg(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable,
+VMMR3DECL(int) DBGFR3BpSet(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
+VMMR3DECL(int) DBGFR3BpSetReg(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable,
uint8_t fType, uint8_t cb, uint32_t *piBp);
-VMMR3DECL(int) DBGFR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
-VMMR3DECL(int) DBGFR3BpClear(PVM pVM, uint32_t iBp);
-VMMR3DECL(int) DBGFR3BpEnable(PVM pVM, uint32_t iBp);
-VMMR3DECL(int) DBGFR3BpDisable(PVM pVM, uint32_t iBp);
+VMMR3DECL(int) DBGFR3BpSetREM(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
+VMMR3DECL(int) DBGFR3BpClear(PUVM pUVM, uint32_t iBp);
+VMMR3DECL(int) DBGFR3BpEnable(PUVM pUVM, uint32_t iBp);
+VMMR3DECL(int) DBGFR3BpDisable(PUVM pUVM, uint32_t iBp);
/**
* Breakpoint enumeration callback function.
*
* @returns VBox status code. Any failure will stop the enumeration.
- * @param pVM The VM handle.
+ * @param pUVM The user mode VM handle.
* @param pvUser The user argument.
* @param pBp Pointer to the breakpoint information. (readonly)
*/
-typedef DECLCALLBACK(int) FNDBGFBPENUM(PVM pVM, void *pvUser, PCDBGFBP pBp);
+typedef DECLCALLBACK(int) FNDBGFBPENUM(PUVM pUVM, void *pvUser, PCDBGFBP pBp);
/** Pointer to a breakpoint enumeration callback function. */
typedef FNDBGFBPENUM *PFNDBGFBPENUM;
-VMMR3DECL(int) DBGFR3BpEnum(PVM pVM, PFNDBGFBPENUM pfnCallback, void *pvUser);
+VMMR3DECL(int) DBGFR3BpEnum(PUVM pUVM, PFNDBGFBPENUM pfnCallback, void *pvUser);
#endif /* IN_RING3 */
-VMMDECL(RTGCUINTREG) DBGFBpGetDR7(PVM pVM);
-VMMDECL(RTGCUINTREG) DBGFBpGetDR0(PVM pVM);
-VMMDECL(RTGCUINTREG) DBGFBpGetDR1(PVM pVM);
-VMMDECL(RTGCUINTREG) DBGFBpGetDR2(PVM pVM);
-VMMDECL(RTGCUINTREG) DBGFBpGetDR3(PVM pVM);
-VMMDECL(bool) DBGFIsStepping(PVMCPU pVCpu);
+VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR7(PVM pVM);
+VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR0(PVM pVM);
+VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR1(PVM pVM);
+VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR2(PVM pVM);
+VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR3(PVM pVM);
+VMM_INT_DECL(bool) DBGFBpIsHwArmed(PVM pVM);
+VMM_INT_DECL(bool) DBGFBpIsHwIoArmed(PVM pVM);
+VMM_INT_DECL(bool) DBGFIsStepping(PVMCPU pVCpu);
+VMM_INT_DECL(VBOXSTRICTRC) DBGFBpCheckIo(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTIOPORT uIoPort, uint8_t cbValue);
#ifdef IN_RING3 /* The CPU mode API only works in ring-3. */
-VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PVM pVM, VMCPUID idCpu);
+VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PUVM pUVM, VMCPUID idCpu);
+VMMR3DECL(VMCPUID) DBGFR3CpuGetCount(PUVM pUVM);
+VMMR3DECL(bool) DBGFR3CpuIsIn64BitCode(PUVM pUVM, VMCPUID idCpu);
#endif
@@ -510,37 +520,37 @@ typedef FNDBGFHANDLEREXT *PFNDBGFHANDLEREXT;
#define DBGFINFO_FLAGS_RUN_ON_EMT RT_BIT(0)
/** @} */
-VMMR3DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns);
-VMMR3DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns);
-VMMR3DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler);
-VMMR3DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags);
-VMMR3DECL(int) DBGFR3InfoRegisterExternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser);
-VMMR3DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName);
-VMMR3DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName);
-VMMR3DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName);
-VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PVM pVM, const char *pszName);
-VMMR3DECL(int) DBGFR3Info(PVM pVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
-VMMR3DECL(int) DBGFR3InfoEx(PVM pVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
-VMMR3DECL(int) DBGFR3InfoLogRel(PVM pVM, const char *pszName, const char *pszArgs);
-VMMR3DECL(int) DBGFR3InfoStdErr(PVM pVM, const char *pszName, const char *pszArgs);
-VMMR3DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat,
- const char *pszSepFmt, PCDBGFINFOHLP pHlp);
+VMMR3_INT_DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns);
+VMMR3_INT_DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns);
+VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler);
+VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags);
+VMMR3DECL(int) DBGFR3InfoRegisterExternal(PUVM pUVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser);
+VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName);
+VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName);
+VMMR3_INT_DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName);
+VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PUVM pUVM, const char *pszName);
+VMMR3DECL(int) DBGFR3Info(PUVM pUVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
+VMMR3DECL(int) DBGFR3InfoEx(PUVM pUVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
+VMMR3DECL(int) DBGFR3InfoLogRel(PUVM pUVM, const char *pszName, const char *pszArgs);
+VMMR3DECL(int) DBGFR3InfoStdErr(PUVM pUVM, const char *pszName, const char *pszArgs);
+VMMR3_INT_DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat,
+ const char *pszSepFmt, PCDBGFINFOHLP pHlp);
/** @def DBGFR3InfoLog
* Display a piece of info writing to the log if enabled.
*
- * @param pVM VM handle.
- * @param pszName The identifier of the info to display.
- * @param pszArgs Arguments to the info handler.
+ * @param a_pVM The shared VM handle.
+ * @param a_pszName The identifier of the info to display.
+ * @param a_pszArgs Arguments to the info handler.
*/
#ifdef LOG_ENABLED
-#define DBGFR3InfoLog(pVM, pszName, pszArgs) \
+# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) \
do { \
if (LogIsEnabled()) \
- DBGFR3Info(pVM, pszName, pszArgs, NULL); \
+ DBGFR3Info((a_pVM)->pUVM, a_pszName, a_pszArgs, NULL); \
} while (0)
#else
-#define DBGFR3InfoLog(pVM, pszName, pszArgs) do { } while (0)
+# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) do { } while (0)
#endif
/**
@@ -549,15 +559,15 @@ VMMR3DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *p
* @returns VBox status code.
* A status code indicating failure will end the enumeration
* and DBGFR3InfoEnum will return with that status code.
- * @param pVM VM handle.
+ * @param pUVM The user mode VM handle.
* @param pszName Info identifier name.
* @param pszDesc The description.
*/
-typedef DECLCALLBACK(int) FNDBGFINFOENUM(PVM pVM, const char *pszName, const char *pszDesc, void *pvUser);
+typedef DECLCALLBACK(int) FNDBGFINFOENUM(PUVM pUVM, const char *pszName, const char *pszDesc, void *pvUser);
/** Pointer to a FNDBGFINFOENUM function. */
typedef FNDBGFINFOENUM *PFNDBGFINFOENUM;
-VMMR3DECL(int) DBGFR3InfoEnum(PVM pVM, PFNDBGFINFOENUM pfnCallback, void *pvUser);
+VMMR3DECL(int) DBGFR3InfoEnum(PUVM pUVM, PFNDBGFINFOENUM pfnCallback, void *pvUser);
VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogHlp(void);
VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void);
@@ -565,9 +575,9 @@ VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void);
#ifdef IN_RING3 /* The log contrl API only works in ring-3. */
-VMMR3DECL(int) DBGFR3LogModifyGroups(PVM pVM, const char *pszGroupSettings);
-VMMR3DECL(int) DBGFR3LogModifyFlags(PVM pVM, const char *pszFlagSettings);
-VMMR3DECL(int) DBGFR3LogModifyDestinations(PVM pVM, const char *pszDestSettings);
+VMMR3DECL(int) DBGFR3LogModifyGroups(PUVM pUVM, const char *pszGroupSettings);
+VMMR3DECL(int) DBGFR3LogModifyFlags(PUVM pUVM, const char *pszFlagSettings);
+VMMR3DECL(int) DBGFR3LogModifyDestinations(PUVM pUVM, const char *pszDestSettings);
#endif /* IN_RING3 */
#ifdef IN_RING3 /* The debug information management APIs only works in ring-3. */
@@ -650,33 +660,32 @@ typedef const DBGFLINE *PCDBGFLINE;
/** @} */
-VMMR3DECL(int) DBGFR3AsAdd(PVM pVM, RTDBGAS hDbgAs, RTPROCESS ProcId);
-VMMR3DECL(int) DBGFR3AsDelete(PVM pVM, RTDBGAS hDbgAs);
-VMMR3DECL(int) DBGFR3AsSetAlias(PVM pVM, RTDBGAS hAlias, RTDBGAS hAliasFor);
-VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PVM pVM, RTDBGAS hAlias);
-VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PVM pVM, RTDBGAS hAlias);
-VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PVM pVM, const char *pszName);
-VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PVM pVM, RTPROCESS ProcId);
-
-VMMR3DECL(int) DBGFR3AsLoadImage(PVM pVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
-VMMR3DECL(int) DBGFR3AsLoadMap(PVM pVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags);
-VMMR3DECL(int) DBGFR3AsLinkModule(PVM pVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
-
-VMMR3DECL(int) DBGFR3AsSymbolByAddr(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
-VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
-VMMR3DECL(int) DBGFR3AsSymbolByName(PVM pVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
-
-/* The following are soon to be obsoleted: */
-VMMR3DECL(int) DBGFR3ModuleLoad(PVM pVM, const char *pszFilename, RTGCUINTPTR AddressDelta, const char *pszName, RTGCUINTPTR ModuleAddress, unsigned cbImage);
-VMMR3DECL(void) DBGFR3ModuleRelocate(PVM pVM, RTGCUINTPTR OldImageBase, RTGCUINTPTR NewImageBase, RTGCUINTPTR cbImage,
- const char *pszFilename, const char *pszName);
-VMMR3DECL(int) DBGFR3SymbolAdd(PVM pVM, RTGCUINTPTR ModuleAddress, RTGCUINTPTR SymbolAddress, RTUINT cbSymbol, const char *pszSymbol);
-VMMR3DECL(int) DBGFR3SymbolByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFSYMBOL pSymbol);
-VMMR3DECL(int) DBGFR3SymbolByName(PVM pVM, const char *pszSymbol, PDBGFSYMBOL pSymbol);
-
-VMMR3DECL(int) DBGFR3LineByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFLINE pLine);
-VMMR3DECL(PDBGFLINE) DBGFR3LineByAddrAlloc(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement);
-VMMR3DECL(void) DBGFR3LineFree(PDBGFLINE pLine);
+VMMR3DECL(RTDBGCFG) DBGFR3AsGetConfig(PUVM pUVM);
+
+VMMR3DECL(int) DBGFR3AsAdd(PUVM pUVM, RTDBGAS hDbgAs, RTPROCESS ProcId);
+VMMR3DECL(int) DBGFR3AsDelete(PUVM pUVM, RTDBGAS hDbgAs);
+VMMR3DECL(int) DBGFR3AsSetAlias(PUVM pUVM, RTDBGAS hAlias, RTDBGAS hAliasFor);
+VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PUVM pUVM, RTDBGAS hAlias);
+VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PUVM pUVM, RTDBGAS hAlias);
+VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PUVM pUVM, const char *pszName);
+VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PUVM pUVM, RTPROCESS ProcId);
+
+VMMR3DECL(int) DBGFR3AsLoadImage(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName,
+ RTLDRARCH enmArch, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
+VMMR3DECL(int) DBGFR3AsLoadMap(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags);
+VMMR3DECL(int) DBGFR3AsLinkModule(PUVM pUVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
+VMMR3DECL(int) DBGFR3AsUnlinkModuleByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszModName);
+
+VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags,
+ PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
+VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t Flags,
+ PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
+VMMR3DECL(int) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
+
+VMMR3DECL(int) DBGFR3AsLineByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
+ PRTGCINTPTR poffDisp, PRTDBGLINE pLine, PRTDBGMOD phMod);
+VMMR3DECL(PRTDBGLINE) DBGFR3AsLineByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
+ PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
#endif /* IN_RING3 */
@@ -769,7 +778,7 @@ typedef struct DBGFSTACKFRAME
/** Pointer to the symbol nearest the program counter (PC). NULL if not found. */
PRTDBGSYMBOL pSymPC;
/** Pointer to the linnumber nearest the program counter (PC). NULL if not found. */
- PDBGFLINE pLinePC;
+ PRTDBGLINE pLinePC;
/** The return frame address.
* The off member is [e|r]bp and the Sel member is ss. */
@@ -786,7 +795,7 @@ typedef struct DBGFSTACKFRAME
/** Pointer to the symbol nearest the return PC. NULL if not found. */
PRTDBGSYMBOL pSymReturnPC;
/** Pointer to the linnumber nearest the return PC. NULL if not found. */
- PDBGFLINE pLineReturnPC;
+ PRTDBGLINE pLineReturnPC;
/** 32-bytes of stack arguments. */
union
@@ -846,8 +855,9 @@ typedef enum DBGFCODETYPE
} DBGFCODETYPE;
/** @} */
-VMMR3DECL(int) DBGFR3StackWalkBegin(PVM pVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFSTACKFRAME *ppFirstFrame);
-VMMR3DECL(int) DBGFR3StackWalkBeginEx(PVM pVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame,
+VMMR3DECL(int) DBGFR3StackWalkBegin(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType,
+ PCDBGFSTACKFRAME *ppFirstFrame);
+VMMR3DECL(int) DBGFR3StackWalkBeginEx(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame,
PCDBGFADDRESS pAddrStack,PCDBGFADDRESS pAddrPC,
DBGFRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame);
VMMR3DECL(PCDBGFSTACKFRAME) DBGFR3StackWalkNext(PCDBGFSTACKFRAME pCurrent);
@@ -872,6 +882,12 @@ VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame);
#define DBGF_DISAS_FLAGS_NO_BYTES RT_BIT(4)
/** No address in the output. */
#define DBGF_DISAS_FLAGS_NO_ADDRESS RT_BIT(5)
+/** Probably a hypervisor instruction. */
+#define DBGF_DISAS_FLAGS_HYPER RT_BIT(6)
+/** Disassemble original unpatched bytes (PATM). */
+#define DBGF_DISAS_FLAGS_UNPATCHED_BYTES RT_BIT(7)
+/** Annotate patched instructions. */
+#define DBGF_DISAS_FLAGS_ANNOTATE_PATCHED RT_BIT(8)
/** Disassemble in the default mode of the specific context. */
#define DBGF_DISAS_FLAGS_DEFAULT_MODE UINT32_C(0x00000000)
/** Disassemble in 16-bit mode. */
@@ -885,29 +901,29 @@ VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame);
/** The disassembly mode mask. */
#define DBGF_DISAS_FLAGS_MODE_MASK UINT32_C(0x70000000)
/** Mask containing the valid flags. */
-#define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x7000007f)
+#define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x700001ff)
/** @} */
/** Special flat selector. */
#define DBGF_SEL_FLAT 1
-VMMR3DECL(int) DBGFR3DisasInstrEx(PVM pVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags,
- char *pszOutput, uint32_t cbOutput, uint32_t *pcbInstr);
-VMMR3DECL(int) DBGFR3DisasInstrCurrent(PVMCPU pVCpu, char *pszOutput, uint32_t cbOutput);
-VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVMCPU pVCpu, const char *pszPrefix);
+VMMR3DECL(int) DBGFR3DisasInstrEx(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags,
+ char *pszOutput, uint32_t cbOutput, uint32_t *pcbInstr);
+VMMR3_INT_DECL(int) DBGFR3DisasInstrCurrent(PVMCPU pVCpu, char *pszOutput, uint32_t cbOutput);
+VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVMCPU pVCpu, const char *pszPrefix);
/** @def DBGFR3DisasInstrCurrentLog
* Disassembles the current guest context instruction and writes it to the log.
* All registers and data will be displayed. Addresses will be attempted resolved to symbols.
*/
#ifdef LOG_ENABLED
-# define DBGFR3DisasInstrCurrentLog(pVCpu, pszPrefix) \
+# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) \
do { \
if (LogIsEnabled()) \
DBGFR3DisasInstrCurrentLogInternal(pVCpu, pszPrefix); \
} while (0)
#else
-# define DBGFR3DisasInstrCurrentLog(pVCpu, pszPrefix) do { } while (0)
+# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) do { } while (0)
#endif
VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPtr, const char *pszPrefix);
@@ -918,23 +934,23 @@ VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPt
* @thread Any EMT.
*/
# ifdef LOG_ENABLED
-# define DBGFR3DisasInstrLog(pVCpu, Sel, GCPtr, pszPrefix) \
+# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) \
do { \
if (LogIsEnabled()) \
DBGFR3DisasInstrLogInternal(pVCpu, Sel, GCPtr, pszPrefix); \
} while (0)
# else
-# define DBGFR3DisasInstrLog(pVCpu, Sel, GCPtr, pszPrefix) do { } while (0)
+# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) do { } while (0)
# endif
#endif
#ifdef IN_RING3
-VMMR3DECL(int) DBGFR3MemScan(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign,
+VMMR3DECL(int) DBGFR3MemScan(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign,
const void *pvNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress);
-VMMR3DECL(int) DBGFR3MemRead(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead);
-VMMR3DECL(int) DBGFR3MemReadString(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf);
-VMMR3DECL(int) DBGFR3MemWrite(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead);
+VMMR3DECL(int) DBGFR3MemRead(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead);
+VMMR3DECL(int) DBGFR3MemReadString(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf);
+VMMR3DECL(int) DBGFR3MemWrite(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead);
#endif
@@ -979,7 +995,7 @@ VMMR3DECL(int) DBGFR3MemWrite(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, vo
/** The mask of bits controlling the paging mode. */
#define DBGFPGDMP_FLAGS_MODE_MASK UINT32_C(0x00000f32)
/** @} */
-VMMDECL(int) DBGFR3PagingDumpEx(PVM pVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
+VMMDECL(int) DBGFR3PagingDumpEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
@@ -993,7 +1009,7 @@ VMMDECL(int) DBGFR3PagingDumpEx(PVM pVM, VMCPUID idCpu, uint32_t fFlags, uint64_
/** If currently executing in in 64-bit mode, blow up data selectors. */
#define DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE UINT32_C(2)
/** @} */
-VMMR3DECL(int) DBGFR3SelQueryInfo(PVM pVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo);
+VMMR3DECL(int) DBGFR3SelQueryInfo(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo);
/**
@@ -1269,6 +1285,11 @@ typedef DBGFREGVALTYPE *PDBGFREGVALTYPE;
*/
typedef union DBGFREGVAL
{
+ uint64_t au64[2]; /**< The 64-bit array view. First because of the initializer. */
+ uint32_t au32[4]; /**< The 32-bit array view. */
+ uint16_t au16[8]; /**< The 16-bit array view. */
+ uint8_t au8[16]; /**< The 8-bit array view. */
+
uint8_t u8; /**< The 8-bit view. */
uint16_t u16; /**< The 16-bit view. */
uint32_t u32; /**< The 32-bit view. */
@@ -1285,10 +1306,6 @@ typedef union DBGFREGVAL
uint32_t u32Limit;
} dtr;
- uint8_t au8[16]; /**< The 8-bit array view. */
- uint16_t au16[8]; /**< The 16-bit array view. */
- uint32_t au32[4]; /**< The 32-bit array view. */
- uint64_t au64[2]; /**< The 64-bit array view. */
RTUINT128U u;
} DBGFREGVAL;
/** Pointer to a generic register value type. */
@@ -1296,6 +1313,12 @@ typedef DBGFREGVAL *PDBGFREGVAL;
/** Pointer to a const generic register value type. */
typedef DBGFREGVAL const *PCDBGFREGVAL;
+/** Initialize a DBGFREGVAL variable to all zeros. */
+#define DBGFREGVAL_INITIALIZE_ZERO { { 0, 0 } }
+/** Initialize a DBGFREGVAL variable to all bits set . */
+#define DBGFREGVAL_INITIALIZE_FFFF { { UINT64_MAX, UINT64_MAX } }
+
+
VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial);
VMMDECL(ssize_t) DBGFR3RegFormatValueEx(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType,
unsigned uBase, signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
@@ -1316,9 +1339,13 @@ typedef struct DBGFREGSUBFIELD
int8_t cShift;
/** Sub-field flags, DBGFREGSUBFIELD_FLAGS_XXX. */
uint8_t fFlags;
- /** Getter (optional). */
+ /** Getter (optional).
+ * @remarks Does not take the device lock or anything like that.
+ */
DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, PRTUINT128U puValue);
- /** Setter (optional). */
+ /** Setter (optional).
+ * @remarks Does not take the device lock or anything like that.
+ */
DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, RTUINT128U uValue, RTUINT128U fMask);
} DBGFREGSUBFIELD;
/** Pointer to a const register sub-field descriptor. */
@@ -1336,6 +1363,9 @@ typedef DBGFREGSUBFIELD const *PCDBGFREGSUBFIELD;
/** Macro for creating a read-write sub-field entry with getters. */
#define DBGFREGSUBFIELD_RW_SG(a_szName, a_cBits, a_cShift, a_pfnGet, a_pfnSet) \
{ a_szName, 0 /*iFirstBit*/, a_cBits, a_cShift, 0 /*fFlags*/, a_pfnGet, a_pfnSet }
+/** Macro for creating a read-only sub-field entry without getters. */
+#define DBGFREGSUBFIELD_RO(a_szName, a_iFirstBit, a_cBits, a_cShift) \
+ { a_szName, a_iFirstBit, a_cBits, a_cShift, DBGFREGSUBFIELD_FLAGS_READ_ONLY, NULL /*pfnGet*/, NULL /*pfnSet*/ }
/** Macro for creating a terminator sub-field entry. */
#define DBGFREGSUBFIELD_TERMINATOR() \
{ NULL, 0, 0, 0, 0, NULL, NULL }
@@ -1370,9 +1400,13 @@ typedef struct DBGFREGDESC
* For CPU registers this is the offset into the CPUMCTX structure,
* thuse the 'off' prefix. */
uint32_t offRegister;
- /** Getter. */
+ /** Getter.
+ * @remarks Does not take the device lock or anything like that.
+ */
DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGDESC const *pDesc, PDBGFREGVAL pValue);
- /** Setter. */
+ /** Setter.
+ * @remarks Does not take the device lock or anything like that.
+ */
DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGDESC const *pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask);
/** Aliases (optional). */
PCDBGFREGALIAS paAliases;
@@ -1430,30 +1464,31 @@ typedef DBGFREGENTRY const *PCDBGFREGENTRY;
* guest. */
#define DBGFREG_HYPER_VMCPUID UINT32_C(0x01000000)
-VMMR3DECL(int) DBGFR3RegCpuQueryU8( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8);
-VMMR3DECL(int) DBGFR3RegCpuQueryU16( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16);
-VMMR3DECL(int) DBGFR3RegCpuQueryU32( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32);
-VMMR3DECL(int) DBGFR3RegCpuQueryU64( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64);
-VMMR3DECL(int) DBGFR3RegCpuQueryU128(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t *pu128);
-VMMR3DECL(int) DBGFR3RegCpuQueryLrd( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, long double *plrd);
-VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit);
+VMMR3DECL(int) DBGFR3RegCpuQueryU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8);
+VMMR3DECL(int) DBGFR3RegCpuQueryU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16);
+VMMR3DECL(int) DBGFR3RegCpuQueryU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32);
+VMMR3DECL(int) DBGFR3RegCpuQueryU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64);
+VMMR3DECL(int) DBGFR3RegCpuQueryU128(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t *pu128);
+VMMR3DECL(int) DBGFR3RegCpuQueryLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double *plrd);
+VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit);
#if 0
-VMMR3DECL(int) DBGFR3RegCpuQueryBatch(PVM pVM,VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
-VMMR3DECL(int) DBGFR3RegCpuQueryAll( PVM pVM, VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
-
-VMMR3DECL(int) DBGFR3RegCpuSetU8( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t u8);
-VMMR3DECL(int) DBGFR3RegCpuSetU16( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t u16);
-VMMR3DECL(int) DBGFR3RegCpuSetU32( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t u32);
-VMMR3DECL(int) DBGFR3RegCpuSetU64( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t u64);
-VMMR3DECL(int) DBGFR3RegCpuSetU128( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t u128);
-VMMR3DECL(int) DBGFR3RegCpuSetLrd( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, long double lrd);
-VMMR3DECL(int) DBGFR3RegCpuSetBatch( PVM pVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs);
+VMMR3DECL(int) DBGFR3RegCpuQueryBatch(PUVM pUVM,VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
+VMMR3DECL(int) DBGFR3RegCpuQueryAll( PUVM pUVM, VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
+
+VMMR3DECL(int) DBGFR3RegCpuSetU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t u8);
+VMMR3DECL(int) DBGFR3RegCpuSetU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t u16);
+VMMR3DECL(int) DBGFR3RegCpuSetU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t u32);
+VMMR3DECL(int) DBGFR3RegCpuSetU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t u64);
+VMMR3DECL(int) DBGFR3RegCpuSetU128( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t u128);
+VMMR3DECL(int) DBGFR3RegCpuSetLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double lrd);
+VMMR3DECL(int) DBGFR3RegCpuSetBatch( PUVM pUVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs);
#endif
-VMMR3DECL(const char *) DBGFR3RegCpuName(PVM pVM, DBGFREG enmReg, DBGFREGVALTYPE enmType);
+VMMR3DECL(const char *) DBGFR3RegCpuName(PUVM pUVM, DBGFREG enmReg, DBGFREGVALTYPE enmType);
VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters, bool fGuestRegs);
-VMMR3DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns, const char *pszPrefix, uint32_t iInstance);
+VMMR3_INT_DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns,
+ const char *pszPrefix, uint32_t iInstance);
/**
* Entry in a named batch query or set operation.
@@ -1472,33 +1507,33 @@ typedef DBGFREGENTRYNM *PDBGFREGENTRYNM;
/** Pointer to a const named register entry in a batch operation. */
typedef DBGFREGENTRYNM const *PCDBGFREGENTRYNM;
-VMMR3DECL(int) DBGFR3RegNmValidate( PVM pVM, VMCPUID idDefCpu, const char *pszReg);
-
-VMMR3DECL(int) DBGFR3RegNmQuery( PVM pVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType);
-VMMR3DECL(int) DBGFR3RegNmQueryU8( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8);
-VMMR3DECL(int) DBGFR3RegNmQueryU16( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16);
-VMMR3DECL(int) DBGFR3RegNmQueryU32( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32);
-VMMR3DECL(int) DBGFR3RegNmQueryU64( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64);
-VMMR3DECL(int) DBGFR3RegNmQueryU128(PVM pVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128);
-/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/
-VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit);
-VMMR3DECL(int) DBGFR3RegNmQueryBatch(PVM pVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs);
-VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PVM pVM, size_t *pcRegs);
-VMMR3DECL(int) DBGFR3RegNmQueryAll( PVM pVM, PDBGFREGENTRYNM paRegs, size_t cRegs);
-
-VMMR3DECL(int) DBGFR3RegNmSet( PVM pVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType);
-VMMR3DECL(int) DBGFR3RegNmSetU8( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint8_t u8);
-VMMR3DECL(int) DBGFR3RegNmSetU16( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint16_t u16);
-VMMR3DECL(int) DBGFR3RegNmSetU32( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint32_t u32);
-VMMR3DECL(int) DBGFR3RegNmSetU64( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t u64);
-VMMR3DECL(int) DBGFR3RegNmSetU128( PVM pVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128);
-VMMR3DECL(int) DBGFR3RegNmSetLrd( PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double lrd);
-VMMR3DECL(int) DBGFR3RegNmSetBatch( PVM pVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs);
+VMMR3DECL(int) DBGFR3RegNmValidate( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg);
+
+VMMR3DECL(int) DBGFR3RegNmQuery( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType);
+VMMR3DECL(int) DBGFR3RegNmQueryU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8);
+VMMR3DECL(int) DBGFR3RegNmQueryU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16);
+VMMR3DECL(int) DBGFR3RegNmQueryU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32);
+VMMR3DECL(int) DBGFR3RegNmQueryU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64);
+VMMR3DECL(int) DBGFR3RegNmQueryU128(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128);
+/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/
+VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit);
+VMMR3DECL(int) DBGFR3RegNmQueryBatch(PUVM pUVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs);
+VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PUVM pUVM, size_t *pcRegs);
+VMMR3DECL(int) DBGFR3RegNmQueryAll( PUVM pUVM, PDBGFREGENTRYNM paRegs, size_t cRegs);
+
+VMMR3DECL(int) DBGFR3RegNmSet( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType);
+VMMR3DECL(int) DBGFR3RegNmSetU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t u8);
+VMMR3DECL(int) DBGFR3RegNmSetU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t u16);
+VMMR3DECL(int) DBGFR3RegNmSetU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t u32);
+VMMR3DECL(int) DBGFR3RegNmSetU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t u64);
+VMMR3DECL(int) DBGFR3RegNmSetU128( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128);
+VMMR3DECL(int) DBGFR3RegNmSetLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double lrd);
+VMMR3DECL(int) DBGFR3RegNmSetBatch( PUVM pUVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs);
/** @todo add enumeration methods. */
-VMMR3DECL(int) DBGFR3RegPrintf( PVM pVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
-VMMR3DECL(int) DBGFR3RegPrintfV(PVM pVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va);
+VMMR3DECL(int) DBGFR3RegPrintf( PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
+VMMR3DECL(int) DBGFR3RegPrintfV(PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va);
/**
@@ -1546,18 +1581,18 @@ typedef struct DBGFOSREG
* Constructs the instance.
*
* @returns VBox status code.
- * @param pVM Pointer to the shared VM structure.
+ * @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
- DECLCALLBACKMEMBER(int, pfnConstruct)(PVM pVM, void *pvData);
+ DECLCALLBACKMEMBER(int, pfnConstruct)(PUVM pUVM, void *pvData);
/**
* Destroys the instance.
*
- * @param pVM Pointer to the shared VM structure.
+ * @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
- DECLCALLBACKMEMBER(void, pfnDestruct)(PVM pVM, void *pvData);
+ DECLCALLBACKMEMBER(void, pfnDestruct)(PUVM pUVM, void *pvData);
/**
* Probes the guest memory for OS finger prints.
@@ -1566,10 +1601,10 @@ typedef struct DBGFOSREG
* or pfnRefresh that should take care of that.
*
* @returns true if is an OS handled by this module, otherwise false.
- * @param pVM Pointer to the shared VM structure.
+ * @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
- DECLCALLBACKMEMBER(bool, pfnProbe)(PVM pVM, void *pvData);
+ DECLCALLBACKMEMBER(bool, pfnProbe)(PUVM pUVM, void *pvData);
/**
* Initializes a fresly detected guest, loading symbols and such useful stuff.
@@ -1577,10 +1612,10 @@ typedef struct DBGFOSREG
* This is called after pfnProbe.
*
* @returns VBox status code.
- * @param pVM Pointer to the shared VM structure.
+ * @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
- DECLCALLBACKMEMBER(int, pfnInit)(PVM pVM, void *pvData);
+ DECLCALLBACKMEMBER(int, pfnInit)(PUVM pUVM, void *pvData);
/**
* Refreshes symbols and stuff following a redetection of the same OS.
@@ -1588,10 +1623,10 @@ typedef struct DBGFOSREG
* This is called after pfnProbe.
*
* @returns VBox status code.
- * @param pVM Pointer to the shared VM structure.
+ * @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
- DECLCALLBACKMEMBER(int, pfnRefresh)(PVM pVM, void *pvData);
+ DECLCALLBACKMEMBER(int, pfnRefresh)(PUVM pUVM, void *pvData);
/**
* Terminates an OS when a new (or none) OS has been detected,
@@ -1599,10 +1634,10 @@ typedef struct DBGFOSREG
*
* This is called after pfnProbe and if needed before pfnDestruct.
*
- * @param pVM Pointer to the shared VM structure.
+ * @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
- DECLCALLBACKMEMBER(void, pfnTerm)(PVM pVM, void *pvData);
+ DECLCALLBACKMEMBER(void, pfnTerm)(PUVM pUVM, void *pvData);
/**
* Queries the version of the running OS.
@@ -1610,12 +1645,12 @@ typedef struct DBGFOSREG
* This is only called after pfnInit().
*
* @returns VBox status code.
- * @param pVM Pointer to the shared VM structure.
+ * @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
* @param pszVersion Where to store the version string.
* @param cchVersion The size of the version string buffer.
*/
- DECLCALLBACKMEMBER(int, pfnQueryVersion)(PVM pVM, void *pvData, char *pszVersion, size_t cchVersion);
+ DECLCALLBACKMEMBER(int, pfnQueryVersion)(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion);
/**
* Queries the pointer to a interface.
@@ -1623,11 +1658,11 @@ typedef struct DBGFOSREG
* This is called after pfnProbe.
*
* @returns Pointer to the interface if available, NULL if not available.
- * @param pVM Pointer to the shared VM structure.
+ * @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
* @param enmIf The interface identifier.
*/
- DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PVM pVM, void *pvData, DBGFOSINTERFACE enmIf);
+ DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf);
/** Trailing magic (DBGFOSREG_MAGIC). */
uint32_t u32EndMagic;
@@ -1640,14 +1675,14 @@ typedef DBGFOSREG const *PCDBGFOSREG;
/** Magic value for DBGFOSREG::u32Magic and DBGFOSREG::u32EndMagic. (Hitomi Kanehara) */
#define DBGFOSREG_MAGIC 0x19830808
-VMMR3DECL(int) DBGFR3OSRegister(PVM pVM, PCDBGFOSREG pReg);
-VMMR3DECL(int) DBGFR3OSDeregister(PVM pVM, PCDBGFOSREG pReg);
-VMMR3DECL(int) DBGFR3OSDetect(PVM pVM, char *pszName, size_t cchName);
-VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PVM pVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion);
-VMMR3DECL(void *) DBGFR3OSQueryInterface(PVM pVM, DBGFOSINTERFACE enmIf);
+VMMR3DECL(int) DBGFR3OSRegister(PUVM pUVM, PCDBGFOSREG pReg);
+VMMR3DECL(int) DBGFR3OSDeregister(PUVM pUVM, PCDBGFOSREG pReg);
+VMMR3DECL(int) DBGFR3OSDetect(PUVM pUVM, char *pszName, size_t cchName);
+VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PUVM pUVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion);
+VMMR3DECL(void *) DBGFR3OSQueryInterface(PUVM pUVM, DBGFOSINTERFACE enmIf);
-VMMR3DECL(int) DBGFR3CoreWrite(PVM pVM, const char *pszFilename, bool fReplaceFile);
+VMMR3DECL(int) DBGFR3CoreWrite(PUVM pUVM, const char *pszFilename, bool fReplaceFile);
/** @} */
diff --git a/include/VBox/vmm/dbgfsel.h b/include/VBox/vmm/dbgfsel.h
index 708666bf..2be4ee84 100644
--- a/include/VBox/vmm/dbgfsel.h
+++ b/include/VBox/vmm/dbgfsel.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/include/VBox/vmm/em.h b/include/VBox/vmm/em.h
index a0efe5fc..d492ecf4 100644
--- a/include/VBox/vmm/em.h
+++ b/include/VBox/vmm/em.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -51,9 +51,9 @@ typedef enum EMSTATE
/** Raw-mode execution. */
EMSTATE_RAW,
/** Hardware accelerated raw-mode execution. */
- EMSTATE_HWACC,
- /** Value reserved for future use (used to be PARAV). */
- EMSTATE_RESERVED,
+ EMSTATE_HM,
+ /** Executing in IEM. */
+ EMSTATE_IEM,
/** Recompiled mode execution. */
EMSTATE_REM,
/** Execution is halted. (waiting for interrupt) */
@@ -67,13 +67,18 @@ typedef enum EMSTATE
/** Guest debug event from raw-mode is being processed. */
EMSTATE_DEBUG_GUEST_RAW,
/** Guest debug event from hardware accelerated mode is being processed. */
- EMSTATE_DEBUG_GUEST_HWACC,
+ EMSTATE_DEBUG_GUEST_HM,
+ /** Guest debug event from interpreted execution mode is being processed. */
+ EMSTATE_DEBUG_GUEST_IEM,
/** Guest debug event from recompiled-mode is being processed. */
EMSTATE_DEBUG_GUEST_REM,
/** Hypervisor debug event being processed. */
EMSTATE_DEBUG_HYPER,
/** The VM has encountered a fatal error. (And everyone is panicing....) */
EMSTATE_GURU_MEDITATION,
+ /** Executing in IEM, falling back on REM if we cannot switch back to HM or
+ * RAW after a short while. */
+ EMSTATE_IEM_THEN_REM,
/** Just a hack to ensure that we get a 32-bit integer. */
EMSTATE_MAKE_32BIT_HACK = 0x7fffffff
} EMSTATE;
@@ -94,8 +99,8 @@ typedef enum
EMCODETYPE_32BIT_HACK = 0x7fffffff
} EMCODETYPE;
-VMMDECL(EMSTATE) EMGetState(PVMCPU pVCpu);
-VMMDECL(void) EMSetState(PVMCPU pVCpu, EMSTATE enmNewState);
+VMM_INT_DECL(EMSTATE) EMGetState(PVMCPU pVCpu);
+VMM_INT_DECL(void) EMSetState(PVMCPU pVCpu, EMSTATE enmNewState);
/** @name Callback handlers for instruction emulation functions.
* These are placed here because IOM wants to use them as well.
@@ -121,7 +126,7 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3;
* @returns false if disabled.
* @param pVM The VM to operate on.
*/
-#define EMIsRawRing3Enabled(pVM) (!(pVM)->fRecompileUser)
+#define EMIsRawRing3Enabled(pVM) (!(pVM)->fRecompileUser)
/**
* Checks if raw ring-0 execute mode is enabled.
@@ -130,7 +135,20 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3;
* @returns false if disabled.
* @param pVM The VM to operate on.
*/
-#define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor)
+#define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor)
+
+#ifdef VBOX_WITH_RAW_RING1
+/**
+ * Checks if raw ring-1 execute mode is enabled.
+ *
+ * @returns true if enabled.
+ * @returns false if disabled.
+ * @param pVM The VM to operate on.
+ */
+# define EMIsRawRing1Enabled(pVM) ((pVM)->fRawRing1Enabled)
+#else
+# define EMIsRawRing1Enabled(pVM) false
+#endif
/**
* Checks if execution with hardware assisted virtualization is enabled.
@@ -139,7 +157,7 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3;
* @returns false if disabled.
* @param pVM The VM to operate on.
*/
-#define EMIsHwVirtExecutionEnabled(pVM) (!(pVM)->fRecompileSupervisor && !(pVM)->fRecompileUser)
+#define EMIsHwVirtExecutionEnabled(pVM) (!(pVM)->fRecompileSupervisor && !(pVM)->fRecompileUser)
/**
* Checks if execution of supervisor code should be done in the
@@ -151,39 +169,39 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3;
*/
#define EMIsSupervisorCodeRecompiled(pVM) ((pVM)->fRecompileSupervisor)
-VMMDECL(void) EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC);
-VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVMCPU pVCpu);
-VMMDECL(int) EMInterpretDisasCurrent(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pCpu, unsigned *pcbInstr);
-VMMDECL(int) EMInterpretDisasOneEx(PVM pVM, PVMCPU pVCpu, RTGCUINTPTR GCPtrInstr, PCCPUMCTXCORE pCtxCore,
- PDISCPUSTATE pDISState, unsigned *pcbInstr);
-VMMDECL(VBOXSTRICTRC) EMInterpretInstruction(PVMCPU pVCpu, PCPUMCTXCORE pCoreCtx, RTGCPTR pvFault);
-VMMDECL(VBOXSTRICTRC) EMInterpretInstructionEx(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbWritten);
-VMMDECL(VBOXSTRICTRC) EMInterpretInstructionDisasState(PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pCoreCtx, RTGCPTR pvFault, EMCODETYPE enmCodeType);
+VMMDECL(void) EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC);
+VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVMCPU pVCpu);
+VMM_INT_DECL(int) EMInterpretDisasCurrent(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pCpu, unsigned *pcbInstr);
+VMM_INT_DECL(int) EMInterpretDisasOneEx(PVM pVM, PVMCPU pVCpu, RTGCUINTPTR GCPtrInstr, PCCPUMCTXCORE pCtxCore,
+ PDISCPUSTATE pDISState, unsigned *pcbInstr);
+VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInstruction(PVMCPU pVCpu, PCPUMCTXCORE pCoreCtx, RTGCPTR pvFault);
+VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInstructionEx(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbWritten);
+VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInstructionDisasState(PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pCoreCtx,
+ RTGCPTR pvFault, EMCODETYPE enmCodeType);
#ifdef IN_RC
-VMMDECL(int) EMInterpretIretV86ForPatm(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMM_INT_DECL(int) EMInterpretIretV86ForPatm(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
#endif
-VMMDECL(int) EMInterpretCpuId(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
-VMMDECL(int) EMInterpretRdtsc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
-VMMDECL(int) EMInterpretRdpmc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
-VMMDECL(int) EMInterpretRdtscp(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-VMMDECL(VBOXSTRICTRC) EMInterpretInvlpg(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pAddrGC);
-VMMDECL(VBOXSTRICTRC) EMInterpretMWait(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
-VMMDECL(int) EMInterpretMonitor(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
-VMMDECL(int) EMInterpretDRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegDrx, uint32_t SrcRegGen);
-VMMDECL(int) EMInterpretDRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegDrx);
-VMMDECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen);
-VMMDECL(int) EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx);
-VMMDECL(int) EMInterpretLMSW(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint16_t u16Data);
-VMMDECL(int) EMInterpretCLTS(PVM pVM, PVMCPU pVCpu);
-#ifndef VBOX_WITH_IEM
-VMMDECL(int) EMInterpretRdmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
-VMMDECL(int) EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
-#endif /* !VBOX_WITH_IEM */
-VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx);
-VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx);
-VMM_INT_DECL(int) EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx);
+VMM_INT_DECL(int) EMInterpretCpuId(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMM_INT_DECL(int) EMInterpretRdtsc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMM_INT_DECL(int) EMInterpretRdpmc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMM_INT_DECL(int) EMInterpretRdtscp(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInvlpg(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pAddrGC);
+VMM_INT_DECL(VBOXSTRICTRC) EMInterpretMWait(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMM_INT_DECL(int) EMInterpretMonitor(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMM_INT_DECL(int) EMInterpretDRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegDrx, uint32_t SrcRegGen);
+VMM_INT_DECL(int) EMInterpretDRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegDrx);
+VMM_INT_DECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen);
+VMM_INT_DECL(int) EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx);
+VMM_INT_DECL(int) EMInterpretLMSW(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint16_t u16Data);
+VMM_INT_DECL(int) EMInterpretCLTS(PVM pVM, PVMCPU pVCpu);
+VMM_INT_DECL(int) EMInterpretRdmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMM_INT_DECL(int) EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx);
+VMM_INT_DECL(bool) EMMonitorWaitShouldContinue(PVMCPU pVCpu, PCPUMCTX pCtx);
+VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx, RTGCPHYS GCPhys);
+VMM_INT_DECL(int) EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx);
/** @name Assembly routines
* @{ */
@@ -213,26 +231,28 @@ VMMDECL(uint32_t) EMEmulateLockXAdd(void *pvParam1, void *pvParam2, size_t cbO
/** @name REM locking routines
* @{ */
-VMMDECL(void) EMRemUnlock(PVM pVM);
-VMMDECL(void) EMRemLock(PVM pVM);
-VMMDECL(bool) EMRemIsLockOwner(PVM pVM);
-VMMDECL(int) EMRemTryLock(PVM pVM);
+VMMDECL(void) EMRemUnlock(PVM pVM);
+VMMDECL(void) EMRemLock(PVM pVM);
+VMMDECL(bool) EMRemIsLockOwner(PVM pVM);
+VMM_INT_DECL(int) EMRemTryLock(PVM pVM);
/** @} */
+
+/** @name EM_ONE_INS_FLAGS_XXX - flags for EMR3HmSingleInstruction (et al).
+ * @{ */
+/** Return when CS:RIP changes or some other important event happens.
+ * This means running whole REP and LOOP $ sequences for instance. */
+#define EM_ONE_INS_FLAGS_RIP_CHANGE RT_BIT_32(0)
+/** Mask of valid flags. */
+#define EM_ONE_INS_FLAGS_MASK UINT32_C(0x00000001)
+/** @} */
+
+
#ifdef IN_RING3
/** @defgroup grp_em_r3 The EM Host Context Ring-3 API
* @ingroup grp_em
* @{
*/
-VMMR3DECL(int) EMR3Init(PVM pVM);
-VMMR3DECL(void) EMR3Relocate(PVM pVM);
-VMMR3DECL(void) EMR3ResetCpu(PVMCPU pVCpu);
-VMMR3DECL(void) EMR3Reset(PVM pVM);
-VMMR3DECL(int) EMR3Term(PVM pVM);
-VMMR3DECL(DECLNORETURN(void)) EMR3FatalError(PVMCPU pVCpu, int rc);
-VMMR3DECL(int) EMR3ExecuteVM(PVM pVM, PVMCPU pVCpu);
-VMMR3DECL(int) EMR3CheckRawForcedActions(PVM pVM, PVMCPU pVCpu);
-VMMR3DECL(int) EMR3Interpret(PVM pVM);
/**
* Command argument for EMR3RawSetMode().
@@ -248,25 +268,30 @@ typedef enum EMEXECPOLICY
EMEXECPOLICY_RECOMPILE_RING0,
/** Whether to recompile ring-3 code or execute it in raw/hm. */
EMEXECPOLICY_RECOMPILE_RING3,
+ /** Whether to only use IEM for execution. */
+ EMEXECPOLICY_IEM_ALL,
/** End of valid value (not included). */
EMEXECPOLICY_END,
/** The customary 32-bit type blowup. */
EMEXECPOLICY_32BIT_HACK = 0x7fffffff
} EMEXECPOLICY;
+VMMR3DECL(int) EMR3SetExecutionPolicy(PUVM pUVM, EMEXECPOLICY enmPolicy, bool fEnforce);
+VMMR3DECL(int) EMR3QueryExecutionPolicy(PUVM pUVM, EMEXECPOLICY enmPolicy, bool *pfEnforced);
-VMMR3DECL(int) EMR3SetExecutionPolicy(PVM pVM, EMEXECPOLICY enmPolicy, bool fEnforce);
-/** @} */
-#endif /* IN_RING3 */
-
+VMMR3_INT_DECL(int) EMR3Init(PVM pVM);
+VMMR3_INT_DECL(void) EMR3Relocate(PVM pVM);
+VMMR3_INT_DECL(void) EMR3ResetCpu(PVMCPU pVCpu);
+VMMR3_INT_DECL(void) EMR3Reset(PVM pVM);
+VMMR3_INT_DECL(int) EMR3Term(PVM pVM);
+VMMR3DECL(DECLNORETURN(void)) EMR3FatalError(PVMCPU pVCpu, int rc);
+VMMR3_INT_DECL(int) EMR3ExecuteVM(PVM pVM, PVMCPU pVCpu);
+VMMR3_INT_DECL(int) EMR3CheckRawForcedActions(PVM pVM, PVMCPU pVCpu);
+VMMR3_INT_DECL(int) EMR3NotifyResume(PVM pVM);
+VMMR3_INT_DECL(int) EMR3NotifySuspend(PVM pVM);
+VMMR3_INT_DECL(VBOXSTRICTRC) EMR3HmSingleInstruction(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
-#ifdef IN_RC
-/** @defgroup grp_em_gc The EM Guest Context API
- * @ingroup grp_em
- * @{
- */
-VMMRCDECL(int) EMGCTrap(PVM pVM, unsigned uTrap, PCPUMCTXCORE pRegFrame);
/** @} */
-#endif /* IN_RC */
+#endif /* IN_RING3 */
/** @} */
diff --git a/include/VBox/vmm/ftm.h b/include/VBox/vmm/ftm.h
index 2fc1ccfe..e8702d67 100644
--- a/include/VBox/vmm/ftm.h
+++ b/include/VBox/vmm/ftm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2010-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -40,24 +40,27 @@ RT_C_DECLS_BEGIN
*/
typedef enum FTMCHECKPOINTTYPE
{
+ FTMCHECKPOINTTYPE_INVALID = 0,
FTMCHECKPOINTTYPE_NETWORK,
FTMCHECKPOINTTYPE_STORAGE,
+ FTMCHECKPOINTTYPE_END,
FTMCHECKPOINTTYPE_32BIT_HACK = 0x7fffffff
} FTMCHECKPOINTTYPE;
-VMMDECL(bool) FTMIsDeltaLoadSaveActive(PVM pVM);
-VMMDECL(int) FTMSetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType);
+VMM_INT_DECL(bool) FTMIsDeltaLoadSaveActive(PVM pVM);
+VMM_INT_DECL(int) FTMSetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType);
#ifdef IN_RING3
/** @defgroup grp_ftm_r3 The FTM Host Context Ring-3 API
* @ingroup grp_ftm
* @{
*/
-VMMR3DECL(int) FTMR3PowerOn(PVM pVM, bool fMaster, unsigned uInterval, const char *pszAddress, unsigned uPort, const char *pszPassword);
-VMMR3DECL(int) FTMR3Init(PVM pVM);
-VMMR3DECL(int) FTMR3Term(PVM pVM);
-VMMR3DECL(int) FTMR3CancelStandby(PVM pVM);
-VMMR3DECL(int) FTMR3SetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType);
+VMMR3DECL(int) FTMR3PowerOn(PUVM pUVM, bool fMaster, unsigned uInterval, const char *pszAddress, unsigned uPort, const char *pszPassword);
+VMMR3DECL(int) FTMR3CancelStandby(PUVM pUVM);
+
+VMMR3_INT_DECL(int) FTMR3Init(PVM pVM);
+VMMR3_INT_DECL(int) FTMR3Term(PVM pVM);
+VMMR3_INT_DECL(int) FTMR3SetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType);
#endif /* IN_RING3 */
diff --git a/include/VBox/vmm/gmm.h b/include/VBox/vmm/gmm.h
index 0f93c94a..e5db104c 100644
--- a/include/VBox/vmm/gmm.h
+++ b/include/VBox/vmm/gmm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2007-2010 Oracle Corporation
+ * Copyright (C) 2007-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/include/VBox/vmm/gvm.h b/include/VBox/vmm/gvm.h
index b0d607de..0fe406b0 100644
--- a/include/VBox/vmm/gvm.h
+++ b/include/VBox/vmm/gvm.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007-2010 Oracle Corporation
+ * Copyright (C) 2007-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/include/VBox/vmm/gvmm.h b/include/VBox/vmm/gvmm.h
index e78d181b..eb86f9b2 100644
--- a/include/VBox/vmm/gvmm.h
+++ b/include/VBox/vmm/gvmm.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007-2010 Oracle Corporation
+ * Copyright (C) 2007-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/include/VBox/vmm/hm.h b/include/VBox/vmm/hm.h
new file mode 100644
index 00000000..12b94167
--- /dev/null
+++ b/include/VBox/vmm/hm.h
@@ -0,0 +1,265 @@
+/** @file
+ * HM - Intel/AMD VM Hardware Assisted Virtualization Manager (VMM)
+ */
+
+/*
+ * Copyright (C) 2006-2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_vmm_hm_h
+#define ___VBox_vmm_hm_h
+
+#include <VBox/vmm/pgm.h>
+#include <VBox/vmm/cpum.h>
+#include <VBox/vmm/vmm.h>
+#include <iprt/mp.h>
+
+
+/** @defgroup grp_hm The VM Hardware Manager API
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Checks whether HM (VT-x/AMD-V) is being used by this VM.
+ *
+ * @retval @c true if used.
+ * @retval @c false if software virtualization (raw-mode) is used.
+ *
+ * @param a_pVM The cross context VM structure.
+ * @sa HMIsEnabledNotMacro, HMR3IsEnabled
+ * @internal
+ */
+#if defined(VBOX_STRICT) && defined(IN_RING3)
+# define HMIsEnabled(a_pVM) HMIsEnabledNotMacro(a_pVM)
+#else
+# define HMIsEnabled(a_pVM) ((a_pVM)->fHMEnabled)
+#endif
+
+/**
+ * Checks whether raw-mode context is required for any purpose.
+ *
+ * @retval @c true if required either by raw-mode itself or by HM for doing
+ * switching the cpu to 64-bit mode.
+ * @retval @c false if not required.
+ *
+ * @param a_pVM The cross context VM structure.
+ * @internal
+ */
+#if HC_ARCH_BITS == 64
+# define HMIsRawModeCtxNeeded(a_pVM) (!HMIsEnabled(a_pVM))
+#else
+# define HMIsRawModeCtxNeeded(a_pVM) (!HMIsEnabled(a_pVM) || (a_pVM)->fHMNeedRawModeCtx)
+#endif
+
+ /**
+ * Check if the current CPU state is valid for emulating IO blocks in the recompiler
+ *
+ * @returns boolean
+ * @param a_pVCpu Pointer to the shared virtual CPU structure.
+ * @internal
+ */
+#define HMCanEmulateIoBlock(a_pVCpu) (!CPUMIsGuestInPagedProtectedMode(a_pVCpu))
+
+ /**
+ * Check if the current CPU state is valid for emulating IO blocks in the recompiler
+ *
+ * @returns boolean
+ * @param a_pCtx Pointer to the CPU context (within PVM).
+ * @internal
+ */
+#define HMCanEmulateIoBlockEx(a_pCtx) (!CPUMIsGuestInPagedProtectedModeEx(a_pCtx))
+
+/**
+ * Checks whether we're in the special hardware virtualization context.
+ * @returns true / false.
+ * @param a_pVCpu The caller's cross context virtual CPU structure.
+ * @thread EMT
+ */
+#ifdef IN_RING0
+# define HMIsInHwVirtCtx(a_pVCpu) (VMCPU_GET_STATE(a_pVCpu) == VMCPUSTATE_STARTED_HM)
+#else
+# define HMIsInHwVirtCtx(a_pVCpu) (false)
+#endif
+
+/**
+ * Checks whether we're in the special hardware virtualization context and we
+ * cannot perform long jump without guru meditating and possibly messing up the
+ * host and/or guest state.
+ *
+ * This is after we've turned interrupts off and such.
+ *
+ * @returns true / false.
+ * @param a_pVCpu The caller's cross context virtual CPU structure.
+ * @thread EMT
+ */
+#ifdef IN_RING0
+# define HMIsInHwVirtNoLongJmpCtx(a_pVCpu) (VMCPU_GET_STATE(a_pVCpu) == VMCPUSTATE_STARTED_EXEC)
+#else
+# define HMIsInHwVirtNoLongJmpCtx(a_pVCpu) (false)
+#endif
+
+/**
+ * 64-bit raw-mode (intermediate memory context) operations.
+ *
+ * These are special hypervisor eip values used when running 64-bit guests on
+ * 32-bit hosts. Each operation corresponds to a routine.
+ *
+ * @note Duplicated in the assembly code!
+ */
+typedef enum HM64ON32OP
+{
+ HM64ON32OP_INVALID = 0,
+ HM64ON32OP_VMXRCStartVM64,
+ HM64ON32OP_SVMRCVMRun64,
+ HM64ON32OP_HMRCSaveGuestFPU64,
+ HM64ON32OP_HMRCSaveGuestDebug64,
+ HM64ON32OP_HMRCTestSwitcher64,
+ HM64ON32OP_END,
+ HM64ON32OP_32BIT_HACK = 0x7fffffff
+} HM64ON32OP;
+
+VMMDECL(bool) HMIsEnabledNotMacro(PVM pVM);
+VMM_INT_DECL(int) HMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCVirt);
+VMM_INT_DECL(bool) HMHasPendingIrq(PVM pVM);
+VMM_INT_DECL(PX86PDPE) HMGetPaePdpes(PVMCPU pVCpu);
+VMM_INT_DECL(int) HMAmdIsSubjectToErratum170(uint32_t *pu32Family, uint32_t *pu32Model, uint32_t *pu32Stepping);
+VMM_INT_DECL(bool) HMSetSingleInstruction(PVMCPU pVCpu, bool fEnable);
+
+#ifndef IN_RC
+VMM_INT_DECL(int) HMFlushTLB(PVMCPU pVCpu);
+VMM_INT_DECL(int) HMFlushTLBOnAllVCpus(PVM pVM);
+VMM_INT_DECL(int) HMInvalidatePageOnAllVCpus(PVM pVM, RTGCPTR GCVirt);
+VMM_INT_DECL(int) HMInvalidatePhysPage(PVM pVM, RTGCPHYS GCPhys);
+VMM_INT_DECL(bool) HMIsNestedPagingActive(PVM pVM);
+VMM_INT_DECL(PGMMODE) HMGetShwPagingMode(PVM pVM);
+#else /* Nops in RC: */
+# define HMFlushTLB(pVCpu) do { } while (0)
+# define HMIsNestedPagingActive(pVM) false
+# define HMFlushTLBOnAllVCpus(pVM) do { } while (0)
+#endif
+
+#ifdef IN_RING0
+/** @defgroup grp_hm_r0 The VM Hardware Manager API
+ * @ingroup grp_hm
+ * @{
+ */
+VMMR0_INT_DECL(int) HMR0Init(void);
+VMMR0_INT_DECL(int) HMR0Term(void);
+VMMR0_INT_DECL(int) HMR0InitVM(PVM pVM);
+VMMR0_INT_DECL(int) HMR0TermVM(PVM pVM);
+VMMR0_INT_DECL(int) HMR0EnableAllCpus(PVM pVM);
+VMMR0_INT_DECL(int) HMR0EnterSwitcher(PVM pVM, VMMSWITCHER enmSwitcher, bool *pfVTxDisabled);
+VMMR0_INT_DECL(void) HMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled);
+
+VMMR0_INT_DECL(void) HMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext,
+ unsigned uPort, unsigned uAndVal, unsigned cbSize);
+VMMR0_INT_DECL(void) HMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext,
+ unsigned uPort, unsigned uAndVal, unsigned cbSize);
+
+/** @} */
+#endif /* IN_RING0 */
+
+
+#ifdef IN_RING3
+/** @defgroup grp_hm_r3 The VM Hardware Manager API
+ * @ingroup grp_hm
+ * @{
+ */
+VMMR3DECL(bool) HMR3IsEnabled(PUVM pUVM);
+VMMR3DECL(bool) HMR3IsNestedPagingActive(PUVM pUVM);
+VMMR3DECL(bool) HMR3IsVpidActive(PUVM pVUM);
+VMMR3DECL(bool) HMR3IsUXActive(PUVM pVUM);
+VMMR3DECL(bool) HMR3IsSvmEnabled(PUVM pUVM);
+VMMR3DECL(bool) HMR3IsVmxEnabled(PUVM pUVM);
+
+VMMR3_INT_DECL(bool) HMR3IsEventPending(PVMCPU pVCpu);
+VMMR3_INT_DECL(int) HMR3Init(PVM pVM);
+VMMR3_INT_DECL(int) HMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
+VMMR3_INT_DECL(void) HMR3Relocate(PVM pVM);
+VMMR3_INT_DECL(int) HMR3Term(PVM pVM);
+VMMR3_INT_DECL(void) HMR3Reset(PVM pVM);
+VMMR3_INT_DECL(void) HMR3ResetCpu(PVMCPU pVCpu);
+VMMR3_INT_DECL(void) HMR3CheckError(PVM pVM, int iStatusCode);
+VMMR3DECL(bool) HMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx);
+VMMR3_INT_DECL(void) HMR3NotifyScheduled(PVMCPU pVCpu);
+VMMR3_INT_DECL(void) HMR3NotifyEmulated(PVMCPU pVCpu);
+VMMR3_INT_DECL(bool) HMR3IsActive(PVMCPU pVCpu);
+VMMR3_INT_DECL(void) HMR3PagingModeChanged(PVM pVM, PVMCPU pVCpu, PGMMODE enmShadowMode, PGMMODE enmGuestMode);
+VMMR3_INT_DECL(int) HMR3EmulateIoBlock(PVM pVM, PCPUMCTX pCtx);
+VMMR3_INT_DECL(VBOXSTRICTRC) HMR3RestartPendingIOInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR3_INT_DECL(int) HMR3EnablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem);
+VMMR3_INT_DECL(int) HMR3DisablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem);
+VMMR3_INT_DECL(int) HMR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR3_INT_DECL(bool) HMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx);
+VMMR3_INT_DECL(bool) HMR3IsVmxPreemptionTimerUsed(PVM pVM);
+
+/** @} */
+#endif /* IN_RING3 */
+
+#ifdef IN_RING0
+/** @addtogroup grp_hm_r0
+ * @{
+ */
+/** Disables preemption if required. */
+# define HM_DISABLE_PREEMPT_IF_NEEDED() \
+ RTTHREADPREEMPTSTATE PreemptStateInternal = RTTHREADPREEMPTSTATE_INITIALIZER; \
+ bool fPreemptDisabledInternal = false; \
+ if (RTThreadPreemptIsEnabled(NIL_RTTHREAD)) \
+ { \
+ Assert(VMMR0ThreadCtxHooksAreRegistered(pVCpu)); \
+ RTThreadPreemptDisable(&PreemptStateInternal); \
+ fPreemptDisabledInternal = true; \
+ }
+
+/** Restores preemption if previously disabled by HM_DISABLE_PREEMPT(). */
+# define HM_RESTORE_PREEMPT_IF_NEEDED() \
+ do \
+ { \
+ if (fPreemptDisabledInternal) \
+ RTThreadPreemptRestore(&PreemptStateInternal); \
+ } while (0)
+
+VMMR0_INT_DECL(int) HMR0SetupVM(PVM pVM);
+VMMR0_INT_DECL(int) HMR0RunGuestCode(PVM pVM, PVMCPU pVCpu);
+VMMR0_INT_DECL(int) HMR0Enter(PVM pVM, PVMCPU pVCpu);
+VMMR0_INT_DECL(int) HMR0Leave(PVM pVM, PVMCPU pVCpu);
+VMMR0_INT_DECL(int) HMR0EnterCpu(PVMCPU pVCpu);
+VMMR0_INT_DECL(int) HMR0LeaveCpu(PVMCPU pVCpu);
+VMMR0_INT_DECL(void) HMR0ThreadCtxCallback(RTTHREADCTXEVENT enmEvent, void *pvUser);
+VMMR0_INT_DECL(bool) HMR0SuspendPending(void);
+
+# if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS)
+VMMR0_INT_DECL(int) HMR0SaveFPUState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR0_INT_DECL(int) HMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR0_INT_DECL(int) HMR0TestSwitcher3264(PVM pVM);
+# endif
+
+/** @} */
+#endif /* IN_RING0 */
+
+
+/** @} */
+RT_C_DECLS_END
+
+
+#endif
+
diff --git a/include/VBox/vmm/hwacc_svm.h b/include/VBox/vmm/hm_svm.h
index 8912e378..7a67c387 100644
--- a/include/VBox/vmm/hwacc_svm.h
+++ b/include/VBox/vmm/hm_svm.h
@@ -1,9 +1,9 @@
/** @file
- * HWACCM - SVM Structures and Definitions. (VMM)
+ * HM - SVM Structures and Definitions. (VMM)
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -32,7 +32,7 @@
#include <iprt/asm.h>
/** @defgroup grp_svm svm Types and Definitions
- * @ingroup grp_hwaccm
+ * @ingroup grp_hm
* @{
*/
@@ -56,13 +56,13 @@
#define AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID RT_BIT(6)
/** Bit 7 - DecodeAssist - Indicate decode assist is supported. */
#define AMD_CPUID_SVM_FEATURE_EDX_DECODE_ASSIST RT_BIT(7)
-/** Where did we get this from? */
-#define AMD_CPUID_SVM_FEATURE_EDX_SSE_3_5_DISABLE RT_BIT(9)
/** Bit 10 - PauseFilter - Indicates support for the PAUSE intercept filter. */
#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER RT_BIT(10)
/** Bit 12 - PauseFilterThreshold - Indicates support for the PAUSE
* intercept filter cycle count threshold. */
#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER_THRESHOLD RT_BIT(12)
+/** Bit 13 - AVIC - Advanced Virtual Interrupt Controller. */
+#define AMD_CPUID_SVM_FEATURE_EDX_AVIC RT_BIT(13)
/** @} */
@@ -70,7 +70,7 @@
* @{
*/
/** Invalid guest state in VMCB. */
-#define SVM_EXIT_INVALID -1
+#define SVM_EXIT_INVALID (-1)
/** Read from CR0-CR15. */
#define SVM_EXIT_READ_CR0 0x0
#define SVM_EXIT_READ_CR1 0x1
@@ -258,17 +258,24 @@
#define SVM_EXIT_WBINVD 0x89
/** MONITOR instruction. */
#define SVM_EXIT_MONITOR 0x8A
-/** MWAIT instruction uncond. */
-#define SVM_EXIT_MWAIT_UNCOND 0x8B
-/** MWAIT instruction when armed. */
+/** MWAIT instruction. */
+#define SVM_EXIT_MWAIT 0x8B
+/** MWAIT instruction, when armed. */
#define SVM_EXIT_MWAIT_ARMED 0x8C
/** Nested paging: host-level page fault occurred (EXITINFO1 contains fault errorcode; EXITINFO2 contains the guest physical address causing the fault). */
#define SVM_EXIT_NPF 0x400
-
+/** AVIC: Virtual IPI delivery not completed. */
+#define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401
+/** AVIC: Attempted access by guest to a vAPIC register not handled by AVIC
+ * hardware. */
+#define SVM_EXIT_AVIC_NOACCEL 0x402
+
+/** The maximum possible exit value. */
+#define SVM_EXIT_MAX (SVM_EXIT_AVIC_NOACCEL)
/** @} */
-/** @name SVM_VMCB.u64ExitInfo2
+/** @name SVMVMCB.u64ExitInfo2 for task switches
* @{
*/
/** Set to 1 if the task switch was caused by an IRET; else cleared to 0. */
@@ -281,7 +288,16 @@
#define SVM_EXIT2_TASK_SWITCH_EFLAGS_RF RT_BIT_64(48)
/** @} */
-/** @name SVM_VMCB.ctrl.u32InterceptCtrl1
+/** @name SVMVMCB.u64ExitInfo1 for MSR accesses
+ * @{
+ */
+/** The access was a read MSR. */
+#define SVM_EXIT1_MSR_READ 0x0
+/** The access was a write MSR. */
+#define SVM_EXIT1_MSR_WRITE 0x1
+/** @} */
+
+/** @name SVMVMCB.ctrl.u32InterceptCtrl1
* @{
*/
/** 0 Intercept INTR (physical maskable interrupt). */
@@ -351,7 +367,7 @@
/** @} */
-/** @name SVM_VMCB.ctrl.u32InterceptCtrl2
+/** @name SVMVMCB.ctrl.u32InterceptCtrl2
* @{
*/
/** 0 Intercept VMRUN instruction. */
@@ -377,27 +393,27 @@
/** 10 Intercept MONITOR instruction. */
#define SVM_CTRL2_INTERCEPT_MONITOR RT_BIT(10)
/** 11 Intercept MWAIT instruction unconditionally. */
-#define SVM_CTRL2_INTERCEPT_MWAIT_UNCOND RT_BIT(11)
+#define SVM_CTRL2_INTERCEPT_MWAIT RT_BIT(11)
/** 12 Intercept MWAIT instruction when armed. */
#define SVM_CTRL2_INTERCEPT_MWAIT_ARMED RT_BIT(12)
/** 13 Intercept XSETBV instruction. */
#define SVM_CTRL2_INTERCEPT_XSETBV RT_BIT(13)
/** @} */
-/** @name SVM_VMCB.ctrl.u64NestedPaging
+/** @name SVMVMCB.ctrl.u64NestedPaging
* @{
*/
#define SVM_NESTED_PAGING_ENABLE RT_BIT(0)
/** @} */
-/** @name SVM_VMCB.ctrl.u64IntShadow
+/** @name SVMVMCB.ctrl.u64IntShadow
* @{
*/
#define SVM_INTERRUPT_SHADOW_ACTIVE RT_BIT(0)
/** @} */
-/** @name SVM_INTCTRL.u3Type
+/** @name SVMINTCTRL.u3Type
* @{
*/
/** External or virtual interrupt. */
@@ -411,7 +427,7 @@
/** @} */
-/** @name SVM_VMCB.ctrl.TLBCtrl.n.u8TLBFlush
+/** @name SVMVMCB.ctrl.TLBCtrl.n.u8TLBFlush
* @{
*/
/** Flush nothing. */
@@ -450,13 +466,11 @@ typedef struct
uint64_t u64Base;
} SVMGDTR;
#pragma pack()
-
typedef SVMGDTR SVMIDTR;
/**
- * SVM Event injection structure.
+ * SVM Event injection structure (EVENTINJ and EXITINTINFO).
*/
-#pragma pack(1)
typedef union
{
struct
@@ -468,15 +482,14 @@ typedef union
uint32_t u1Valid : 1;
uint32_t u32ErrorCode : 32;
} n;
- uint64_t au64[1];
-} SVM_EVENT;
-#pragma pack()
-
+ uint64_t u;
+} SVMEVENT;
+/** Pointer to the SVMEVENT union. */
+typedef SVMEVENT *PSVMEVENT;
/**
- * SVM Interrupt control structure.
+ * SVM Interrupt control structure (Virtual Interrupt Control).
*/
-#pragma pack(1)
typedef union
{
struct
@@ -488,19 +501,17 @@ typedef union
uint32_t u1IgnoreTPR : 1;
uint32_t u3Reserved : 3;
uint32_t u1VIrqMasking : 1;
- uint32_t u7Reserved2 : 7;
+ uint32_t u6Reserved : 6;
+ uint32_t u1AvicEnable : 1;
uint32_t u8VIrqVector : 8;
uint32_t u24Reserved : 24;
} n;
- uint64_t au64[1];
-} SVM_INTCTRL;
-#pragma pack()
-
+ uint64_t u;
+} SVMINTCTRL;
/**
* SVM TLB control structure.
*/
-#pragma pack(1)
typedef union
{
struct
@@ -509,15 +520,12 @@ typedef union
uint32_t u8TLBFlush : 8;
uint32_t u24Reserved : 24;
} n;
- uint64_t au64[1];
-} SVM_TLBCTRL;
-#pragma pack()
-
+ uint64_t u;
+} SVMTLBCTRL;
/**
- * SVM IOIO exit structure.
+ * SVM IOIO exit structure (EXITINFO1 for IOIO intercepts).
*/
-#pragma pack(1)
typedef union
{
struct
@@ -535,29 +543,65 @@ typedef union
uint32_t u6Reserved : 6;
uint32_t u16Port : 16;
} n;
- uint32_t au32[1];
-} SVM_IOIO_EXIT;
-#pragma pack()
+ uint32_t u;
+} SVMIOIOEXIT;
+
+/** @name SVMIOIOEXIT.u1Type
+ * @{ */
+/** IO write. */
+#define SVM_IOIO_WRITE 0
+/** IO read. */
+#define SVM_IOIO_READ 1
+/** @}*/
/**
* SVM nested paging structure.
*/
-#pragma pack(1)
typedef union
{
struct
{
- uint32_t u1NestedPaging : 1; /**< enabled/disabled */
+ uint32_t u1NestedPaging : 1; /**< enabled/disabled */
} n;
- uint64_t au64[1];
-} SVM_NPCTRL;
-#pragma pack()
+ uint64_t u;
+} SVMNPCTRL;
+
+/**
+ * SVM AVIC.
+ */
+typedef union
+{
+ struct
+ {
+ uint64_t u12Reserved1 : 12;
+ uint64_t u40Addr : 40;
+ uint64_t u12Reserved2 : 12;
+ } n;
+ uint64_t u;
+} SVMAVIC;
+AssertCompileSize(SVMAVIC, 8);
+
+/**
+ * SVM AVIC PHYSICAL_TABLE pointer.
+ */
+typedef union
+{
+ struct
+ {
+ uint64_t u8LastGuestCoreId : 8;
+ uint64_t u4Reserved : 4;
+ uint64_t u40Addr : 40;
+ uint64_t u12Reserved : 12;
+ } n;
+ uint64_t u;
+} SVMAVICPHYS;
+AssertCompileSize(SVMAVICPHYS, 8);
/**
* SVM VM Control Block. (VMCB)
*/
#pragma pack(1)
-typedef struct _SVM_VMCB
+typedef struct SVMVMCB
{
/** Control Area. */
struct
@@ -577,7 +621,9 @@ typedef struct _SVM_VMCB
/** Offset 0x0C - Intercept control field 2. */
uint32_t u32InterceptCtrl2;
/** Offset 0x14-0x3F - Reserved. */
- uint8_t u8Reserved[0x3e - 0x14];
+ uint8_t u8Reserved[0x3c - 0x14];
+ /** Offset 0x3c - PAUSE filter threshold. */
+ uint16_t u16PauseFilterThreshold;
/** Offset 0x3e - PAUSE intercept filter count. */
uint16_t u16PauseFilterCount;
/** Offset 0x40 - Physical address of IOPM. */
@@ -587,9 +633,9 @@ typedef struct _SVM_VMCB
/** Offset 0x50 - TSC Offset. */
uint64_t u64TSCOffset;
/** Offset 0x58 - TLB control field. */
- SVM_TLBCTRL TLBCtrl;
+ SVMTLBCTRL TLBCtrl;
/** Offset 0x60 - Interrupt control field. */
- SVM_INTCTRL IntCtrl;
+ SVMINTCTRL IntCtrl;
/** Offset 0x68 - Interrupt shadow. */
uint64_t u64IntShadow;
/** Offset 0x70 - Exit code. */
@@ -599,29 +645,39 @@ typedef struct _SVM_VMCB
/** Offset 0x80 - Exit info 2. */
uint64_t u64ExitInfo2;
/** Offset 0x88 - Exit Interrupt info. */
- SVM_EVENT ExitIntInfo;
+ SVMEVENT ExitIntInfo;
/** Offset 0x90 - Nested Paging. */
- SVM_NPCTRL NestedPaging;
- /** Offset 0x98-0xA7 - Reserved. */
- uint8_t u8Reserved2[0xA8-0x98];
+ SVMNPCTRL NestedPaging;
+ /** Offset 0x98 - AVIC APIC BAR. */
+ SVMAVIC AvicBar;
+ /** Offset 0xA0-0xA7 - Reserved. */
+ uint8_t u8Reserved2[0xA8-0xA0];
/** Offset 0xA8 - Event injection. */
- SVM_EVENT EventInject;
+ SVMEVENT EventInject;
/** Offset 0xB0 - Host CR3 for nested paging. */
uint64_t u64NestedPagingCR3;
/** Offset 0xB8 - LBR Virtualization. */
uint64_t u64LBRVirt;
/** Offset 0xC0 - VMCB Clean Bits. */
- uint64_t u64VMCBCleanBits;
+ uint64_t u64VmcbCleanBits;
/** Offset 0xC8 - Next sequential instruction pointer. */
uint64_t u64NextRIP;
/** Offset 0xD0 - Number of bytes fetched. */
uint8_t cbInstrFetched;
/** Offset 0xD1 - Number of bytes fetched. */
uint8_t abInstr[15];
+ /** Offset 0xE0 - AVIC APIC_BACKING_PAGE pointer. */
+ SVMAVIC AvicBackingPagePtr;
+ /** Offset 0xE8-0xEF - Reserved. */
+ uint8_t u8Reserved3[0xF0 - 0xE8];
+ /** Offset 0xF0 - AVIC LOGICAL_TABLE pointer. */
+ SVMAVIC AvicLogicalTablePtr;
+ /** Offset 0xF8 - AVIC PHYSICAL_TABLE pointer. */
+ SVMAVICPHYS AvicPhysicalTablePtr;
} ctrl;
- /** Offset 0xC0-0x3FF - Reserved. */
- uint8_t u8Reserved3[0x400-0xE0];
+ /** Offset 0x100-0x3FF - Reserved. */
+ uint8_t u8Reserved3[0x400-0x100];
/** State Save Area. Starts at offset 0x400. */
struct
@@ -714,25 +770,36 @@ typedef struct _SVM_VMCB
/** Offset 0x698-0xFFF- Reserved. */
uint8_t u8Reserved10[0x1000-0x698];
-} SVM_VMCB;
+} SVMVMCB;
#pragma pack()
-AssertCompileSize(SVM_VMCB, 0x1000);
-AssertCompileMemberOffset(SVM_VMCB, ctrl.u16InterceptRdCRx, 0x000);
-AssertCompileMemberOffset(SVM_VMCB, ctrl.u16PauseFilterCount,0x03e);
-AssertCompileMemberOffset(SVM_VMCB, ctrl.TLBCtrl, 0x058);
-AssertCompileMemberOffset(SVM_VMCB, ctrl.ExitIntInfo, 0x088);
-AssertCompileMemberOffset(SVM_VMCB, ctrl.EventInject, 0x0A8);
-AssertCompileMemberOffset(SVM_VMCB, ctrl.abInstr, 0x0D1);
-AssertCompileMemberOffset(SVM_VMCB, guest, 0x400);
-AssertCompileMemberOffset(SVM_VMCB, guest.ES, 0x400);
-AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved4, 0x4A0);
-AssertCompileMemberOffset(SVM_VMCB, guest.u8CPL, 0x4CB);
-AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved6, 0x4D8);
-AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved7, 0x580);
-AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved9, 0x648);
-AssertCompileMemberOffset(SVM_VMCB, guest.u64GPAT, 0x668);
-AssertCompileMemberOffset(SVM_VMCB, guest.u64LASTEXCPTO, 0x690);
-AssertCompileMemberOffset(SVM_VMCB, u8Reserved10, 0x698);
+/** Pointer to the SVMVMCB structure. */
+typedef SVMVMCB *PSVMVMCB;
+AssertCompileMemberOffset(SVMVMCB, ctrl.u16InterceptRdCRx, 0x000);
+AssertCompileMemberOffset(SVMVMCB, ctrl.u16PauseFilterCount, 0x03e);
+AssertCompileMemberOffset(SVMVMCB, ctrl.TLBCtrl, 0x058);
+AssertCompileMemberOffset(SVMVMCB, ctrl.ExitIntInfo, 0x088);
+AssertCompileMemberOffset(SVMVMCB, ctrl.EventInject, 0x0A8);
+AssertCompileMemberOffset(SVMVMCB, ctrl.abInstr, 0x0D1);
+AssertCompileMemberOffset(SVMVMCB, ctrl.AvicBackingPagePtr, 0x0E0);
+AssertCompileMemberOffset(SVMVMCB, ctrl.AvicLogicalTablePtr, 0x0F0);
+AssertCompileMemberOffset(SVMVMCB, ctrl.AvicPhysicalTablePtr, 0x0F8);
+AssertCompileMemberOffset(SVMVMCB, guest, 0x400);
+AssertCompileMemberOffset(SVMVMCB, guest.ES, 0x400);
+AssertCompileMemberOffset(SVMVMCB, guest.TR, 0x490);
+AssertCompileMemberOffset(SVMVMCB, guest.u64EFER, 0x4D0);
+AssertCompileMemberOffset(SVMVMCB, guest.u64CR4, 0x548);
+AssertCompileMemberOffset(SVMVMCB, guest.u64RIP, 0x578);
+AssertCompileMemberOffset(SVMVMCB, guest.u64RSP, 0x5D8);
+AssertCompileMemberOffset(SVMVMCB, guest.u64CR2, 0x640);
+AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved4, 0x4A0);
+AssertCompileMemberOffset(SVMVMCB, guest.u8CPL, 0x4CB);
+AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved6, 0x4D8);
+AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved7, 0x580);
+AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved9, 0x648);
+AssertCompileMemberOffset(SVMVMCB, guest.u64GPAT, 0x668);
+AssertCompileMemberOffset(SVMVMCB, guest.u64LASTEXCPTO, 0x690);
+AssertCompileMemberOffset(SVMVMCB, u8Reserved10, 0x698);
+AssertCompileSize(SVMVMCB, 0x1000);
#ifdef IN_RING0
VMMR0DECL(int) SVMR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt);
diff --git a/include/VBox/vmm/hm_vmx.h b/include/VBox/vmm/hm_vmx.h
new file mode 100644
index 00000000..a84b01ca
--- /dev/null
+++ b/include/VBox/vmm/hm_vmx.h
@@ -0,0 +1,2343 @@
+/** @file
+ * HM - VMX Structures and Definitions. (VMM)
+ */
+
+/*
+ * Copyright (C) 2006-2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_vmm_vmx_h
+#define ___VBox_vmm_vmx_h
+
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include <iprt/x86.h>
+#include <iprt/assert.h>
+
+/* In Visual C++ versions prior to 2012, the vmx intrinsics are only available
+ when targeting AMD64. */
+#if RT_INLINE_ASM_USES_INTRIN >= 16 && defined(RT_ARCH_AMD64)
+# include <intrin.h>
+/* We always want them as intrinsics, no functions. */
+# pragma intrinsic(__vmx_on)
+# pragma intrinsic(__vmx_off)
+# pragma intrinsic(__vmx_vmclear)
+# pragma intrinsic(__vmx_vmptrld)
+# pragma intrinsic(__vmx_vmread)
+# pragma intrinsic(__vmx_vmwrite)
+# define VMX_USE_MSC_INTRINSICS 1
+#else
+# define VMX_USE_MSC_INTRINSICS 0
+#endif
+
+
+/** @defgroup grp_vmx vmx Types and Definitions
+ * @ingroup grp_hm
+ * @{
+ */
+
+/** @def HMVMXCPU_GST_SET_UPDATED
+ * Sets a guest-state-updated flag.
+ *
+ * @param pVCpu Pointer to the VMCPU.
+ * @param fFlag The flag to set.
+ */
+#define HMVMXCPU_GST_SET_UPDATED(pVCpu, fFlag) (ASMAtomicUoOrU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState, (fFlag)))
+
+/** @def HMVMXCPU_GST_IS_SET
+ * Checks if all the flags in the specified guest-state-updated set is pending.
+ *
+ * @param pVCpu Pointer to the VMCPU.
+ * @param fFlag The flag to check.
+ */
+#define HMVMXCPU_GST_IS_SET(pVCpu, fFlag) ((ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState) & (fFlag)) == (fFlag))
+
+/** @def HMVMXCPU_GST_IS_UPDATED
+ * Checks if one or more of the flags in the specified guest-state-updated set
+ * is updated.
+ *
+ * @param pVCpu Pointer to the VMCPU.
+ * @param fFlags The flags to check for.
+ */
+#define HMVMXCPU_GST_IS_UPDATED(pVCpu, fFlags) RT_BOOL(ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState) & (fFlags))
+
+/** @def HMVMXCPU_GST_RESET_TO
+ * Resets the guest-state-updated flags to the specified value.
+ *
+ * @param pVCpu Pointer to the VMCPU.
+ * @param fFlags The new value.
+ */
+#define HMVMXCPU_GST_RESET_TO(pVCpu, fFlags) (ASMAtomicUoWriteU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState, (fFlags)))
+
+/** @def HMVMXCPU_GST_VALUE
+ * Returns the current guest-state-updated flags value.
+ *
+ * @param pVCpu Pointer to the VMCPU.
+ */
+#define HMVMXCPU_GST_VALUE(pVCpu) (ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState))
+
+/** @name Host-state restoration flags.
+ * @{
+ */
+/* If you change these values don't forget to update the assembly defines as well! */
+#define VMX_RESTORE_HOST_SEL_DS RT_BIT(0)
+#define VMX_RESTORE_HOST_SEL_ES RT_BIT(1)
+#define VMX_RESTORE_HOST_SEL_FS RT_BIT(2)
+#define VMX_RESTORE_HOST_SEL_GS RT_BIT(3)
+#define VMX_RESTORE_HOST_SEL_TR RT_BIT(4)
+#define VMX_RESTORE_HOST_GDTR RT_BIT(5)
+#define VMX_RESTORE_HOST_IDTR RT_BIT(6)
+#define VMX_RESTORE_HOST_REQUIRED RT_BIT(7)
+/** @} */
+
+/**
+ * Host-state restoration structure.
+ * This holds host-state fields that require manual restoration.
+ * Assembly version found in hm_vmx.mac (should be automatically verified).
+ */
+typedef struct VMXRESTOREHOST
+{
+ RTSEL uHostSelDS; /* 0x00 */
+ RTSEL uHostSelES; /* 0x02 */
+ RTSEL uHostSelFS; /* 0x04 */
+ RTSEL uHostSelGS; /* 0x06 */
+ RTSEL uHostSelTR; /* 0x08 */
+ uint8_t abPadding0[4];
+ X86XDTR64 HostGdtr; /**< 0x0e - should be aligned by it's 64-bit member. */
+ uint8_t abPadding1[6];
+ X86XDTR64 HostIdtr; /**< 0x1e - should be aligned by it's 64-bit member. */
+ uint64_t uHostFSBase; /* 0x28 */
+ uint64_t uHostGSBase; /* 0x30 */
+} VMXRESTOREHOST;
+/** Pointer to VMXRESTOREHOST. */
+typedef VMXRESTOREHOST *PVMXRESTOREHOST;
+AssertCompileSize(X86XDTR64, 10);
+AssertCompileMemberOffset(VMXRESTOREHOST, HostGdtr.uAddr, 16);
+AssertCompileMemberOffset(VMXRESTOREHOST, HostIdtr.uAddr, 32);
+AssertCompileMemberOffset(VMXRESTOREHOST, uHostFSBase, 40);
+AssertCompileSize(VMXRESTOREHOST, 56);
+
+/** @name VMX HM-error codes for VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO.
+ * UFC = Unsupported Feature Combination.
+ * @{
+ */
+/** Unsupported pin-based VM-execution controls combo. */
+#define VMX_UFC_CTRL_PIN_EXEC 0
+/** Unsupported processor-based VM-execution controls combo. */
+#define VMX_UFC_CTRL_PROC_EXEC 1
+/** Unsupported pin-based VM-execution controls combo. */
+#define VMX_UFC_CTRL_PROC_MOV_DRX_EXIT 2
+/** Unsupported VM-entry controls combo. */
+#define VMX_UFC_CTRL_ENTRY 3
+/** Unsupported VM-exit controls combo. */
+#define VMX_UFC_CTRL_EXIT 4
+/** MSR storage capacity of the VMCS autoload/store area is not sufficient
+ * for storing host MSRs. */
+#define VMX_UFC_INSUFFICIENT_HOST_MSR_STORAGE 5
+/** MSR storage capacity of the VMCS autoload/store area is not sufficient
+ * for storing guest MSRs. */
+#define VMX_UFC_INSUFFICIENT_GUEST_MSR_STORAGE 6
+/** Invalid VMCS size. */
+#define VMX_UFC_INVALID_VMCS_SIZE 7
+/** @} */
+
+/** @name VMX HM-error codes for VERR_VMX_INVALID_GUEST_STATE.
+ * IGS = Invalid Guest State.
+ * @{
+ */
+/** An error occurred while checking invalid-guest-state. */
+#define VMX_IGS_ERROR 0
+/** The invalid guest-state checks did not find any reason why. */
+#define VMX_IGS_REASON_NOT_FOUND 1
+/** CR0 fixed1 bits invalid. */
+#define VMX_IGS_CR0_FIXED1 2
+/** CR0 fixed0 bits invalid. */
+#define VMX_IGS_CR0_FIXED0 3
+/** CR0.PE and CR0.PE invalid VT-x/host combination. */
+#define VMX_IGS_CR0_PG_PE_COMBO 4
+/** CR4 fixed1 bits invalid. */
+#define VMX_IGS_CR4_FIXED1 5
+/** CR4 fixed0 bits invalid. */
+#define VMX_IGS_CR4_FIXED0 6
+/** Reserved bits in VMCS' DEBUGCTL MSR field not set to 0 when
+ * VMX_VMCS_CTRL_ENTRY_LOAD_DEBUG is used. */
+#define VMX_IGS_DEBUGCTL_MSR_RESERVED 7
+/** CR0.PG not set for long-mode when not using unrestricted guest. */
+#define VMX_IGS_CR0_PG_LONGMODE 8
+/** CR4.PAE not set for long-mode guest when not using unrestricted guest. */
+#define VMX_IGS_CR4_PAE_LONGMODE 9
+/** CR4.PCIDE set for 32-bit guest. */
+#define VMX_IGS_CR4_PCIDE 10
+/** VMCS' DR7 reserved bits not set to 0. */
+#define VMX_IGS_DR7_RESERVED 11
+/** VMCS' PERF_GLOBAL MSR reserved bits not set to 0. */
+#define VMX_IGS_PERF_GLOBAL_MSR_RESERVED 12
+/** VMCS' EFER MSR reserved bits not set to 0. */
+#define VMX_IGS_EFER_MSR_RESERVED 13
+/** VMCS' EFER MSR.LMA does not match the IA32e mode guest control. */
+#define VMX_IGS_EFER_LMA_GUEST_MODE_MISMATCH 14
+/** VMCS' EFER MSR.LMA does not match CR0.PG of the guest when not using
+ * unrestricted guest. */
+#define VMX_IGS_EFER_LMA_PG_MISMATCH 15
+/** CS.Attr.P bit invalid. */
+#define VMX_IGS_CS_ATTR_P_INVALID 16
+/** CS.Attr reserved bits not set to 0. */
+#define VMX_IGS_CS_ATTR_RESERVED 17
+/** CS.Attr.G bit invalid. */
+#define VMX_IGS_CS_ATTR_G_INVALID 18
+/** CS is unusable. */
+#define VMX_IGS_CS_ATTR_UNUSABLE 19
+/** CS and SS DPL unequal. */
+#define VMX_IGS_CS_SS_ATTR_DPL_UNEQUAL 20
+/** CS and SS DPL mismatch. */
+#define VMX_IGS_CS_SS_ATTR_DPL_MISMATCH 21
+/** CS Attr.Type invalid. */
+#define VMX_IGS_CS_ATTR_TYPE_INVALID 22
+/** CS and SS RPL unequal. */
+#define VMX_IGS_SS_CS_RPL_UNEQUAL 23
+/** SS.Attr.DPL and SS RPL unequal. */
+#define VMX_IGS_SS_ATTR_DPL_RPL_UNEQUAL 24
+/** SS.Attr.DPL invalid for segment type. */
+#define VMX_IGS_SS_ATTR_DPL_INVALID 25
+/** SS.Attr.Type invalid. */
+#define VMX_IGS_SS_ATTR_TYPE_INVALID 26
+/** SS.Attr.P bit invalid. */
+#define VMX_IGS_SS_ATTR_P_INVALID 27
+/** SS.Attr reserved bits not set to 0. */
+#define VMX_IGS_SS_ATTR_RESERVED 28
+/** SS.Attr.G bit invalid. */
+#define VMX_IGS_SS_ATTR_G_INVALID 29
+/** DS.Attr.A bit invalid. */
+#define VMX_IGS_DS_ATTR_A_INVALID 30
+/** DS.Attr.P bit invalid. */
+#define VMX_IGS_DS_ATTR_P_INVALID 31
+/** DS.Attr.DPL and DS RPL unequal. */
+#define VMX_IGS_DS_ATTR_DPL_RPL_UNEQUAL 32
+/** DS.Attr reserved bits not set to 0. */
+#define VMX_IGS_DS_ATTR_RESERVED 33
+/** DS.Attr.G bit invalid. */
+#define VMX_IGS_DS_ATTR_G_INVALID 34
+/** DS.Attr.Type invalid. */
+#define VMX_IGS_DS_ATTR_TYPE_INVALID 35
+/** ES.Attr.A bit invalid. */
+#define VMX_IGS_ES_ATTR_A_INVALID 36
+/** ES.Attr.P bit invalid. */
+#define VMX_IGS_ES_ATTR_P_INVALID 37
+/** ES.Attr.DPL and DS RPL unequal. */
+#define VMX_IGS_ES_ATTR_DPL_RPL_UNEQUAL 38
+/** ES.Attr reserved bits not set to 0. */
+#define VMX_IGS_ES_ATTR_RESERVED 39
+/** ES.Attr.G bit invalid. */
+#define VMX_IGS_ES_ATTR_G_INVALID 40
+/** ES.Attr.Type invalid. */
+#define VMX_IGS_ES_ATTR_TYPE_INVALID 41
+/** FS.Attr.A bit invalid. */
+#define VMX_IGS_FS_ATTR_A_INVALID 42
+/** FS.Attr.P bit invalid. */
+#define VMX_IGS_FS_ATTR_P_INVALID 43
+/** FS.Attr.DPL and DS RPL unequal. */
+#define VMX_IGS_FS_ATTR_DPL_RPL_UNEQUAL 44
+/** FS.Attr reserved bits not set to 0. */
+#define VMX_IGS_FS_ATTR_RESERVED 45
+/** FS.Attr.G bit invalid. */
+#define VMX_IGS_FS_ATTR_G_INVALID 46
+/** FS.Attr.Type invalid. */
+#define VMX_IGS_FS_ATTR_TYPE_INVALID 47
+/** GS.Attr.A bit invalid. */
+#define VMX_IGS_GS_ATTR_A_INVALID 48
+/** GS.Attr.P bit invalid. */
+#define VMX_IGS_GS_ATTR_P_INVALID 49
+/** GS.Attr.DPL and DS RPL unequal. */
+#define VMX_IGS_GS_ATTR_DPL_RPL_UNEQUAL 50
+/** GS.Attr reserved bits not set to 0. */
+#define VMX_IGS_GS_ATTR_RESERVED 51
+/** GS.Attr.G bit invalid. */
+#define VMX_IGS_GS_ATTR_G_INVALID 52
+/** GS.Attr.Type invalid. */
+#define VMX_IGS_GS_ATTR_TYPE_INVALID 53
+/** V86 mode CS.Base invalid. */
+#define VMX_IGS_V86_CS_BASE_INVALID 54
+/** V86 mode CS.Limit invalid. */
+#define VMX_IGS_V86_CS_LIMIT_INVALID 55
+/** V86 mode CS.Attr invalid. */
+#define VMX_IGS_V86_CS_ATTR_INVALID 56
+/** V86 mode SS.Base invalid. */
+#define VMX_IGS_V86_SS_BASE_INVALID 57
+/** V86 mode SS.Limit invalid. */
+#define VMX_IGS_V86_SS_LIMIT_INVALID 59
+/** V86 mode SS.Attr invalid. */
+#define VMX_IGS_V86_SS_ATTR_INVALID 59
+/** V86 mode DS.Base invalid. */
+#define VMX_IGS_V86_DS_BASE_INVALID 60
+/** V86 mode DS.Limit invalid. */
+#define VMX_IGS_V86_DS_LIMIT_INVALID 61
+/** V86 mode DS.Attr invalid. */
+#define VMX_IGS_V86_DS_ATTR_INVALID 62
+/** V86 mode ES.Base invalid. */
+#define VMX_IGS_V86_ES_BASE_INVALID 63
+/** V86 mode ES.Limit invalid. */
+#define VMX_IGS_V86_ES_LIMIT_INVALID 64
+/** V86 mode ES.Attr invalid. */
+#define VMX_IGS_V86_ES_ATTR_INVALID 65
+/** V86 mode FS.Base invalid. */
+#define VMX_IGS_V86_FS_BASE_INVALID 66
+/** V86 mode FS.Limit invalid. */
+#define VMX_IGS_V86_FS_LIMIT_INVALID 67
+/** V86 mode FS.Attr invalid. */
+#define VMX_IGS_V86_FS_ATTR_INVALID 68
+/** V86 mode GS.Base invalid. */
+#define VMX_IGS_V86_GS_BASE_INVALID 69
+/** V86 mode GS.Limit invalid. */
+#define VMX_IGS_V86_GS_LIMIT_INVALID 70
+/** V86 mode GS.Attr invalid. */
+#define VMX_IGS_V86_GS_ATTR_INVALID 71
+/** Longmode CS.Base invalid. */
+#define VMX_IGS_LONGMODE_CS_BASE_INVALID 72
+/** Longmode SS.Base invalid. */
+#define VMX_IGS_LONGMODE_SS_BASE_INVALID 73
+/** Longmode DS.Base invalid. */
+#define VMX_IGS_LONGMODE_DS_BASE_INVALID 74
+/** Longmode ES.Base invalid. */
+#define VMX_IGS_LONGMODE_ES_BASE_INVALID 75
+/** SYSENTER ESP is not canonical. */
+#define VMX_IGS_SYSENTER_ESP_NOT_CANONICAL 76
+/** SYSENTER EIP is not canonical. */
+#define VMX_IGS_SYSENTER_EIP_NOT_CANONICAL 77
+/** PAT MSR invalid. */
+#define VMX_IGS_PAT_MSR_INVALID 78
+/** PAT MSR reserved bits not set to 0. */
+#define VMX_IGS_PAT_MSR_RESERVED 79
+/** GDTR.Base is not canonical. */
+#define VMX_IGS_GDTR_BASE_NOT_CANONICAL 80
+/** IDTR.Base is not canonical. */
+#define VMX_IGS_IDTR_BASE_NOT_CANONICAL 81
+/** GDTR.Limit invalid. */
+#define VMX_IGS_GDTR_LIMIT_INVALID 82
+/** IDTR.Limit invalid. */
+#define VMX_IGS_IDTR_LIMIT_INVALID 83
+/** Longmode RIP is invalid. */
+#define VMX_IGS_LONGMODE_RIP_INVALID 84
+/** RFLAGS reserved bits not set to 0. */
+#define VMX_IGS_RFLAGS_RESERVED 85
+/** RFLAGS RA1 reserved bits not set to 1. */
+#define VMX_IGS_RFLAGS_RESERVED1 86
+/** RFLAGS.VM (V86 mode) invalid. */
+#define VMX_IGS_RFLAGS_VM_INVALID 87
+/** RFLAGS.IF invalid. */
+#define VMX_IGS_RFLAGS_IF_INVALID 88
+/** Activity state invalid. */
+#define VMX_IGS_ACTIVITY_STATE_INVALID 89
+/** Activity state HLT invalid when SS.Attr.DPL is not zero. */
+#define VMX_IGS_ACTIVITY_STATE_HLT_INVALID 90
+/** Activity state ACTIVE invalid when block-by-STI or MOV SS. */
+#define VMX_IGS_ACTIVITY_STATE_ACTIVE_INVALID 91
+/** Activity state SIPI WAIT invalid. */
+#define VMX_IGS_ACTIVITY_STATE_SIPI_WAIT_INVALID 92
+/** Interruptibility state reserved bits not set to 0. */
+#define VMX_IGS_INTERRUPTIBILITY_STATE_RESERVED 93
+/** Interruptibility state cannot be block-by-STI -and- MOV SS. */
+#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_MOVSS_INVALID 94
+/** Interruptibility state block-by-STI invalid for EFLAGS. */
+#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_EFL_INVALID 95
+/** Interruptibility state invalid while trying to deliver external
+ * interrupt. */
+#define VMX_IGS_INTERRUPTIBILITY_STATE_EXT_INT_INVALID 96
+/** Interruptibility state block-by-MOVSS invalid while trying to deliver an
+ * NMI. */
+#define VMX_IGS_INTERRUPTIBILITY_STATE_MOVSS_INVALID 97
+/** Interruptibility state block-by-SMI invalid when CPU is not in SMM. */
+#define VMX_IGS_INTERRUPTIBILITY_STATE_SMI_INVALID 98
+/** Interruptibility state block-by-SMI invalid when trying to enter SMM. */
+#define VMX_IGS_INTERRUPTIBILITY_STATE_SMI_SMM_INVALID 99
+/** Interruptibilty state block-by-STI (maybe) invalid when trying to deliver
+ * an NMI. */
+#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_INVALID 100
+/** Interruptibility state block-by-NMI invalid when virtual-NMIs control is
+ * active. */
+#define VMX_IGS_INTERRUPTIBILITY_STATE_NMI_INVALID 101
+/** Pending debug exceptions reserved bits not set to 0. */
+#define VMX_IGS_PENDING_DEBUG_RESERVED 102
+/** Longmode pending debug exceptions reserved bits not set to 0. */
+#define VMX_IGS_LONGMODE_PENDING_DEBUG_RESERVED 103
+/** Pending debug exceptions.BS bit is not set when it should be. */
+#define VMX_IGS_PENDING_DEBUG_XCPT_BS_NOT_SET 104
+/** Pending debug exceptions.BS bit is not clear when it should be. */
+#define VMX_IGS_PENDING_DEBUG_XCPT_BS_NOT_CLEAR 105
+/** VMCS link pointer reserved bits not set to 0. */
+#define VMX_IGS_VMCS_LINK_PTR_RESERVED 106
+/** TR cannot index into LDT, TI bit MBZ. */
+#define VMX_IGS_TR_TI_INVALID 107
+/** LDTR cannot index into LDT. TI bit MBZ. */
+#define VMX_IGS_LDTR_TI_INVALID 108
+/** TR.Base is not canonical. */
+#define VMX_IGS_TR_BASE_NOT_CANONICAL 109
+/** FS.Base is not canonical. */
+#define VMX_IGS_FS_BASE_NOT_CANONICAL 110
+/** GS.Base is not canonical. */
+#define VMX_IGS_GS_BASE_NOT_CANONICAL 111
+/** LDTR.Base is not canonical. */
+#define VMX_IGS_LDTR_BASE_NOT_CANONICAL 112
+/** TR is unusable. */
+#define VMX_IGS_TR_ATTR_UNUSABLE 113
+/** TR.Attr.S bit invalid. */
+#define VMX_IGS_TR_ATTR_S_INVALID 114
+/** TR is not present. */
+#define VMX_IGS_TR_ATTR_P_INVALID 115
+/** TR.Attr reserved bits not set to 0. */
+#define VMX_IGS_TR_ATTR_RESERVED 116
+/** TR.Attr.G bit invalid. */
+#define VMX_IGS_TR_ATTR_G_INVALID 117
+/** Longmode TR.Attr.Type invalid. */
+#define VMX_IGS_LONGMODE_TR_ATTR_TYPE_INVALID 118
+/** TR.Attr.Type invalid. */
+#define VMX_IGS_TR_ATTR_TYPE_INVALID 119
+/** CS.Attr.S invalid. */
+#define VMX_IGS_CS_ATTR_S_INVALID 120
+/** CS.Attr.DPL invalid. */
+#define VMX_IGS_CS_ATTR_DPL_INVALID 121
+/** PAE PDPTE reserved bits not set to 0. */
+#define VMX_IGS_PAE_PDPTE_RESERVED 123
+/** @} */
+
+/** @name VMX VMCS-Read cache indices.
+ * @{
+ */
+# define VMX_VMCS_GUEST_ES_BASE_CACHE_IDX 0
+# define VMX_VMCS_GUEST_CS_BASE_CACHE_IDX 1
+# define VMX_VMCS_GUEST_SS_BASE_CACHE_IDX 2
+# define VMX_VMCS_GUEST_DS_BASE_CACHE_IDX 3
+# define VMX_VMCS_GUEST_FS_BASE_CACHE_IDX 4
+# define VMX_VMCS_GUEST_GS_BASE_CACHE_IDX 5
+# define VMX_VMCS_GUEST_LDTR_BASE_CACHE_IDX 6
+# define VMX_VMCS_GUEST_TR_BASE_CACHE_IDX 7
+# define VMX_VMCS_GUEST_GDTR_BASE_CACHE_IDX 8
+# define VMX_VMCS_GUEST_IDTR_BASE_CACHE_IDX 9
+# define VMX_VMCS_GUEST_RSP_CACHE_IDX 10
+# define VMX_VMCS_GUEST_RIP_CACHE_IDX 11
+# define VMX_VMCS_GUEST_SYSENTER_ESP_CACHE_IDX 12
+# define VMX_VMCS_GUEST_SYSENTER_EIP_CACHE_IDX 13
+# define VMX_VMCS_RO_EXIT_QUALIFICATION_CACHE_IDX 14
+# define VMX_VMCS_MAX_CACHE_IDX (VMX_VMCS_RO_EXIT_QUALIFICATION_CACHE_IDX + 1)
+# define VMX_VMCS_GUEST_CR3_CACHE_IDX 15
+# define VMX_VMCS_MAX_NESTED_PAGING_CACHE_IDX (VMX_VMCS_GUEST_CR3_CACHE_IDX + 1)
+/** @} */
+
+/** @name VMX EPT paging structures
+ * @{
+ */
+
+/**
+ * Number of page table entries in the EPT. (PDPTE/PDE/PTE)
+ */
+#define EPT_PG_ENTRIES X86_PG_PAE_ENTRIES
+
+/**
+ * EPT Page Directory Pointer Entry. Bit view.
+ * @todo uint64_t isn't safe for bitfields (gcc pedantic warnings, and IIRC,
+ * this did cause trouble with one compiler/version).
+ */
+#pragma pack(1)
+typedef struct EPTPML4EBITS
+{
+ /** Present bit. */
+ uint64_t u1Present : 1;
+ /** Writable bit. */
+ uint64_t u1Write : 1;
+ /** Executable bit. */
+ uint64_t u1Execute : 1;
+ /** Reserved (must be 0). */
+ uint64_t u5Reserved : 5;
+ /** Available for software. */
+ uint64_t u4Available : 4;
+ /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
+ uint64_t u40PhysAddr : 40;
+ /** Availabe for software. */
+ uint64_t u12Available : 12;
+} EPTPML4EBITS;
+#pragma pack()
+AssertCompileSize(EPTPML4EBITS, 8);
+
+/** Bits 12-51 - - EPT - Physical Page number of the next level. */
+#define EPT_PML4E_PG_MASK X86_PML4E_PG_MASK
+/** The page shift to get the PML4 index. */
+#define EPT_PML4_SHIFT X86_PML4_SHIFT
+/** The PML4 index mask (apply to a shifted page address). */
+#define EPT_PML4_MASK X86_PML4_MASK
+
+/**
+ * EPT PML4E.
+ */
+#pragma pack(1)
+typedef union EPTPML4E
+{
+ /** Normal view. */
+ EPTPML4EBITS n;
+ /** Unsigned integer view. */
+ X86PGPAEUINT u;
+ /** 64 bit unsigned integer view. */
+ uint64_t au64[1];
+ /** 32 bit unsigned integer view. */
+ uint32_t au32[2];
+} EPTPML4E;
+#pragma pack()
+/** Pointer to a PML4 table entry. */
+typedef EPTPML4E *PEPTPML4E;
+/** Pointer to a const PML4 table entry. */
+typedef const EPTPML4E *PCEPTPML4E;
+AssertCompileSize(EPTPML4E, 8);
+
+/**
+ * EPT PML4 Table.
+ */
+#pragma pack(1)
+typedef struct EPTPML4
+{
+ EPTPML4E a[EPT_PG_ENTRIES];
+} EPTPML4;
+#pragma pack()
+/** Pointer to an EPT PML4 Table. */
+typedef EPTPML4 *PEPTPML4;
+/** Pointer to a const EPT PML4 Table. */
+typedef const EPTPML4 *PCEPTPML4;
+
+/**
+ * EPT Page Directory Pointer Entry. Bit view.
+ */
+#pragma pack(1)
+typedef struct EPTPDPTEBITS
+{
+ /** Present bit. */
+ uint64_t u1Present : 1;
+ /** Writable bit. */
+ uint64_t u1Write : 1;
+ /** Executable bit. */
+ uint64_t u1Execute : 1;
+ /** Reserved (must be 0). */
+ uint64_t u5Reserved : 5;
+ /** Available for software. */
+ uint64_t u4Available : 4;
+ /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
+ uint64_t u40PhysAddr : 40;
+ /** Availabe for software. */
+ uint64_t u12Available : 12;
+} EPTPDPTEBITS;
+#pragma pack()
+AssertCompileSize(EPTPDPTEBITS, 8);
+
+/** Bits 12-51 - - EPT - Physical Page number of the next level. */
+#define EPT_PDPTE_PG_MASK X86_PDPE_PG_MASK
+/** The page shift to get the PDPT index. */
+#define EPT_PDPT_SHIFT X86_PDPT_SHIFT
+/** The PDPT index mask (apply to a shifted page address). */
+#define EPT_PDPT_MASK X86_PDPT_MASK_AMD64
+
+/**
+ * EPT Page Directory Pointer.
+ */
+#pragma pack(1)
+typedef union EPTPDPTE
+{
+ /** Normal view. */
+ EPTPDPTEBITS n;
+ /** Unsigned integer view. */
+ X86PGPAEUINT u;
+ /** 64 bit unsigned integer view. */
+ uint64_t au64[1];
+ /** 32 bit unsigned integer view. */
+ uint32_t au32[2];
+} EPTPDPTE;
+#pragma pack()
+/** Pointer to an EPT Page Directory Pointer Entry. */
+typedef EPTPDPTE *PEPTPDPTE;
+/** Pointer to a const EPT Page Directory Pointer Entry. */
+typedef const EPTPDPTE *PCEPTPDPTE;
+AssertCompileSize(EPTPDPTE, 8);
+
+/**
+ * EPT Page Directory Pointer Table.
+ */
+#pragma pack(1)
+typedef struct EPTPDPT
+{
+ EPTPDPTE a[EPT_PG_ENTRIES];
+} EPTPDPT;
+#pragma pack()
+/** Pointer to an EPT Page Directory Pointer Table. */
+typedef EPTPDPT *PEPTPDPT;
+/** Pointer to a const EPT Page Directory Pointer Table. */
+typedef const EPTPDPT *PCEPTPDPT;
+
+
+/**
+ * EPT Page Directory Table Entry. Bit view.
+ */
+#pragma pack(1)
+typedef struct EPTPDEBITS
+{
+ /** Present bit. */
+ uint64_t u1Present : 1;
+ /** Writable bit. */
+ uint64_t u1Write : 1;
+ /** Executable bit. */
+ uint64_t u1Execute : 1;
+ /** Reserved (must be 0). */
+ uint64_t u4Reserved : 4;
+ /** Big page (must be 0 here). */
+ uint64_t u1Size : 1;
+ /** Available for software. */
+ uint64_t u4Available : 4;
+ /** Physical address of page table. Restricted by maximum physical address width of the cpu. */
+ uint64_t u40PhysAddr : 40;
+ /** Availabe for software. */
+ uint64_t u12Available : 12;
+} EPTPDEBITS;
+#pragma pack()
+AssertCompileSize(EPTPDEBITS, 8);
+
+/** Bits 12-51 - - EPT - Physical Page number of the next level. */
+#define EPT_PDE_PG_MASK X86_PDE_PAE_PG_MASK
+/** The page shift to get the PD index. */
+#define EPT_PD_SHIFT X86_PD_PAE_SHIFT
+/** The PD index mask (apply to a shifted page address). */
+#define EPT_PD_MASK X86_PD_PAE_MASK
+
+/**
+ * EPT 2MB Page Directory Table Entry. Bit view.
+ */
+#pragma pack(1)
+typedef struct EPTPDE2MBITS
+{
+ /** Present bit. */
+ uint64_t u1Present : 1;
+ /** Writable bit. */
+ uint64_t u1Write : 1;
+ /** Executable bit. */
+ uint64_t u1Execute : 1;
+ /** EPT Table Memory Type. MBZ for non-leaf nodes. */
+ uint64_t u3EMT : 3;
+ /** Ignore PAT memory type */
+ uint64_t u1IgnorePAT : 1;
+ /** Big page (must be 1 here). */
+ uint64_t u1Size : 1;
+ /** Available for software. */
+ uint64_t u4Available : 4;
+ /** Reserved (must be 0). */
+ uint64_t u9Reserved : 9;
+ /** Physical address of the 2MB page. Restricted by maximum physical address width of the cpu. */
+ uint64_t u31PhysAddr : 31;
+ /** Availabe for software. */
+ uint64_t u12Available : 12;
+} EPTPDE2MBITS;
+#pragma pack()
+AssertCompileSize(EPTPDE2MBITS, 8);
+
+/** Bits 21-51 - - EPT - Physical Page number of the next level. */
+#define EPT_PDE2M_PG_MASK X86_PDE2M_PAE_PG_MASK
+
+/**
+ * EPT Page Directory Table Entry.
+ */
+#pragma pack(1)
+typedef union EPTPDE
+{
+ /** Normal view. */
+ EPTPDEBITS n;
+ /** 2MB view (big). */
+ EPTPDE2MBITS b;
+ /** Unsigned integer view. */
+ X86PGPAEUINT u;
+ /** 64 bit unsigned integer view. */
+ uint64_t au64[1];
+ /** 32 bit unsigned integer view. */
+ uint32_t au32[2];
+} EPTPDE;
+#pragma pack()
+/** Pointer to an EPT Page Directory Table Entry. */
+typedef EPTPDE *PEPTPDE;
+/** Pointer to a const EPT Page Directory Table Entry. */
+typedef const EPTPDE *PCEPTPDE;
+AssertCompileSize(EPTPDE, 8);
+
+/**
+ * EPT Page Directory Table.
+ */
+#pragma pack(1)
+typedef struct EPTPD
+{
+ EPTPDE a[EPT_PG_ENTRIES];
+} EPTPD;
+#pragma pack()
+/** Pointer to an EPT Page Directory Table. */
+typedef EPTPD *PEPTPD;
+/** Pointer to a const EPT Page Directory Table. */
+typedef const EPTPD *PCEPTPD;
+
+
+/**
+ * EPT Page Table Entry. Bit view.
+ */
+#pragma pack(1)
+typedef struct EPTPTEBITS
+{
+ /** 0 - Present bit.
+ * @remark This is a convenience "misnomer". The bit actually indicates
+ * read access and the CPU will consider an entry with any of the
+ * first three bits set as present. Since all our valid entries
+ * will have this bit set, it can be used as a present indicator
+ * and allow some code sharing. */
+ uint64_t u1Present : 1;
+ /** 1 - Writable bit. */
+ uint64_t u1Write : 1;
+ /** 2 - Executable bit. */
+ uint64_t u1Execute : 1;
+ /** 5:3 - EPT Memory Type. MBZ for non-leaf nodes. */
+ uint64_t u3EMT : 3;
+ /** 6 - Ignore PAT memory type */
+ uint64_t u1IgnorePAT : 1;
+ /** 11:7 - Available for software. */
+ uint64_t u5Available : 5;
+ /** 51:12 - Physical address of page. Restricted by maximum physical
+ * address width of the cpu. */
+ uint64_t u40PhysAddr : 40;
+ /** 63:52 - Available for software. */
+ uint64_t u12Available : 12;
+} EPTPTEBITS;
+#pragma pack()
+AssertCompileSize(EPTPTEBITS, 8);
+
+/** Bits 12-51 - - EPT - Physical Page number of the next level. */
+#define EPT_PTE_PG_MASK X86_PTE_PAE_PG_MASK
+/** The page shift to get the EPT PTE index. */
+#define EPT_PT_SHIFT X86_PT_PAE_SHIFT
+/** The EPT PT index mask (apply to a shifted page address). */
+#define EPT_PT_MASK X86_PT_PAE_MASK
+
+/**
+ * EPT Page Table Entry.
+ */
+#pragma pack(1)
+typedef union EPTPTE
+{
+ /** Normal view. */
+ EPTPTEBITS n;
+ /** Unsigned integer view. */
+ X86PGPAEUINT u;
+ /** 64 bit unsigned integer view. */
+ uint64_t au64[1];
+ /** 32 bit unsigned integer view. */
+ uint32_t au32[2];
+} EPTPTE;
+#pragma pack()
+/** Pointer to an EPT Page Directory Table Entry. */
+typedef EPTPTE *PEPTPTE;
+/** Pointer to a const EPT Page Directory Table Entry. */
+typedef const EPTPTE *PCEPTPTE;
+AssertCompileSize(EPTPTE, 8);
+
+/**
+ * EPT Page Table.
+ */
+#pragma pack(1)
+typedef struct EPTPT
+{
+ EPTPTE a[EPT_PG_ENTRIES];
+} EPTPT;
+#pragma pack()
+/** Pointer to an extended page table. */
+typedef EPTPT *PEPTPT;
+/** Pointer to a const extended table. */
+typedef const EPTPT *PCEPTPT;
+
+/**
+ * VPID flush types.
+ */
+typedef enum
+{
+ /** Invalidate a specific page. */
+ VMX_FLUSH_VPID_INDIV_ADDR = 0,
+ /** Invalidate one context (specific VPID). */
+ VMX_FLUSH_VPID_SINGLE_CONTEXT = 1,
+ /** Invalidate all contexts (all VPIDs). */
+ VMX_FLUSH_VPID_ALL_CONTEXTS = 2,
+ /** Invalidate a single VPID context retaining global mappings. */
+ VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS = 3,
+ /** Unsupported by VirtualBox. */
+ VMX_FLUSH_VPID_NOT_SUPPORTED = 0xbad,
+ /** Unsupported by CPU. */
+ VMX_FLUSH_VPID_NONE = 0xb00,
+ /** 32bit hackishness. */
+ VMX_FLUSH_VPID_32BIT_HACK = 0x7fffffff
+} VMX_FLUSH_VPID;
+
+/**
+ * EPT flush types.
+ */
+typedef enum
+{
+ /** Invalidate one context (specific EPT). */
+ VMX_FLUSH_EPT_SINGLE_CONTEXT = 1,
+ /* Invalidate all contexts (all EPTs) */
+ VMX_FLUSH_EPT_ALL_CONTEXTS = 2,
+ /** Unsupported by VirtualBox. */
+ VMX_FLUSH_EPT_NOT_SUPPORTED = 0xbad,
+ /** Unsupported by CPU. */
+ VMX_FLUSH_EPT_NONE = 0xb00,
+ /** 32bit hackishness. */
+ VMX_FLUSH_EPT_32BIT_HACK = 0x7fffffff
+} VMX_FLUSH_EPT;
+/** @} */
+
+/** @name MSR autoload/store elements
+ * @{
+ */
+#pragma pack(1)
+typedef struct
+{
+ uint32_t u32Msr;
+ uint32_t u32Reserved;
+ uint64_t u64Value;
+} VMXAUTOMSR;
+#pragma pack()
+/** Pointer to an MSR load/store element. */
+typedef VMXAUTOMSR *PVMXAUTOMSR;
+/** Pointer to a const MSR load/store element. */
+typedef const VMXAUTOMSR *PCVMXAUTOMSR;
+/** @} */
+
+/** @name VMX-capability qword
+ * @{
+ */
+#pragma pack(1)
+typedef union
+{
+ struct
+ {
+ /** Bits set here -must- be set in the correpsonding VM-execution controls. */
+ uint32_t disallowed0;
+ /** Bits cleared here -must- be cleared in the corresponding VM-execution
+ * controls. */
+ uint32_t allowed1;
+ } n;
+ uint64_t u;
+} VMX_CAPABILITY;
+#pragma pack()
+/** @} */
+
+/** @name VMX MSRs.
+ * @{
+ */
+typedef struct VMXMSRS
+{
+ uint64_t u64FeatureCtrl;
+ uint64_t u64BasicInfo;
+ VMX_CAPABILITY VmxPinCtls;
+ VMX_CAPABILITY VmxProcCtls;
+ VMX_CAPABILITY VmxProcCtls2;
+ VMX_CAPABILITY VmxExit;
+ VMX_CAPABILITY VmxEntry;
+ uint64_t u64Misc;
+ uint64_t u64Cr0Fixed0;
+ uint64_t u64Cr0Fixed1;
+ uint64_t u64Cr4Fixed0;
+ uint64_t u64Cr4Fixed1;
+ uint64_t u64VmcsEnum;
+ uint64_t u64Vmfunc;
+ uint64_t u64EptVpidCaps;
+} VMXMSRS;
+/** Pointer to a VMXMSRS struct. */
+typedef VMXMSRS *PVMXMSRS;
+/** @} */
+
+/** @name VMX EFLAGS reserved bits.
+ * @{
+ */
+/** And-mask for setting reserved bits to zero */
+#define VMX_EFLAGS_RESERVED_0 (~0xffc08028)
+/** Or-mask for setting reserved bits to 1 */
+#define VMX_EFLAGS_RESERVED_1 0x00000002
+/** @} */
+
+/** @name VMX Basic Exit Reasons.
+ * @{
+ */
+/** -1 Invalid exit code */
+#define VMX_EXIT_INVALID -1
+/** 0 Exception or non-maskable interrupt (NMI). */
+#define VMX_EXIT_XCPT_OR_NMI 0
+/** 1 External interrupt. */
+#define VMX_EXIT_EXT_INT 1
+/** 2 Triple fault. */
+#define VMX_EXIT_TRIPLE_FAULT 2
+/** 3 INIT signal. */
+#define VMX_EXIT_INIT_SIGNAL 3
+/** 4 Start-up IPI (SIPI). */
+#define VMX_EXIT_SIPI 4
+/** 5 I/O system-management interrupt (SMI). */
+#define VMX_EXIT_IO_SMI 5
+/** 6 Other SMI. */
+#define VMX_EXIT_SMI 6
+/** 7 Interrupt window exiting. */
+#define VMX_EXIT_INT_WINDOW 7
+/** 8 NMI window exiting. */
+#define VMX_EXIT_NMI_WINDOW 8
+/** 9 Task switch. */
+#define VMX_EXIT_TASK_SWITCH 9
+/** 10 Guest software attempted to execute CPUID. */
+#define VMX_EXIT_CPUID 10
+/** 10 Guest software attempted to execute GETSEC. */
+#define VMX_EXIT_GETSEC 11
+/** 12 Guest software attempted to execute HLT. */
+#define VMX_EXIT_HLT 12
+/** 13 Guest software attempted to execute INVD. */
+#define VMX_EXIT_INVD 13
+/** 14 Guest software attempted to execute INVLPG. */
+#define VMX_EXIT_INVLPG 14
+/** 15 Guest software attempted to execute RDPMC. */
+#define VMX_EXIT_RDPMC 15
+/** 16 Guest software attempted to execute RDTSC. */
+#define VMX_EXIT_RDTSC 16
+/** 17 Guest software attempted to execute RSM in SMM. */
+#define VMX_EXIT_RSM 17
+/** 18 Guest software executed VMCALL. */
+#define VMX_EXIT_VMCALL 18
+/** 19 Guest software executed VMCLEAR. */
+#define VMX_EXIT_VMCLEAR 19
+/** 20 Guest software executed VMLAUNCH. */
+#define VMX_EXIT_VMLAUNCH 20
+/** 21 Guest software executed VMPTRLD. */
+#define VMX_EXIT_VMPTRLD 21
+/** 22 Guest software executed VMPTRST. */
+#define VMX_EXIT_VMPTRST 22
+/** 23 Guest software executed VMREAD. */
+#define VMX_EXIT_VMREAD 23
+/** 24 Guest software executed VMRESUME. */
+#define VMX_EXIT_VMRESUME 24
+/** 25 Guest software executed VMWRITE. */
+#define VMX_EXIT_VMWRITE 25
+/** 26 Guest software executed VMXOFF. */
+#define VMX_EXIT_VMXOFF 26
+/** 27 Guest software executed VMXON. */
+#define VMX_EXIT_VMXON 27
+/** 28 Control-register accesses. */
+#define VMX_EXIT_MOV_CRX 28
+/** 29 Debug-register accesses. */
+#define VMX_EXIT_MOV_DRX 29
+/** 30 I/O instruction. */
+#define VMX_EXIT_IO_INSTR 30
+/** 31 RDMSR. Guest software attempted to execute RDMSR. */
+#define VMX_EXIT_RDMSR 31
+/** 32 WRMSR. Guest software attempted to execute WRMSR. */
+#define VMX_EXIT_WRMSR 32
+/** 33 VM-entry failure due to invalid guest state. */
+#define VMX_EXIT_ERR_INVALID_GUEST_STATE 33
+/** 34 VM-entry failure due to MSR loading. */
+#define VMX_EXIT_ERR_MSR_LOAD 34
+/** 36 Guest software executed MWAIT. */
+#define VMX_EXIT_MWAIT 36
+/** 37 VM exit due to monitor trap flag. */
+#define VMX_EXIT_MTF 37
+/** 39 Guest software attempted to execute MONITOR. */
+#define VMX_EXIT_MONITOR 39
+/** 40 Guest software attempted to execute PAUSE. */
+#define VMX_EXIT_PAUSE 40
+/** 41 VM-entry failure due to machine-check. */
+#define VMX_EXIT_ERR_MACHINE_CHECK 41
+/** 43 TPR below threshold. Guest software executed MOV to CR8. */
+#define VMX_EXIT_TPR_BELOW_THRESHOLD 43
+/** 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */
+#define VMX_EXIT_APIC_ACCESS 44
+/** 46 Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT. */
+#define VMX_EXIT_XDTR_ACCESS 46
+/** 47 Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR. */
+#define VMX_EXIT_TR_ACCESS 47
+/** 48 EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures. */
+#define VMX_EXIT_EPT_VIOLATION 48
+/** 49 EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry. */
+#define VMX_EXIT_EPT_MISCONFIG 49
+/** 50 INVEPT. Guest software attempted to execute INVEPT. */
+#define VMX_EXIT_INVEPT 50
+/** 51 RDTSCP. Guest software attempted to execute RDTSCP. */
+#define VMX_EXIT_RDTSCP 51
+/** 52 VMX-preemption timer expired. The preemption timer counted down to zero. */
+#define VMX_EXIT_PREEMPT_TIMER 52
+/** 53 INVVPID. Guest software attempted to execute INVVPID. */
+#define VMX_EXIT_INVVPID 53
+/** 54 WBINVD. Guest software attempted to execute WBINVD. */
+#define VMX_EXIT_WBINVD 54
+/** 55 XSETBV. Guest software attempted to execute XSETBV. */
+#define VMX_EXIT_XSETBV 55
+/** 57 RDRAND. Guest software attempted to execute RDRAND. */
+#define VMX_EXIT_RDRAND 57
+/** 58 INVPCID. Guest software attempted to execute INVPCID. */
+#define VMX_EXIT_INVPCID 58
+/** 59 VMFUNC. Guest software attempted to execute VMFUNC. */
+#define VMX_EXIT_VMFUNC 59
+/** The maximum exit value (inclusive). */
+#define VMX_EXIT_MAX (VMX_EXIT_VMFUNC)
+/** @} */
+
+
+/** @name VM Instruction Errors
+ * @{
+ */
+/** VMCALL executed in VMX root operation. */
+#define VMX_ERROR_VMCALL 1
+/** VMCLEAR with invalid physical address. */
+#define VMX_ERROR_VMCLEAR_INVALID_PHYS_ADDR 2
+/** VMCLEAR with VMXON pointer. */
+#define VMX_ERROR_VMCLEAR_INVALID_VMXON_PTR 3
+/** VMLAUNCH with non-clear VMCS. */
+#define VMX_ERROR_VMLAUCH_NON_CLEAR_VMCS 4
+/** VMRESUME with non-launched VMCS. */
+#define VMX_ERROR_VMRESUME_NON_LAUNCHED_VMCS 5
+/** VMRESUME with a corrupted VMCS (indicates corruption of the current VMCS). */
+#define VMX_ERROR_VMRESUME_CORRUPTED_VMCS 6
+/** VM-entry with invalid control field(s). */
+#define VMX_ERROR_VMENTRY_INVALID_CONTROL_FIELDS 7
+/** VM-entry with invalid host-state field(s). */
+#define VMX_ERROR_VMENTRY_INVALID_HOST_STATE 8
+/** VMPTRLD with invalid physical address. */
+#define VMX_ERROR_VMPTRLD_INVALID_PHYS_ADDR 9
+/** VMPTRLD with VMXON pointer. */
+#define VMX_ERROR_VMPTRLD_VMXON_PTR 10
+/** VMPTRLD with incorrect VMCS revision identifier. */
+#define VMX_ERROR_VMPTRLD_WRONG_VMCS_REVISION 11
+/** VMREAD/VMWRITE from/to unsupported VMCS component. */
+#define VMX_ERROR_VMREAD_INVALID_COMPONENT 12
+#define VMX_ERROR_VMWRITE_INVALID_COMPONENT VMX_ERROR_VMREAD_INVALID_COMPONENT
+/** VMWRITE to read-only VMCS component. */
+#define VMX_ERROR_VMWRITE_READONLY_COMPONENT 13
+/** VMXON executed in VMX root operation. */
+#define VMX_ERROR_VMXON_IN_VMX_ROOT_OP 15
+/** VM entry with invalid executive-VMCS pointer. */
+#define VMX_ERROR_VMENTRY_INVALID_VMCS_EXEC_PTR 16
+/** VM entry with non-launched executive VMCS. */
+#define VMX_ERROR_VMENTRY_NON_LAUNCHED_EXEC_VMCS 17
+/** VM entry with executive-VMCS pointer not VMXON pointer. */
+#define VMX_ERROR_VMENTRY_EXEC_VMCS_PTR 18
+/** VMCALL with non-clear VMCS. */
+#define VMX_ERROR_VMCALL_NON_CLEAR_VMCS 19
+/** VMCALL with invalid VM-exit control fields. */
+#define VMX_ERROR_VMCALL_INVALID_VMEXIT_FIELDS 20
+/** VMCALL with incorrect MSEG revision identifier. */
+#define VMX_ERROR_VMCALL_INVALID_MSEG_REVISION 22
+/** VMXOFF under dual-monitor treatment of SMIs and SMM. */
+#define VMX_ERROR_VMXOFF_DUAL_MONITOR 23
+/** VMCALL with invalid SMM-monitor features. */
+#define VMX_ERROR_VMCALL_INVALID_SMM_MONITOR 24
+/** VM entry with invalid VM-execution control fields in executive VMCS. */
+#define VMX_ERROR_VMENTRY_INVALID_VM_EXEC_CTRL 25
+/** VM entry with events blocked by MOV SS. */
+#define VMX_ERROR_VMENTRY_MOV_SS 26
+/** Invalid operand to INVEPT/INVVPID. */
+#define VMX_ERROR_INVEPTVPID_INVALID_OPERAND 28
+
+/** @} */
+
+
+/** @name VMX MSRs - Basic VMX information.
+ * @{
+ */
+/** VMCS revision identifier used by the processor. */
+#define MSR_IA32_VMX_BASIC_INFO_VMCS_ID(a) ((a) & 0x7FFFFFFF)
+/** Size of the VMCS. */
+#define MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(a) (((a) >> 32) & 0x1FFF)
+/** Width of physical address used for the VMCS.
+ * 0 -> limited to the available amount of physical ram
+ * 1 -> within the first 4 GB
+ */
+#define MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(a) (((a) >> 48) & 1)
+/** Whether the processor supports the dual-monitor treatment of system-management interrupts and system-management code. (always 1) */
+#define MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(a) (((a) >> 49) & 1)
+/** Memory type that must be used for the VMCS. */
+#define MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(a) (((a) >> 50) & 0xF)
+/** Whether the processor provides additional information for exits due to INS/OUTS. */
+#define MSR_IA32_VMX_BASIC_INFO_VMCS_INS_OUTS(a) RT_BOOL((a) & RT_BIT_64(54))
+/** @} */
+
+
+/** @name VMX MSRs - Misc VMX info.
+ * @{
+ */
+/** Relationship between the preemption timer and tsc; count down every time bit x of the tsc changes. */
+#define MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(a) ((a) & 0x1f)
+/** Whether VM-exit stores EFER.LMA into the "IA32e mode guest" field. */
+#define MSR_IA32_VMX_MISC_STORE_EFERLMA_VMEXIT(a) (((a) >> 5) & 1)
+/** Activity states supported by the implementation. */
+#define MSR_IA32_VMX_MISC_ACTIVITY_STATES(a) (((a) >> 6) & 0x7)
+/** Number of CR3 target values supported by the processor. (0-256) */
+#define MSR_IA32_VMX_MISC_CR3_TARGET(a) (((a) >> 16) & 0x1FF)
+/** Maximum nr of MSRs in the VMCS. (N+1)*512. */
+#define MSR_IA32_VMX_MISC_MAX_MSR(a) (((((a) >> 25) & 0x7) + 1) * 512)
+/** Whether RDMSR can be used to read IA32_SMBASE_MSR in SMM. */
+#define MSR_IA32_VMX_MISC_RDMSR_SMBASE_MSR_SMM(a) (((a) >> 15) & 1)
+/** Whether bit 2 of IA32_SMM_MONITOR_CTL can be set to 1. */
+#define MSR_IA32_VMX_MISC_SMM_MONITOR_CTL_B2(a) (((a) >> 28) & 1)
+/** Whether VMWRITE can be used to write VM-exit information fields. */
+#define MSR_IA32_VMX_MISC_VMWRITE_VMEXIT_INFO(a) (((a) >> 29) & 1)
+/** MSEG revision identifier used by the processor. */
+#define MSR_IA32_VMX_MISC_MSEG_ID(a) ((a) >> 32)
+/** @} */
+
+
+/** @name VMX MSRs - VMCS enumeration field info
+ * @{
+ */
+/** Highest field index. */
+#define MSR_IA32_VMX_VMCS_ENUM_HIGHEST_INDEX(a) (((a) >> 1) & 0x1FF)
+/** @} */
+
+
+/** @name MSR_IA32_VMX_EPT_VPID_CAPS; EPT capabilities MSR
+ * @{
+ */
+#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_X_ONLY RT_BIT_64(0)
+#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_W_ONLY RT_BIT_64(1)
+#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_WX_ONLY RT_BIT_64(2)
+#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_21_BITS RT_BIT_64(3)
+#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_30_BITS RT_BIT_64(4)
+#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_39_BITS RT_BIT_64(5)
+#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_48_BITS RT_BIT_64(6)
+#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_57_BITS RT_BIT_64(7)
+#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_UC RT_BIT_64(8)
+#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WC RT_BIT_64(9)
+#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WT RT_BIT_64(12)
+#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WP RT_BIT_64(13)
+#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WB RT_BIT_64(14)
+#define MSR_IA32_VMX_EPT_VPID_CAP_SP_21_BITS RT_BIT_64(16)
+#define MSR_IA32_VMX_EPT_VPID_CAP_SP_30_BITS RT_BIT_64(17)
+#define MSR_IA32_VMX_EPT_VPID_CAP_SP_39_BITS RT_BIT_64(18)
+#define MSR_IA32_VMX_EPT_VPID_CAP_SP_48_BITS RT_BIT_64(19)
+#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT RT_BIT_64(20)
+#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_SINGLE_CONTEXT RT_BIT_64(25)
+#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_ALL_CONTEXTS RT_BIT_64(26)
+#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID RT_BIT_64(32)
+#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_INDIV_ADDR RT_BIT_64(40)
+#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT RT_BIT_64(41)
+#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_ALL_CONTEXTS RT_BIT_64(42)
+#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT_RETAIN_GLOBALS RT_BIT_64(43)
+
+/** @} */
+
+/** @name Extended Page Table Pointer (EPTP)
+ * @{
+ */
+/** Uncachable EPT paging structure memory type. */
+#define VMX_EPT_MEMTYPE_UC 0
+/** Write-back EPT paging structure memory type. */
+#define VMX_EPT_MEMTYPE_WB 6
+/** Shift value to get the EPT page walk length (bits 5-3) */
+#define VMX_EPT_PAGE_WALK_LENGTH_SHIFT 3
+/** Mask value to get the EPT page walk length (bits 5-3) */
+#define VMX_EPT_PAGE_WALK_LENGTH_MASK 7
+/** Default EPT page-walk length (1 less than the actual EPT page-walk
+ * length) */
+#define VMX_EPT_PAGE_WALK_LENGTH_DEFAULT 3
+/** @} */
+
+
+/** @name VMCS field encoding - 16 bits guest fields
+ * @{
+ */
+#define VMX_VMCS16_GUEST_FIELD_VPID 0x0
+#define VMX_VMCS16_GUEST_FIELD_ES 0x800
+#define VMX_VMCS16_GUEST_FIELD_CS 0x802
+#define VMX_VMCS16_GUEST_FIELD_SS 0x804
+#define VMX_VMCS16_GUEST_FIELD_DS 0x806
+#define VMX_VMCS16_GUEST_FIELD_FS 0x808
+#define VMX_VMCS16_GUEST_FIELD_GS 0x80A
+#define VMX_VMCS16_GUEST_FIELD_LDTR 0x80C
+#define VMX_VMCS16_GUEST_FIELD_TR 0x80E
+/** @} */
+
+/** @name VMCS field encoding - 16 bits host fields
+ * @{
+ */
+#define VMX_VMCS16_HOST_FIELD_ES 0xC00
+#define VMX_VMCS16_HOST_FIELD_CS 0xC02
+#define VMX_VMCS16_HOST_FIELD_SS 0xC04
+#define VMX_VMCS16_HOST_FIELD_DS 0xC06
+#define VMX_VMCS16_HOST_FIELD_FS 0xC08
+#define VMX_VMCS16_HOST_FIELD_GS 0xC0A
+#define VMX_VMCS16_HOST_FIELD_TR 0xC0C
+/** @} */
+
+/** @name VMCS field encoding - 64 bits host fields
+ * @{
+ */
+#define VMX_VMCS64_HOST_FIELD_PAT_FULL 0x2C00
+#define VMX_VMCS64_HOST_FIELD_PAT_HIGH 0x2C01
+#define VMX_VMCS64_HOST_FIELD_EFER_FULL 0x2C02
+#define VMX_VMCS64_HOST_FIELD_EFER_HIGH 0x2C03
+#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_FULL 0x2C04 /**< MSR IA32_PERF_GLOBAL_CTRL */
+#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_HIGH 0x2C05 /**< MSR IA32_PERF_GLOBAL_CTRL */
+/** @} */
+
+
+/** @name VMCS field encoding - 64 Bits control fields
+ * @{
+ */
+#define VMX_VMCS64_CTRL_IO_BITMAP_A_FULL 0x2000
+#define VMX_VMCS64_CTRL_IO_BITMAP_A_HIGH 0x2001
+#define VMX_VMCS64_CTRL_IO_BITMAP_B_FULL 0x2002
+#define VMX_VMCS64_CTRL_IO_BITMAP_B_HIGH 0x2003
+
+/* Optional */
+#define VMX_VMCS64_CTRL_MSR_BITMAP_FULL 0x2004
+#define VMX_VMCS64_CTRL_MSR_BITMAP_HIGH 0x2005
+
+#define VMX_VMCS64_CTRL_EXIT_MSR_STORE_FULL 0x2006
+#define VMX_VMCS64_CTRL_EXIT_MSR_STORE_HIGH 0x2007
+#define VMX_VMCS64_CTRL_EXIT_MSR_LOAD_FULL 0x2008
+#define VMX_VMCS64_CTRL_EXIT_MSR_LOAD_HIGH 0x2009
+
+#define VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_FULL 0x200A
+#define VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_HIGH 0x200B
+
+#define VMX_VMCS64_CTRL_EXEC_VMCS_PTR_FULL 0x200C
+#define VMX_VMCS64_CTRL_EXEC_VMCS_PTR_HIGH 0x200D
+
+#define VMX_VMCS64_CTRL_TSC_OFFSET_FULL 0x2010
+#define VMX_VMCS64_CTRL_TSC_OFFSET_HIGH 0x2011
+
+/** Optional (VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW) */
+#define VMX_VMCS64_CTRL_VAPIC_PAGEADDR_FULL 0x2012
+#define VMX_VMCS64_CTRL_VAPIC_PAGEADDR_HIGH 0x2013
+
+/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) */
+#define VMX_VMCS64_CTRL_APIC_ACCESSADDR_FULL 0x2014
+#define VMX_VMCS64_CTRL_APIC_ACCESSADDR_HIGH 0x2015
+
+/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VMFUNC) */
+#define VMX_VMCS64_CTRL_VMFUNC_CTRLS_FULL 0x2018
+#define VMX_VMCS64_CTRL_VMFUNC_CTRLS_HIGH 0x2019
+
+/** Extended page table pointer. */
+#define VMX_VMCS64_CTRL_EPTP_FULL 0x201a
+#define VMX_VMCS64_CTRL_EPTP_HIGH 0x201b
+
+/** Extended page table pointer lists. */
+#define VMX_VMCS64_CTRL_EPTP_LIST_FULL 0x2024
+#define VMX_VMCS64_CTRL_EPTP_LIST_HIGH 0x2025
+
+/** VM-exit guest phyiscal address. */
+#define VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_FULL 0x2400
+#define VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_HIGH 0x2401
+/** @} */
+
+
+/** @name VMCS field encoding - 64 Bits guest fields
+ * @{
+ */
+#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_FULL 0x2800
+#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_HIGH 0x2801
+#define VMX_VMCS64_GUEST_DEBUGCTL_FULL 0x2802 /**< MSR IA32_DEBUGCTL */
+#define VMX_VMCS64_GUEST_DEBUGCTL_HIGH 0x2803 /**< MSR IA32_DEBUGCTL */
+#define VMX_VMCS64_GUEST_PAT_FULL 0x2804
+#define VMX_VMCS64_GUEST_PAT_HIGH 0x2805
+#define VMX_VMCS64_GUEST_EFER_FULL 0x2806
+#define VMX_VMCS64_GUEST_EFER_HIGH 0x2807
+#define VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_FULL 0x2808 /**< MSR IA32_PERF_GLOBAL_CTRL */
+#define VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_HIGH 0x2809 /**< MSR IA32_PERF_GLOBAL_CTRL */
+#define VMX_VMCS64_GUEST_PDPTE0_FULL 0x280A
+#define VMX_VMCS64_GUEST_PDPTE0_HIGH 0x280B
+#define VMX_VMCS64_GUEST_PDPTE1_FULL 0x280C
+#define VMX_VMCS64_GUEST_PDPTE1_HIGH 0x280D
+#define VMX_VMCS64_GUEST_PDPTE2_FULL 0x280E
+#define VMX_VMCS64_GUEST_PDPTE2_HIGH 0x280F
+#define VMX_VMCS64_GUEST_PDPTE3_FULL 0x2810
+#define VMX_VMCS64_GUEST_PDPTE3_HIGH 0x2811
+/** @} */
+
+
+/** @name VMCS field encoding - 32 Bits control fields
+ * @{
+ */
+#define VMX_VMCS32_CTRL_PIN_EXEC 0x4000
+#define VMX_VMCS32_CTRL_PROC_EXEC 0x4002
+#define VMX_VMCS32_CTRL_EXCEPTION_BITMAP 0x4004
+#define VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MASK 0x4006
+#define VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MATCH 0x4008
+#define VMX_VMCS32_CTRL_CR3_TARGET_COUNT 0x400A
+#define VMX_VMCS32_CTRL_EXIT 0x400C
+#define VMX_VMCS32_CTRL_EXIT_MSR_STORE_COUNT 0x400E
+#define VMX_VMCS32_CTRL_EXIT_MSR_LOAD_COUNT 0x4010
+#define VMX_VMCS32_CTRL_ENTRY 0x4012
+#define VMX_VMCS32_CTRL_ENTRY_MSR_LOAD_COUNT 0x4014
+#define VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO 0x4016
+#define VMX_VMCS32_CTRL_ENTRY_EXCEPTION_ERRCODE 0x4018
+#define VMX_VMCS32_CTRL_ENTRY_INSTR_LENGTH 0x401A
+#define VMX_VMCS32_CTRL_TPR_THRESHOLD 0x401C
+#define VMX_VMCS32_CTRL_PROC_EXEC2 0x401E
+/** @} */
+
+
+/** @name VMX_VMCS_CTRL_PIN_EXEC
+ * @{
+ */
+/** External interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */
+#define VMX_VMCS_CTRL_PIN_EXEC_EXT_INT_EXIT RT_BIT(0)
+/** Non-maskable interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */
+#define VMX_VMCS_CTRL_PIN_EXEC_NMI_EXIT RT_BIT(3)
+/** Virtual NMIs. */
+#define VMX_VMCS_CTRL_PIN_EXEC_VIRTUAL_NMI RT_BIT(5)
+/** Activate VMX preemption timer. */
+#define VMX_VMCS_CTRL_PIN_EXEC_PREEMPT_TIMER RT_BIT(6)
+/* All other bits are reserved and must be set according to MSR IA32_VMX_PROCBASED_CTLS. */
+/** @} */
+
+/** @name VMX_VMCS_CTRL_PROC_EXEC
+ * @{
+ */
+/** VM Exit as soon as RFLAGS.IF=1 and no blocking is active. */
+#define VMX_VMCS_CTRL_PROC_EXEC_INT_WINDOW_EXIT RT_BIT(2)
+/** Use timestamp counter offset. */
+#define VMX_VMCS_CTRL_PROC_EXEC_USE_TSC_OFFSETTING RT_BIT(3)
+/** VM Exit when executing the HLT instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_HLT_EXIT RT_BIT(7)
+/** VM Exit when executing the INVLPG instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_INVLPG_EXIT RT_BIT(9)
+/** VM Exit when executing the MWAIT instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_MWAIT_EXIT RT_BIT(10)
+/** VM Exit when executing the RDPMC instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_RDPMC_EXIT RT_BIT(11)
+/** VM Exit when executing the RDTSC/RDTSCP instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT RT_BIT(12)
+/** VM Exit when executing the MOV to CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
+#define VMX_VMCS_CTRL_PROC_EXEC_CR3_LOAD_EXIT RT_BIT(15)
+/** VM Exit when executing the MOV from CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
+#define VMX_VMCS_CTRL_PROC_EXEC_CR3_STORE_EXIT RT_BIT(16)
+/** VM Exit on CR8 loads. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CR8_LOAD_EXIT RT_BIT(19)
+/** VM Exit on CR8 stores. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CR8_STORE_EXIT RT_BIT(20)
+/** Use TPR shadow. */
+#define VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW RT_BIT(21)
+/** VM Exit when virtual nmi blocking is disabled. */
+#define VMX_VMCS_CTRL_PROC_EXEC_NMI_WINDOW_EXIT RT_BIT(22)
+/** VM Exit when executing a MOV DRx instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_MOV_DR_EXIT RT_BIT(23)
+/** VM Exit when executing IO instructions. */
+#define VMX_VMCS_CTRL_PROC_EXEC_UNCOND_IO_EXIT RT_BIT(24)
+/** Use IO bitmaps. */
+#define VMX_VMCS_CTRL_PROC_EXEC_USE_IO_BITMAPS RT_BIT(25)
+/** Monitor trap flag. */
+#define VMX_VMCS_CTRL_PROC_EXEC_MONITOR_TRAP_FLAG RT_BIT(27)
+/** Use MSR bitmaps. */
+#define VMX_VMCS_CTRL_PROC_EXEC_USE_MSR_BITMAPS RT_BIT(28)
+/** VM Exit when executing the MONITOR instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_MONITOR_EXIT RT_BIT(29)
+/** VM Exit when executing the PAUSE instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_PAUSE_EXIT RT_BIT(30)
+/** Determines whether the secondary processor based VM-execution controls are used. */
+#define VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL RT_BIT(31)
+/** @} */
+
+/** @name VMX_VMCS_CTRL_PROC_EXEC2
+ * @{
+ */
+/** Virtualize APIC access. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC RT_BIT(0)
+/** EPT supported/enabled. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_EPT RT_BIT(1)
+/** Descriptor table instructions cause VM-exits. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_TABLE_EXIT RT_BIT(2)
+/** RDTSCP supported/enabled. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP RT_BIT(3)
+/** Virtualize x2APIC mode. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_X2APIC RT_BIT(4)
+/** VPID supported/enabled. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_VPID RT_BIT(5)
+/** VM Exit when executing the WBINVD instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT RT_BIT(6)
+/** Unrestricted guest execution. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_UNRESTRICTED_GUEST RT_BIT(7)
+/** A specified nr of pause loops cause a VM-exit. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT RT_BIT(10)
+/** VM Exit when executing RDRAND instructions. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_RDRAND_EXIT RT_BIT(11)
+/** Enables INVPCID instructions. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_INVPCID RT_BIT(12)
+/** Enables VMFUNC instructions. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_VMFUNC RT_BIT(13)
+/** @} */
+
+
+/** @name VMX_VMCS_CTRL_ENTRY
+ * @{
+ */
+/** Load guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
+#define VMX_VMCS_CTRL_ENTRY_LOAD_DEBUG RT_BIT(2)
+/** 64 bits guest mode. Must be 0 for CPUs that don't support AMD64. */
+#define VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST RT_BIT(9)
+/** In SMM mode after VM-entry. */
+#define VMX_VMCS_CTRL_ENTRY_ENTRY_SMM RT_BIT(10)
+/** Disable dual treatment of SMI and SMM; must be zero for VM-entry outside of SMM. */
+#define VMX_VMCS_CTRL_ENTRY_DEACTIVATE_DUALMON RT_BIT(11)
+/** Whether the guest IA32_PERF_GLOBAL_CTRL MSR is loaded on VM entry. */
+#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_PERF_MSR RT_BIT(13)
+/** Whether the guest IA32_PAT MSR is loaded on VM entry. */
+#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_PAT_MSR RT_BIT(14)
+/** Whether the guest IA32_EFER MSR is loaded on VM entry. */
+#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_EFER_MSR RT_BIT(15)
+/** @} */
+
+
+/** @name VMX_VMCS_CTRL_EXIT
+ * @{
+ */
+/** Save guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
+#define VMX_VMCS_CTRL_EXIT_SAVE_DEBUG RT_BIT(2)
+/** Return to long mode after a VM-exit. */
+#define VMX_VMCS_CTRL_EXIT_HOST_ADDR_SPACE_SIZE RT_BIT(9)
+/** Whether the IA32_PERF_GLOBAL_CTRL MSR is loaded on VM exit. */
+#define VMX_VMCS_CTRL_EXIT_LOAD_PERF_MSR RT_BIT(12)
+/** Acknowledge external interrupts with the irq controller if one caused a VM-exit. */
+#define VMX_VMCS_CTRL_EXIT_ACK_EXT_INT RT_BIT(15)
+/** Whether the guest IA32_PAT MSR is saved on VM exit. */
+#define VMX_VMCS_CTRL_EXIT_SAVE_GUEST_PAT_MSR RT_BIT(18)
+/** Whether the host IA32_PAT MSR is loaded on VM exit. */
+#define VMX_VMCS_CTRL_EXIT_LOAD_HOST_PAT_MSR RT_BIT(19)
+/** Whether the guest IA32_EFER MSR is saved on VM exit. */
+#define VMX_VMCS_CTRL_EXIT_SAVE_GUEST_EFER_MSR RT_BIT(20)
+/** Whether the host IA32_EFER MSR is loaded on VM exit. */
+#define VMX_VMCS_CTRL_EXIT_LOAD_HOST_EFER_MSR RT_BIT(21)
+/** Whether the value of the VMX preemption timer is saved on every VM exit. */
+#define VMX_VMCS_CTRL_EXIT_SAVE_VMX_PREEMPT_TIMER RT_BIT(22)
+/** @} */
+
+
+/** @name VMX_VMCS_CTRL_VMFUNC
+ * @{
+ */
+/** EPTP-switching function changes the value of the EPTP to one chosen from the EPTP list. */
+#define VMX_VMCS_CTRL_VMFUNC_EPTP_SWITCHING RT_BIT_64(0)
+/** @} */
+
+
+/** @name VMCS field encoding - 32 Bits read-only fields
+ * @{
+ */
+#define VMX_VMCS32_RO_VM_INSTR_ERROR 0x4400
+#define VMX_VMCS32_RO_EXIT_REASON 0x4402
+#define VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO 0x4404
+#define VMX_VMCS32_RO_EXIT_INTERRUPTION_ERROR_CODE 0x4406
+#define VMX_VMCS32_RO_IDT_INFO 0x4408
+#define VMX_VMCS32_RO_IDT_ERROR_CODE 0x440A
+#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH 0x440C
+#define VMX_VMCS32_RO_EXIT_INSTR_INFO 0x440E
+/** @} */
+
+/** @name VMX_VMCS32_RO_EXIT_REASON
+ * @{
+ */
+#define VMX_EXIT_REASON_BASIC(a) ((a) & 0xffff)
+/** @} */
+
+/** @name VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO
+ * @{
+ */
+#define VMX_ENTRY_INTERRUPTION_INFO_IS_VALID(a) RT_BOOL((a) & RT_BIT(31))
+#define VMX_ENTRY_INTERRUPTION_INFO_TYPE_SHIFT 8
+#define VMX_ENTRY_INTERRUPTION_INFO_TYPE(a) ((a >> VMX_ENTRY_INTERRUPTION_INFO_TYPE_SHIFT) & 7)
+/** @} */
+
+
+/** @name VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO
+ * @{
+ */
+#define VMX_EXIT_INTERRUPTION_INFO_VECTOR(a) ((a) & 0xff)
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT 8
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE(a) (((a) >> VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT) & 7)
+#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID RT_BIT(11)
+#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(a) RT_BOOL((a) & VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID)
+#define VMX_EXIT_INTERRUPTION_INFO_NMI_UNBLOCK(a) ((a) & RT_BIT(12))
+#define VMX_EXIT_INTERRUPTION_INFO_VALID RT_BIT(31)
+#define VMX_EXIT_INTERRUPTION_INFO_IS_VALID(a) RT_BOOL((a) & RT_BIT(31))
+/** Construct an irq event injection value from the exit interruption info value (same except that bit 12 is reserved). */
+#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(a) ((a) & ~RT_BIT(12))
+/** @} */
+
+/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO_TYPE
+ * @{
+ */
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT_INT 0
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI 2
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT 3
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_INT 4
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_PRIV_SW_XCPT 5
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_XCPT 6
+/** @} */
+
+/** @name VMX_VMCS32_RO_IDT_VECTORING_INFO
+ * @{
+ */
+#define VMX_IDT_VECTORING_INFO_VECTOR(a) ((a) & 0xff)
+#define VMX_IDT_VECTORING_INFO_TYPE_SHIFT 8
+#define VMX_IDT_VECTORING_INFO_TYPE(a) (((a) >> VMX_IDT_VECTORING_INFO_TYPE_SHIFT) & 7)
+#define VMX_IDT_VECTORING_INFO_ERROR_CODE_VALID RT_BIT(11)
+#define VMX_IDT_VECTORING_INFO_ERROR_CODE_IS_VALID(a) RT_BOOL((a) & VMX_IDT_VECTORING_INFO_ERROR_CODE_VALID)
+#define VMX_IDT_VECTORING_INFO_VALID(a) ((a) & RT_BIT(31))
+#define VMX_ENTRY_INT_INFO_FROM_EXIT_IDT_INFO(a) ((a) & ~RT_BIT(12))
+/** @} */
+
+/** @name VMX_VMCS_RO_IDT_VECTORING_INFO_TYPE
+ * @{
+ */
+#define VMX_IDT_VECTORING_INFO_TYPE_EXT_INT 0
+#define VMX_IDT_VECTORING_INFO_TYPE_NMI 2
+#define VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT 3
+#define VMX_IDT_VECTORING_INFO_TYPE_SW_INT 4
+#define VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT 5
+#define VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT 6
+/** @} */
+
+
+/** @name VMCS field encoding - 32 Bits guest state fields
+ * @{
+ */
+#define VMX_VMCS32_GUEST_ES_LIMIT 0x4800
+#define VMX_VMCS32_GUEST_CS_LIMIT 0x4802
+#define VMX_VMCS32_GUEST_SS_LIMIT 0x4804
+#define VMX_VMCS32_GUEST_DS_LIMIT 0x4806
+#define VMX_VMCS32_GUEST_FS_LIMIT 0x4808
+#define VMX_VMCS32_GUEST_GS_LIMIT 0x480A
+#define VMX_VMCS32_GUEST_LDTR_LIMIT 0x480C
+#define VMX_VMCS32_GUEST_TR_LIMIT 0x480E
+#define VMX_VMCS32_GUEST_GDTR_LIMIT 0x4810
+#define VMX_VMCS32_GUEST_IDTR_LIMIT 0x4812
+#define VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS 0x4814
+#define VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS 0x4816
+#define VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS 0x4818
+#define VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS 0x481A
+#define VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS 0x481C
+#define VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS 0x481E
+#define VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS 0x4820
+#define VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS 0x4822
+#define VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE 0x4824
+#define VMX_VMCS32_GUEST_ACTIVITY_STATE 0x4826
+#define VMX_VMCS32_GUEST_SYSENTER_CS 0x482A /**< MSR IA32_SYSENTER_CS */
+#define VMX_VMCS32_GUEST_PREEMPT_TIMER_VALUE 0x482E
+/** @} */
+
+
+/** @name VMX_VMCS_GUEST_ACTIVITY_STATE
+ * @{
+ */
+/** The logical processor is active. */
+#define VMX_VMCS_GUEST_ACTIVITY_ACTIVE 0x0
+/** The logical processor is inactive, because executed a HLT instruction. */
+#define VMX_VMCS_GUEST_ACTIVITY_HLT 0x1
+/** The logical processor is inactive, because of a triple fault or other serious error. */
+#define VMX_VMCS_GUEST_ACTIVITY_SHUTDOWN 0x2
+/** The logical processor is inactive, because it's waiting for a startup-IPI */
+#define VMX_VMCS_GUEST_ACTIVITY_SIPI_WAIT 0x3
+/** @} */
+
+
+/** @name VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE
+ * @{
+ */
+#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI RT_BIT(0)
+#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS RT_BIT(1)
+#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_SMI RT_BIT(2)
+#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_NMI RT_BIT(3)
+/** @} */
+
+
+/** @name VMCS field encoding - 32 Bits host state fields
+ * @{
+ */
+#define VMX_VMCS32_HOST_SYSENTER_CS 0x4C00
+/** @} */
+
+/** @name Natural width control fields
+ * @{
+ */
+#define VMX_VMCS_CTRL_CR0_MASK 0x6000
+#define VMX_VMCS_CTRL_CR4_MASK 0x6002
+#define VMX_VMCS_CTRL_CR0_READ_SHADOW 0x6004
+#define VMX_VMCS_CTRL_CR4_READ_SHADOW 0x6006
+#define VMX_VMCS_CTRL_CR3_TARGET_VAL0 0x6008
+#define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0x600A
+#define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0x600C
+#define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0x600E
+/** @} */
+
+
+/** @name Natural width read-only data fields
+ * @{
+ */
+#define VMX_VMCS_RO_EXIT_QUALIFICATION 0x6400
+#define VMX_VMCS_RO_IO_RCX 0x6402
+#define VMX_VMCS_RO_IO_RSX 0x6404
+#define VMX_VMCS_RO_IO_RDI 0x6406
+#define VMX_VMCS_RO_IO_RIP 0x6408
+#define VMX_VMCS_RO_EXIT_GUEST_LINEAR_ADDR 0x640A
+/** @} */
+
+
+/** @name VMX_VMCS_RO_EXIT_QUALIFICATION
+ * @{
+ */
+/** 0-2: Debug register number */
+#define VMX_EXIT_QUALIFICATION_DRX_REGISTER(a) ((a) & 7)
+/** 3: Reserved; cleared to 0. */
+#define VMX_EXIT_QUALIFICATION_DRX_RES1(a) (((a) >> 3) & 1)
+/** 4: Direction of move (0 = write, 1 = read) */
+#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION(a) (((a) >> 4) & 1)
+/** 5-7: Reserved; cleared to 0. */
+#define VMX_EXIT_QUALIFICATION_DRX_RES2(a) (((a) >> 5) & 7)
+/** 8-11: General purpose register number. */
+#define VMX_EXIT_QUALIFICATION_DRX_GENREG(a) (((a) >> 8) & 0xF)
+/** Rest: reserved. */
+/** @} */
+
+/** @name VMX_EXIT_QUALIFICATION_DRX_DIRECTION values
+ * @{
+ */
+#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE 0
+#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_READ 1
+/** @} */
+
+
+
+/** @name CRx accesses
+ * @{
+ */
+/** 0-3: Control register number (0 for CLTS & LMSW) */
+#define VMX_EXIT_QUALIFICATION_CRX_REGISTER(a) ((a) & 0xF)
+/** 4-5: Access type. */
+#define VMX_EXIT_QUALIFICATION_CRX_ACCESS(a) (((a) >> 4) & 3)
+/** 6: LMSW operand type */
+#define VMX_EXIT_QUALIFICATION_CRX_LMSW_OP(a) (((a) >> 6) & 1)
+/** 7: Reserved; cleared to 0. */
+#define VMX_EXIT_QUALIFICATION_CRX_RES1(a) (((a) >> 7) & 1)
+/** 8-11: General purpose register number (0 for CLTS & LMSW). */
+#define VMX_EXIT_QUALIFICATION_CRX_GENREG(a) (((a) >> 8) & 0xF)
+/** 12-15: Reserved; cleared to 0. */
+#define VMX_EXIT_QUALIFICATION_CRX_RES2(a) (((a) >> 12) & 0xF)
+/** 16-31: LMSW source data (else 0). */
+#define VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(a) (((a) >> 16) & 0xFFFF)
+/** Rest: reserved. */
+/** @} */
+
+/** @name VMX_EXIT_QUALIFICATION_CRX_ACCESS
+ * @{
+ */
+#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE 0
+#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ 1
+#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS 2
+#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW 3
+/** @} */
+
+/** @name VMX_EXIT_QUALIFICATION_TASK_SWITCH
+ * @{
+ */
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_SELECTOR(a) ((a) & 0xffff)
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE(a) (((a) >> 30) & 0x3)
+/** Task switch caused by a call instruction. */
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_CALL 0
+/** Task switch caused by an iret instruction. */
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IRET 1
+/** Task switch caused by a jmp instruction. */
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_JMP 2
+/** Task switch caused by an interrupt gate. */
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IDT 3
+/** @} */
+
+
+/** @name VMX_EXIT_EPT_VIOLATION
+ * @{
+ */
+/** Set if the violation was caused by a data read. */
+#define VMX_EXIT_QUALIFICATION_EPT_DATA_READ RT_BIT(0)
+/** Set if the violation was caused by a data write. */
+#define VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE RT_BIT(1)
+/** Set if the violation was caused by an insruction fetch. */
+#define VMX_EXIT_QUALIFICATION_EPT_INSTR_FETCH RT_BIT(2)
+/** AND of the present bit of all EPT structures. */
+#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT RT_BIT(3)
+/** AND of the write bit of all EPT structures. */
+#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_WRITE RT_BIT(4)
+/** AND of the execute bit of all EPT structures. */
+#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_EXECUTE RT_BIT(5)
+/** Set if the guest linear address field contains the faulting address. */
+#define VMX_EXIT_QUALIFICATION_EPT_GUEST_ADDR_VALID RT_BIT(7)
+/** If bit 7 is one: (reserved otherwise)
+ * 1 - violation due to physical address access.
+ * 0 - violation caused by page walk or access/dirty bit updates
+ */
+#define VMX_EXIT_QUALIFICATION_EPT_TRANSLATED_ACCESS RT_BIT(8)
+/** @} */
+
+
+/** @name VMX_EXIT_PORT_IO
+ * @{
+ */
+/** 0-2: IO operation width. */
+#define VMX_EXIT_QUALIFICATION_IO_WIDTH(a) ((a) & 7)
+/** 3: IO operation direction. */
+#define VMX_EXIT_QUALIFICATION_IO_DIRECTION(a) (((a) >> 3) & 1)
+/** 4: String IO operation (INS / OUTS). */
+#define VMX_EXIT_QUALIFICATION_IO_IS_STRING(a) RT_BOOL((a) & RT_BIT_64(4))
+/** 5: Repeated IO operation. */
+#define VMX_EXIT_QUALIFICATION_IO_IS_REP(a) RT_BOOL((a) & RT_BIT_64(5))
+/** 6: Operand encoding. */
+#define VMX_EXIT_QUALIFICATION_IO_ENCODING(a) (((a) >> 6) & 1)
+/** 16-31: IO Port (0-0xffff). */
+#define VMX_EXIT_QUALIFICATION_IO_PORT(a) (((a) >> 16) & 0xffff)
+/* Rest reserved. */
+/** @} */
+
+/** @name VMX_EXIT_QUALIFICATION_IO_DIRECTION
+ * @{
+ */
+#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT 0
+#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_IN 1
+/** @} */
+
+
+/** @name VMX_EXIT_QUALIFICATION_IO_ENCODING
+ * @{
+ */
+#define VMX_EXIT_QUALIFICATION_IO_ENCODING_DX 0
+#define VMX_EXIT_QUALIFICATION_IO_ENCODING_IMM 1
+/** @} */
+
+/** @name VMX_EXIT_APIC_ACCESS
+ * @{
+ */
+/** 0-11: If the APIC-access VM exit is due to a linear access, the offset of access within the APIC page. */
+#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(a) ((a) & 0xfff)
+/** 12-15: Access type. */
+#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(a) ((a) & 0xf000)
+/* Rest reserved. */
+/** @} */
+
+
+/** @name VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE; access types
+ * @{
+ */
+/** Linear read access. */
+#define VMX_APIC_ACCESS_TYPE_LINEAR_READ 0
+/** Linear write access. */
+#define VMX_APIC_ACCESS_TYPE_LINEAR_WRITE 1
+/** Linear instruction fetch access. */
+#define VMX_APIC_ACCESS_TYPE_LINEAR_INSTR_FETCH 2
+/** Linear read/write access during event delivery. */
+#define VMX_APIC_ACCESS_TYPE_LINEAR_EVENT_DELIVERY 3
+/** Physical read/write access during event delivery. */
+#define VMX_APIC_ACCESS_TYPE_PHYSICAL_EVENT_DELIVERY 10
+/** Physical access for an instruction fetch or during instruction execution. */
+#define VMX_APIC_ACCESS_TYPE_PHYSICAL_INSTR 15
+/** @} */
+
+/** @} */
+
+/** @name VMCS field encoding - Natural width guest state fields
+ * @{
+ */
+#define VMX_VMCS_GUEST_CR0 0x6800
+#define VMX_VMCS_GUEST_CR3 0x6802
+#define VMX_VMCS_GUEST_CR4 0x6804
+#define VMX_VMCS_GUEST_ES_BASE 0x6806
+#define VMX_VMCS_GUEST_CS_BASE 0x6808
+#define VMX_VMCS_GUEST_SS_BASE 0x680A
+#define VMX_VMCS_GUEST_DS_BASE 0x680C
+#define VMX_VMCS_GUEST_FS_BASE 0x680E
+#define VMX_VMCS_GUEST_GS_BASE 0x6810
+#define VMX_VMCS_GUEST_LDTR_BASE 0x6812
+#define VMX_VMCS_GUEST_TR_BASE 0x6814
+#define VMX_VMCS_GUEST_GDTR_BASE 0x6816
+#define VMX_VMCS_GUEST_IDTR_BASE 0x6818
+#define VMX_VMCS_GUEST_DR7 0x681A
+#define VMX_VMCS_GUEST_RSP 0x681C
+#define VMX_VMCS_GUEST_RIP 0x681E
+#define VMX_VMCS_GUEST_RFLAGS 0x6820
+#define VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS 0x6822
+#define VMX_VMCS_GUEST_SYSENTER_ESP 0x6824 /**< MSR IA32_SYSENTER_ESP */
+#define VMX_VMCS_GUEST_SYSENTER_EIP 0x6826 /**< MSR IA32_SYSENTER_EIP */
+/** @} */
+
+
+/** @name VMX_VMCS_GUEST_DEBUG_EXCEPTIONS
+ * @{
+ */
+/** Hardware breakpoint 0 was met. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B0 RT_BIT(0)
+/** Hardware breakpoint 1 was met. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B1 RT_BIT(1)
+/** Hardware breakpoint 2 was met. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B2 RT_BIT(2)
+/** Hardware breakpoint 3 was met. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B3 RT_BIT(3)
+/** At least one data or IO breakpoint was hit. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BREAKPOINT_ENABLED RT_BIT(12)
+/** A debug exception would have been triggered by single-step execution mode. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS RT_BIT(14)
+/** Bits 4-11, 13 and 15-63 are reserved. */
+
+/** @} */
+
+/** @name VMCS field encoding - Natural width host state fields
+ * @{
+ */
+#define VMX_VMCS_HOST_CR0 0x6C00
+#define VMX_VMCS_HOST_CR3 0x6C02
+#define VMX_VMCS_HOST_CR4 0x6C04
+#define VMX_VMCS_HOST_FS_BASE 0x6C06
+#define VMX_VMCS_HOST_GS_BASE 0x6C08
+#define VMX_VMCS_HOST_TR_BASE 0x6C0A
+#define VMX_VMCS_HOST_GDTR_BASE 0x6C0C
+#define VMX_VMCS_HOST_IDTR_BASE 0x6C0E
+#define VMX_VMCS_HOST_SYSENTER_ESP 0x6C10
+#define VMX_VMCS_HOST_SYSENTER_EIP 0x6C12
+#define VMX_VMCS_HOST_RSP 0x6C14
+#define VMX_VMCS_HOST_RIP 0x6C16
+/** @} */
+
+/** @} */
+
+
+/** @defgroup grp_vmx_asm vmx assembly helpers
+ * @ingroup grp_vmx
+ * @{
+ */
+
+/**
+ * Restores some host-state fields that need not be done on every VM-exit.
+ *
+ * @returns VBox status code.
+ * @param fRestoreHostFlags Flags of which host registers needs to be
+ * restored.
+ * @param pRestoreHost Pointer to the host-restore structure.
+ */
+DECLASM(int) VMXRestoreHostState(uint32_t fRestoreHostFlags, PVMXRESTOREHOST pRestoreHost);
+
+
+/**
+ * Dispatches an NMI to the host.
+ */
+DECLASM(int) VMXDispatchHostNmi(void);
+
+
+/**
+ * Executes VMXON
+ *
+ * @returns VBox status code
+ * @param pVMXOn Physical address of VMXON structure
+ */
+#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+DECLASM(int) VMXEnable(RTHCPHYS pVMXOn);
+#else
+DECLINLINE(int) VMXEnable(RTHCPHYS pVMXOn)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ int rc = VINF_SUCCESS;
+ __asm__ __volatile__ (
+ "push %3 \n\t"
+ "push %2 \n\t"
+ ".byte 0xF3, 0x0F, 0xC7, 0x34, 0x24 # VMXON [esp] \n\t"
+ "ja 2f \n\t"
+ "je 1f \n\t"
+ "movl $"RT_XSTR(VERR_VMX_INVALID_VMXON_PTR)", %0 \n\t"
+ "jmp 2f \n\t"
+ "1: \n\t"
+ "movl $"RT_XSTR(VERR_VMX_VMXON_FAILED)", %0 \n\t"
+ "2: \n\t"
+ "add $8, %%esp \n\t"
+ :"=rm"(rc)
+ :"0"(VINF_SUCCESS),
+ "ir"((uint32_t)pVMXOn), /* don't allow direct memory reference here, */
+ "ir"((uint32_t)(pVMXOn >> 32)) /* this would not work with -fomit-frame-pointer */
+ :"memory"
+ );
+ return rc;
+
+# elif VMX_USE_MSC_INTRINSICS
+ unsigned char rcMsc = __vmx_on(&pVMXOn);
+ if (RT_LIKELY(rcMsc == 0))
+ return VINF_SUCCESS;
+ return rcMsc == 2 ? VERR_VMX_INVALID_VMXON_PTR : VERR_VMX_VMXON_FAILED;
+
+# else
+ int rc = VINF_SUCCESS;
+ __asm
+ {
+ push dword ptr [pVMXOn+4]
+ push dword ptr [pVMXOn]
+ _emit 0xF3
+ _emit 0x0F
+ _emit 0xC7
+ _emit 0x34
+ _emit 0x24 /* VMXON [esp] */
+ jnc vmxon_good
+ mov dword ptr [rc], VERR_VMX_INVALID_VMXON_PTR
+ jmp the_end
+
+vmxon_good:
+ jnz the_end
+ mov dword ptr [rc], VERR_VMX_VMXON_FAILED
+the_end:
+ add esp, 8
+ }
+ return rc;
+# endif
+}
+#endif
+
+
+/**
+ * Executes VMXOFF
+ */
+#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+DECLASM(void) VMXDisable(void);
+#else
+DECLINLINE(void) VMXDisable(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__ (
+ ".byte 0x0F, 0x01, 0xC4 # VMXOFF \n\t"
+ );
+
+# elif VMX_USE_MSC_INTRINSICS
+ __vmx_off();
+
+# else
+ __asm
+ {
+ _emit 0x0F
+ _emit 0x01
+ _emit 0xC4 /* VMXOFF */
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Executes VMCLEAR
+ *
+ * @returns VBox status code
+ * @param pVMCS Physical address of VM control structure
+ */
+#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+DECLASM(int) VMXClearVmcs(RTHCPHYS pVMCS);
+#else
+DECLINLINE(int) VMXClearVmcs(RTHCPHYS pVMCS)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ int rc = VINF_SUCCESS;
+ __asm__ __volatile__ (
+ "push %3 \n\t"
+ "push %2 \n\t"
+ ".byte 0x66, 0x0F, 0xC7, 0x34, 0x24 # VMCLEAR [esp] \n\t"
+ "jnc 1f \n\t"
+ "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
+ "1: \n\t"
+ "add $8, %%esp \n\t"
+ :"=rm"(rc)
+ :"0"(VINF_SUCCESS),
+ "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */
+ "ir"((uint32_t)(pVMCS >> 32)) /* this would not work with -fomit-frame-pointer */
+ :"memory"
+ );
+ return rc;
+
+# elif VMX_USE_MSC_INTRINSICS
+ unsigned char rcMsc = __vmx_vmclear(&pVMCS);
+ if (RT_LIKELY(rcMsc == 0))
+ return VINF_SUCCESS;
+ return VERR_VMX_INVALID_VMCS_PTR;
+
+# else
+ int rc = VINF_SUCCESS;
+ __asm
+ {
+ push dword ptr [pVMCS+4]
+ push dword ptr [pVMCS]
+ _emit 0x66
+ _emit 0x0F
+ _emit 0xC7
+ _emit 0x34
+ _emit 0x24 /* VMCLEAR [esp] */
+ jnc success
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
+success:
+ add esp, 8
+ }
+ return rc;
+# endif
+}
+#endif
+
+
+/**
+ * Executes VMPTRLD
+ *
+ * @returns VBox status code
+ * @param pVMCS Physical address of VMCS structure
+ */
+#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+DECLASM(int) VMXActivateVmcs(RTHCPHYS pVMCS);
+#else
+DECLINLINE(int) VMXActivateVmcs(RTHCPHYS pVMCS)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ int rc = VINF_SUCCESS;
+ __asm__ __volatile__ (
+ "push %3 \n\t"
+ "push %2 \n\t"
+ ".byte 0x0F, 0xC7, 0x34, 0x24 # VMPTRLD [esp] \n\t"
+ "jnc 1f \n\t"
+ "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
+ "1: \n\t"
+ "add $8, %%esp \n\t"
+ :"=rm"(rc)
+ :"0"(VINF_SUCCESS),
+ "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */
+ "ir"((uint32_t)(pVMCS >> 32)) /* this will not work with -fomit-frame-pointer */
+ );
+ return rc;
+
+# elif VMX_USE_MSC_INTRINSICS
+ unsigned char rcMsc = __vmx_vmptrld(&pVMCS);
+ if (RT_LIKELY(rcMsc == 0))
+ return VINF_SUCCESS;
+ return VERR_VMX_INVALID_VMCS_PTR;
+
+# else
+ int rc = VINF_SUCCESS;
+ __asm
+ {
+ push dword ptr [pVMCS+4]
+ push dword ptr [pVMCS]
+ _emit 0x0F
+ _emit 0xC7
+ _emit 0x34
+ _emit 0x24 /* VMPTRLD [esp] */
+ jnc success
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
+
+success:
+ add esp, 8
+ }
+ return rc;
+# endif
+}
+#endif
+
+/**
+ * Executes VMPTRST
+ *
+ * @returns VBox status code
+ * @param pVMCS Address that will receive the current pointer
+ */
+DECLASM(int) VMXGetActivatedVmcs(RTHCPHYS *pVMCS);
+
+/**
+ * Executes VMWRITE
+ *
+ * @returns VBox status code
+ * @retval VINF_SUCCESS
+ * @retval VERR_VMX_INVALID_VMCS_PTR
+ * @retval VERR_VMX_INVALID_VMCS_FIELD
+ *
+ * @param idxField VMCS index
+ * @param u32Val 32 bits value
+ *
+ * @remarks The values of the two status codes can be ORed together, the result
+ * will be VERR_VMX_INVALID_VMCS_PTR.
+ */
+#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+DECLASM(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val);
+#else
+DECLINLINE(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ int rc = VINF_SUCCESS;
+ __asm__ __volatile__ (
+ ".byte 0x0F, 0x79, 0xC2 # VMWRITE eax, edx \n\t"
+ "ja 2f \n\t"
+ "je 1f \n\t"
+ "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
+ "jmp 2f \n\t"
+ "1: \n\t"
+ "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t"
+ "2: \n\t"
+ :"=rm"(rc)
+ :"0"(VINF_SUCCESS),
+ "a"(idxField),
+ "d"(u32Val)
+ );
+ return rc;
+
+# elif VMX_USE_MSC_INTRINSICS
+ unsigned char rcMsc = __vmx_vmwrite(idxField, u32Val);
+ if (RT_LIKELY(rcMsc == 0))
+ return VINF_SUCCESS;
+ return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD;
+
+#else
+ int rc = VINF_SUCCESS;
+ __asm
+ {
+ push dword ptr [u32Val]
+ mov eax, [idxField]
+ _emit 0x0F
+ _emit 0x79
+ _emit 0x04
+ _emit 0x24 /* VMWRITE eax, [esp] */
+ jnc valid_vmcs
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
+ jmp the_end
+
+valid_vmcs:
+ jnz the_end
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD
+the_end:
+ add esp, 4
+ }
+ return rc;
+# endif
+}
+#endif
+
+/**
+ * Executes VMWRITE
+ *
+ * @returns VBox status code
+ * @retval VINF_SUCCESS
+ * @retval VERR_VMX_INVALID_VMCS_PTR
+ * @retval VERR_VMX_INVALID_VMCS_FIELD
+ *
+ * @param idxField VMCS index
+ * @param u64Val 16, 32 or 64 bits value
+ *
+ * @remarks The values of the two status codes can be ORed together, the result
+ * will be VERR_VMX_INVALID_VMCS_PTR.
+ */
+#if !defined(RT_ARCH_X86) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+# if !VMX_USE_MSC_INTRINSICS || ARCH_BITS != 64
+DECLASM(int) VMXWriteVmcs64(uint32_t idxField, uint64_t u64Val);
+# else /* VMX_USE_MSC_INTRINSICS */
+DECLINLINE(int) VMXWriteVmcs64(uint32_t idxField, uint64_t u64Val)
+{
+ unsigned char rcMsc = __vmx_vmwrite(idxField, u64Val);
+ if (RT_LIKELY(rcMsc == 0))
+ return VINF_SUCCESS;
+ return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD;
+}
+# endif /* VMX_USE_MSC_INTRINSICS */
+#else
+# define VMXWriteVmcs64(idxField, u64Val) VMXWriteVmcs64Ex(pVCpu, idxField, u64Val) /** @todo dead ugly, picking up pVCpu like this */
+VMMR0DECL(int) VMXWriteVmcs64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val);
+#endif
+
+#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+# define VMXWriteVmcsHstN(idxField, uVal) HMVMX_IS_64BIT_HOST_MODE() ? \
+ VMXWriteVmcs64(idxField, uVal) \
+ : VMXWriteVmcs32(idxField, uVal)
+# define VMXWriteVmcsGstN(idxField, u64Val) (pVCpu->CTX_SUFF(pVM)->hm.s.fAllow64BitGuests) ? \
+ VMXWriteVmcs64(idxField, u64Val) \
+ : VMXWriteVmcs32(idxField, u64Val)
+#elif ARCH_BITS == 32
+# define VMXWriteVmcsHstN VMXWriteVmcs32
+# define VMXWriteVmcsGstN(idxField, u64Val) VMXWriteVmcs64Ex(pVCpu, idxField, u64Val)
+# else /* ARCH_BITS == 64 */
+# define VMXWriteVmcsHstN VMXWriteVmcs64
+# define VMXWriteVmcsGstN VMXWriteVmcs64
+# endif
+
+
+/**
+ * Invalidate a page using invept
+ * @returns VBox status code
+ * @param enmFlush Type of flush
+ * @param pDescriptor Descriptor
+ */
+DECLASM(int) VMXR0InvEPT(VMX_FLUSH_EPT enmFlush, uint64_t *pDescriptor);
+
+/**
+ * Invalidate a page using invvpid
+ * @returns VBox status code
+ * @param enmFlush Type of flush
+ * @param pDescriptor Descriptor
+ */
+DECLASM(int) VMXR0InvVPID(VMX_FLUSH_VPID enmFlush, uint64_t *pDescriptor);
+
+/**
+ * Executes VMREAD
+ *
+ * @returns VBox status code
+ * @retval VINF_SUCCESS
+ * @retval VERR_VMX_INVALID_VMCS_PTR
+ * @retval VERR_VMX_INVALID_VMCS_FIELD
+ *
+ * @param idxField VMCS index
+ * @param pData Ptr to store VM field value
+ *
+ * @remarks The values of the two status codes can be ORed together, the result
+ * will be VERR_VMX_INVALID_VMCS_PTR.
+ */
+#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+DECLASM(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData);
+#else
+DECLINLINE(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ int rc = VINF_SUCCESS;
+ __asm__ __volatile__ (
+ "movl $"RT_XSTR(VINF_SUCCESS)", %0 \n\t"
+ ".byte 0x0F, 0x78, 0xc2 # VMREAD eax, edx \n\t"
+ "ja 2f \n\t"
+ "je 1f \n\t"
+ "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
+ "jmp 2f \n\t"
+ "1: \n\t"
+ "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t"
+ "2: \n\t"
+ :"=&r"(rc),
+ "=d"(*pData)
+ :"a"(idxField),
+ "d"(0)
+ );
+ return rc;
+
+# elif VMX_USE_MSC_INTRINSICS
+ unsigned char rcMsc;
+# if ARCH_BITS == 32
+ rcMsc = __vmx_vmread(idxField, pData);
+# else
+ uint64_t u64Tmp;
+ rcMsc = __vmx_vmread(idxField, &u64Tmp);
+ *pData = (uint32_t)u64Tmp;
+# endif
+ if (RT_LIKELY(rcMsc == 0))
+ return VINF_SUCCESS;
+ return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD;
+
+#else
+ int rc = VINF_SUCCESS;
+ __asm
+ {
+ sub esp, 4
+ mov dword ptr [esp], 0
+ mov eax, [idxField]
+ _emit 0x0F
+ _emit 0x78
+ _emit 0x04
+ _emit 0x24 /* VMREAD eax, [esp] */
+ mov edx, pData
+ pop dword ptr [edx]
+ jnc valid_vmcs
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
+ jmp the_end
+
+valid_vmcs:
+ jnz the_end
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD
+the_end:
+ }
+ return rc;
+# endif
+}
+#endif
+
+/**
+ * Executes VMREAD
+ *
+ * @returns VBox status code
+ * @retval VINF_SUCCESS
+ * @retval VERR_VMX_INVALID_VMCS_PTR
+ * @retval VERR_VMX_INVALID_VMCS_FIELD
+ *
+ * @param idxField VMCS index
+ * @param pData Ptr to store VM field value
+ *
+ * @remarks The values of the two status codes can be ORed together, the result
+ * will be VERR_VMX_INVALID_VMCS_PTR.
+ */
+#if (!defined(RT_ARCH_X86) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+DECLASM(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData);
+#else
+DECLINLINE(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData)
+{
+# if VMX_USE_MSC_INTRINSICS
+ unsigned char rcMsc;
+# if ARCH_BITS == 32
+ size_t uLow;
+ size_t uHigh;
+ rcMsc = __vmx_vmread(idxField, &uLow);
+ rcMsc |= __vmx_vmread(idxField + 1, &uHigh);
+ *pData = RT_MAKE_U64(uLow, uHigh);
+# else
+ rcMsc = __vmx_vmread(idxField, pData);
+# endif
+ if (RT_LIKELY(rcMsc == 0))
+ return VINF_SUCCESS;
+ return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD;
+
+# elif ARCH_BITS == 32
+ int rc;
+ uint32_t val_hi, val;
+ rc = VMXReadVmcs32(idxField, &val);
+ rc |= VMXReadVmcs32(idxField + 1, &val_hi);
+ AssertRC(rc);
+ *pData = RT_MAKE_U64(val, val_hi);
+ return rc;
+
+# else
+# error "Shouldn't be here..."
+# endif
+}
+#endif
+
+/**
+ * Gets the last instruction error value from the current VMCS
+ *
+ * @returns error value
+ */
+DECLINLINE(uint32_t) VMXGetLastError(void)
+{
+#if ARCH_BITS == 64
+ uint64_t uLastError = 0;
+ int rc = VMXReadVmcs64(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
+ AssertRC(rc);
+ return (uint32_t)uLastError;
+
+#else /* 32-bit host: */
+ uint32_t uLastError = 0;
+ int rc = VMXReadVmcs32(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
+ AssertRC(rc);
+ return uLastError;
+#endif
+}
+
+#ifdef IN_RING0
+VMMR0DECL(int) VMXR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt);
+VMMR0DECL(int) VMXR0InvalidatePhysPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys);
+#endif /* IN_RING0 */
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/vmm/hwacc_vmx.mac b/include/VBox/vmm/hm_vmx.mac
index 3fc11b43..3a3a1c7b 100644
--- a/include/VBox/vmm/hwacc_vmx.mac
+++ b/include/VBox/vmm/hm_vmx.mac
@@ -1,9 +1,9 @@
;; @file
-; HWACCM - VMX Structures and Definitions.
+; HM - VMX Structures and Definitions.
;
;
-; Copyright (C) 2006-2010 Oracle Corporation
+; Copyright (C) 2006-2013 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
@@ -60,16 +60,16 @@
%define VMX_VMCS_GUEST_LINK_PTR_HIGH 02801h
%define VMX_VMCS_GUEST_DEBUGCTL_FULL 02802h
%define VMX_VMCS_GUEST_DEBUGCTL_HIGH 02803h
-%define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS 04000h
-%define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS 04002h
+%define VMX_VMCS_CTRL_PIN_EXEC 04000h
+%define VMX_VMCS_CTRL_PROC_EXEC 04002h
%define VMX_VMCS_CTRL_EXCEPTION_BITMAP 04004h
%define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MASK 04006h
%define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH 04008h
%define VMX_VMCS_CTRL_CR3_TARGET_COUNT 0400Ah
-%define VMX_VMCS_CTRL_EXIT_CONTROLS 0400Ch
+%define VMX_VMCS_CTRL_EXIT 0400Ch
%define VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT 0400Eh
%define VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT 04010h
-%define VMX_VMCS_CTRL_ENTRY_CONTROLS 04012h
+%define VMX_VMCS_CTRL_ENTRY 04012h
%define VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT 04014h
%define VMX_VMCS_CTRL_ENTRY_IRQ_INFO 04016h
%define VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE 04018h
@@ -118,26 +118,26 @@
%define VMX_VMCS_RO_IO_RDI 06406h
%define VMX_VMCS_RO_IO_RIP 06408h
%define VMX_VMCS_GUEST_LINEAR_ADDR 0640Ah
-%define VMX_VMCS64_GUEST_CR0 06800h
-%define VMX_VMCS64_GUEST_CR3 06802h
-%define VMX_VMCS64_GUEST_CR4 06804h
-%define VMX_VMCS64_GUEST_ES_BASE 06806h
-%define VMX_VMCS64_GUEST_CS_BASE 06808h
-%define VMX_VMCS64_GUEST_SS_BASE 0680Ah
-%define VMX_VMCS64_GUEST_DS_BASE 0680Ch
-%define VMX_VMCS64_GUEST_FS_BASE 0680Eh
-%define VMX_VMCS64_GUEST_GS_BASE 06810h
-%define VMX_VMCS64_GUEST_LDTR_BASE 06812h
-%define VMX_VMCS64_GUEST_TR_BASE 06814h
-%define VMX_VMCS64_GUEST_GDTR_BASE 06816h
-%define VMX_VMCS64_GUEST_IDTR_BASE 06818h
-%define VMX_VMCS64_GUEST_DR7 0681Ah
-%define VMX_VMCS64_GUEST_RSP 0681Ch
-%define VMX_VMCS64_GUEST_RIP 0681Eh
-%define VMX_VMCS64_GUEST_RFLAGS 06820h
+%define VMX_VMCS64_GUEST_CR0 06800h
+%define VMX_VMCS64_GUEST_CR3 06802h
+%define VMX_VMCS64_GUEST_CR4 06804h
+%define VMX_VMCS64_GUEST_ES_BASE 06806h
+%define VMX_VMCS64_GUEST_CS_BASE 06808h
+%define VMX_VMCS64_GUEST_SS_BASE 0680Ah
+%define VMX_VMCS64_GUEST_DS_BASE 0680Ch
+%define VMX_VMCS64_GUEST_FS_BASE 0680Eh
+%define VMX_VMCS64_GUEST_GS_BASE 06810h
+%define VMX_VMCS64_GUEST_LDTR_BASE 06812h
+%define VMX_VMCS64_GUEST_TR_BASE 06814h
+%define VMX_VMCS64_GUEST_GDTR_BASE 06816h
+%define VMX_VMCS64_GUEST_IDTR_BASE 06818h
+%define VMX_VMCS64_GUEST_DR7 0681Ah
+%define VMX_VMCS64_GUEST_RSP 0681Ch
+%define VMX_VMCS64_GUEST_RIP 0681Eh
+%define VMX_VMCS64_GUEST_RFLAGS 06820h
%define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS 06822h
-%define VMX_VMCS64_GUEST_SYSENTER_ESP 06824h
-%define VMX_VMCS64_GUEST_SYSENTER_EIP 06826h
+%define VMX_VMCS64_GUEST_SYSENTER_ESP 06824h
+%define VMX_VMCS64_GUEST_SYSENTER_EIP 06826h
%define VMX_VMCS_HOST_CR0 06C00h
%define VMX_VMCS_HOST_CR3 06C02h
%define VMX_VMCS_HOST_CR4 06C04h
@@ -151,4 +151,31 @@
%define VMX_VMCS_HOST_RSP 06C14h
%define VMX_VMCS_HOST_RIP 06C16h
-%define VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64 RT_BIT(9)
+%define VMX_RESTORE_HOST_SEL_DS 1h ;RT_BIT(0)
+%define VMX_RESTORE_HOST_SEL_ES 2h ;RT_BIT(1)
+%define VMX_RESTORE_HOST_SEL_FS 4h ;RT_BIT(2)
+%define VMX_RESTORE_HOST_SEL_GS 8h ;RT_BIT(3)
+%define VMX_RESTORE_HOST_SEL_TR 10h ;RT_BIT(4)
+%define VMX_RESTORE_HOST_GDTR 20h ;RT_BIT(5)
+%define VMX_RESTORE_HOST_IDTR 40h ;RT_BIT(6)
+%define VMX_RESTORE_HOST_REQUIRED 80h ;RT_BIT(7)
+
+;; C version hm_vmx.h.
+struc VMXRESTOREHOST
+ .uHostSelDS resw 1
+ .uHostSelES resw 1
+ .uHostSelFS resw 1
+ .uHostSelGS resw 1
+ .uHostSelTR resw 1
+ .abPadding0 resb 4
+ .HostGdtr resb 10
+ .abPadding1 resb 6
+ .HostIdtr resb 10
+ .uHostFSBase resq 1
+ .uHostGSBase resq 1
+endstruc
+AssertCompileMemberOffset(VMXRESTOREHOST, HostGdtr, 16-2)
+AssertCompileMemberOffset(VMXRESTOREHOST, HostIdtr, 32-2)
+AssertCompileMemberOffset(VMXRESTOREHOST, uHostFSBase, 40)
+AssertCompileSize(VMXRESTOREHOST, 56)
+
diff --git a/include/VBox/vmm/hwacc_vmx.h b/include/VBox/vmm/hwacc_vmx.h
deleted file mode 100644
index a96f587e..00000000
--- a/include/VBox/vmm/hwacc_vmx.h
+++ /dev/null
@@ -1,1708 +0,0 @@
-/** @file
- * HWACCM - VMX Structures and Definitions. (VMM)
- */
-
-/*
- * Copyright (C) 2006-2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- */
-
-#ifndef ___VBox_vmm_vmx_h
-#define ___VBox_vmm_vmx_h
-
-#include <VBox/types.h>
-#include <VBox/err.h>
-#include <iprt/x86.h>
-#include <iprt/assert.h>
-
-/** @defgroup grp_vmx vmx Types and Definitions
- * @ingroup grp_hwaccm
- * @{
- */
-
-/** @name VMX EPT paging structures
- * @{
- */
-
-/**
- * Number of page table entries in the EPT. (PDPTE/PDE/PTE)
- */
-#define EPT_PG_ENTRIES X86_PG_PAE_ENTRIES
-
-/**
- * EPT Page Directory Pointer Entry. Bit view.
- * @todo uint64_t isn't safe for bitfields (gcc pedantic warnings, and IIRC,
- * this did cause trouble with one compiler/version).
- */
-#pragma pack(1)
-typedef struct EPTPML4EBITS
-{
- /** Present bit. */
- uint64_t u1Present : 1;
- /** Writable bit. */
- uint64_t u1Write : 1;
- /** Executable bit. */
- uint64_t u1Execute : 1;
- /** Reserved (must be 0). */
- uint64_t u5Reserved : 5;
- /** Available for software. */
- uint64_t u4Available : 4;
- /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
- uint64_t u40PhysAddr : 40;
- /** Availabe for software. */
- uint64_t u12Available : 12;
-} EPTPML4EBITS;
-#pragma pack()
-AssertCompileSize(EPTPML4EBITS, 8);
-
-/** Bits 12-51 - - EPT - Physical Page number of the next level. */
-#define EPT_PML4E_PG_MASK X86_PML4E_PG_MASK
-/** The page shift to get the PML4 index. */
-#define EPT_PML4_SHIFT X86_PML4_SHIFT
-/** The PML4 index mask (apply to a shifted page address). */
-#define EPT_PML4_MASK X86_PML4_MASK
-
-/**
- * EPT PML4E.
- */
-#pragma pack(1)
-typedef union EPTPML4E
-{
- /** Normal view. */
- EPTPML4EBITS n;
- /** Unsigned integer view. */
- X86PGPAEUINT u;
- /** 64 bit unsigned integer view. */
- uint64_t au64[1];
- /** 32 bit unsigned integer view. */
- uint32_t au32[2];
-} EPTPML4E;
-#pragma pack()
-/** Pointer to a PML4 table entry. */
-typedef EPTPML4E *PEPTPML4E;
-/** Pointer to a const PML4 table entry. */
-typedef const EPTPML4E *PCEPTPML4E;
-AssertCompileSize(EPTPML4E, 8);
-
-/**
- * EPT PML4 Table.
- */
-#pragma pack(1)
-typedef struct EPTPML4
-{
- EPTPML4E a[EPT_PG_ENTRIES];
-} EPTPML4;
-#pragma pack()
-/** Pointer to an EPT PML4 Table. */
-typedef EPTPML4 *PEPTPML4;
-/** Pointer to a const EPT PML4 Table. */
-typedef const EPTPML4 *PCEPTPML4;
-
-/**
- * EPT Page Directory Pointer Entry. Bit view.
- */
-#pragma pack(1)
-typedef struct EPTPDPTEBITS
-{
- /** Present bit. */
- uint64_t u1Present : 1;
- /** Writable bit. */
- uint64_t u1Write : 1;
- /** Executable bit. */
- uint64_t u1Execute : 1;
- /** Reserved (must be 0). */
- uint64_t u5Reserved : 5;
- /** Available for software. */
- uint64_t u4Available : 4;
- /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
- uint64_t u40PhysAddr : 40;
- /** Availabe for software. */
- uint64_t u12Available : 12;
-} EPTPDPTEBITS;
-#pragma pack()
-AssertCompileSize(EPTPDPTEBITS, 8);
-
-/** Bits 12-51 - - EPT - Physical Page number of the next level. */
-#define EPT_PDPTE_PG_MASK X86_PDPE_PG_MASK
-/** The page shift to get the PDPT index. */
-#define EPT_PDPT_SHIFT X86_PDPT_SHIFT
-/** The PDPT index mask (apply to a shifted page address). */
-#define EPT_PDPT_MASK X86_PDPT_MASK_AMD64
-
-/**
- * EPT Page Directory Pointer.
- */
-#pragma pack(1)
-typedef union EPTPDPTE
-{
- /** Normal view. */
- EPTPDPTEBITS n;
- /** Unsigned integer view. */
- X86PGPAEUINT u;
- /** 64 bit unsigned integer view. */
- uint64_t au64[1];
- /** 32 bit unsigned integer view. */
- uint32_t au32[2];
-} EPTPDPTE;
-#pragma pack()
-/** Pointer to an EPT Page Directory Pointer Entry. */
-typedef EPTPDPTE *PEPTPDPTE;
-/** Pointer to a const EPT Page Directory Pointer Entry. */
-typedef const EPTPDPTE *PCEPTPDPTE;
-AssertCompileSize(EPTPDPTE, 8);
-
-/**
- * EPT Page Directory Pointer Table.
- */
-#pragma pack(1)
-typedef struct EPTPDPT
-{
- EPTPDPTE a[EPT_PG_ENTRIES];
-} EPTPDPT;
-#pragma pack()
-/** Pointer to an EPT Page Directory Pointer Table. */
-typedef EPTPDPT *PEPTPDPT;
-/** Pointer to a const EPT Page Directory Pointer Table. */
-typedef const EPTPDPT *PCEPTPDPT;
-
-
-/**
- * EPT Page Directory Table Entry. Bit view.
- */
-#pragma pack(1)
-typedef struct EPTPDEBITS
-{
- /** Present bit. */
- uint64_t u1Present : 1;
- /** Writable bit. */
- uint64_t u1Write : 1;
- /** Executable bit. */
- uint64_t u1Execute : 1;
- /** Reserved (must be 0). */
- uint64_t u4Reserved : 4;
- /** Big page (must be 0 here). */
- uint64_t u1Size : 1;
- /** Available for software. */
- uint64_t u4Available : 4;
- /** Physical address of page table. Restricted by maximum physical address width of the cpu. */
- uint64_t u40PhysAddr : 40;
- /** Availabe for software. */
- uint64_t u12Available : 12;
-} EPTPDEBITS;
-#pragma pack()
-AssertCompileSize(EPTPDEBITS, 8);
-
-/** Bits 12-51 - - EPT - Physical Page number of the next level. */
-#define EPT_PDE_PG_MASK X86_PDE_PAE_PG_MASK
-/** The page shift to get the PD index. */
-#define EPT_PD_SHIFT X86_PD_PAE_SHIFT
-/** The PD index mask (apply to a shifted page address). */
-#define EPT_PD_MASK X86_PD_PAE_MASK
-
-/**
- * EPT 2MB Page Directory Table Entry. Bit view.
- */
-#pragma pack(1)
-typedef struct EPTPDE2MBITS
-{
- /** Present bit. */
- uint64_t u1Present : 1;
- /** Writable bit. */
- uint64_t u1Write : 1;
- /** Executable bit. */
- uint64_t u1Execute : 1;
- /** EPT Table Memory Type. MBZ for non-leaf nodes. */
- uint64_t u3EMT : 3;
- /** Ignore PAT memory type */
- uint64_t u1IgnorePAT : 1;
- /** Big page (must be 1 here). */
- uint64_t u1Size : 1;
- /** Available for software. */
- uint64_t u4Available : 4;
- /** Reserved (must be 0). */
- uint64_t u9Reserved : 9;
- /** Physical address of the 2MB page. Restricted by maximum physical address width of the cpu. */
- uint64_t u31PhysAddr : 31;
- /** Availabe for software. */
- uint64_t u12Available : 12;
-} EPTPDE2MBITS;
-#pragma pack()
-AssertCompileSize(EPTPDE2MBITS, 8);
-
-/** Bits 21-51 - - EPT - Physical Page number of the next level. */
-#define EPT_PDE2M_PG_MASK X86_PDE2M_PAE_PG_MASK
-
-/**
- * EPT Page Directory Table Entry.
- */
-#pragma pack(1)
-typedef union EPTPDE
-{
- /** Normal view. */
- EPTPDEBITS n;
- /** 2MB view (big). */
- EPTPDE2MBITS b;
- /** Unsigned integer view. */
- X86PGPAEUINT u;
- /** 64 bit unsigned integer view. */
- uint64_t au64[1];
- /** 32 bit unsigned integer view. */
- uint32_t au32[2];
-} EPTPDE;
-#pragma pack()
-/** Pointer to an EPT Page Directory Table Entry. */
-typedef EPTPDE *PEPTPDE;
-/** Pointer to a const EPT Page Directory Table Entry. */
-typedef const EPTPDE *PCEPTPDE;
-AssertCompileSize(EPTPDE, 8);
-
-/**
- * EPT Page Directory Table.
- */
-#pragma pack(1)
-typedef struct EPTPD
-{
- EPTPDE a[EPT_PG_ENTRIES];
-} EPTPD;
-#pragma pack()
-/** Pointer to an EPT Page Directory Table. */
-typedef EPTPD *PEPTPD;
-/** Pointer to a const EPT Page Directory Table. */
-typedef const EPTPD *PCEPTPD;
-
-
-/**
- * EPT Page Table Entry. Bit view.
- */
-#pragma pack(1)
-typedef struct EPTPTEBITS
-{
- /** 0 - Present bit.
- * @remark This is a convenience "misnomer". The bit actually indicates
- * read access and the CPU will consider an entry with any of the
- * first three bits set as present. Since all our valid entries
- * will have this bit set, it can be used as a present indicator
- * and allow some code sharing. */
- uint64_t u1Present : 1;
- /** 1 - Writable bit. */
- uint64_t u1Write : 1;
- /** 2 - Executable bit. */
- uint64_t u1Execute : 1;
- /** 5:3 - EPT Memory Type. MBZ for non-leaf nodes. */
- uint64_t u3EMT : 3;
- /** 6 - Ignore PAT memory type */
- uint64_t u1IgnorePAT : 1;
- /** 11:7 - Available for software. */
- uint64_t u5Available : 5;
- /** 51:12 - Physical address of page. Restricted by maximum physical
- * address width of the cpu. */
- uint64_t u40PhysAddr : 40;
- /** 63:52 - Available for software. */
- uint64_t u12Available : 12;
-} EPTPTEBITS;
-#pragma pack()
-AssertCompileSize(EPTPTEBITS, 8);
-
-/** Bits 12-51 - - EPT - Physical Page number of the next level. */
-#define EPT_PTE_PG_MASK X86_PTE_PAE_PG_MASK
-/** The page shift to get the EPT PTE index. */
-#define EPT_PT_SHIFT X86_PT_PAE_SHIFT
-/** The EPT PT index mask (apply to a shifted page address). */
-#define EPT_PT_MASK X86_PT_PAE_MASK
-
-/**
- * EPT Page Table Entry.
- */
-#pragma pack(1)
-typedef union EPTPTE
-{
- /** Normal view. */
- EPTPTEBITS n;
- /** Unsigned integer view. */
- X86PGPAEUINT u;
- /** 64 bit unsigned integer view. */
- uint64_t au64[1];
- /** 32 bit unsigned integer view. */
- uint32_t au32[2];
-} EPTPTE;
-#pragma pack()
-/** Pointer to an EPT Page Directory Table Entry. */
-typedef EPTPTE *PEPTPTE;
-/** Pointer to a const EPT Page Directory Table Entry. */
-typedef const EPTPTE *PCEPTPTE;
-AssertCompileSize(EPTPTE, 8);
-
-/**
- * EPT Page Table.
- */
-#pragma pack(1)
-typedef struct EPTPT
-{
- EPTPTE a[EPT_PG_ENTRIES];
-} EPTPT;
-#pragma pack()
-/** Pointer to an extended page table. */
-typedef EPTPT *PEPTPT;
-/** Pointer to a const extended table. */
-typedef const EPTPT *PCEPTPT;
-
-/**
- * VPID flush types.
- */
-typedef enum
-{
- /** Invalidate a specific page. */
- VMX_FLUSH_VPID_INDIV_ADDR = 0,
- /** Invalidate one context (specific VPID). */
- VMX_FLUSH_VPID_SINGLE_CONTEXT = 1,
- /** Invalidate all contexts (all VPIDs). */
- VMX_FLUSH_VPID_ALL_CONTEXTS = 2,
- /** Invalidate a single VPID context retaining global mappings. */
- VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS = 3,
- /** Unsupported by VirtualBox. */
- VMX_FLUSH_VPID_NOT_SUPPORTED = 0xbad,
- /** Unsupported by CPU. */
- VMX_FLUSH_VPID_NONE = 0xb00,
- /** 32bit hackishness. */
- VMX_FLUSH_VPID_32BIT_HACK = 0x7fffffff
-} VMX_FLUSH_VPID;
-
-/**
- * EPT flush types.
- */
-typedef enum
-{
- /** Invalidate one context (specific EPT). */
- VMX_FLUSH_EPT_SINGLE_CONTEXT = 1,
- /* Invalidate all contexts (all EPTs) */
- VMX_FLUSH_EPT_ALL_CONTEXTS = 2,
- /** Unsupported by VirtualBox. */
- VMX_FLUSH_EPT_NOT_SUPPORTED = 0xbad,
- /** Unsupported by CPU. */
- VMX_FLUSH_EPT_NONE = 0xb00,
- /** 32bit hackishness. */
- VMX_FLUSH_EPT_32BIT_HACK = 0x7fffffff
-} VMX_FLUSH_EPT;
-/** @} */
-
-/** @name MSR load/store elements
- * @{
- */
-#pragma pack(1)
-typedef struct
-{
- uint32_t u32IndexMSR;
- uint32_t u32Reserved;
- uint64_t u64Value;
-} VMXMSR;
-#pragma pack()
-/** Pointer to an MSR load/store element. */
-typedef VMXMSR *PVMXMSR;
-/** Pointer to a const MSR load/store element. */
-typedef const VMXMSR *PCVMXMSR;
-
-/** @} */
-
-
-/** @name VT-x capability qword
- * @{
- */
-#pragma pack(1)
-typedef union
-{
- struct
- {
- uint32_t disallowed0;
- uint32_t allowed1;
- } n;
- uint64_t u;
-} VMX_CAPABILITY;
-#pragma pack()
-/** @} */
-
-/** @name VMX Basic Exit Reasons.
- * @{
- */
-/** And-mask for setting reserved bits to zero */
-#define VMX_EFLAGS_RESERVED_0 (~0xffc08028)
-/** Or-mask for setting reserved bits to 1 */
-#define VMX_EFLAGS_RESERVED_1 0x00000002
-/** @} */
-
-/** @name VMX Basic Exit Reasons.
- * @{
- */
-/** -1 Invalid exit code */
-#define VMX_EXIT_INVALID -1
-/** 0 Exception or non-maskable interrupt (NMI). */
-#define VMX_EXIT_EXCEPTION 0
-/** 1 External interrupt. */
-#define VMX_EXIT_EXTERNAL_IRQ 1
-/** 2 Triple fault. */
-#define VMX_EXIT_TRIPLE_FAULT 2
-/** 3 INIT signal. */
-#define VMX_EXIT_INIT_SIGNAL 3
-/** 4 Start-up IPI (SIPI). */
-#define VMX_EXIT_SIPI 4
-/** 5 I/O system-management interrupt (SMI). */
-#define VMX_EXIT_IO_SMI_IRQ 5
-/** 6 Other SMI. */
-#define VMX_EXIT_SMI_IRQ 6
-/** 7 Interrupt window. */
-#define VMX_EXIT_IRQ_WINDOW 7
-/** 9 Task switch. */
-#define VMX_EXIT_TASK_SWITCH 9
-/** 10 Guest software attempted to execute CPUID. */
-#define VMX_EXIT_CPUID 10
-/** 12 Guest software attempted to execute HLT. */
-#define VMX_EXIT_HLT 12
-/** 13 Guest software attempted to execute INVD. */
-#define VMX_EXIT_INVD 13
-/** 14 Guest software attempted to execute INVLPG. */
-#define VMX_EXIT_INVLPG 14
-/** 15 Guest software attempted to execute RDPMC. */
-#define VMX_EXIT_RDPMC 15
-/** 16 Guest software attempted to execute RDTSC. */
-#define VMX_EXIT_RDTSC 16
-/** 17 Guest software attempted to execute RSM in SMM. */
-#define VMX_EXIT_RSM 17
-/** 18 Guest software executed VMCALL. */
-#define VMX_EXIT_VMCALL 18
-/** 19 Guest software executed VMCLEAR. */
-#define VMX_EXIT_VMCLEAR 19
-/** 20 Guest software executed VMLAUNCH. */
-#define VMX_EXIT_VMLAUNCH 20
-/** 21 Guest software executed VMPTRLD. */
-#define VMX_EXIT_VMPTRLD 21
-/** 22 Guest software executed VMPTRST. */
-#define VMX_EXIT_VMPTRST 22
-/** 23 Guest software executed VMREAD. */
-#define VMX_EXIT_VMREAD 23
-/** 24 Guest software executed VMRESUME. */
-#define VMX_EXIT_VMRESUME 24
-/** 25 Guest software executed VMWRITE. */
-#define VMX_EXIT_VMWRITE 25
-/** 26 Guest software executed VMXOFF. */
-#define VMX_EXIT_VMXOFF 26
-/** 27 Guest software executed VMXON. */
-#define VMX_EXIT_VMXON 27
-/** 28 Control-register accesses. */
-#define VMX_EXIT_CRX_MOVE 28
-/** 29 Debug-register accesses. */
-#define VMX_EXIT_DRX_MOVE 29
-/** 30 I/O instruction. */
-#define VMX_EXIT_PORT_IO 30
-/** 31 RDMSR. Guest software attempted to execute RDMSR. */
-#define VMX_EXIT_RDMSR 31
-/** 32 WRMSR. Guest software attempted to execute WRMSR. */
-#define VMX_EXIT_WRMSR 32
-/** 33 VM-entry failure due to invalid guest state. */
-#define VMX_EXIT_ERR_INVALID_GUEST_STATE 33
-/** 34 VM-entry failure due to MSR loading. */
-#define VMX_EXIT_ERR_MSR_LOAD 34
-/** 36 Guest software executed MWAIT. */
-#define VMX_EXIT_MWAIT 36
-/** 37 VM exit due to monitor trap flag. */
-#define VMX_EXIT_MTF 37
-/** 39 Guest software attempted to execute MONITOR. */
-#define VMX_EXIT_MONITOR 39
-/** 40 Guest software attempted to execute PAUSE. */
-#define VMX_EXIT_PAUSE 40
-/** 41 VM-entry failure due to machine-check. */
-#define VMX_EXIT_ERR_MACHINE_CHECK 41
-/** 43 TPR below threshold. Guest software executed MOV to CR8. */
-#define VMX_EXIT_TPR 43
-/** 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */
-#define VMX_EXIT_APIC_ACCESS 44
-/** 46 Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT. */
-#define VMX_EXIT_XDTR_ACCESS 46
-/** 47 Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR. */
-#define VMX_EXIT_TR_ACCESS 47
-/** 48 EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures. */
-#define VMX_EXIT_EPT_VIOLATION 48
-/** 49 EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry. */
-#define VMX_EXIT_EPT_MISCONFIG 49
-/** 50 INVEPT. Guest software attempted to execute INVEPT. */
-#define VMX_EXIT_INVEPT 50
-/** 51 RDTSCP. Guest software attempted to execute RDTSCP. */
-#define VMX_EXIT_RDTSCP 51
-/** 52 VMX-preemption timer expired. The preemption timer counted down to zero. */
-#define VMX_EXIT_PREEMPTION_TIMER 52
-/** 53 INVVPID. Guest software attempted to execute INVVPID. */
-#define VMX_EXIT_INVVPID 53
-/** 54 WBINVD. Guest software attempted to execute WBINVD. */
-#define VMX_EXIT_WBINVD 54
-/** 55 XSETBV. Guest software attempted to execute XSETBV. */
-#define VMX_EXIT_XSETBV 55
-/** @} */
-
-
-/** @name VM Instruction Errors
- * @{
- */
-/** 1 VMCALL executed in VMX root operation. */
-#define VMX_ERROR_VMCALL 1
-/** 2 VMCLEAR with invalid physical address. */
-#define VMX_ERROR_VMCLEAR_INVALID_PHYS_ADDR 2
-/** 3 VMCLEAR with VMXON pointer. */
-#define VMX_ERROR_VMCLEAR_INVALID_VMXON_PTR 3
-/** 4 VMLAUNCH with non-clear VMCS. */
-#define VMX_ERROR_VMLAUCH_NON_CLEAR_VMCS 4
-/** 5 VMRESUME with non-launched VMCS. */
-#define VMX_ERROR_VMRESUME_NON_LAUNCHED_VMCS 5
-/** 6 VMRESUME with a corrupted VMCS (indicates corruption of the current VMCS). */
-#define VMX_ERROR_VMRESUME_CORRUPTED_VMCS 6
-/** 7 VM entry with invalid control field(s). */
-#define VMX_ERROR_VMENTRY_INVALID_CONTROL_FIELDS 7
-/** 8 VM entry with invalid host-state field(s). */
-#define VMX_ERROR_VMENTRY_INVALID_HOST_STATE 8
-/** 9 VMPTRLD with invalid physical address. */
-#define VMX_ERROR_VMPTRLD_INVALID_PHYS_ADDR 9
-/** 10 VMPTRLD with VMXON pointer. */
-#define VMX_ERROR_VMPTRLD_VMXON_PTR 10
-/** 11 VMPTRLD with incorrect VMCS revision identifier. */
-#define VMX_ERROR_VMPTRLD_WRONG_VMCS_REVISION 11
-/** 12 VMREAD/VMWRITE from/to unsupported VMCS component. */
-#define VMX_ERROR_VMREAD_INVALID_COMPONENT 12
-#define VMX_ERROR_VMWRITE_INVALID_COMPONENT VMX_ERROR_VMREAD_INVALID_COMPONENT
-/** 13 VMWRITE to read-only VMCS component. */
-#define VMX_ERROR_VMWRITE_READONLY_COMPONENT 13
-/** 15 VMXON executed in VMX root operation. */
-#define VMX_ERROR_VMXON_IN_VMX_ROOT_OP 15
-/** 16 VM entry with invalid executive-VMCS pointer. */
-#define VMX_ERROR_VMENTRY_INVALID_VMCS_EXEC_PTR 16
-/** 17 VM entry with non-launched executive VMCS. */
-#define VMX_ERROR_VMENTRY_NON_LAUNCHED_EXEC_VMCS 17
-/** 18 VM entry with executive-VMCS pointer not VMXON pointer. */
-#define VMX_ERROR_VMENTRY_EXEC_VMCS_PTR 18
-/** 19 VMCALL with non-clear VMCS. */
-#define VMX_ERROR_VMCALL_NON_CLEAR_VMCS 19
-/** 20 VMCALL with invalid VM-exit control fields. */
-#define VMX_ERROR_VMCALL_INVALID_VMEXIT_FIELDS 20
-/** 22 VMCALL with incorrect MSEG revision identifier. */
-#define VMX_ERROR_VMCALL_INVALID_MSEG_REVISION 22
-/** 23 VMXOFF under dual-monitor treatment of SMIs and SMM. */
-#define VMX_ERROR_VMXOFF_DUAL_MONITOR 23
-/** 24 VMCALL with invalid SMM-monitor features. */
-#define VMX_ERROR_VMCALL_INVALID_SMM_MONITOR 24
-/** 25 VM entry with invalid VM-execution control fields in executive VMCS. */
-#define VMX_ERROR_VMENTRY_INVALID_VM_EXEC_CTRL 25
-/** 26 VM entry with events blocked by MOV SS. */
-#define VMX_ERROR_VMENTRY_MOV_SS 26
-/** 26 Invalid operand to INVEPT/INVVPID. */
-#define VMX_ERROR_INVEPTVPID_INVALID_OPERAND 28
-
-/** @} */
-
-
-/** @name VMX MSRs - Basic VMX information.
- * @{
- */
-/** VMCS revision identifier used by the processor. */
-#define MSR_IA32_VMX_BASIC_INFO_VMCS_ID(a) (a & 0x7FFFFFFF)
-/** Size of the VMCS. */
-#define MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(a) (((a) >> 32) & 0xFFF)
-/** Width of physical address used for the VMCS.
- * 0 -> limited to the available amount of physical ram
- * 1 -> within the first 4 GB
- */
-#define MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(a) (((a) >> 48) & 1)
-/** Whether the processor supports the dual-monitor treatment of system-management interrupts and system-management code. (always 1) */
-#define MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(a) (((a) >> 49) & 1)
-/** Memory type that must be used for the VMCS. */
-#define MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(a) (((a) >> 50) & 0xF)
-/** @} */
-
-
-/** @name VMX MSRs - Misc VMX info.
- * @{
- */
-/** Relationship between the preemption timer and tsc; count down every time bit x of the tsc changes. */
-#define MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(a) ((a) & 0x1f)
-/** Activity states supported by the implementation. */
-#define MSR_IA32_VMX_MISC_ACTIVITY_STATES(a) (((a) >> 6) & 0x7)
-/** Number of CR3 target values supported by the processor. (0-256) */
-#define MSR_IA32_VMX_MISC_CR3_TARGET(a) (((a) >> 16) & 0x1FF)
-/** Maximum nr of MSRs in the VMCS. (N+1)*512. */
-#define MSR_IA32_VMX_MISC_MAX_MSR(a) (((((a) >> 25) & 0x7) + 1) * 512)
-/** MSEG revision identifier used by the processor. */
-#define MSR_IA32_VMX_MISC_MSEG_ID(a) ((a) >> 32)
-/** @} */
-
-
-/** @name VMX MSRs - VMCS enumeration field info
- * @{
- */
-/** Highest field index. */
-#define MSR_IA32_VMX_VMCS_ENUM_HIGHEST_INDEX(a) (((a) >> 1) & 0x1FF)
-
-/** @} */
-
-
-/** @name MSR_IA32_VMX_EPT_CAPS; EPT capabilities MSR
- * @{
- */
-#define MSR_IA32_VMX_EPT_CAPS_RWX_X_ONLY RT_BIT_64(0)
-#define MSR_IA32_VMX_EPT_CAPS_RWX_W_ONLY RT_BIT_64(1)
-#define MSR_IA32_VMX_EPT_CAPS_RWX_WX_ONLY RT_BIT_64(2)
-#define MSR_IA32_VMX_EPT_CAPS_GAW_21_BITS RT_BIT_64(3)
-#define MSR_IA32_VMX_EPT_CAPS_GAW_30_BITS RT_BIT_64(4)
-#define MSR_IA32_VMX_EPT_CAPS_GAW_39_BITS RT_BIT_64(5)
-#define MSR_IA32_VMX_EPT_CAPS_GAW_48_BITS RT_BIT_64(6)
-#define MSR_IA32_VMX_EPT_CAPS_GAW_57_BITS RT_BIT_64(7)
-#define MSR_IA32_VMX_EPT_CAPS_EMT_UC RT_BIT_64(8)
-#define MSR_IA32_VMX_EPT_CAPS_EMT_WC RT_BIT_64(9)
-#define MSR_IA32_VMX_EPT_CAPS_EMT_WT RT_BIT_64(12)
-#define MSR_IA32_VMX_EPT_CAPS_EMT_WP RT_BIT_64(13)
-#define MSR_IA32_VMX_EPT_CAPS_EMT_WB RT_BIT_64(14)
-#define MSR_IA32_VMX_EPT_CAPS_SP_21_BITS RT_BIT_64(16)
-#define MSR_IA32_VMX_EPT_CAPS_SP_30_BITS RT_BIT_64(17)
-#define MSR_IA32_VMX_EPT_CAPS_SP_39_BITS RT_BIT_64(18)
-#define MSR_IA32_VMX_EPT_CAPS_SP_48_BITS RT_BIT_64(19)
-#define MSR_IA32_VMX_EPT_CAPS_INVEPT RT_BIT_64(20)
-#define MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_SINGLE_CONTEXT RT_BIT_64(25)
-#define MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL_CONTEXTS RT_BIT_64(26)
-#define MSR_IA32_VMX_EPT_CAPS_INVVPID RT_BIT_64(32)
-#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR RT_BIT_64(40)
-#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT RT_BIT_64(41)
-#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS RT_BIT_64(42)
-#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT_RETAIN_GLOBALS RT_BIT_64(43)
-
-/** @} */
-
-/** @name Extended Page Table Pointer (EPTP)
- * @{
- */
-/** Uncachable EPT paging structure memory type. */
-#define VMX_EPT_MEMTYPE_UC 0
-/** Write-back EPT paging structure memory type. */
-#define VMX_EPT_MEMTYPE_WB 6
-/** Shift value to get the EPT page walk length (bits 5-3) */
-#define VMX_EPT_PAGE_WALK_LENGTH_SHIFT 3
-/** Mask value to get the EPT page walk length (bits 5-3) */
-#define VMX_EPT_PAGE_WALK_LENGTH_MASK 7
-/** Default EPT page walk length */
-#define VMX_EPT_PAGE_WALK_LENGTH_DEFAULT 3
-/** @} */
-
-
-/** @name VMCS field encoding - 16 bits guest fields
- * @{
- */
-#define VMX_VMCS16_GUEST_FIELD_VPID 0x0
-#define VMX_VMCS16_GUEST_FIELD_ES 0x800
-#define VMX_VMCS16_GUEST_FIELD_CS 0x802
-#define VMX_VMCS16_GUEST_FIELD_SS 0x804
-#define VMX_VMCS16_GUEST_FIELD_DS 0x806
-#define VMX_VMCS16_GUEST_FIELD_FS 0x808
-#define VMX_VMCS16_GUEST_FIELD_GS 0x80A
-#define VMX_VMCS16_GUEST_FIELD_LDTR 0x80C
-#define VMX_VMCS16_GUEST_FIELD_TR 0x80E
-/** @} */
-
-/** @name VMCS field encoding - 16 bits host fields
- * @{
- */
-#define VMX_VMCS16_HOST_FIELD_ES 0xC00
-#define VMX_VMCS16_HOST_FIELD_CS 0xC02
-#define VMX_VMCS16_HOST_FIELD_SS 0xC04
-#define VMX_VMCS16_HOST_FIELD_DS 0xC06
-#define VMX_VMCS16_HOST_FIELD_FS 0xC08
-#define VMX_VMCS16_HOST_FIELD_GS 0xC0A
-#define VMX_VMCS16_HOST_FIELD_TR 0xC0C
-/** @} */
-
-/** @name VMCS field encoding - 64 bits host fields
- * @{
- */
-#define VMX_VMCS_HOST_FIELD_PAT_FULL 0x2C00
-#define VMX_VMCS_HOST_FIELD_PAT_HIGH 0x2C01
-#define VMX_VMCS_HOST_FIELD_EFER_FULL 0x2C02
-#define VMX_VMCS_HOST_FIELD_EFER_HIGH 0x2C03
-#define VMX_VMCS_HOST_PERF_GLOBAL_CTRL_FULL 0x2C04 /**< MSR IA32_PERF_GLOBAL_CTRL */
-#define VMX_VMCS_HOST_PERF_GLOBAL_CTRL_HIGH 0x2C05 /**< MSR IA32_PERF_GLOBAL_CTRL */
-/** @} */
-
-
-/** @name VMCS field encoding - 64 Bits control fields
- * @{
- */
-#define VMX_VMCS_CTRL_IO_BITMAP_A_FULL 0x2000
-#define VMX_VMCS_CTRL_IO_BITMAP_A_HIGH 0x2001
-#define VMX_VMCS_CTRL_IO_BITMAP_B_FULL 0x2002
-#define VMX_VMCS_CTRL_IO_BITMAP_B_HIGH 0x2003
-
-/* Optional */
-#define VMX_VMCS_CTRL_MSR_BITMAP_FULL 0x2004
-#define VMX_VMCS_CTRL_MSR_BITMAP_HIGH 0x2005
-
-#define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL 0x2006
-#define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_HIGH 0x2007
-#define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL 0x2008
-#define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_HIGH 0x2009
-
-#define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL 0x200A
-#define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_HIGH 0x200B
-
-#define VMX_VMCS_CTRL_EXEC_VMCS_PTR_FULL 0x200C
-#define VMX_VMCS_CTRL_EXEC_VMCS_PTR_HIGH 0x200D
-
-#define VMX_VMCS_CTRL_TSC_OFFSET_FULL 0x2010
-#define VMX_VMCS_CTRL_TSC_OFFSET_HIGH 0x2011
-
-/** Optional (VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW) */
-#define VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL 0x2012
-#define VMX_VMCS_CTRL_VAPIC_PAGEADDR_HIGH 0x2013
-
-/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) */
-#define VMX_VMCS_CTRL_APIC_ACCESSADDR_FULL 0x2014
-#define VMX_VMCS_CTRL_APIC_ACCESSADDR_HIGH 0x2015
-
-/** Extended page table pointer. */
-#define VMX_VMCS_CTRL_EPTP_FULL 0x201a
-#define VMX_VMCS_CTRL_EPTP_HIGH 0x201b
-
-/** VM-exit phyiscal address. */
-#define VMX_VMCS_EXIT_PHYS_ADDR_FULL 0x2400
-#define VMX_VMCS_EXIT_PHYS_ADDR_HIGH 0x2401
-/** @} */
-
-
-/** @name VMCS field encoding - 64 Bits guest fields
- * @{
- */
-#define VMX_VMCS_GUEST_LINK_PTR_FULL 0x2800
-#define VMX_VMCS_GUEST_LINK_PTR_HIGH 0x2801
-#define VMX_VMCS_GUEST_DEBUGCTL_FULL 0x2802 /**< MSR IA32_DEBUGCTL */
-#define VMX_VMCS_GUEST_DEBUGCTL_HIGH 0x2803 /**< MSR IA32_DEBUGCTL */
-#define VMX_VMCS_GUEST_PAT_FULL 0x2804
-#define VMX_VMCS_GUEST_PAT_HIGH 0x2805
-#define VMX_VMCS_GUEST_EFER_FULL 0x2806
-#define VMX_VMCS_GUEST_EFER_HIGH 0x2807
-#define VMX_VMCS_GUEST_PERF_GLOBAL_CTRL_FULL 0x2808 /**< MSR IA32_PERF_GLOBAL_CTRL */
-#define VMX_VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH 0x2809 /**< MSR IA32_PERF_GLOBAL_CTRL */
-#define VMX_VMCS_GUEST_PDPTR0_FULL 0x280A
-#define VMX_VMCS_GUEST_PDPTR0_HIGH 0x280B
-#define VMX_VMCS_GUEST_PDPTR1_FULL 0x280C
-#define VMX_VMCS_GUEST_PDPTR1_HIGH 0x280D
-#define VMX_VMCS_GUEST_PDPTR2_FULL 0x280E
-#define VMX_VMCS_GUEST_PDPTR2_HIGH 0x280F
-#define VMX_VMCS_GUEST_PDPTR3_FULL 0x2810
-#define VMX_VMCS_GUEST_PDPTR3_HIGH 0x2811
-/** @} */
-
-
-/** @name VMCS field encoding - 32 Bits control fields
- * @{
- */
-#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS 0x4000
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS 0x4002
-#define VMX_VMCS_CTRL_EXCEPTION_BITMAP 0x4004
-#define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MASK 0x4006
-#define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH 0x4008
-#define VMX_VMCS_CTRL_CR3_TARGET_COUNT 0x400A
-#define VMX_VMCS_CTRL_EXIT_CONTROLS 0x400C
-#define VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT 0x400E
-#define VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT 0x4010
-#define VMX_VMCS_CTRL_ENTRY_CONTROLS 0x4012
-#define VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT 0x4014
-#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO 0x4016
-#define VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE 0x4018
-#define VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH 0x401A
-/** This field exists only on processors that support the 1-setting of the “use TPR shadow” VM-execution control. */
-#define VMX_VMCS_CTRL_TPR_THRESHOLD 0x401C
-/** This field exists only on processors that support the 1-setting of the “activate secondary controls” VM-execution control. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2 0x401E
-/** @} */
-
-
-/** @name VMX_VMCS_CTRL_PIN_EXEC_CONTROLS
- * @{
- */
-/** External interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */
-#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT RT_BIT(0)
-/** Non-maskable interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */
-#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT RT_BIT(3)
-/** Virtual NMIs. */
-#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI RT_BIT(5)
-/** Activate VMX preemption timer. */
-#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER RT_BIT(6)
-/* All other bits are reserved and must be set according to MSR IA32_VMX_PROCBASED_CTLS. */
-/** @} */
-
-/** @name VMX_VMCS_CTRL_PROC_EXEC_CONTROLS
- * @{
- */
-/** VM Exit as soon as RFLAGS.IF=1 and no blocking is active. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT RT_BIT(2)
-/** Use timestamp counter offset. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET RT_BIT(3)
-/** VM Exit when executing the HLT instruction. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT RT_BIT(7)
-/** VM Exit when executing the INVLPG instruction. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT RT_BIT(9)
-/** VM Exit when executing the MWAIT instruction. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT RT_BIT(10)
-/** VM Exit when executing the RDPMC instruction. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT RT_BIT(11)
-/** VM Exit when executing the RDTSC/RDTSCP instruction. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT RT_BIT(12)
-/** VM Exit when executing the MOV to CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT RT_BIT(15)
-/** VM Exit when executing the MOV from CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT RT_BIT(16)
-/** VM Exit on CR8 loads. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT RT_BIT(19)
-/** VM Exit on CR8 stores. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT RT_BIT(20)
-/** Use TPR shadow. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW RT_BIT(21)
-/** VM Exit when virtual nmi blocking is disabled. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT RT_BIT(22)
-/** VM Exit when executing a MOV DRx instruction. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT RT_BIT(23)
-/** VM Exit when executing IO instructions. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT RT_BIT(24)
-/** Use IO bitmaps. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS RT_BIT(25)
-/** Monitor trap flag. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG RT_BIT(27)
-/** Use MSR bitmaps. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS RT_BIT(28)
-/** VM Exit when executing the MONITOR instruction. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT RT_BIT(29)
-/** VM Exit when executing the PAUSE instruction. */
-#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT RT_BIT(30)
-/** Determines whether the secondary processor based VM-execution controls are used. */
-#define VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL RT_BIT(31)
-/** @} */
-
-/** @name VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2
- * @{
- */
-/** Virtualize APIC access. */
-#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC RT_BIT(0)
-/** EPT supported/enabled. */
-#define VMX_VMCS_CTRL_PROC_EXEC2_EPT RT_BIT(1)
-/** Descriptor table instructions cause VM-exits. */
-#define VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT RT_BIT(2)
-/** RDTSCP supported/enabled. */
-#define VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP RT_BIT(3)
-/** Virtualize x2APIC mode. */
-#define VMX_VMCS_CTRL_PROC_EXEC2_X2APIC RT_BIT(4)
-/** VPID supported/enabled. */
-#define VMX_VMCS_CTRL_PROC_EXEC2_VPID RT_BIT(5)
-/** VM Exit when executing the WBINVD instruction. */
-#define VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT RT_BIT(6)
-/** Unrestricted guest execution. */
-#define VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE RT_BIT(7)
-/** A specified nr of pause loops cause a VM-exit. */
-#define VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT RT_BIT(10)
-/** @} */
-
-
-/** @name VMX_VMCS_CTRL_ENTRY_CONTROLS
- * @{
- */
-/** Load guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
-#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG RT_BIT(2)
-/** 64 bits guest mode. Must be 0 for CPUs that don't support AMD64. */
-#define VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE RT_BIT(9)
-/** In SMM mode after VM-entry. */
-#define VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM RT_BIT(10)
-/** Disable dual treatment of SMI and SMM; must be zero for VM-entry outside of SMM. */
-#define VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON RT_BIT(11)
-/** This control determines whether the guest IA32_PERF_GLOBAL_CTRL MSR is loaded on VM entry. */
-#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR RT_BIT(13)
-/** This control determines whether the guest IA32_PAT MSR is loaded on VM entry. */
-#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR RT_BIT(14)
-/** This control determines whether the guest IA32_EFER MSR is loaded on VM entry. */
-#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR RT_BIT(15)
-/** @} */
-
-
-/** @name VMX_VMCS_CTRL_EXIT_CONTROLS
- * @{
- */
-/** Save guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
-#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG RT_BIT(2)
-/** Return to long mode after a VM-exit. */
-#define VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64 RT_BIT(9)
-/** This control determines whether the IA32_PERF_GLOBAL_CTRL MSR is loaded on VM exit. */
-#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_PERF_MSR RT_BIT(12)
-/** Acknowledge external interrupts with the irq controller if one caused a VM-exit. */
-#define VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ RT_BIT(15)
-/** This control determines whether the guest IA32_PAT MSR is saved on VM exit. */
-#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR RT_BIT(18)
-/** This control determines whether the host IA32_PAT MSR is loaded on VM exit. */
-#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR RT_BIT(19)
-/** This control determines whether the guest IA32_EFER MSR is saved on VM exit. */
-#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR RT_BIT(20)
-/** This control determines whether the host IA32_EFER MSR is loaded on VM exit. */
-#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR RT_BIT(21)
-/** This control determines whether the value of the VMX preemption timer is saved on VM exit. */
-#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER RT_BIT(22)
-/** @} */
-
-/** @name VMCS field encoding - 32 Bits read-only fields
- * @{
- */
-#define VMX_VMCS32_RO_VM_INSTR_ERROR 0x4400
-#define VMX_VMCS32_RO_EXIT_REASON 0x4402
-#define VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO 0x4404
-#define VMX_VMCS32_RO_EXIT_INTERRUPTION_ERRCODE 0x4406
-#define VMX_VMCS32_RO_IDT_INFO 0x4408
-#define VMX_VMCS32_RO_IDT_ERRCODE 0x440A
-#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH 0x440C
-#define VMX_VMCS32_RO_EXIT_INSTR_INFO 0x440E
-/** @} */
-
-/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO
- * @{
- */
-#define VMX_EXIT_INTERRUPTION_INFO_VECTOR(a) (a & 0xff)
-#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT 8
-#define VMX_EXIT_INTERRUPTION_INFO_TYPE(a) ((a >> VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT) & 7)
-#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID RT_BIT(11)
-#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(a) (a & VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID)
-#define VMX_EXIT_INTERRUPTION_INFO_NMI_UNBLOCK(a) (a & RT_BIT(12))
-#define VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT 31
-#define VMX_EXIT_INTERRUPTION_INFO_VALID(a) (a & RT_BIT(31))
-/** Construct an irq event injection value from the exit interruption info value (same except that bit 12 is reserved). */
-#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(a) (a & ~RT_BIT(12))
-/** @} */
-
-/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO_TYPE
- * @{
- */
-#define VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT 0
-#define VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI 2
-#define VMX_EXIT_INTERRUPTION_INFO_TYPE_HWEXCPT 3
-#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW 4 /**< int xx */
-#define VMX_EXIT_INTERRUPTION_INFO_TYPE_DBEXCPT 5 /**< Why are we getting this one?? */
-#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT 6
-/** @} */
-
-
-/** @name VMCS field encoding - 32 Bits guest state fields
- * @{
- */
-#define VMX_VMCS32_GUEST_ES_LIMIT 0x4800
-#define VMX_VMCS32_GUEST_CS_LIMIT 0x4802
-#define VMX_VMCS32_GUEST_SS_LIMIT 0x4804
-#define VMX_VMCS32_GUEST_DS_LIMIT 0x4806
-#define VMX_VMCS32_GUEST_FS_LIMIT 0x4808
-#define VMX_VMCS32_GUEST_GS_LIMIT 0x480A
-#define VMX_VMCS32_GUEST_LDTR_LIMIT 0x480C
-#define VMX_VMCS32_GUEST_TR_LIMIT 0x480E
-#define VMX_VMCS32_GUEST_GDTR_LIMIT 0x4810
-#define VMX_VMCS32_GUEST_IDTR_LIMIT 0x4812
-#define VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS 0x4814
-#define VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS 0x4816
-#define VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS 0x4818
-#define VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS 0x481A
-#define VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS 0x481C
-#define VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS 0x481E
-#define VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS 0x4820
-#define VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS 0x4822
-#define VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE 0x4824
-#define VMX_VMCS32_GUEST_ACTIVITY_STATE 0x4826
-#define VMX_VMCS32_GUEST_SYSENTER_CS 0x482A /**< MSR IA32_SYSENTER_CS */
-#define VMX_VMCS32_GUEST_PREEMPTION_TIMER_VALUE 0x482E
-/** @} */
-
-
-/** @name VMX_VMCS_GUEST_ACTIVITY_STATE
- * @{
- */
-/** The logical processor is active. */
-#define VMX_CMS_GUEST_ACTIVITY_ACTIVE 0x0
-/** The logical processor is inactive, because executed a HLT instruction. */
-#define VMX_CMS_GUEST_ACTIVITY_HLT 0x1
-/** The logical processor is inactive, because of a triple fault or other serious error. */
-#define VMX_CMS_GUEST_ACTIVITY_SHUTDOWN 0x2
-/** The logical processor is inactive, because it's waiting for a startup-IPI */
-#define VMX_CMS_GUEST_ACTIVITY_SIPI_WAIT 0x3
-/** @} */
-
-
-/** @name VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE
- * @{
- */
-#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI RT_BIT(0)
-#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS RT_BIT(1)
-#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_SMI RT_BIT(2)
-#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_NMI RT_BIT(3)
-/** @} */
-
-
-/** @name VMCS field encoding - 32 Bits host state fields
- * @{
- */
-#define VMX_VMCS32_HOST_SYSENTER_CS 0x4C00
-/** @} */
-
-/** @name Natural width control fields
- * @{
- */
-#define VMX_VMCS_CTRL_CR0_MASK 0x6000
-#define VMX_VMCS_CTRL_CR4_MASK 0x6002
-#define VMX_VMCS_CTRL_CR0_READ_SHADOW 0x6004
-#define VMX_VMCS_CTRL_CR4_READ_SHADOW 0x6006
-#define VMX_VMCS_CTRL_CR3_TARGET_VAL0 0x6008
-#define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0x600A
-#define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0x600C
-#define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0x600E
-/** @} */
-
-
-/** @name Natural width read-only data fields
- * @{
- */
-#define VMX_VMCS_RO_EXIT_QUALIFICATION 0x6400
-#define VMX_VMCS_RO_IO_RCX 0x6402
-#define VMX_VMCS_RO_IO_RSX 0x6404
-#define VMX_VMCS_RO_IO_RDI 0x6406
-#define VMX_VMCS_RO_IO_RIP 0x6408
-#define VMX_VMCS_EXIT_GUEST_LINEAR_ADDR 0x640A
-/** @} */
-
-
-/** @name VMX_VMCS_RO_EXIT_QUALIFICATION
- * @{
- */
-/** 0-2: Debug register number */
-#define VMX_EXIT_QUALIFICATION_DRX_REGISTER(a) (a & 7)
-/** 3: Reserved; cleared to 0. */
-#define VMX_EXIT_QUALIFICATION_DRX_RES1(a) ((a >> 3) & 1)
-/** 4: Direction of move (0 = write, 1 = read) */
-#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION(a) ((a >> 4) & 1)
-/** 5-7: Reserved; cleared to 0. */
-#define VMX_EXIT_QUALIFICATION_DRX_RES2(a) ((a >> 5) & 7)
-/** 8-11: General purpose register number. */
-#define VMX_EXIT_QUALIFICATION_DRX_GENREG(a) ((a >> 8) & 0xF)
-/** Rest: reserved. */
-/** @} */
-
-/** @name VMX_EXIT_QUALIFICATION_DRX_DIRECTION values
- * @{
- */
-#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE 0
-#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_READ 1
-/** @} */
-
-
-
-/** @name CRx accesses
- * @{
- */
-/** 0-3: Control register number (0 for CLTS & LMSW) */
-#define VMX_EXIT_QUALIFICATION_CRX_REGISTER(a) (a & 0xF)
-/** 4-5: Access type. */
-#define VMX_EXIT_QUALIFICATION_CRX_ACCESS(a) ((a >> 4) & 3)
-/** 6: LMSW operand type */
-#define VMX_EXIT_QUALIFICATION_CRX_LMSW_OP(a) ((a >> 6) & 1)
-/** 7: Reserved; cleared to 0. */
-#define VMX_EXIT_QUALIFICATION_CRX_RES1(a) ((a >> 7) & 1)
-/** 8-11: General purpose register number (0 for CLTS & LMSW). */
-#define VMX_EXIT_QUALIFICATION_CRX_GENREG(a) ((a >> 8) & 0xF)
-/** 12-15: Reserved; cleared to 0. */
-#define VMX_EXIT_QUALIFICATION_CRX_RES2(a) ((a >> 12) & 0xF)
-/** 16-31: LMSW source data (else 0). */
-#define VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(a) ((a >> 16) & 0xFFFF)
-/** Rest: reserved. */
-/** @} */
-
-/** @name VMX_EXIT_QUALIFICATION_CRX_ACCESS
- * @{
- */
-#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE 0
-#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ 1
-#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS 2
-#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW 3
-/** @} */
-
-/** @name VMX_EXIT_QUALIFICATION_TASK_SWITCH
- * @{
- */
-#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_SELECTOR(a) (a & 0xffff)
-#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE(a) ((a >> 30)& 0x3)
-/** Task switch caused by a call instruction. */
-#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_CALL 0
-/** Task switch caused by an iret instruction. */
-#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IRET 1
-/** Task switch caused by a jmp instruction. */
-#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_JMP 2
-/** Task switch caused by an interrupt gate. */
-#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IDT 3
-
-/** @} */
-
-
-/** @name VMX_EXIT_EPT_VIOLATION
- * @{
- */
-/** Set if the violation was caused by a data read. */
-#define VMX_EXIT_QUALIFICATION_EPT_DATA_READ RT_BIT(0)
-/** Set if the violation was caused by a data write. */
-#define VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE RT_BIT(1)
-/** Set if the violation was caused by an insruction fetch. */
-#define VMX_EXIT_QUALIFICATION_EPT_INSTR_FETCH RT_BIT(2)
-/** AND of the present bit of all EPT structures. */
-#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT RT_BIT(3)
-/** AND of the write bit of all EPT structures. */
-#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_WRITE RT_BIT(4)
-/** AND of the execute bit of all EPT structures. */
-#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_EXECUTE RT_BIT(5)
-/** Set if the guest linear address field contains the faulting address. */
-#define VMX_EXIT_QUALIFICATION_EPT_GUEST_ADDR_VALID RT_BIT(7)
-/** If bit 7 is one: (reserved otherwise)
- * 1 - violation due to physical address access.
- * 0 - violation caused by page walk or access/dirty bit updates
- */
-#define VMX_EXIT_QUALIFICATION_EPT_TRANSLATED_ACCESS RT_BIT(8)
-/** @} */
-
-
-/** @name VMX_EXIT_PORT_IO
- * @{
- */
-/** 0-2: IO operation width. */
-#define VMX_EXIT_QUALIFICATION_IO_WIDTH(a) (a & 7)
-/** 3: IO operation direction. */
-#define VMX_EXIT_QUALIFICATION_IO_DIRECTION(a) ((a >> 3) & 1)
-/** 4: String IO operation. */
-#define VMX_EXIT_QUALIFICATION_IO_STRING(a) ((a >> 4) & 1)
-/** 5: Repeated IO operation. */
-#define VMX_EXIT_QUALIFICATION_IO_REP(a) ((a >> 5) & 1)
-/** 6: Operand encoding. */
-#define VMX_EXIT_QUALIFICATION_IO_ENCODING(a) ((a >> 6) & 1)
-/** 16-31: IO Port (0-0xffff). */
-#define VMX_EXIT_QUALIFICATION_IO_PORT(a) ((a >> 16) & 0xffff)
-/* Rest reserved. */
-/** @} */
-
-/** @name VMX_EXIT_QUALIFICATION_IO_DIRECTION
- * @{
- */
-#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT 0
-#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_IN 1
-/** @} */
-
-
-/** @name VMX_EXIT_QUALIFICATION_IO_ENCODING
- * @{
- */
-#define VMX_EXIT_QUALIFICATION_IO_ENCODING_DX 0
-#define VMX_EXIT_QUALIFICATION_IO_ENCODING_IMM 1
-/** @} */
-
-/** @name VMX_EXIT_APIC_ACCESS
- * @{
- */
-/** 0-11: If the APIC-access VM exit is due to a linear access, the offset of access within the APIC page. */
-#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(a) (a & 0xfff)
-/** 12-15: Access type. */
-#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(a) ((a >> 12) & 0xf)
-/* Rest reserved. */
-/** @} */
-
-
-/** @name VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE; access types
- * @{
- */
-/** Linear read access. */
-#define VMX_APIC_ACCESS_TYPE_LINEAR_READ 0
-/** Linear write access. */
-#define VMX_APIC_ACCESS_TYPE_LINEAR_WRITE 1
-/** Linear instruction fetch access. */
-#define VMX_APIC_ACCESS_TYPE_LINEAR_INSTR_FETCH 2
-/** Linear read/write access during event delivery. */
-#define VMX_APIC_ACCESS_TYPE_LINEAR_EVENT_DELIVERY 3
-/** Physical read/write access during event delivery. */
-#define VMX_APIC_ACCESS_TYPE_PHYSICAL_EVENT_DELIVERY 10
-/** Physical access for an instruction fetch or during instruction execution. */
-#define VMX_APIC_ACCESS_TYPE_PHYSICAL_INSTR 15
-/** @} */
-
-/** @} */
-
-/** @name VMCS field encoding - Natural width guest state fields
- * @{
- */
-#define VMX_VMCS64_GUEST_CR0 0x6800
-#define VMX_VMCS64_GUEST_CR3 0x6802
-#define VMX_VMCS64_GUEST_CR4 0x6804
-#define VMX_VMCS64_GUEST_ES_BASE 0x6806
-#define VMX_VMCS64_GUEST_CS_BASE 0x6808
-#define VMX_VMCS64_GUEST_SS_BASE 0x680A
-#define VMX_VMCS64_GUEST_DS_BASE 0x680C
-#define VMX_VMCS64_GUEST_FS_BASE 0x680E
-#define VMX_VMCS64_GUEST_GS_BASE 0x6810
-#define VMX_VMCS64_GUEST_LDTR_BASE 0x6812
-#define VMX_VMCS64_GUEST_TR_BASE 0x6814
-#define VMX_VMCS64_GUEST_GDTR_BASE 0x6816
-#define VMX_VMCS64_GUEST_IDTR_BASE 0x6818
-#define VMX_VMCS64_GUEST_DR7 0x681A
-#define VMX_VMCS64_GUEST_RSP 0x681C
-#define VMX_VMCS64_GUEST_RIP 0x681E
-#define VMX_VMCS_GUEST_RFLAGS 0x6820
-#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS 0x6822
-#define VMX_VMCS64_GUEST_SYSENTER_ESP 0x6824 /**< MSR IA32_SYSENTER_ESP */
-#define VMX_VMCS64_GUEST_SYSENTER_EIP 0x6826 /**< MSR IA32_SYSENTER_EIP */
-/** @} */
-
-
-/** @name VMX_VMCS_GUEST_DEBUG_EXCEPTIONS
- * @{
- */
-/** Hardware breakpoint 0 was met. */
-#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B0 RT_BIT(0)
-/** Hardware breakpoint 1 was met. */
-#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B1 RT_BIT(1)
-/** Hardware breakpoint 2 was met. */
-#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B2 RT_BIT(2)
-/** Hardware breakpoint 3 was met. */
-#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B3 RT_BIT(3)
-/** At least one data or IO breakpoint was hit. */
-#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BREAKPOINT_ENABLED RT_BIT(12)
-/** A debug exception would have been triggered by single-step execution mode. */
-#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS RT_BIT(14)
-/** Bits 4-11, 13 and 15-63 are reserved. */
-
-/** @} */
-
-/** @name VMCS field encoding - Natural width host state fields
- * @{
- */
-#define VMX_VMCS_HOST_CR0 0x6C00
-#define VMX_VMCS_HOST_CR3 0x6C02
-#define VMX_VMCS_HOST_CR4 0x6C04
-#define VMX_VMCS_HOST_FS_BASE 0x6C06
-#define VMX_VMCS_HOST_GS_BASE 0x6C08
-#define VMX_VMCS_HOST_TR_BASE 0x6C0A
-#define VMX_VMCS_HOST_GDTR_BASE 0x6C0C
-#define VMX_VMCS_HOST_IDTR_BASE 0x6C0E
-#define VMX_VMCS_HOST_SYSENTER_ESP 0x6C10
-#define VMX_VMCS_HOST_SYSENTER_EIP 0x6C12
-#define VMX_VMCS_HOST_RSP 0x6C14
-#define VMX_VMCS_HOST_RIP 0x6C16
-/** @} */
-
-/** @} */
-
-
-#if RT_INLINE_ASM_GNU_STYLE
-# define __STR(x) #x
-# define STR(x) __STR(x)
-#endif
-
-
-/** @defgroup grp_vmx_asm vmx assembly helpers
- * @ingroup grp_vmx
- * @{
- */
-
-/**
- * Executes VMXON
- *
- * @returns VBox status code
- * @param pVMXOn Physical address of VMXON structure
- */
-#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
-DECLASM(int) VMXEnable(RTHCPHYS pVMXOn);
-#else
-DECLINLINE(int) VMXEnable(RTHCPHYS pVMXOn)
-{
- int rc = VINF_SUCCESS;
-# if RT_INLINE_ASM_GNU_STYLE
- __asm__ __volatile__ (
- "push %3 \n\t"
- "push %2 \n\t"
- ".byte 0xF3, 0x0F, 0xC7, 0x34, 0x24 # VMXON [esp] \n\t"
- "ja 2f \n\t"
- "je 1f \n\t"
- "movl $"STR(VERR_VMX_INVALID_VMXON_PTR)", %0 \n\t"
- "jmp 2f \n\t"
- "1: \n\t"
- "movl $"STR(VERR_VMX_GENERIC)", %0 \n\t"
- "2: \n\t"
- "add $8, %%esp \n\t"
- :"=rm"(rc)
- :"0"(VINF_SUCCESS),
- "ir"((uint32_t)pVMXOn), /* don't allow direct memory reference here, */
- "ir"((uint32_t)(pVMXOn >> 32)) /* this would not work with -fomit-frame-pointer */
- :"memory"
- );
-# else
- __asm
- {
- push dword ptr [pVMXOn+4]
- push dword ptr [pVMXOn]
- _emit 0xF3
- _emit 0x0F
- _emit 0xC7
- _emit 0x34
- _emit 0x24 /* VMXON [esp] */
- jnc vmxon_good
- mov dword ptr [rc], VERR_VMX_INVALID_VMXON_PTR
- jmp the_end
-
-vmxon_good:
- jnz the_end
- mov dword ptr [rc], VERR_VMX_GENERIC
-the_end:
- add esp, 8
- }
-# endif
- return rc;
-}
-#endif
-
-
-/**
- * Executes VMXOFF
- */
-#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
-DECLASM(void) VMXDisable(void);
-#else
-DECLINLINE(void) VMXDisable(void)
-{
-# if RT_INLINE_ASM_GNU_STYLE
- __asm__ __volatile__ (
- ".byte 0x0F, 0x01, 0xC4 # VMXOFF \n\t"
- );
-# else
- __asm
- {
- _emit 0x0F
- _emit 0x01
- _emit 0xC4 /* VMXOFF */
- }
-# endif
-}
-#endif
-
-
-/**
- * Executes VMCLEAR
- *
- * @returns VBox status code
- * @param pVMCS Physical address of VM control structure
- */
-#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
-DECLASM(int) VMXClearVMCS(RTHCPHYS pVMCS);
-#else
-DECLINLINE(int) VMXClearVMCS(RTHCPHYS pVMCS)
-{
- int rc = VINF_SUCCESS;
-# if RT_INLINE_ASM_GNU_STYLE
- __asm__ __volatile__ (
- "push %3 \n\t"
- "push %2 \n\t"
- ".byte 0x66, 0x0F, 0xC7, 0x34, 0x24 # VMCLEAR [esp] \n\t"
- "jnc 1f \n\t"
- "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
- "1: \n\t"
- "add $8, %%esp \n\t"
- :"=rm"(rc)
- :"0"(VINF_SUCCESS),
- "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */
- "ir"((uint32_t)(pVMCS >> 32)) /* this would not work with -fomit-frame-pointer */
- :"memory"
- );
-# else
- __asm
- {
- push dword ptr [pVMCS+4]
- push dword ptr [pVMCS]
- _emit 0x66
- _emit 0x0F
- _emit 0xC7
- _emit 0x34
- _emit 0x24 /* VMCLEAR [esp] */
- jnc success
- mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
-success:
- add esp, 8
- }
-# endif
- return rc;
-}
-#endif
-
-
-/**
- * Executes VMPTRLD
- *
- * @returns VBox status code
- * @param pVMCS Physical address of VMCS structure
- */
-#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
-DECLASM(int) VMXActivateVMCS(RTHCPHYS pVMCS);
-#else
-DECLINLINE(int) VMXActivateVMCS(RTHCPHYS pVMCS)
-{
- int rc = VINF_SUCCESS;
-# if RT_INLINE_ASM_GNU_STYLE
- __asm__ __volatile__ (
- "push %3 \n\t"
- "push %2 \n\t"
- ".byte 0x0F, 0xC7, 0x34, 0x24 # VMPTRLD [esp] \n\t"
- "jnc 1f \n\t"
- "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
- "1: \n\t"
- "add $8, %%esp \n\t"
- :"=rm"(rc)
- :"0"(VINF_SUCCESS),
- "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */
- "ir"((uint32_t)(pVMCS >> 32)) /* this will not work with -fomit-frame-pointer */
- );
-# else
- __asm
- {
- push dword ptr [pVMCS+4]
- push dword ptr [pVMCS]
- _emit 0x0F
- _emit 0xC7
- _emit 0x34
- _emit 0x24 /* VMPTRLD [esp] */
- jnc success
- mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
-
-success:
- add esp, 8
- }
-# endif
- return rc;
-}
-#endif
-
-/**
- * Executes VMPTRST
- *
- * @returns VBox status code
- * @param pVMCS Address that will receive the current pointer
- */
-DECLASM(int) VMXGetActivateVMCS(RTHCPHYS *pVMCS);
-
-/**
- * Executes VMWRITE
- *
- * @returns VBox status code
- * @param idxField VMCS index
- * @param u32Val 32 bits value
- */
-#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
-DECLASM(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Val);
-#else
-DECLINLINE(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Val)
-{
- int rc = VINF_SUCCESS;
-# if RT_INLINE_ASM_GNU_STYLE
- __asm__ __volatile__ (
- ".byte 0x0F, 0x79, 0xC2 # VMWRITE eax, edx \n\t"
- "ja 2f \n\t"
- "je 1f \n\t"
- "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
- "jmp 2f \n\t"
- "1: \n\t"
- "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t"
- "2: \n\t"
- :"=rm"(rc)
- :"0"(VINF_SUCCESS),
- "a"(idxField),
- "d"(u32Val)
- );
-# else
- __asm
- {
- push dword ptr [u32Val]
- mov eax, [idxField]
- _emit 0x0F
- _emit 0x79
- _emit 0x04
- _emit 0x24 /* VMWRITE eax, [esp] */
- jnc valid_vmcs
- mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
- jmp the_end
-
-valid_vmcs:
- jnz the_end
- mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD
-the_end:
- add esp, 4
- }
-# endif
- return rc;
-}
-#endif
-
-/**
- * Executes VMWRITE
- *
- * @returns VBox status code
- * @param idxField VMCS index
- * @param u64Val 16, 32 or 64 bits value
- */
-#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
-DECLASM(int) VMXWriteVMCS64(uint32_t idxField, uint64_t u64Val);
-#else
-VMMR0DECL(int) VMXWriteVMCS64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val);
-
-#define VMXWriteVMCS64(idxField, u64Val) VMXWriteVMCS64Ex(pVCpu, idxField, u64Val)
-#endif
-
-#if HC_ARCH_BITS == 64
-#define VMXWriteVMCS VMXWriteVMCS64
-#else
-#define VMXWriteVMCS VMXWriteVMCS32
-#endif /* HC_ARCH_BITS == 64 */
-
-
-/**
- * Invalidate a page using invept
- * @returns VBox status code
- * @param enmFlush Type of flush
- * @param pDescriptor Descriptor
- */
-DECLASM(int) VMXR0InvEPT(VMX_FLUSH_EPT enmFlush, uint64_t *pDescriptor);
-
-/**
- * Invalidate a page using invvpid
- * @returns VBox status code
- * @param enmFlush Type of flush
- * @param pDescriptor Descriptor
- */
-DECLASM(int) VMXR0InvVPID(VMX_FLUSH_VPID enmFlush, uint64_t *pDescriptor);
-
-/**
- * Executes VMREAD
- *
- * @returns VBox status code
- * @param idxField VMCS index
- * @param pData Ptr to store VM field value
- */
-#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
-DECLASM(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pData);
-#else
-DECLINLINE(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pData)
-{
- int rc = VINF_SUCCESS;
-# if RT_INLINE_ASM_GNU_STYLE
- __asm__ __volatile__ (
- "movl $"STR(VINF_SUCCESS)", %0 \n\t"
- ".byte 0x0F, 0x78, 0xc2 # VMREAD eax, edx \n\t"
- "ja 2f \n\t"
- "je 1f \n\t"
- "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
- "jmp 2f \n\t"
- "1: \n\t"
- "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t"
- "2: \n\t"
- :"=&r"(rc),
- "=d"(*pData)
- :"a"(idxField),
- "d"(0)
- );
-# else
- __asm
- {
- sub esp, 4
- mov dword ptr [esp], 0
- mov eax, [idxField]
- _emit 0x0F
- _emit 0x78
- _emit 0x04
- _emit 0x24 /* VMREAD eax, [esp] */
- mov edx, pData
- pop dword ptr [edx]
- jnc valid_vmcs
- mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
- jmp the_end
-
-valid_vmcs:
- jnz the_end
- mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD
-the_end:
- }
-# endif
- return rc;
-}
-#endif
-
-/**
- * Executes VMREAD
- *
- * @returns VBox status code
- * @param idxField VMCS index
- * @param pData Ptr to store VM field value
- */
-#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
-DECLASM(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData);
-#else
-DECLINLINE(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData)
-{
- int rc;
-
- uint32_t val_hi, val;
- rc = VMXReadVMCS32(idxField, &val);
- rc |= VMXReadVMCS32(idxField + 1, &val_hi);
- AssertRC(rc);
- *pData = RT_MAKE_U64(val, val_hi);
- return rc;
-}
-#endif
-
-#if HC_ARCH_BITS == 64
-# define VMXReadVMCS VMXReadVMCS64
-#else
-# define VMXReadVMCS VMXReadVMCS32
-#endif /* HC_ARCH_BITS == 64 */
-
-/**
- * Gets the last instruction error value from the current VMCS
- *
- * @returns error value
- */
-DECLINLINE(uint32_t) VMXGetLastError(void)
-{
-#if HC_ARCH_BITS == 64
- uint64_t uLastError = 0;
- int rc = VMXReadVMCS(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
- AssertRC(rc);
- return (uint32_t)uLastError;
-
-#else /* 32-bit host: */
- uint32_t uLastError = 0;
- int rc = VMXReadVMCS32(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
- AssertRC(rc);
- return uLastError;
-#endif
-}
-
-#ifdef IN_RING0
-VMMR0DECL(int) VMXR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt);
-VMMR0DECL(int) VMXR0InvalidatePhysPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys);
-#endif /* IN_RING0 */
-
-/** @} */
-
-#endif
-
diff --git a/include/VBox/vmm/hwaccm.h b/include/VBox/vmm/hwaccm.h
deleted file mode 100644
index 98a7d02e..00000000
--- a/include/VBox/vmm/hwaccm.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/** @file
- * HWACCM - Intel/AMD VM Hardware Support Manager (VMM)
- */
-
-/*
- * Copyright (C) 2006-2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- */
-
-#ifndef ___VBox_vmm_hwaccm_h
-#define ___VBox_vmm_hwaccm_h
-
-#include <VBox/vmm/pgm.h>
-#include <VBox/vmm/cpum.h>
-#include <iprt/mp.h>
-
-
-/** @defgroup grp_hwaccm The VM Hardware Manager API
- * @{
- */
-
-RT_C_DECLS_BEGIN
-
-/**
- * Query HWACCM state (enabled/disabled)
- *
- * @returns 0 - disabled, 1 - enabled
- * @param pVM The VM to operate on.
- */
-#define HWACCMIsEnabled(pVM) ((pVM)->fHWACCMEnabled)
-
- /**
- * Check if the current CPU state is valid for emulating IO blocks in the recompiler
- *
- * @returns boolean
- * @param pCtx CPU context
- */
-#define HWACCMCanEmulateIoBlock(pVCpu) (!CPUMIsGuestInPagedProtectedMode(pVCpu))
-#define HWACCMCanEmulateIoBlockEx(pCtx) (!CPUMIsGuestInPagedProtectedModeEx(pCtx))
-
-VMMDECL(int) HWACCMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCVirt);
-VMMDECL(bool) HWACCMHasPendingIrq(PVM pVM);
-
-#ifndef IN_RC
-VMMDECL(int) HWACCMFlushTLB(PVMCPU pVCpu);
-VMMDECL(int) HWACCMFlushTLBOnAllVCpus(PVM pVM);
-VMMDECL(int) HWACCMInvalidatePageOnAllVCpus(PVM pVM, RTGCPTR GCVirt);
-VMMDECL(int) HWACCMInvalidatePhysPage(PVM pVM, RTGCPHYS GCPhys);
-VMMDECL(bool) HWACCMIsNestedPagingActive(PVM pVM);
-VMMDECL(PGMMODE) HWACCMGetShwPagingMode(PVM pVM);
-#else
-/* Nop in GC */
-# define HWACCMFlushTLB(pVCpu) do { } while (0)
-# define HWACCMIsNestedPagingActive(pVM) false
-# define HWACCMFlushTLBOnAllVCpus(pVM) do { } while (0)
-#endif
-
-#ifdef IN_RING0
-/** @defgroup grp_hwaccm_r0 The VM Hardware Manager API
- * @ingroup grp_hwaccm
- * @{
- */
-VMMR0DECL(int) HWACCMR0Init(void);
-VMMR0DECL(int) HWACCMR0Term(void);
-VMMR0DECL(int) HWACCMR0InitVM(PVM pVM);
-VMMR0DECL(int) HWACCMR0TermVM(PVM pVM);
-VMMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM);
-VMMR0DECL(int) HWACCMR0EnterSwitcher(PVM pVM, bool *pfVTxDisabled);
-VMMR0DECL(int) HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled);
-
-VMMR0DECL(void) HWACCMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize);
-VMMR0DECL(void) HWACCMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize);
-
-/** @} */
-#endif /* IN_RING0 */
-
-
-#ifdef IN_RING3
-/** @defgroup grp_hwaccm_r3 The VM Hardware Manager API
- * @ingroup grp_hwaccm
- * @{
- */
-VMMR3DECL(bool) HWACCMR3IsEventPending(PVMCPU pVCpu);
-VMMR3DECL(int) HWACCMR3Init(PVM pVM);
-VMMR3_INT_DECL(int) HWACCMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
-VMMR3DECL(void) HWACCMR3Relocate(PVM pVM);
-VMMR3DECL(int) HWACCMR3Term(PVM pVM);
-VMMR3DECL(void) HWACCMR3Reset(PVM pVM);
-VMMR3DECL(void) HWACCMR3ResetCpu(PVMCPU pVCpu);
-VMMR3DECL(void) HWACCMR3CheckError(PVM pVM, int iStatusCode);
-VMMR3DECL(bool) HWACCMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx);
-VMMR3DECL(void) HWACCMR3NotifyScheduled(PVMCPU pVCpu);
-VMMR3DECL(void) HWACCMR3NotifyEmulated(PVMCPU pVCpu);
-VMMR3DECL(bool) HWACCMR3IsActive(PVMCPU pVCpu);
-VMMR3DECL(bool) HWACCMR3IsNestedPagingActive(PVM pVM);
-VMMR3DECL(bool) HWACCMR3IsAllowed(PVM pVM);
-VMMR3DECL(void) HWACCMR3PagingModeChanged(PVM pVM, PVMCPU pVCpu, PGMMODE enmShadowMode, PGMMODE enmGuestMode);
-VMMR3DECL(bool) HWACCMR3IsVPIDActive(PVM pVM);
-VMMR3DECL(int) HWACCMR3InjectNMI(PVM pVM);
-VMMR3DECL(int) HWACCMR3EmulateIoBlock(PVM pVM, PCPUMCTX pCtx);
-VMMR3DECL(VBOXSTRICTRC) HWACCMR3RestartPendingIOInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-VMMR3DECL(int) HWACMMR3EnablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem);
-VMMR3DECL(int) HWACMMR3DisablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem);
-VMMR3DECL(int) HWACCMR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-VMMR3DECL(bool) HWACCMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx);
-VMMR3DECL(bool) HWACCMR3IsVmxPreemptionTimerUsed(PVM pVM);
-
-/** @} */
-#endif /* IN_RING3 */
-
-#ifdef IN_RING0
-/** @addtogroup grp_hwaccm_r0
- * @{
- */
-VMMR0DECL(int) HWACCMR0SetupVM(PVM pVM);
-VMMR0DECL(int) HWACCMR0RunGuestCode(PVM pVM, PVMCPU pVCpu);
-VMMR0DECL(int) HWACCMR0Enter(PVM pVM, PVMCPU pVCpu);
-VMMR0DECL(int) HWACCMR0Leave(PVM pVM, PVMCPU pVCpu);
-VMMR0DECL(int) HWACCMR0InvalidatePage(PVM pVM, PVMCPU pVCpu);
-VMMR0DECL(int) HWACCMR0FlushTLB(PVM pVM);
-VMMR0DECL(bool) HWACCMR0SuspendPending(void);
-
-# if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS)
-VMMR0DECL(int) HWACCMR0SaveFPUState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-VMMR0DECL(int) HWACCMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-VMMR0DECL(int) HWACCMR0TestSwitcher3264(PVM pVM);
-# endif
-
-/** @} */
-#endif /* IN_RING0 */
-
-
-/** @} */
-RT_C_DECLS_END
-
-
-#endif
-
diff --git a/include/VBox/vmm/iem.h b/include/VBox/vmm/iem.h
index 617a05a6..32168660 100644
--- a/include/VBox/vmm/iem.h
+++ b/include/VBox/vmm/iem.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -28,6 +28,7 @@
#include <VBox/types.h>
#include <VBox/vmm/trpm.h>
+#include <iprt/assert.h>
RT_C_DECLS_BEGIN
@@ -37,6 +38,17 @@ RT_C_DECLS_BEGIN
*/
+/**
+ * Operand or addressing mode.
+ */
+typedef enum IEMMODE
+{
+ IEMMODE_16BIT = 0,
+ IEMMODE_32BIT,
+ IEMMODE_64BIT
+} IEMMODE;
+AssertCompileSize(IEMMODE, 4);
+
VMMDECL(VBOXSTRICTRC) IEMExecOne(PVMCPU pVCpu);
VMMDECL(VBOXSTRICTRC) IEMExecOneEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten);
@@ -53,7 +65,10 @@ VMM_INT_DECL(int) IEMBreakpointClear(PVM pVM, RTGCPTR GCPtrBp);
/** @name Given Instruction Interpreters
* @{ */
-
+VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoWrite(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode,
+ bool fRepPrefix, uint8_t cbInstr, uint8_t iEffSeg);
+VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoRead(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode,
+ bool fRepPrefix, uint8_t cbInstr);
/** @} */
#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
diff --git a/include/VBox/vmm/iom.h b/include/VBox/vmm/iom.h
index a7e552c9..a69ac4cd 100644
--- a/include/VBox/vmm/iom.h
+++ b/include/VBox/vmm/iom.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -57,13 +57,11 @@ RT_C_DECLS_BEGIN
* more than once!
*
* @remark To avoid making assumptions about the layout of the
- * VINF_EM_FIRST...VINF_EM_LAST range we're checking
- * explicitly for each for exach the exceptions.
- * However, for efficieny we ASSUME that the
- * VINF_EM_LAST is smaller than most of the relevant
- * status codes. We also ASSUME that the
- * VINF_EM_RESCHEDULE_REM status code is the most
- * frequent status code we'll enounter in this range.
+ * VINF_EM_FIRST...VINF_EM_LAST range we're checking explicitly for
+ * each exact exception. However, for efficiency we ASSUME that the
+ * VINF_EM_LAST is smaller than most of the relevant status codes. We
+ * also ASSUME that the VINF_EM_RESCHEDULE_REM status code is the
+ * most frequent status code we'll enounter in this range.
*
* @todo Will have to add VINF_EM_DBG_HYPER_BREAKPOINT if the
* I/O port and MMIO breakpoints should trigger before
@@ -75,7 +73,7 @@ RT_C_DECLS_BEGIN
&& (rc) != VINF_EM_RESCHEDULE_REM \
&& (rc) >= VINF_EM_FIRST \
&& (rc) != VINF_EM_RESCHEDULE_RAW \
- && (rc) != VINF_EM_RESCHEDULE_HWACC \
+ && (rc) != VINF_EM_RESCHEDULE_HM \
) \
)
@@ -116,6 +114,16 @@ RT_C_DECLS_BEGIN
* simplifications of devices where reads doesn't change the device
* state in any way. */
#define IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING UINT32_C(0x00000040)
+/** All write accesses are DWORD (32-bit) sized and aligned, attempts at other
+ * accesses are ignored.
+ * @remarks E1000, APIC */
+#define IOMMMIO_FLAGS_WRITE_ONLY_DWORD UINT32_C(0x00000050)
+/** All write accesses are DWORD (32-bit) or QWORD (64-bit) sized and aligned,
+ * attempts at other accesses are ignored.
+ * @remarks Seemingly required by AHCI (although I doubt it's _really_
+ * required as EM/REM doesn't do the right thing in ring-3 anyway,
+ * esp. not in raw-mode). */
+#define IOMMMIO_FLAGS_WRITE_ONLY_DWORD_QWORD UINT32_C(0x00000060)
/** The read access mode mask. */
#define IOMMMIO_FLAGS_WRITE_MODE UINT32_C(0x00000070)
@@ -132,6 +140,14 @@ RT_C_DECLS_BEGIN
#define IOMMMIO_FLAGS_VALID_MASK UINT32_C(0x00000373)
/** @} */
+/**
+ * Checks whether the write mode allows aligned QWORD accesses to be passed
+ * thru to the device handler.
+ * @param a_fFlags The MMIO handler flags.
+ * @remarks The current implementation makes ASSUMPTIONS about the mode values!
+ */
+#define IOMMMIO_DOES_WRITE_MODE_ALLOW_QWORD(a_fFlags) RT_BOOL((a_fFlags) & UINT32_C(0x00000020))
+
/**
* Port I/O Handler for IN operations.
@@ -145,6 +161,7 @@ RT_C_DECLS_BEGIN
* @param pu32 Where to store the result. This is always a 32-bit
* variable regardless of what @a cb might say.
* @param cb Number of bytes read.
+ * @remarks Caller enters the device critical section.
*/
typedef DECLCALLBACK(int) FNIOMIOPORTIN(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
/** Pointer to a FNIOMIOPORTIN(). */
@@ -162,6 +179,7 @@ typedef FNIOMIOPORTIN *PFNIOMIOPORTIN;
* @param pGCPtrDst Pointer to the destination buffer (GC, incremented appropriately).
* @param pcTransfers Pointer to the number of transfer units to read, on return remaining transfer units.
* @param cb Size of the transfer unit (1, 2 or 4 bytes).
+ * @remarks Caller enters the device critical section.
*/
typedef DECLCALLBACK(int) FNIOMIOPORTINSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb);
/** Pointer to a FNIOMIOPORTINSTRING(). */
@@ -177,6 +195,7 @@ typedef FNIOMIOPORTINSTRING *PFNIOMIOPORTINSTRING;
* @param uPort Port number used for the OUT operation.
* @param u32 The value to output.
* @param cb The value size in bytes.
+ * @remarks Caller enters the device critical section.
*/
typedef DECLCALLBACK(int) FNIOMIOPORTOUT(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
/** Pointer to a FNIOMIOPORTOUT(). */
@@ -193,6 +212,7 @@ typedef FNIOMIOPORTOUT *PFNIOMIOPORTOUT;
* @param pGCPtrSrc Pointer to the source buffer (GC, incremented appropriately).
* @param pcTransfers Pointer to the number of transfer units to write, on return remaining transfer units.
* @param cb Size of the transfer unit (1, 2 or 4 bytes).
+ * @remarks Caller enters the device critical section.
*/
typedef DECLCALLBACK(int) FNIOMIOPORTOUTSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb);
/** Pointer to a FNIOMIOPORTOUTSTRING(). */
@@ -209,6 +229,7 @@ typedef FNIOMIOPORTOUTSTRING *PFNIOMIOPORTOUTSTRING;
* @param GCPhysAddr Physical address (in GC) where the read starts.
* @param pv Where to store the result.
* @param cb Number of bytes read.
+ * @remarks Caller enters the device critical section.
*/
typedef DECLCALLBACK(int) FNIOMMMIOREAD(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
/** Pointer to a FNIOMMMIOREAD(). */
@@ -224,6 +245,7 @@ typedef FNIOMMMIOREAD *PFNIOMMMIOREAD;
* @param GCPhysAddr Physical address (in GC) where the read starts.
* @param pv Where to fetch the result.
* @param cb Number of bytes to write.
+ * @remarks Caller enters the device critical section.
*/
typedef DECLCALLBACK(int) FNIOMMMIOWRITE(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb);
/** Pointer to a FNIOMMMIOWRITE(). */
@@ -240,36 +262,37 @@ typedef FNIOMMMIOWRITE *PFNIOMMMIOWRITE;
* @param u32Item Byte/Word/Dword data to fill.
* @param cbItem Size of data in u32Item parameter, restricted to 1/2/4 bytes.
* @param cItems Number of iterations.
+ * @remarks Caller enters the device critical section.
*/
typedef DECLCALLBACK(int) FNIOMMMIOFILL(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems);
/** Pointer to a FNIOMMMIOFILL(). */
typedef FNIOMMMIOFILL *PFNIOMMMIOFILL;
-VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
-VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
-VMMDECL(VBOXSTRICTRC) IOMInterpretOUT(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
-VMMDECL(VBOXSTRICTRC) IOMInterpretIN(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
-VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb);
-VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb);
-VMMDECL(VBOXSTRICTRC) IOMInterpretINS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
-VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
-VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
-VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
-VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue);
-VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue);
-VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault);
+VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
+VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
+VMMDECL(VBOXSTRICTRC) IOMInterpretOUT(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+VMMDECL(VBOXSTRICTRC) IOMInterpretIN(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, PRTGCPTR pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb);
+VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb);
+VMMDECL(VBOXSTRICTRC) IOMInterpretINS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
+VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
+VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue);
+VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue);
+VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault);
VMMDECL(VBOXSTRICTRC) IOMInterpretCheckPortIOAccess(PVM pVM, PCPUMCTXCORE pCtxCore, RTIOPORT Port, unsigned cb);
VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags);
-VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags);
+VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags);
VMMDECL(int) IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys);
-VMMDECL(bool) IOMIsLockOwner(PVM pVM);
+VMMDECL(bool) IOMIsLockWriteOwner(PVM pVM);
#ifdef IN_RC
/** @defgroup grp_iom_rc The IOM Raw-Mode Context API
* @ingroup grp_iom
* @{
*/
-VMMRCDECL(VBOXSTRICTRC) IOMRCIOPortHandler(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+VMMRCDECL(VBOXSTRICTRC) IOMRCIOPortHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
/** @} */
#endif /* IN_RC */
diff --git a/include/VBox/vmm/mm.h b/include/VBox/vmm/mm.h
index 66490fce..bcb55c14 100644
--- a/include/VBox/vmm/mm.h
+++ b/include/VBox/vmm/mm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -58,6 +58,8 @@ typedef enum MMTAG
MM_TAG_CSAM_PATCH,
MM_TAG_CPUM_CTX,
+ MM_TAG_CPUM_CPUID,
+ MM_TAG_CPUM_MSRS,
MM_TAG_DBGF,
MM_TAG_DBGF_AS,
@@ -130,7 +132,7 @@ typedef enum MMTAG
MM_TAG_VMM,
- MM_TAG_HWACCM,
+ MM_TAG_HM,
MM_TAG_32BIT_HACK = 0x7fffffff
} MMTAG;
@@ -205,6 +207,7 @@ DECLINLINE(RTRCPTR) MMHyperCCToRC(PVM pVM, void *pv)
VMMDECL(int) MMHyperAlloc(PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, void **ppv);
+VMMDECL(int) MMHyperDupMem(PVM pVM, const void *pvSrc, size_t cb, unsigned uAlignment, MMTAG enmTag, void **ppv);
VMMDECL(int) MMHyperFree(PVM pVM, void *pv);
VMMDECL(void) MMHyperHeapCheck(PVM pVM);
VMMDECL(int) MMR3LockCall(PVM pVM);
diff --git a/include/VBox/vmm/patm.h b/include/VBox/vmm/patm.h
index 70b7fa55..6f9adca0 100644
--- a/include/VBox/vmm/patm.h
+++ b/include/VBox/vmm/patm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -29,6 +29,7 @@
#include <VBox/types.h>
#include <VBox/dis.h>
+#if defined(VBOX_WITH_RAW_MODE) || defined(DOXYGEN_RUNNING)
RT_C_DECLS_BEGIN
@@ -41,18 +42,18 @@ RT_C_DECLS_BEGIN
* Flags for specifying the type of patch to install with PATMR3InstallPatch
* @{
*/
-#define PATMFL_CODE32 RT_BIT_64(0)
-#define PATMFL_INTHANDLER RT_BIT_64(1)
-#define PATMFL_SYSENTER RT_BIT_64(2)
-#define PATMFL_GUEST_SPECIFIC RT_BIT_64(3)
-#define PATMFL_USER_MODE RT_BIT_64(4)
-#define PATMFL_IDTHANDLER RT_BIT_64(5)
-#define PATMFL_TRAPHANDLER RT_BIT_64(6)
-#define PATMFL_DUPLICATE_FUNCTION RT_BIT_64(7)
-#define PATMFL_REPLACE_FUNCTION_CALL RT_BIT_64(8)
+#define PATMFL_CODE32 RT_BIT_64(0)
+#define PATMFL_INTHANDLER RT_BIT_64(1)
+#define PATMFL_SYSENTER RT_BIT_64(2)
+#define PATMFL_GUEST_SPECIFIC RT_BIT_64(3)
+#define PATMFL_USER_MODE RT_BIT_64(4)
+#define PATMFL_IDTHANDLER RT_BIT_64(5)
+#define PATMFL_TRAPHANDLER RT_BIT_64(6)
+#define PATMFL_DUPLICATE_FUNCTION RT_BIT_64(7)
+#define PATMFL_REPLACE_FUNCTION_CALL RT_BIT_64(8)
#define PATMFL_TRAPHANDLER_WITH_ERRORCODE RT_BIT_64(9)
#define PATMFL_INTHANDLER_WITH_ERRORCODE (PATMFL_TRAPHANDLER_WITH_ERRORCODE)
-#define PATMFL_MMIO_ACCESS RT_BIT_64(10)
+#define PATMFL_MMIO_ACCESS RT_BIT_64(10)
/* no more room -> change PATMInternal.h if more is needed!! */
/*
@@ -70,32 +71,32 @@ RT_C_DECLS_BEGIN
typedef struct PATMGCSTATE
{
- /* Virtual Flags register (IF + more later on) */
+ /** Virtual Flags register (IF + more later on) */
uint32_t uVMFlags;
- /* Pending PATM actions (internal use only) */
+ /** Pending PATM actions (internal use only) */
uint32_t uPendingAction;
- /* Records the number of times all patches are called (indicating how many exceptions we managed to avoid) */
+ /** Records the number of times all patches are called (indicating how many exceptions we managed to avoid) */
uint32_t uPatchCalls;
- /* Scratchpad dword */
+ /** Scratchpad dword */
uint32_t uScratch;
- /* Debugging info */
+ /** Debugging info */
uint32_t uIretEFlags, uIretCS, uIretEIP;
- /* PATM stack pointer */
+ /** PATM stack pointer */
uint32_t Psp;
- /* PATM interrupt flag */
+ /** PATM interrupt flag */
uint32_t fPIF;
- /* PATM inhibit irq address (used by sti) */
+ /** PATM inhibit irq address (used by sti) */
RTRCPTR GCPtrInhibitInterrupts;
- /* Scratch room for call patch */
+ /** Scratch room for call patch */
RTRCPTR GCCallPatchTargetAddr;
RTRCPTR GCCallReturnAddr;
- /* Temporary storage for guest registers. */
+ /** Temporary storage for guest registers. */
struct
{
uint32_t uEAX;
@@ -108,11 +109,11 @@ typedef struct PATMGCSTATE
typedef struct PATMTRAPREC
{
- /* pointer to original guest code instruction (for emulation) */
+ /** pointer to original guest code instruction (for emulation) */
RTRCPTR pNewEIP;
- /* pointer to the next guest code instruction */
+ /** pointer to the next guest code instruction */
RTRCPTR pNextInstr;
- /* pointer to the corresponding next instruction in the patch block */
+ /** pointer to the corresponding next instruction in the patch block */
RTRCPTR pNextPatchInstr;
} PATMTRAPREC, *PPATMTRAPREC;
@@ -122,198 +123,50 @@ typedef struct PATMTRAPREC
*/
typedef enum
{
- PATMTRANS_FAILED,
- PATMTRANS_SAFE, /* Safe translation */
- PATMTRANS_PATCHSTART, /* Instruction starts a patch block */
- PATMTRANS_OVERWRITTEN, /* Instruction overwritten by patchjump */
- PATMTRANS_INHIBITIRQ /* Instruction must be executed due to instruction fusing */
+ PATMTRANS_FAILED,
+ PATMTRANS_SAFE, /**< Safe translation */
+ PATMTRANS_PATCHSTART, /**< Instruction starts a patch block */
+ PATMTRANS_OVERWRITTEN, /**< Instruction overwritten by patchjump */
+ PATMTRANS_INHIBITIRQ /**< Instruction must be executed due to instruction fusing */
} PATMTRANSSTATE;
-/**
- * Load virtualized flags.
- *
- * This function is called from CPUMRawEnter(). It doesn't have to update the
- * IF and IOPL eflags bits, the caller will enforce those to set and 0 respectively.
- *
- * @param pVM VM handle.
- * @param pCtxCore The cpu context core.
- * @see pg_raw
- */
-VMMDECL(void) PATMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore);
-
-/**
- * Restores virtualized flags.
- *
- * This function is called from CPUMRawLeave(). It will update the eflags register.
- *
- * @param pVM VM handle.
- * @param pCtxCore The cpu context core.
- * @param rawRC Raw mode return code
- * @see @ref pg_raw
- */
-VMMDECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC);
-
-/**
- * Get the EFLAGS.
- * This is a worker for CPUMRawGetEFlags().
- *
- * @returns The eflags.
- * @param pVM The VM handle.
- * @param pCtxCore The context core.
- */
-VMMDECL(uint32_t) PATMRawGetEFlags(PVM pVM, PCCPUMCTXCORE pCtxCore);
-
-/**
- * Updates the EFLAGS.
- * This is a worker for CPUMRawSetEFlags().
- *
- * @param pVM The VM handle.
- * @param pCtxCore The context core.
- * @param efl The new EFLAGS value.
- */
-VMMDECL(void) PATMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t efl);
-
-/**
- * Returns the guest context pointer of the GC context structure
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- */
-VMMDECL(RCPTRTYPE(PPATMGCSTATE)) PATMQueryGCState(PVM pVM);
-
-/**
- * Checks whether the GC address is part of our patch region
- *
- * @returns true -> yes, false -> no
- * @param pVM The VM to operate on.
- * @param pAddr Guest context address
- */
-VMMDECL(bool) PATMIsPatchGCAddr(PVM pVM, RTRCUINTPTR pAddr);
-
-/**
- * Check if we must use raw mode (patch code being executed or marked safe for IF=0)
- *
- * @param pVM VM handle.
- * @param pAddrGC Guest context address
- */
-VMMDECL(bool) PATMShouldUseRawMode(PVM pVM, RTRCPTR pAddrGC);
/**
* Query PATM state (enabled/disabled)
*
* @returns 0 - disabled, 1 - enabled
* @param pVM The VM to operate on.
+ * @internal
*/
-#define PATMIsEnabled(pVM) (pVM->fPATMEnabled)
+#define PATMIsEnabled(a_pVM) ((a_pVM)->fPATMEnabled)
-/**
- * Set parameters for pending MMIO patch operation
- *
- * @returns VBox status code.
- * @param pDevIns Device instance.
- * @param GCPhys MMIO physical address
- * @param pCachedData GC pointer to cached data
- */
-VMMDECL(int) PATMSetMMIOPatchInfo(PVM pVM, RTGCPHYS GCPhys, RTRCPTR pCachedData);
-
-
-/**
- * Adds branch pair to the lookup cache of the particular branch instruction
- *
- * @returns VBox status
- * @param pVM The VM to operate on.
- * @param pJumpTableGC Pointer to branch instruction lookup cache
- * @param pBranchTarget Original branch target
- * @param pRelBranchPatch Relative duplicated function address
- */
-VMMDECL(int) PATMAddBranchToLookupCache(PVM pVM, RTRCPTR pJumpTableGC, RTRCPTR pBranchTarget, RTRCUINTPTR pRelBranchPatch);
-
-
-/**
- * Checks if the int 3 was caused by a patched instruction
- *
- * @returns VBox status
- *
- * @param pVM The VM handle.
- * @param pCtxCore The relevant core context.
- */
-VMMRCDECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame);
-
-/**
- * Checks if the int 3 was caused by a patched instruction
- *
- * @returns VBox status
- *
- * @param pVM The VM handle.
- * @param pInstrGC Instruction pointer
- * @param pOpcode Original instruction opcode (out, optional)
- * @param pSize Original instruction size (out, optional)
- */
-VMMDECL(bool) PATMIsInt3Patch(PVM pVM, RTRCPTR pInstrGC, uint32_t *pOpcode, uint32_t *pSize);
-
-
-/**
- * Checks if the interrupt flag is enabled or not.
- *
- * @returns true if it's enabled.
- * @returns false if it's disabled.
- *
- * @param pVM The VM handle.
- */
-VMMDECL(bool) PATMAreInterruptsEnabled(PVM pVM);
+VMMDECL(bool) PATMIsPatchGCAddr(PVM pVM, RTRCUINTPTR pAddr);
+VMM_INT_DECL(int) PATMReadPatchCode(PVM pVM, RTGCPTR GCPtrPatchCode, void *pvDst, size_t cbToRead, size_t *pcbRead);
-/**
- * Checks if the interrupt flag is enabled or not.
- *
- * @returns true if it's enabled.
- * @returns false if it's disabled.
- *
- * @param pVM The VM handle.
- * @param pCtxCore CPU context
- */
-VMMDECL(bool) PATMAreInterruptsEnabledByCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore);
+VMM_INT_DECL(void) PATMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore);
+VMM_INT_DECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC);
+VMM_INT_DECL(uint32_t) PATMRawGetEFlags(PVM pVM, PCCPUMCTXCORE pCtxCore);
+VMM_INT_DECL(void) PATMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t efl);
+VMM_INT_DECL(RCPTRTYPE(PPATMGCSTATE)) PATMGetGCState(PVM pVM);
+VMM_INT_DECL(bool) PATMShouldUseRawMode(PVM pVM, RTRCPTR pAddrGC);
+VMM_INT_DECL(int) PATMSetMMIOPatchInfo(PVM pVM, RTGCPHYS GCPhys, RTRCPTR pCachedData);
+VMM_INT_DECL(bool) PATMIsInt3Patch(PVM pVM, RTRCPTR pInstrGC, uint32_t *pOpcode, uint32_t *pSize);
+VMM_INT_DECL(bool) PATMAreInterruptsEnabled(PVM pVM);
+VMM_INT_DECL(bool) PATMAreInterruptsEnabledByCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore);
#ifdef PATM_EMULATE_SYSENTER
-/**
- * Emulate sysenter, sysexit and syscall instructions
- *
- * @returns VBox status
- *
- * @param pVM The VM handle.
- * @param pCtxCore The relevant core context.
- * @param pCpu Disassembly context
- */
-VMMDECL(int) PATMSysCall(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+VMM_INT_DECL(int) PATMSysCall(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
#endif
#ifdef IN_RC
-/** @defgroup grp_patm_gc The Patch Manager API
+/** @defgroup grp_patm_rc The Patch Manager RC API
* @ingroup grp_patm
* @{
*/
-/**
- * Checks if the write is located on a page with was patched before.
- * (if so, then we are not allowed to turn on r/w)
- *
- * @returns VBox status
- * @param pVM The VM to operate on.
- * @param pRegFrame CPU context
- * @param GCPtr GC pointer to write address
- * @param cbWrite Nr of bytes to write
- *
- */
-VMMRCDECL(int) PATMGCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite);
-
-/**
- * Checks if the illegal instruction was caused by a patched instruction
- *
- * @returns VBox status
- *
- * @param pVM The VM handle.
- * @param pCtxCore The relevant core context.
- */
-VMMDECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame);
+VMMRC_INT_DECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame);
+VMMRC_INT_DECL(int) PATMRCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite);
+VMMRC_INT_DECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame);
/** @} */
@@ -325,341 +178,41 @@ VMMDECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame);
* @{
*/
-/**
- * Query PATM state (enabled/disabled)
- *
- * @returns 0 - disabled, 1 - enabled
- * @param pVM The VM to operate on.
- */
-VMMR3DECL(int) PATMR3IsEnabled(PVM pVM);
-
-/**
- * Initializes the PATM.
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- */
-VMMR3DECL(int) PATMR3Init(PVM pVM);
-
-/**
- * Finalizes HMA page attributes.
- *
- * @returns VBox status code.
- * @param pVM The VM handle.
- */
-VMMR3DECL(int) PATMR3InitFinalize(PVM pVM);
-
-/**
- * Applies relocations to data and code managed by this
- * component. This function will be called at init and
- * whenever the VMM need to relocate it self inside the GC.
- *
- * The PATM will update the addresses used by the switcher.
- *
- * @param pVM The VM.
- */
-VMMR3DECL(void) PATMR3Relocate(PVM pVM);
-
-/**
- * Terminates the PATM.
- *
- * Termination means cleaning up and freeing all resources,
- * the VM it self is at this point powered off or suspended.
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- */
-VMMR3DECL(int) PATMR3Term(PVM pVM);
-
-/**
- * PATM reset callback.
- *
- * @returns VBox status code.
- * @param pVM The VM which is reset.
- */
-VMMR3DECL(int) PATMR3Reset(PVM pVM);
-
-/**
- * Returns the host context pointer and size of the patch memory block
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pcb Size of the patch memory block
- */
-VMMR3DECL(void *) PATMR3QueryPatchMemHC(PVM pVM, uint32_t *pcb);
-
-/**
- * Returns the guest context pointer and size of the patch memory block
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pcb Size of the patch memory block
- */
-VMMR3DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb);
-
-/**
- * Checks whether the GC address is inside a generated patch jump
- *
- * @returns true -> yes, false -> no
- * @param pVM The VM to operate on.
- * @param pAddr Guest context address
- * @param pPatchAddr Guest context patch address (if true)
- */
-VMMR3DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatchAddr);
-
-
-/**
- * Returns the GC pointer of the patch for the specified GC address
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pAddrGC Guest context address
- */
-VMMR3DECL(RTRCPTR) PATMR3QueryPatchGCPtr(PVM pVM, RTRCPTR pAddrGC);
-
-/**
- * Checks whether the HC address is part of our patch region
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pAddrGC Guest context address
- */
-VMMR3DECL(bool) PATMR3IsPatchHCAddr(PVM pVM, R3PTRTYPE(uint8_t *) pAddrHC);
-
-/**
- * Convert a GC patch block pointer to a HC patch pointer
- *
- * @returns HC pointer or NULL if it's not a GC patch pointer
- * @param pVM The VM to operate on.
- * @param pAddrGC GC pointer
- */
-VMMR3DECL(R3PTRTYPE(void *)) PATMR3GCPtrToHCPtr(PVM pVM, RTRCPTR pAddrGC);
-
-
-/**
- * Returns the host context pointer and size of the GC context structure
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- */
-VMMR3DECL(PPATMGCSTATE) PATMR3QueryGCStateHC(PVM pVM);
-
-/**
- * Handle trap inside patch code
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pCtx CPU context
- * @param pEip GC pointer of trapping instruction
- * @param pNewEip GC pointer to new instruction
- */
-VMMR3DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *ppNewEip);
-
-/**
- * Handle page-fault in monitored page
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- */
-VMMR3DECL(int) PATMR3HandleMonitoredPage(PVM pVM);
-
-/**
- * Notifies PATM about a (potential) write to code that has been patched.
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param GCPtr GC pointer to write address
- * @param cbWrite Nr of bytes to write
- *
- */
-VMMR3DECL(int) PATMR3PatchWrite(PVM pVM, RTRCPTR GCPtr, uint32_t cbWrite);
-
-/**
- * Notify PATM of a page flush
- *
- * @returns VBox status code
- * @param pVM The VM to operate on.
- * @param addr GC address of the page to flush
- */
-VMMR3DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr);
-
-/**
- * Allows or disallow patching of privileged instructions executed by the guest OS
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param fAllowPatching Allow/disallow patching
- */
-VMMR3DECL(int) PATMR3AllowPatching(PVM pVM, uint32_t fAllowPatching);
-
-/**
- * Patch privileged instruction at specified location
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pInstr Guest context point to privileged instruction (0:32 flat address)
- * @param flags Patch flags
- *
- * @note returns failure if patching is not allowed or possible
- */
-VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags);
-
-/**
- * Gives hint to PATM about supervisor guest instructions
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pInstr Guest context point to privileged instruction
- * @param flags Patch flags
- */
-VMMR3DECL(int) PATMR3AddHint(PVM pVM, RTRCPTR pInstrGC, uint32_t flags);
-
-/**
- * Patch branch target function for call/jump at specified location.
- * (in responds to a VINF_PATM_DUPLICATE_FUNCTION GC exit reason)
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pCtx Guest context
- *
- */
-VMMR3DECL(int) PATMR3DuplicateFunctionRequest(PVM pVM, PCPUMCTX pCtx);
-
-/**
- * Query the corresponding GC instruction pointer from a pointer inside the patch block itself
- *
- * @returns original GC instruction pointer or 0 if not found
- * @param pVM The VM to operate on.
- * @param pPatchGC GC address in patch block
- * @param pEnmState State of the translated address (out)
- *
- */
-VMMR3DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE *pEnmState);
-
-/**
- * Converts Guest code GC ptr to Patch code GC ptr (if found)
- *
- * @returns corresponding GC pointer in patch block
- * @param pVM The VM to operate on.
- * @param pInstrGC Guest context pointer to privileged instruction
- *
- */
-VMMR3DECL(RTRCPTR) PATMR3GuestGCPtrToPatchGCPtr(PVM pVM, RCPTRTYPE(uint8_t*) pInstrGC);
-
-/**
- * Query the opcode of the original code that was overwritten by the 5 bytes patch jump
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pInstrGC GC address of instr
- * @param pByte opcode byte pointer (OUT)
- * @returns VBOX error code
- *
- */
-VMMR3DECL(int) PATMR3QueryOpcode(PVM pVM, RTRCPTR pInstrGC, uint8_t *pByte);
-VMMR3DECL(int) PATMR3ReadOrgInstr(PVM pVM, RTGCPTR32 GCPtrInstr, uint8_t *pbDst, size_t cbToRead, size_t *pcbRead);
-
-/**
- * Disable patch for privileged instruction at specified location
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pInstr Guest context point to privileged instruction
- *
- * @note returns failure if patching is not allowed or possible
- *
- */
-VMMR3DECL(int) PATMR3DisablePatch(PVM pVM, RTRCPTR pInstrGC);
-
-
-/**
- * Enable patch for privileged instruction at specified location
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pInstr Guest context point to privileged instruction
- *
- * @note returns failure if patching is not allowed or possible
- *
- */
-VMMR3DECL(int) PATMR3EnablePatch(PVM pVM, RTRCPTR pInstrGC);
-
-
-/**
- * Remove patch for privileged instruction at specified location
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on.
- * @param pInstr Guest context point to privileged instruction
- *
- * @note returns failure if patching is not allowed or possible
- *
- */
-VMMR3DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC);
-
-
-/**
- * Detects it the specified address falls within a 5 byte jump generated for an active patch.
- * If so, this patch is permanently disabled.
- *
- * @param pVM The VM to operate on.
- * @param pInstrGC Guest context pointer to instruction
- * @param pConflictGC Guest context pointer to check
- */
-VMMR3DECL(int) PATMR3DetectConflict(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflictGC);
-
-
-/**
- * Checks if the instructions at the specified address has been patched already.
- *
- * @returns boolean, patched or not
- * @param pVM The VM to operate on.
- * @param pInstrGC Guest context pointer to instruction
- */
-VMMR3DECL(bool) PATMR3HasBeenPatched(PVM pVM, RTRCPTR pInstrGC);
-
-
-/**
- * Install Linux 2.6 spinlock patch
- *
- * @returns VBox status code.
- * @param pVM The VM to operate on
- * @param pCallAcquireSpinlockGC GC pointer of call instruction
- * @param cbAcquireSpinlockCall Instruction size
- *
- */
-VMMR3DECL(int) PATMInstallSpinlockPatch(PVM pVM, RTRCPTR pCallAcquireSpinlockGC, uint32_t cbAcquireSpinlockCall);
-
-
-/**
- * Check if supplied call target is the Linux 2.6 spinlock acquire function
- *
- * @returns boolean
- * @param pVM The VM to operate on
- * @param pCallAcquireSpinlockGC Call target GC address
- *
- */
-VMMR3DECL(bool) PATMIsSpinlockAcquire(PVM pVM, RTRCPTR pCallTargetGC);
-
-/**
- * Check if supplied call target is the Linux 2.6 spinlock release function
- *
- * @returns boolean
- * @param pVM The VM to operate on
- * @param pCallTargetGC Call target GC address
- *
- */
-VMMR3DECL(bool) PATMIsSpinlockRelease(PVM pVM, RTRCPTR pCallTargetGC);
-
-/**
- * Check if supplied call target is the Linux 2.6 spinlock release function (patched equivalent)
- *
- * @returns boolean
- * @param pVM The VM to operate on
- * @param pCallTargetGC Call target GC address
- *
- */
-VMMR3DECL(bool) PATMIsSpinlockReleasePatch(PVM pVM, RTRCPTR pCallTargetGC);
+VMMR3DECL(int) PATMR3AllowPatching(PUVM pUVM, bool fAllowPatching);
+VMMR3DECL(bool) PATMR3IsEnabled(PUVM pUVM);
+
+VMMR3_INT_DECL(int) PATMR3Init(PVM pVM);
+VMMR3_INT_DECL(int) PATMR3InitFinalize(PVM pVM);
+VMMR3_INT_DECL(void) PATMR3Relocate(PVM pVM);
+VMMR3_INT_DECL(int) PATMR3Term(PVM pVM);
+VMMR3_INT_DECL(int) PATMR3Reset(PVM pVM);
+
+VMMR3_INT_DECL(void *) PATMR3QueryPatchMemHC(PVM pVM, uint32_t *pcb);
+VMMR3_INT_DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb);
+VMMR3_INT_DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatchAddr);
+VMMR3_INT_DECL(RTRCPTR) PATMR3QueryPatchGCPtr(PVM pVM, RTRCPTR pAddrGC);
+VMMR3_INT_DECL(bool) PATMR3IsPatchHCAddr(PVM pVM, void *pAddrHC);
+VMMR3_INT_DECL(void *) PATMR3GCPtrToHCPtr(PVM pVM, RTRCPTR pAddrGC);
+VMMR3_INT_DECL(PPATMGCSTATE) PATMR3QueryGCStateHC(PVM pVM);
+VMMR3_INT_DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *ppNewEip);
+VMMR3_INT_DECL(int) PATMR3HandleMonitoredPage(PVM pVM);
+VMMR3_INT_DECL(int) PATMR3PatchWrite(PVM pVM, RTRCPTR GCPtr, uint32_t cbWrite);
+VMMR3_INT_DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr);
+VMMR3_INT_DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags);
+VMMR3_INT_DECL(int) PATMR3AddHint(PVM pVM, RTRCPTR pInstrGC, uint32_t flags);
+VMMR3_INT_DECL(int) PATMR3DuplicateFunctionRequest(PVM pVM, PCPUMCTX pCtx);
+VMMR3_INT_DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE *pEnmState);
+VMMR3DECL(int) PATMR3QueryOpcode(PVM pVM, RTRCPTR pInstrGC, uint8_t *pByte);
+VMMR3_INT_DECL(int) PATMR3ReadOrgInstr(PVM pVM, RTGCPTR32 GCPtrInstr, uint8_t *pbDst, size_t cbToRead, size_t *pcbRead);
+VMMR3_INT_DECL(int) PATMR3DisablePatch(PVM pVM, RTRCPTR pInstrGC);
+VMMR3_INT_DECL(int) PATMR3EnablePatch(PVM pVM, RTRCPTR pInstrGC);
+VMMR3_INT_DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC);
+VMMR3_INT_DECL(int) PATMR3DetectConflict(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflictGC);
+VMMR3_INT_DECL(bool) PATMR3HasBeenPatched(PVM pVM, RTRCPTR pInstrGC);
+
+VMMR3_INT_DECL(void) PATMR3DbgPopulateAddrSpace(PVM pVM, RTDBGAS hDbgAs);
+VMMR3_INT_DECL(void) PATMR3DbgAnnotatePatchedInstruction(PVM pVM, RTRCPTR RCPtr, uint8_t cbInstr,
+ char *pszBuf, size_t cbBuf);
/** @} */
#endif
@@ -668,5 +221,6 @@ VMMR3DECL(bool) PATMIsSpinlockReleasePatch(PVM pVM, RTRCPTR pCallTargetGC);
/** @} */
RT_C_DECLS_END
+#endif /* VBOX_WITH_RAW_MODE */
#endif
diff --git a/include/VBox/vmm/pdm.h b/include/VBox/vmm/pdm.h
index ff95ea82..527d3d14 100644
--- a/include/VBox/vmm/pdm.h
+++ b/include/VBox/vmm/pdm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -29,6 +29,7 @@
#include <VBox/vmm/pdmapi.h>
#include <VBox/vmm/pdmqueue.h>
#include <VBox/vmm/pdmcritsect.h>
+#include <VBox/vmm/pdmcritsectrw.h>
#include <VBox/vmm/pdmthread.h>
#include <VBox/vmm/pdmifs.h>
#include <VBox/vmm/pdmdrv.h>
diff --git a/include/VBox/vmm/pdmapi.h b/include/VBox/vmm/pdmapi.h
index 1fb8aef6..321865a1 100644
--- a/include/VBox/vmm/pdmapi.h
+++ b/include/VBox/vmm/pdmapi.h
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -40,20 +40,21 @@ RT_C_DECLS_BEGIN
* @{
*/
-VMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt);
-VMMDECL(int) PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc);
-VMM_INT_DECL(int) PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc);
-VMM_INT_DECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc);
-VMMDECL(bool) PDMHasIoApic(PVM pVM);
-VMMDECL(int) PDMApicHasPendingIrq(PVM pVM, bool *pfPending);
-VMMDECL(int) PDMApicSetBase(PVM pVM, uint64_t u64Base);
-VMMDECL(int) PDMApicGetBase(PVM pVM, uint64_t *pu64Base);
-VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR);
-VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending);
-VMMDECL(int) PDMApicWriteMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value);
-VMMDECL(int) PDMApicReadMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value);
-VMMDECL(int) PDMVMMDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys);
-VMMDECL(bool) PDMVMMDevHeapIsEnabled(PVM pVM);
+VMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt);
+VMMDECL(int) PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc);
+VMM_INT_DECL(bool) PDMHasIoApic(PVM pVM);
+VMM_INT_DECL(int) PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc);
+VMM_INT_DECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc);
+VMM_INT_DECL(bool) PDMHasApic(PVM pVM);
+VMM_INT_DECL(int) PDMApicHasPendingIrq(PVM pVM, bool *pfPending);
+VMMDECL(int) PDMApicSetBase(PVMCPU pVCpu, uint64_t u64Base);
+VMMDECL(int) PDMApicGetBase(PVMCPU pVCpu, uint64_t *pu64Base);
+VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR);
+VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIrq);
+VMM_INT_DECL(int) PDMApicWriteMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value);
+VMM_INT_DECL(int) PDMApicReadMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value);
+VMM_INT_DECL(int) PDMVmmDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys);
+VMM_INT_DECL(bool) PDMVmmDevHeapIsEnabled(PVM pVM);
/** @defgroup grp_pdm_r3 The PDM Host Context Ring-3 API
@@ -61,18 +62,36 @@ VMMDECL(bool) PDMVMMDevHeapIsEnabled(PVM pVM);
* @{
*/
-VMMR3DECL(int) PDMR3InitUVM(PUVM pUVM);
-VMMR3DECL(int) PDMR3LdrLoadVMMR0U(PUVM pUVM);
-VMMR3DECL(int) PDMR3Init(PVM pVM);
-VMMR3DECL(void) PDMR3PowerOn(PVM pVM);
-VMMR3DECL(void) PDMR3ResetCpu(PVMCPU pVCpu);
-VMMR3DECL(void) PDMR3Reset(PVM pVM);
-VMMR3DECL(void) PDMR3Suspend(PVM pVM);
-VMMR3DECL(void) PDMR3Resume(PVM pVM);
-VMMR3DECL(void) PDMR3PowerOff(PVM pVM);
-VMMR3DECL(void) PDMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
-VMMR3DECL(int) PDMR3Term(PVM pVM);
-VMMR3DECL(void) PDMR3TermUVM(PUVM pUVM);
+VMMR3_INT_DECL(int) PDMR3InitUVM(PUVM pUVM);
+VMMR3_INT_DECL(int) PDMR3LdrLoadVMMR0U(PUVM pUVM);
+VMMR3_INT_DECL(int) PDMR3Init(PVM pVM);
+VMMR3DECL(void) PDMR3PowerOn(PVM pVM);
+VMMR3_INT_DECL(void) PDMR3ResetCpu(PVMCPU pVCpu);
+VMMR3_INT_DECL(void) PDMR3Reset(PVM pVM);
+VMMR3_INT_DECL(void) PDMR3MemSetup(PVM pVM, bool fAtReset);
+VMMR3_INT_DECL(void) PDMR3Suspend(PVM pVM);
+VMMR3_INT_DECL(void) PDMR3Resume(PVM pVM);
+VMMR3DECL(void) PDMR3PowerOff(PVM pVM);
+VMMR3_INT_DECL(void) PDMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+VMMR3_INT_DECL(int) PDMR3Term(PVM pVM);
+VMMR3_INT_DECL(void) PDMR3TermUVM(PUVM pUVM);
+
+/** PDM loader context indicator. */
+typedef enum PDMLDRCTX
+{
+ /** Invalid zero value. */
+ PDMLDRCTX_INVALID = 0,
+ /** Ring-0 context. */
+ PDMLDRCTX_RING_0,
+ /** Ring-3 context. */
+ PDMLDRCTX_RING_3,
+ /** Raw-mode context. */
+ PDMLDRCTX_RAW_MODE,
+ /** End of valid context values. */
+ PDMLDRCTX_END,
+ /** 32-bit type hack. */
+ PDMLDRCTX_32BIT_HACK = 0x7fffffff
+} PDMLDRCTX;
/**
* Module enumeration callback function.
@@ -85,54 +104,57 @@ VMMR3DECL(void) PDMR3TermUVM(PUVM pUVM);
* @param pszName Module name. (short and unique)
* @param ImageBase Address where to executable image is loaded.
* @param cbImage Size of the executable image.
- * @param fRC Set if raw-mode context, clear if host context.
+ * @param enmCtx The context the module is loaded into.
* @param pvArg User argument.
*/
typedef DECLCALLBACK(int) FNPDMR3ENUM(PVM pVM, const char *pszFilename, const char *pszName,
- RTUINTPTR ImageBase, size_t cbImage, bool fRC, void *pvArg);
+ RTUINTPTR ImageBase, size_t cbImage, PDMLDRCTX enmCtx, void *pvArg);
/** Pointer to a FNPDMR3ENUM() function. */
typedef FNPDMR3ENUM *PFNPDMR3ENUM;
-VMMR3DECL(int) PDMR3LdrEnumModules(PVM pVM, PFNPDMR3ENUM pfnCallback, void *pvArg);
-VMMR3DECL(void) PDMR3LdrRelocateU(PUVM pUVM, RTGCINTPTR offDelta);
-VMMR3DECL(int) PDMR3LdrGetSymbolR3(PVM pVM, const char *pszModule, const char *pszSymbol, void **ppvValue);
-VMMR3DECL(int) PDMR3LdrGetSymbolR0(PVM pVM, const char *pszModule, const char *pszSymbol, PRTR0PTR ppvValue);
-VMMR3DECL(int) PDMR3LdrGetSymbolR0Lazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, PRTR0PTR ppvValue);
-VMMR3DECL(int) PDMR3LdrLoadRC(PVM pVM, const char *pszFilename, const char *pszName);
-VMMR3DECL(int) PDMR3LdrGetSymbolRC(PVM pVM, const char *pszModule, const char *pszSymbol, PRTRCPTR pRCPtrValue);
-VMMR3DECL(int) PDMR3LdrGetSymbolRCLazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, PRTRCPTR pRCPtrValue);
-VMMR3DECL(int) PDMR3LdrQueryRCModFromPC(PVM pVM, RTRCPTR uPC,
- char *pszModName, size_t cchModName, PRTRCPTR pMod,
- char *pszNearSym1, size_t cchNearSym1, PRTRCPTR pNearSym1,
- char *pszNearSym2, size_t cchNearSym2, PRTRCPTR pNearSym2);
-VMMR3DECL(int) PDMR3LdrQueryR0ModFromPC(PVM pVM, RTR0PTR uPC,
- char *pszModName, size_t cchModName, PRTR0PTR pMod,
- char *pszNearSym1, size_t cchNearSym1, PRTR0PTR pNearSym1,
- char *pszNearSym2, size_t cchNearSym2, PRTR0PTR pNearSym2);
-VMMR3DECL(int) PDMR3LdrGetInterfaceSymbols(PVM pVM,
- void *pvInterface, size_t cbInterface,
- const char *pszModule, const char *pszSearchPath,
- const char *pszSymPrefix, const char *pszSymList,
- bool fRing0OrRC);
-
-VMMR3DECL(int) PDMR3QueryDevice(PVM pVM, const char *pszDevice, unsigned iInstance, PPPDMIBASE ppBase);
-VMMR3DECL(int) PDMR3QueryDeviceLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase);
-VMMR3DECL(int) PDMR3QueryLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase);
-VMMR3DECL(int) PDMR3QueryDriverOnLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, const char *pszDriver,
- PPPDMIBASE ppBase);
-VMMR3DECL(int) PDMR3DeviceAttach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags, PPDMIBASE *ppBase);
-VMMR3DECL(int) PDMR3DeviceDetach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags);
+VMMR3DECL(int) PDMR3LdrEnumModules(PVM pVM, PFNPDMR3ENUM pfnCallback, void *pvArg);
+VMMR3_INT_DECL(void) PDMR3LdrRelocateU(PUVM pUVM, RTGCINTPTR offDelta);
+VMMR3_INT_DECL(int) PDMR3LdrGetSymbolR3(PVM pVM, const char *pszModule, const char *pszSymbol, void **ppvValue);
+VMMR3DECL(int) PDMR3LdrGetSymbolR0(PVM pVM, const char *pszModule, const char *pszSymbol, PRTR0PTR ppvValue);
+VMMR3DECL(int) PDMR3LdrGetSymbolR0Lazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, PRTR0PTR ppvValue);
+VMMR3DECL(int) PDMR3LdrLoadRC(PVM pVM, const char *pszFilename, const char *pszName);
+VMMR3DECL(int) PDMR3LdrGetSymbolRC(PVM pVM, const char *pszModule, const char *pszSymbol, PRTRCPTR pRCPtrValue);
+VMMR3DECL(int) PDMR3LdrGetSymbolRCLazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol,
+ PRTRCPTR pRCPtrValue);
+VMMR3_INT_DECL(int) PDMR3LdrQueryRCModFromPC(PVM pVM, RTRCPTR uPC,
+ char *pszModName, size_t cchModName, PRTRCPTR pMod,
+ char *pszNearSym1, size_t cchNearSym1, PRTRCPTR pNearSym1,
+ char *pszNearSym2, size_t cchNearSym2, PRTRCPTR pNearSym2);
+VMMR3_INT_DECL(int) PDMR3LdrQueryR0ModFromPC(PVM pVM, RTR0PTR uPC,
+ char *pszModName, size_t cchModName, PRTR0PTR pMod,
+ char *pszNearSym1, size_t cchNearSym1, PRTR0PTR pNearSym1,
+ char *pszNearSym2, size_t cchNearSym2, PRTR0PTR pNearSym2);
+VMMR3_INT_DECL(int) PDMR3LdrGetInterfaceSymbols(PVM pVM, void *pvInterface, size_t cbInterface,
+ const char *pszModule, const char *pszSearchPath,
+ const char *pszSymPrefix, const char *pszSymList,
+ bool fRing0OrRC);
+
+VMMR3DECL(int) PDMR3QueryDevice(PUVM pUVM, const char *pszDevice, unsigned iInstance, PPPDMIBASE ppBase);
+VMMR3DECL(int) PDMR3QueryDeviceLun(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase);
+VMMR3DECL(int) PDMR3QueryLun(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase);
+VMMR3DECL(int) PDMR3QueryDriverOnLun(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun,
+ const char *pszDriver, PPPDMIBASE ppBase);
+VMMR3DECL(int) PDMR3DeviceAttach(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags,
+ PPDMIBASE *ppBase);
+VMMR3DECL(int) PDMR3DeviceDetach(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags);
VMMR3_INT_DECL(PPDMCRITSECT) PDMR3DevGetCritSect(PVM pVM, PPDMDEVINS pDevIns);
-VMMR3DECL(int) PDMR3DriverAttach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, uint32_t fFlags, PPPDMIBASE ppBase);
-VMMR3DECL(int) PDMR3DriverDetach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun,
- const char *pszDriver, unsigned iOccurance, uint32_t fFlags);
-VMMR3DECL(int) PDMR3DriverReattach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun,
- const char *pszDriver, unsigned iOccurance, uint32_t fFlags, PCFGMNODE pCfg, PPPDMIBASE ppBase);
-VMMR3DECL(void) PDMR3DmaRun(PVM pVM);
-VMMR3DECL(int) PDMR3LockCall(PVM pVM);
-VMMR3DECL(int) PDMR3RegisterVMMDevHeap(PVM pVM, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize);
-VMMR3DECL(int) PDMR3VMMDevHeapAlloc(PVM pVM, unsigned cbSize, RTR3PTR *ppv);
-VMMR3DECL(int) PDMR3VMMDevHeapFree(PVM pVM, RTR3PTR pv);
-VMMR3DECL(int) PDMR3UnregisterVMMDevHeap(PVM pVM, RTGCPHYS GCPhys);
+VMMR3DECL(int) PDMR3DriverAttach(PUVM pUVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, uint32_t fFlags,
+ PPPDMIBASE ppBase);
+VMMR3DECL(int) PDMR3DriverDetach(PUVM pUVM, const char *pszDevice, unsigned iDevIns, unsigned iLun,
+ const char *pszDriver, unsigned iOccurance, uint32_t fFlags);
+VMMR3DECL(int) PDMR3DriverReattach(PUVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun,
+ const char *pszDriver, unsigned iOccurance, uint32_t fFlags, PCFGMNODE pCfg,
+ PPPDMIBASE ppBase);
+VMMR3DECL(void) PDMR3DmaRun(PVM pVM);
+VMMR3_INT_DECL(int) PDMR3LockCall(PVM pVM);
+VMMR3_INT_DECL(int) PDMR3VmmDevHeapRegister(PVM pVM, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize);
+VMMR3_INT_DECL(int) PDMR3VmmDevHeapUnregister(PVM pVM, RTGCPHYS GCPhys);
+VMMR3_INT_DECL(int) PDMR3VmmDevHeapAlloc(PVM pVM, size_t cbSize, RTR3PTR *ppv);
+VMMR3_INT_DECL(int) PDMR3VmmDevHeapFree(PVM pVM, RTR3PTR pv);
VMMR3_INT_DECL(int) PDMR3TracingConfig(PVM pVM, const char *pszName, size_t cchName, bool fEnable, bool fApply);
VMMR3_INT_DECL(bool) PDMR3TracingAreAll(PVM pVM, bool fEnabled);
VMMR3_INT_DECL(int) PDMR3TracingQueryConfig(PVM pVM, char *pszConfig, size_t cbConfig);
diff --git a/include/VBox/vmm/pdmasynccompletion.h b/include/VBox/vmm/pdmasynccompletion.h
index 1d1af265..74285945 100644
--- a/include/VBox/vmm/pdmasynccompletion.h
+++ b/include/VBox/vmm/pdmasynccompletion.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2007-2010 Oracle Corporation
+ * Copyright (C) 2007-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -104,122 +104,8 @@ typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEINT(PVM pVM, void *pvUser, void *pv
/** Pointer to a FNPDMASYNCCOMPLETEINT(). */
typedef FNPDMASYNCCOMPLETEINT *PFNPDMASYNCCOMPLETEINT;
-
-/**
- * Creates an async completion template for a device instance.
- *
- * The template is used when creating new completion tasks.
- *
- * @returns VBox status code.
- * @param pVM Pointer to the shared VM structure.
- * @param pDevIns The device instance.
- * @param ppTemplate Where to store the template pointer on success.
- * @param pfnCompleted The completion callback routine.
- * @param pszDesc Description.
- */
-VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDEV pfnCompleted, const char *pszDesc);
-
-/**
- * Creates an async completion template for a driver instance.
- *
- * The template is used when creating new completion tasks.
- *
- * @returns VBox status code.
- * @param pVM Pointer to the shared VM structure.
- * @param pDrvIns The driver instance.
- * @param ppTemplate Where to store the template pointer on success.
- * @param pfnCompleted The completion callback routine.
- * @param pvTemplateUser Template user argument.
- * @param pszDesc Description.
- */
-VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc);
-
-/**
- * Creates an async completion template for a USB device instance.
- *
- * The template is used when creating new completion tasks.
- *
- * @returns VBox status code.
- * @param pVM Pointer to the shared VM structure.
- * @param pUsbIns The USB device instance.
- * @param ppTemplate Where to store the template pointer on success.
- * @param pfnCompleted The completion callback routine.
- * @param pszDesc Description.
- */
-VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEUSB pfnCompleted, const char *pszDesc);
-
-/**
- * Creates an async completion template for internally by the VMM.
- *
- * The template is used when creating new completion tasks.
- *
- * @returns VBox status code.
- * @param pVM Pointer to the shared VM structure.
- * @param ppTemplate Where to store the template pointer on success.
- * @param pfnCompleted The completion callback routine.
- * @param pvUser2 The 2nd user argument for the callback.
- * @param pszDesc Description.
- */
VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateInternal(PVM pVM, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEINT pfnCompleted, void *pvUser2, const char *pszDesc);
-
-/**
- * Destroys the specified async completion template.
- *
- * @returns VBox status codes:
- * @retval VINF_SUCCESS on success.
- * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if the template is still in use.
- *
- * @param pTemplate The template in question.
- */
VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroy(PPDMASYNCCOMPLETIONTEMPLATE pTemplate);
-
-/**
- * Destroys all the specified async completion templates for the given device instance.
- *
- * @returns VBox status codes:
- * @retval VINF_SUCCESS on success.
- * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use.
- *
- * @param pVM Pointer to the shared VM structure.
- * @param pDevIns The device instance.
- */
-VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
-
-/**
- * Destroys all the specified async completion templates for the given driver instance.
- *
- * @returns VBox status codes:
- * @retval VINF_SUCCESS on success.
- * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use.
- *
- * @param pVM Pointer to the shared VM structure.
- * @param pDrvIns The driver instance.
- */
-VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
-
-/**
- * Destroys all the specified async completion templates for the given USB device instance.
- *
- * @returns VBox status codes:
- * @retval VINF_SUCCESS on success.
- * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use.
- *
- * @param pVM Pointer to the shared VM structure.
- * @param pUsbIns The USB device instance.
- */
-VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
-
-
-/**
- * Opens a file as an async completion endpoint.
- *
- * @returns VBox status code.
- * @param ppEndpoint Where to store the opaque endpoint handle on success.
- * @param pszFilename Path to the file which is to be opened. (UTF-8)
- * @param fFlags Open flags, see grp_pdmacep_file_flags.
- * @param pTemplate Handle to the completion callback template to use
- * for this end point.
- */
VMMR3DECL(int) PDMR3AsyncCompletionEpCreateForFile(PPPDMASYNCCOMPLETIONENDPOINT ppEndpoint,
const char *pszFilename, uint32_t fFlags,
PPDMASYNCCOMPLETIONTEMPLATE pTemplate);
@@ -238,127 +124,21 @@ VMMR3DECL(int) PDMR3AsyncCompletionEpCreateForFile(PPPDMASYNCCOMPLETIONENDPOINT
#define PDMACEP_FILE_FLAGS_HOST_CACHE_ENABLED RT_BIT_32(3)
/** @} */
-/**
- * Closes a endpoint waiting for any pending tasks to finish.
- *
- * @returns nothing.
- * @param pEndpoint Handle of the endpoint.
- */
VMMR3DECL(void) PDMR3AsyncCompletionEpClose(PPDMASYNCCOMPLETIONENDPOINT pEndpoint);
-
-/**
- * Creates a read task on the given endpoint.
- *
- * @returns VBox status code.
- * @param pEndpoint The file endpoint to read from.
- * @param off Where to start reading from.
- * @param paSegments Scatter gather list to store the data in.
- * @param cSegments Number of segments in the list.
- * @param cbRead The overall number of bytes to read.
- * @param pvUser Opaque user data returned in the completion callback
- * upon completion of the task.
- * @param ppTask Where to store the task handle on success.
- */
VMMR3DECL(int) PDMR3AsyncCompletionEpRead(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
PCRTSGSEG paSegments, unsigned cSegments,
size_t cbRead, void *pvUser,
PPPDMASYNCCOMPLETIONTASK ppTask);
-
-/**
- * Creates a write task on the given endpoint.
- *
- * @returns VBox status code.
- * @param pEndpoint The file endpoint to write to.
- * @param off Where to start writing at.
- * @param paSegments Scatter gather list of the data to write.
- * @param cSegments Number of segments in the list.
- * @param cbWrite The overall number of bytes to write.
- * @param pvUser Opaque user data returned in the completion callback
- * upon completion of the task.
- * @param ppTask Where to store the task handle on success.
- */
VMMR3DECL(int) PDMR3AsyncCompletionEpWrite(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
PCRTSGSEG paSegments, unsigned cSegments,
size_t cbWrite, void *pvUser,
PPPDMASYNCCOMPLETIONTASK ppTask);
-
-/**
- * Creates a flush task on the given endpoint.
- *
- * Every read and write task initiated before the flush task is
- * finished upon completion of this task.
- *
- * @returns VBox status code.
- * @param pEndpoint The file endpoint to flush.
- * @param pvUser Opaque user data returned in the completion callback
- * upon completion of the task.
- * @param ppTask Where to store the task handle on success.
- */
-VMMR3DECL(int) PDMR3AsyncCompletionEpFlush(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
- void *pvUser,
- PPPDMASYNCCOMPLETIONTASK ppTask);
-
-/**
- * Queries the size of an endpoint.
- * Not that some endpoints may not support this and will return an error
- * (sockets for example).
- *
- * @returns VBox status code.
- * @retval VERR_NOT_SUPPORTED if the endpoint does not support this operation.
- * @param pEndpoint The file endpoint.
- * @param pcbSize Where to store the size of the endpoint.
- */
-VMMR3DECL(int) PDMR3AsyncCompletionEpGetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
- uint64_t *pcbSize);
-
-/**
- * Sets the size of an endpoint.
- * Not that some endpoints may not support this and will return an error
- * (sockets for example).
- *
- * @returns VBox status code.
- * @retval VERR_NOT_SUPPORTED if the endpoint does not support this operation.
- * @param pEndpoint The file endpoint.
- * @param cbSize The size to set.
- *
- * @note PDMR3AsyncCompletionEpFlush should be called before this operation is executed.
- */
-VMMR3DECL(int) PDMR3AsyncCompletionEpSetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
- uint64_t cbSize);
-
-/**
- * Assigns or removes a bandwidth control manager to/from the endpoint.
- *
- * @returns VBox status code.
- * @param pEndpoint The endpoint.
- * @param pcszBwMgr The identifer of the new bandwidth manager to assign
- * or NULL to remove the current one.
- */
-VMMR3DECL(int) PDMR3AsyncCompletionEpSetBwMgr(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
- const char *pcszBwMgr);
-
-/**
- * Cancels an async completion task.
- *
- * If you want to use this method, you have to take great create to make sure
- * you will never attempt cancel a task which has been completed. Since there is
- * no reference counting or anything on the task it self, you have to serialize
- * the cancelation and completion paths such that the aren't racing one another.
- *
- * @returns VBox status code
- * @param pTask The Task to cancel.
- */
+VMMR3DECL(int) PDMR3AsyncCompletionEpFlush(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, void *pvUser, PPPDMASYNCCOMPLETIONTASK ppTask);
+VMMR3DECL(int) PDMR3AsyncCompletionEpGetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint64_t *pcbSize);
+VMMR3DECL(int) PDMR3AsyncCompletionEpSetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint64_t cbSize);
+VMMR3DECL(int) PDMR3AsyncCompletionEpSetBwMgr(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, const char *pszBwMgr);
VMMR3DECL(int) PDMR3AsyncCompletionTaskCancel(PPDMASYNCCOMPLETIONTASK pTask);
-
-/**
- * Changes the limit of a bandwidth manager for file endpoints to the given value.
- *
- * @returns VBox status code.
- * @param pVM Pointer to the shared VM structure.
- * @param pcszBwMgr The identifer of the bandwidth manager to change.
- * @param cbMaxNew The new maximum for the bandwidth manager in bytes/sec.
- */
-VMMR3DECL(int) PDMR3AsyncCompletionBwMgrSetMaxForFile(PVM pVM, const char *pcszBwMgr, uint32_t cbMaxNew);
+VMMR3DECL(int) PDMR3AsyncCompletionBwMgrSetMaxForFile(PUVM pUVM, const char *pszBwMgr, uint32_t cbMaxNew);
/** @} */
diff --git a/include/VBox/vmm/pdmblkcache.h b/include/VBox/vmm/pdmblkcache.h
index fc92bc4f..14d85f67 100644
--- a/include/VBox/vmm/pdmblkcache.h
+++ b/include/VBox/vmm/pdmblkcache.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2007-2010 Oracle Corporation
+ * Copyright (C) 2007-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/include/VBox/vmm/pdmcardreaderinfs.h b/include/VBox/vmm/pdmcardreaderinfs.h
index e1ad5a2d..7cb3ca75 100644
--- a/include/VBox/vmm/pdmcardreaderinfs.h
+++ b/include/VBox/vmm/pdmcardreaderinfs.h
@@ -1,5 +1,4 @@
/* $Id: pdmcardreaderinfs.h $ */
-
/** @file
* cardreaderinfs - interface between Usb Card Reader device and its driver.
*/
@@ -26,11 +25,10 @@
*/
#ifndef ___VBox_vmm_pdmcardreaderinfs_h
-# define ___VBox_vmm_pdmcardreaderinfs_h
+#define ___VBox_vmm_pdmcardreaderinfs_h
#include <VBox/types.h>
-#define PDMICARDREADERDOWN_IID "78d65378-889c-4418-8bc2-7a89a5af2817"
typedef struct PDMICARDREADER_IO_REQUEST
{
@@ -49,41 +47,41 @@ typedef struct PDMICARDREADER_READERSTATE
} PDMICARDREADER_READERSTATE;
+#define PDMICARDREADERDOWN_IID "78d65378-889c-4418-8bc2-7a89a5af2817"
typedef struct PDMICARDREADERDOWN PDMICARDREADERDOWN;
typedef PDMICARDREADERDOWN *PPDMICARDREADERDOWN;
struct PDMICARDREADERDOWN
{
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownEstablishContext,(PPDMICARDREADERDOWN pInterface));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownConnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, const char *pszCardReaderName,
- uint32_t u32ShareMode, uint32_t u32PreferredProtocols));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownDisconnect,(PPDMICARDREADERDOWN pInterface, void *pvUser,
- uint32_t u32Disposition));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownStatus,(PPDMICARDREADERDOWN pInterface, void *pvUser,
- uint32_t cchReaderName, uint32_t cbAtrLen));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownReleaseContext,(PPDMICARDREADERDOWN pInterface, void *pvUser));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownGetStatusChange,(PPDMICARDREADERDOWN pInterface, void *pvUser,
- uint32_t u32Timeout, PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownBeginTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownEndTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser,
- uint32_t u32Disposition));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownTransmit,(PPDMICARDREADERDOWN pInterface, void *pvUser,
- const PDMICARDREADER_IO_REQUEST *pioSendRequest,
- const uint8_t *pu8SendBuffer, uint32_t cbSendBuffer, uint32_t cbRecvBuffer));
+ DECLR3CALLBACKMEMBER(int, pfnEstablishContext,(PPDMICARDREADERDOWN pInterface));
+ DECLR3CALLBACKMEMBER(int, pfnConnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, const char *pszCardReaderName,
+ uint32_t u32ShareMode, uint32_t u32PreferredProtocols));
+ DECLR3CALLBACKMEMBER(int, pfnDisconnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t u32Disposition));
+ DECLR3CALLBACKMEMBER(int, pfnStatus,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t cchReaderName, uint32_t cbAtrLen));
+ DECLR3CALLBACKMEMBER(int, pfnReleaseContext,(PPDMICARDREADERDOWN pInterface, void *pvUser));
+ DECLR3CALLBACKMEMBER(int, pfnGetStatusChange,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t u32Timeout,
+ PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats));
+ DECLR3CALLBACKMEMBER(int, pfnBeginTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser));
+ DECLR3CALLBACKMEMBER(int, pfnEndTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t u32Disposition));
+ DECLR3CALLBACKMEMBER(int, pfnTransmit,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ const PDMICARDREADER_IO_REQUEST *pioSendRequest,
+ const uint8_t *pu8SendBuffer, uint32_t cbSendBuffer, uint32_t cbRecvBuffer));
/**
* Up level provides pvInBuffer of cbInBuffer bytes to call SCardControl, also it specify bytes it expects to receive
- * @note: device/driver implementation should copy buffers before execution in async mode, and both layers shouldn't
- * expect permanent storage for the buffer.
+ * @note Device/driver implementation should copy buffers before execution in
+ * async mode, and both layers shouldn't expect permanent storage for the
+ * buffer.
*/
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownControl,(PPDMICARDREADERDOWN pInterface, void *pvUser,
- uint32_t u32ControlCode, const void *pvInBuffer, uint32_t cbInBuffer, uint32_t cbOutBuffer));
+ DECLR3CALLBACKMEMBER(int, pfnControl,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ uint32_t u32ControlCode, const void *pvInBuffer,
+ uint32_t cbInBuffer, uint32_t cbOutBuffer));
/**
* This function ask driver to provide attribute (dwAttribId) and provide limit (cbAttrib) of buffer size for attribute value,
* Callback UpGetAttrib returns buffer containing the value and altered size of the buffer.
*/
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownGetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser,
- uint32_t u32AttribId, uint32_t cbAttrib));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderDownSetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser,
- uint32_t u32AttribId, const void *pvAttrib, uint32_t cbAttrib));
+ DECLR3CALLBACKMEMBER(int, pfnGetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ uint32_t u32AttribId, uint32_t cbAttrib));
+ DECLR3CALLBACKMEMBER(int, pfnSetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ uint32_t u32AttribId, const void *pvAttrib, uint32_t cbAttrib));
};
#define PDMICARDREADERUP_IID "c0d7498e-0635-48ca-aab1-b11b6a55cf7d"
@@ -91,26 +89,27 @@ typedef struct PDMICARDREADERUP PDMICARDREADERUP;
typedef PDMICARDREADERUP *PPDMICARDREADERUP;
struct PDMICARDREADERUP
{
- DECLR3CALLBACKMEMBER(int, pfnCardReaderUpEstablishContext,(PPDMICARDREADERUP pInterface, int32_t lSCardRc));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderUpStatus,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
- char *pszReaderName, uint32_t cchReaderName, uint32_t u32CardState,
- uint32_t u32Protocol, uint8_t *pu8Atr, uint32_t cbAtr));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderUpConnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
- uint32_t u32ActiveProtocol));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderUpDisconnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderUpSetStatusChange,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
- PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderUpBeginTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderUpEndTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc));
+ DECLR3CALLBACKMEMBER(int, pfnEstablishContext,(PPDMICARDREADERUP pInterface, int32_t lSCardRc));
+ DECLR3CALLBACKMEMBER(int, pfnStatus,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ char *pszReaderName, uint32_t cchReaderName, uint32_t u32CardState,
+ uint32_t u32Protocol, uint8_t *pu8Atr, uint32_t cbAtr));
+ DECLR3CALLBACKMEMBER(int, pfnConnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ uint32_t u32ActiveProtocol));
+ DECLR3CALLBACKMEMBER(int, pfnDisconnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc));
+ DECLR3CALLBACKMEMBER(int, pfnSetStatusChange,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats));
+ DECLR3CALLBACKMEMBER(int, pfnBeginTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc));
+ DECLR3CALLBACKMEMBER(int, pfnEndTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc));
/* Note: pioRecvPci stack variable */
- DECLR3CALLBACKMEMBER(int, pfnCardReaderUpTransmit,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
- const PDMICARDREADER_IO_REQUEST *pioRecvPci, uint8_t *pu8RecvBuffer, uint32_t cbRecvBuffer));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderUpControl,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
- uint32_t u32ControlCode, void *pvOutBuffer, uint32_t cbOutBuffer));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderUpGetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
- uint32_t u32AttribId, void *pvAttrib, uint32_t cbAttrib));
- DECLR3CALLBACKMEMBER(int, pfnCardReaderUpSetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
- uint32_t u32AttribId));
+ DECLR3CALLBACKMEMBER(int, pfnTransmit,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ const PDMICARDREADER_IO_REQUEST *pioRecvPci,
+ uint8_t *pu8RecvBuffer, uint32_t cbRecvBuffer));
+ DECLR3CALLBACKMEMBER(int, pfnControl,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ uint32_t u32ControlCode, void *pvOutBuffer, uint32_t cbOutBuffer));
+ DECLR3CALLBACKMEMBER(int, pfnGetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ uint32_t u32AttribId, void *pvAttrib, uint32_t cbAttrib));
+ DECLR3CALLBACKMEMBER(int, pfnSetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, uint32_t u32AttribId));
};
#endif
+
diff --git a/include/VBox/vmm/pdmcommon.h b/include/VBox/vmm/pdmcommon.h
index c4e1be26..d62210a0 100644
--- a/include/VBox/vmm/pdmcommon.h
+++ b/include/VBox/vmm/pdmcommon.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -109,7 +109,7 @@ typedef FNPDMUSBASYNCNOTIFY *PFNPDMUSBASYNCNOTIFY;
* @returns true if done, false if more work to be done.
*
* @param pDevIns The device instance.
- *
+ * @remarks The caller will enter the device critical section.
* @thread EMT(0)
*/
typedef DECLCALLBACK(bool) FNPDMDEVASYNCNOTIFY(PPDMDEVINS pDevIns);
diff --git a/include/VBox/vmm/pdmcritsect.h b/include/VBox/vmm/pdmcritsect.h
index 02d7924d..0895b52b 100644
--- a/include/VBox/vmm/pdmcritsect.h
+++ b/include/VBox/vmm/pdmcritsect.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -51,26 +51,31 @@ typedef union PDMCRITSECT
#endif
} PDMCRITSECT;
+VMMR3_INT_DECL(int) PDMR3CritSectBothTerm(PVM pVM);
+VMMR3_INT_DECL(void) PDMR3CritSectLeaveAll(PVM pVM);
+VMM_INT_DECL(void) PDMCritSectBothFF(PVMCPU pVCpu);
+
+
+VMMR3DECL(uint32_t) PDMR3CritSectCountOwned(PVM pVM, char *pszNames, size_t cbNames);
+
VMMR3DECL(int) PDMR3CritSectInit(PVM pVM, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...);
+VMMR3DECL(int) PDMR3CritSectEnterEx(PPDMCRITSECT pCritSect, bool fCallRing3);
+VMMR3DECL(bool) PDMR3CritSectYield(PPDMCRITSECT pCritSect);
+VMMR3DECL(const char *) PDMR3CritSectName(PCPDMCRITSECT pCritSect);
+VMMR3DECL(int) PDMR3CritSectScheduleExitEvent(PPDMCRITSECT pCritSect, RTSEMEVENT EventToSignal);
+VMMR3DECL(int) PDMR3CritSectDelete(PPDMCRITSECT pCritSect);
+
VMMDECL(int) PDMCritSectEnter(PPDMCRITSECT pCritSect, int rcBusy);
VMMDECL(int) PDMCritSectEnterDebug(PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL);
VMMDECL(int) PDMCritSectTryEnter(PPDMCRITSECT pCritSect);
VMMDECL(int) PDMCritSectTryEnterDebug(PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL);
-VMMR3DECL(int) PDMR3CritSectEnterEx(PPDMCRITSECT pCritSect, bool fCallRing3);
VMMDECL(int) PDMCritSectLeave(PPDMCRITSECT pCritSect);
+
VMMDECL(bool) PDMCritSectIsOwner(PCPDMCRITSECT pCritSect);
VMMDECL(bool) PDMCritSectIsOwnerEx(PCPDMCRITSECT pCritSect, PVMCPU pVCpu);
VMMDECL(bool) PDMCritSectIsInitialized(PCPDMCRITSECT pCritSect);
VMMDECL(bool) PDMCritSectHasWaiters(PCPDMCRITSECT pCritSect);
VMMDECL(uint32_t) PDMCritSectGetRecursion(PCPDMCRITSECT pCritSect);
-VMMR3DECL(bool) PDMR3CritSectYield(PPDMCRITSECT pCritSect);
-VMMR3DECL(const char *) PDMR3CritSectName(PCPDMCRITSECT pCritSect);
-VMMR3DECL(int) PDMR3CritSectScheduleExitEvent(PPDMCRITSECT pCritSect, RTSEMEVENT EventToSignal);
-VMMR3DECL(int) PDMR3CritSectDelete(PPDMCRITSECT pCritSect);
-VMMDECL(int) PDMR3CritSectTerm(PVM pVM);
-VMMDECL(void) PDMCritSectFF(PVMCPU pVCpu);
-VMMR3DECL(uint32_t) PDMR3CritSectCountOwned(PVM pVM, char *pszNames, size_t cbNames);
-VMMR3DECL(void) PDMR3CritSectLeaveAll(PVM pVM);
VMMR3DECL(PPDMCRITSECT) PDMR3CritSectGetNop(PVM pVM);
VMMR3DECL(R0PTRTYPE(PPDMCRITSECT)) PDMR3CritSectGetNopR0(PVM pVM);
diff --git a/include/VBox/vmm/pdmcritsectrw.h b/include/VBox/vmm/pdmcritsectrw.h
new file mode 100644
index 00000000..9c922017
--- /dev/null
+++ b/include/VBox/vmm/pdmcritsectrw.h
@@ -0,0 +1,97 @@
+/** @file
+ * PDM - Pluggable Device Manager, Read/Write Critical Section.
+ */
+
+/*
+ * Copyright (C) 2006-2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_vmm_pdmcritsectrw_h
+#define ___VBox_vmm_pdmcritsectrw_h
+
+#include <VBox/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_critsectrw The PDM Read/Write Critical Section API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/**
+ * A PDM read/write critical section.
+ * Initialize using PDMDRVHLP::pfnCritSectRwInit().
+ */
+typedef union PDMCRITSECTRW
+{
+ /** Padding. */
+ uint8_t padding[HC_ARCH_BITS == 32 ? 0xc0 : 0x100];
+#ifdef PDMCRITSECTRWINT_DECLARED
+ /** The internal structure (not normally visible). */
+ struct PDMCRITSECTRWINT s;
+#endif
+} PDMCRITSECTRW;
+
+VMMR3DECL(int) PDMR3CritSectRwInit(PVM pVM, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...);
+VMMR3DECL(int) PDMR3CritSectRwDelete(PPDMCRITSECTRW pCritSect);
+VMMR3DECL(const char *) PDMR3CritSectRwName(PCPDMCRITSECTRW pCritSect);
+VMMR3DECL(int) PDMR3CritSectRwEnterSharedEx(PPDMCRITSECTRW pThis, bool fCallRing3);
+VMMR3DECL(int) PDMR3CritSectRwEnterExclEx(PPDMCRITSECTRW pThis, bool fCallRing3);
+
+VMMDECL(int) PDMCritSectRwEnterShared(PPDMCRITSECTRW pCritSect, int rcBusy);
+VMMDECL(int) PDMCritSectRwEnterSharedDebug(PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+VMMDECL(int) PDMCritSectRwTryEnterShared(PPDMCRITSECTRW pCritSect);
+VMMDECL(int) PDMCritSectRwTryEnterSharedDebug(PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+VMMDECL(int) PDMCritSectRwLeaveShared(PPDMCRITSECTRW pCritSect);
+VMMDECL(int) PDMCritSectRwEnterExcl(PPDMCRITSECTRW pCritSect, int rcBusy);
+VMMDECL(int) PDMCritSectRwEnterExclDebug(PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+VMMDECL(int) PDMCritSectRwTryEnterExcl(PPDMCRITSECTRW pCritSect);
+VMMDECL(int) PDMCritSectRwTryEnterExclDebug(PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+VMMDECL(int) PDMCritSectRwLeaveExcl(PPDMCRITSECTRW pCritSect);
+
+VMMDECL(bool) PDMCritSectRwIsWriteOwner(PPDMCRITSECTRW pCritSect);
+VMMDECL(bool) PDMCritSectRwIsReadOwner(PPDMCRITSECTRW pCritSect, bool fWannaHear);
+VMMDECL(uint32_t) PDMCritSectRwGetWriteRecursion(PPDMCRITSECTRW pCritSect);
+VMMDECL(uint32_t) PDMCritSectRwGetWriterReadRecursion(PPDMCRITSECTRW pCritSect);
+VMMDECL(uint32_t) PDMCritSectRwGetReadCount(PPDMCRITSECTRW pCritSect);
+VMMDECL(bool) PDMCritSectRwIsInitialized(PCPDMCRITSECTRW pCritSect);
+
+/* Lock strict build: Remap the three enter calls to the debug versions. */
+#ifdef VBOX_STRICT
+# ifdef ___iprt_asm_h
+# define PDMCritSectRwEnterExcl(pCritSect, rcBusy) PDMCritSectRwEnterExclDebug(pCritSect, rcBusy, (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define PDMCritSectRwTryEnterExcl(pCritSect) PDMCritSectRwTryEnterExclDebug(pCritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define PDMCritSectRwEnterShared(pCritSect, rcBusy) PDMCritSectRwEnterSharedDebug(pCritSect, rcBusy, (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define PDMCritSectRwTryEnterShared(pCritSect) PDMCritSectRwTryEnterSharedDebug(pCritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# else
+# define PDMCritSectRwEnterExcl(pCritSect, rcBusy) PDMCritSectRwEnterExclDebug(pCritSect, rcBusy, 0, RT_SRC_POS)
+# define PDMCritSectRwTryEnterExcl(pCritSect) PDMCritSectRwTryEnterExclDebug(pCritSect, 0, RT_SRC_POS)
+# define PDMCritSectRwEnterShared(pCritSect, rcBusy) PDMCritSectRwEnterSharedDebug(pCritSect, rcBusy, 0, RT_SRC_POS)
+# define PDMCritSectRwTryEnterShared(pCritSect) PDMCritSectRwTryEnterSharedDebug(pCritSect, 0, RT_SRC_POS)
+# endif
+#endif
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/pdmdev.h b/include/VBox/vmm/pdmdev.h
index 892ed590..7a964b74 100644
--- a/include/VBox/vmm/pdmdev.h
+++ b/include/VBox/vmm/pdmdev.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -39,6 +39,7 @@
#include <VBox/vmm/dbgf.h>
#include <VBox/err.h>
#include <VBox/pci.h>
+#include <VBox/sup.h>
#include <iprt/stdarg.h>
@@ -108,30 +109,6 @@ typedef DECLCALLBACK(void) FNPDMDEVRELOCATE(PPDMDEVINS pDevIns, RTGCINTPTR offDe
typedef FNPDMDEVRELOCATE *PFNPDMDEVRELOCATE;
/**
- * Device I/O Control interface.
- *
- * This is used by external components, such as the COM interface, to
- * communicate with devices using a class wide interface or a device
- * specific interface.
- *
- * @returns VBox status code.
- * @param pDevIns Pointer to the device instance.
- * @param uFunction Function to perform.
- * @param pvIn Pointer to input data.
- * @param cbIn Size of input data.
- * @param pvOut Pointer to output data.
- * @param cbOut Size of output data.
- * @param pcbOut Where to store the actual size of the output data.
- *
- * @remarks Not used.
- */
-typedef DECLCALLBACK(int) FNPDMDEVIOCTL(PPDMDEVINS pDevIns, uint32_t uFunction,
- void *pvIn, uint32_t cbIn,
- void *pvOut, uint32_t cbOut, PRTUINT pcbOut);
-/** Pointer to a FNPDMDEVIOCTL() function. */
-typedef FNPDMDEVIOCTL *PFNPDMDEVIOCTL;
-
-/**
* Power On notification.
*
* @returns VBox status.
@@ -185,7 +162,7 @@ typedef FNPDMDEVRESUME *PFNPDMDEVRESUME;
*
* This is only called when the VMR3PowerOff call is made on a running VM. This
* means that there is no notification if the VM was suspended before being
- * powered of. There will also be no callback when hot plugging devices.
+ * powered off. There will also be no callback when hot plugging devices.
*
* @param pDevIns The device instance data.
* @thread EMT(0)
@@ -264,6 +241,21 @@ typedef DECLCALLBACK(int) FNPDMDEVINITCOMPLETE(PPDMDEVINS pDevIns);
typedef FNPDMDEVINITCOMPLETE *PFNPDMDEVINITCOMPLETE;
+/**
+ * The context of a pfnMemSetup call.
+ */
+typedef enum PDMDEVMEMSETUPCTX
+{
+ /** Invalid zero value. */
+ PDMDEVMEMSETUPCTX_INVALID = 0,
+ /** After construction. */
+ PDMDEVMEMSETUPCTX_AFTER_CONSTRUCTION,
+ /** After reset. */
+ PDMDEVMEMSETUPCTX_AFTER_RESET,
+ /** Type size hack. */
+ PDMDEVMEMSETUPCTX_32BIT_HACK = 0x7fffffff
+} PDMDEVMEMSETUPCTX;
+
/**
* PDM Device Registration Structure.
@@ -304,9 +296,16 @@ typedef struct PDMDEVREG
/** Relocation command - optional.
* Critical section NOT entered. */
PFNPDMDEVRELOCATE pfnRelocate;
- /** I/O Control interface - optional.
- * Not used. */
- PFNPDMDEVIOCTL pfnIOCtl;
+
+ /**
+ * Memory setup callback.
+ *
+ * @param pDevIns The device instance data.
+ * @param enmCtx Indicates the context of the call.
+ * @remarks The critical section is entered prior to calling this method.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnMemSetup, (PPDMDEVINS pDevIns, PDMDEVMEMSETUPCTX enmCtx));
+
/** Power on notification - optional.
* Critical section is entered. */
PFNPDMDEVPOWERON pfnPowerOn;
@@ -345,7 +344,7 @@ typedef PDMDEVREG *PPDMDEVREG;
typedef PDMDEVREG const *PCPDMDEVREG;
/** Current DEVREG version number. */
-#define PDM_DEVREG_VERSION PDM_VERSION_MAKE(0xffff, 1, 0)
+#define PDM_DEVREG_VERSION PDM_VERSION_MAKE(0xffff, 2, 0)
/** PDM Device Flags.
* @{ */
@@ -503,6 +502,7 @@ typedef struct PDMPCIBUSREG
* @param pszName Pointer to device name (permanent, readonly). For debugging, not unique.
* @param iDev The device number ((dev << 3) | function) the device should have on the bus.
* If negative, the pci bus device will assign one.
+ * @remarks Caller enters the PDM critical section.
*/
DECLR3CALLBACKMEMBER(int, pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev));
@@ -513,6 +513,7 @@ typedef struct PDMPCIBUSREG
* @param pDevIns Device instance of the PCI Bus.
* @param pPciDev The PCI device structure.
* @param pMsiReg MSI registration structure
+ * @remarks Caller enters the PDM critical section.
*/
DECLR3CALLBACKMEMBER(int, pfnRegisterMsiR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg));
@@ -526,6 +527,7 @@ typedef struct PDMPCIBUSREG
* @param cbRegion Size of the region.
* @param iType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
* @param pfnCallback Callback for doing the mapping.
+ * @remarks Caller enters the PDM critical section.
*/
DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
@@ -542,6 +544,7 @@ typedef struct PDMPCIBUSREG
* @param pfnWriteOld Pointer to function pointer which will receive the old (default)
* PCI config write function. This way, user can decide when (and if)
* to call default PCI config write function. Can be NULL.
+ * @remarks Caller enters the PDM critical section.
* @thread EMT
*/
DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
@@ -555,36 +558,18 @@ typedef struct PDMPCIBUSREG
* @param iIrq IRQ number to set.
* @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
* @param uTagSrc The IRQ tag and source (for tracing).
+ * @remarks Caller enters the PDM critical section.
*/
DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
/**
- * Saves a state of the PCI device.
- *
- * @returns VBox status code.
- * @param pDevIns Device instance of the PCI Bus.
- * @param pPciDev Pointer to PCI device.
- * @param pSSMHandle The handle to save the state to.
- */
- DECLR3CALLBACKMEMBER(int, pfnSaveExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
-
- /**
- * Loads a saved PCI device state.
- *
- * @returns VBox status code.
- * @param pDevIns Device instance of the PCI Bus.
- * @param pPciDev Pointer to PCI device.
- * @param pSSMHandle The handle to the saved state.
- */
- DECLR3CALLBACKMEMBER(int, pfnLoadExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
-
- /**
* Called to perform the job of the bios.
* This is only called for the first PCI Bus - it is expected to
* service all the PCI buses.
*
* @returns VBox status.
* @param pDevIns Device instance of the first bus.
+ * @remarks Caller enters the PDM critical section.
*/
DECLR3CALLBACKMEMBER(int, pfnFakePCIBIOSR3,(PPDMDEVINS pDevIns));
@@ -599,7 +584,7 @@ typedef struct PDMPCIBUSREG
typedef PDMPCIBUSREG *PPDMPCIBUSREG;
/** Current PDMPCIBUSREG version number. */
-#define PDM_PCIBUSREG_VERSION PDM_VERSION_MAKE(0xfffe, 3, 0)
+#define PDM_PCIBUSREG_VERSION PDM_VERSION_MAKE(0xfffe, 4, 0)
/**
* PCI Bus RC helpers.
@@ -858,6 +843,7 @@ typedef struct PDMPICREG
* @param iIrq IRQ number to set.
* @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
* @param uTagSrc The IRQ tag and source (for tracing).
+ * @remarks Caller enters the PDM critical section.
*/
DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
@@ -867,6 +853,7 @@ typedef struct PDMPICREG
* @returns Pending interrupt number.
* @param pDevIns Device instance of the PIC.
* @param puTagSrc Where to return the IRQ tag and source.
+ * @remarks Caller enters the PDM critical section.
*/
DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
@@ -1077,40 +1064,52 @@ typedef struct PDMAPICREG
*
* @returns Pending interrupt number.
* @param pDevIns Device instance of the APIC.
+ * @param idCpu The VCPU Id.
* @param puTagSrc Where to return the tag source.
+ * @remarks Caller enters the PDM critical section
*/
- DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
+ DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t *puTagSrc));
/**
* Check if the APIC has a pending interrupt/if a TPR change would active one
*
* @returns Pending interrupt yes/no
* @param pDevIns Device instance of the APIC.
+ * @param idCpu The VCPU Id.
+ * @param pu8PendingIrq Where to store the highest priority pending IRQ
+ * (optional, can be NULL).
+ * @remarks Unlike the other callbacks, the PDM lock may not always be entered
+ * prior to calling this method.
*/
- DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns));
+ DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t *pu8PendingIrq));
/**
* Set the APIC base.
*
* @param pDevIns Device instance of the APIC.
+ * @param idCpu The VCPU Id.
* @param u64Base The new base.
+ * @remarks Caller enters the PDM critical section.
*/
- DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, uint64_t u64Base));
+ DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint64_t u64Base));
/**
* Get the APIC base.
*
* @returns Current base.
* @param pDevIns Device instance of the APIC.
+ * @param idCpu The VCPU Id.
+ * @remarks Caller enters the PDM critical section.
*/
- DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns));
+ DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns, VMCPUID idCpu));
/**
* Set the TPR (task priority register).
*
* @param pDevIns Device instance of the APIC.
- * @param idCpu VCPU id
+ * @param idCpu The VCPU id.
* @param u8TPR The new TPR.
+ * @remarks Caller enters the PDM critical section.
*/
DECLR3CALLBACKMEMBER(void, pfnSetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t u8TPR));
@@ -1120,6 +1119,7 @@ typedef struct PDMAPICREG
* @returns The current TPR.
* @param pDevIns Device instance of the APIC.
* @param idCpu VCPU id
+ * @remarks Caller enters the PDM critical section.
*/
DECLR3CALLBACKMEMBER(uint8_t, pfnGetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu));
@@ -1169,6 +1169,7 @@ typedef struct PDMAPICREG
* @param u8Polarity See APIC implementation.
* @param u8TriggerMode See APIC implementation.
* @param uTagSrc The IRQ tag and source (for tracing).
+ * @remarks Caller enters the PDM critical section
*/
DECLR3CALLBACKMEMBER(int, pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
@@ -1184,6 +1185,7 @@ typedef struct PDMAPICREG
* @param u8Pin Local pin number (0 or 1 for current CPUs).
* @param u8Level The level.
* @param uTagSrc The IRQ tag and source (for tracing).
+ * @remarks Caller enters the PDM critical section
*/
DECLR3CALLBACKMEMBER(int, pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
@@ -1572,6 +1574,7 @@ typedef struct PDMIOAPICREG
* @param iIrq IRQ number to set.
* @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
* @param uTagSrc The IRQ tag and source (for tracing).
+ * @remarks Caller enters the PDM critical section
*/
DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
@@ -1588,6 +1591,7 @@ typedef struct PDMIOAPICREG
* @param GCPhys Request address.
* @param uValue Request value.
* @param uTagSrc The IRQ tag and source (for tracing).
+ * @remarks Caller enters the PDM critical section
*/
DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
@@ -2017,11 +2021,12 @@ typedef R3PTRTYPE(const PDMPCIRAWHLPR3 *) PCPDMPCIRAWHLPR3;
* DMA Transfer Handler.
*
* @returns Number of bytes transferred.
- * @param pDevIns Device instance of the DMA.
- * @param pvUser User pointer.
- * @param uChannel Channel number.
- * @param off DMA position.
- * @param cb Block size.
+ * @param pDevIns Device instance of the DMA.
+ * @param pvUser User pointer.
+ * @param uChannel Channel number.
+ * @param off DMA position.
+ * @param cb Block size.
+ * @remarks The device lock is not taken, however, the DMA device lock is held.
*/
typedef DECLCALLBACK(uint32_t) FNDMATRANSFERHANDLER(PPDMDEVINS pDevIns, void *pvUser, unsigned uChannel, uint32_t off, uint32_t cb);
/** Pointer to a FNDMATRANSFERHANDLER(). */
@@ -2040,6 +2045,7 @@ typedef struct PDMDMAREG
*
* @returns A more work indiciator. I.e. 'true' if there is more to be done, and 'false' if all is done.
* @param pDevIns Device instance of the DMAC.
+ * @remarks No locks held, called on EMT(0) as a form of serialization.
*/
DECLR3CALLBACKMEMBER(bool, pfnRun,(PPDMDEVINS pDevIns));
@@ -2050,6 +2056,7 @@ typedef struct PDMDMAREG
* @param uChannel Channel number.
* @param pfnTransferHandler Device specific transfer function.
* @param pvUSer User pointer to be passed to the callback.
+ * @remarks No locks held, called on an EMT.
*/
DECLR3CALLBACKMEMBER(void, pfnRegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
@@ -2061,6 +2068,7 @@ typedef struct PDMDMAREG
* @param pvBuffer Pointer to target buffer.
* @param off DMA position.
* @param cbBlock Block size.
+ * @remarks No locks held, called on an EMT.
*/
DECLR3CALLBACKMEMBER(uint32_t, pfnReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock));
@@ -2072,6 +2080,7 @@ typedef struct PDMDMAREG
* @param pvBuffer Memory to write.
* @param off DMA position.
* @param cbBlock Block size.
+ * @remarks No locks held, called on an EMT.
*/
DECLR3CALLBACKMEMBER(uint32_t, pfnWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock));
@@ -2081,6 +2090,7 @@ typedef struct PDMDMAREG
* @param pDevIns Device instance of the DMAC.
* @param uChannel Channel number.
* @param uLevel Level of the line.
+ * @remarks No locks held, called on an EMT.
*/
DECLR3CALLBACKMEMBER(void, pfnSetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
@@ -2090,6 +2100,7 @@ typedef struct PDMDMAREG
* @returns Channel mode.
* @param pDevIns Device instance of the DMAC.
* @param uChannel Channel number.
+ * @remarks No locks held, called on an EMT.
*/
DECLR3CALLBACKMEMBER(uint8_t, pfnGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
@@ -2140,6 +2151,7 @@ typedef struct PDMRTCREG
* @param pDevIns Device instance of the RTC.
* @param iReg The CMOS register index.
* @param u8Value The CMOS register value.
+ * @remarks Caller enters the device critical section.
*/
DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
@@ -2150,6 +2162,7 @@ typedef struct PDMRTCREG
* @param pDevIns Device instance of the RTC.
* @param iReg The CMOS register index.
* @param pu8Value Where to store the CMOS register value.
+ * @remarks Caller enters the device critical section.
*/
DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
@@ -2160,7 +2173,7 @@ typedef PDMRTCREG *PPDMRTCREG;
typedef const PDMRTCREG *PCPDMRTCREG;
/** Current PDMRTCREG version number. */
-#define PDM_RTCREG_VERSION PDM_VERSION_MAKE(0xffe9, 1, 0)
+#define PDM_RTCREG_VERSION PDM_VERSION_MAKE(0xffe9, 2, 0)
/**
@@ -2211,6 +2224,8 @@ typedef struct PDMDEVHLPR3
* @param pfnOutStr Pointer to function which is gonna handle string OUT operations.
* @param pfnInStr Pointer to function which is gonna handle string IN operations.
* @param pszDesc Pointer to description string. This must not be freed.
+ * @remarks Caller enters the device critical section prior to invoking the
+ * registered callback methods.
*/
DECLR3CALLBACKMEMBER(int, pfnIOPortRegister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTHCPTR pvUser,
PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
@@ -2235,6 +2250,8 @@ typedef struct PDMDEVHLPR3
* @param pszOutStr Name of the RC function which is gonna handle string OUT operations.
* @param pszInStr Name of the RC function which is gonna handle string IN operations.
* @param pszDesc Pointer to description string. This must not be freed.
+ * @remarks Caller enters the device critical section prior to invoking the
+ * registered callback methods.
*/
DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterRC,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTRCPTR pvUser,
const char *pszOut, const char *pszIn,
@@ -2256,6 +2273,8 @@ typedef struct PDMDEVHLPR3
* @param pszOutStr Name of the R0 function which is gonna handle string OUT operations.
* @param pszInStr Name of the R0 function which is gonna handle string IN operations.
* @param pszDesc Pointer to description string. This must not be freed.
+ * @remarks Caller enters the device critical section prior to invoking the
+ * registered callback methods.
*/
DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterR0,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTR0PTR pvUser,
const char *pszOut, const char *pszIn,
@@ -2290,6 +2309,8 @@ typedef struct PDMDEVHLPR3
* @param pfnFill Pointer to function which is gonna handle Fill/memset operations. (optional)
* @param fFlags Flags, IOMMMIO_FLAGS_XXX.
* @param pszDesc Pointer to description string. This must not be freed.
+ * @remarks Caller enters the device critical section prior to invoking the
+ * registered callback methods.
*/
DECLR3CALLBACKMEMBER(int, pfnMMIORegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTHCPTR pvUser,
PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
@@ -2310,6 +2331,8 @@ typedef struct PDMDEVHLPR3
* @param pszWrite Name of the RC function which is gonna handle Write operations.
* @param pszRead Name of the RC function which is gonna handle Read operations.
* @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional)
+ * @remarks Caller enters the device critical section prior to invoking the
+ * registered callback methods.
*/
DECLR3CALLBACKMEMBER(int, pfnMMIORegisterRC,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTRCPTR pvUser,
const char *pszWrite, const char *pszRead, const char *pszFill));
@@ -2330,6 +2353,8 @@ typedef struct PDMDEVHLPR3
* @param pszRead Name of the RC function which is gonna handle Read operations.
* @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional)
* @param pszDesc Obsolete. NULL is fine.
+ * @remarks Caller enters the device critical section prior to invoking the
+ * registered callback methods.
*/
DECLR3CALLBACKMEMBER(int, pfnMMIORegisterR0,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTR0PTR pvUser,
const char *pszWrite, const char *pszRead, const char *pszFill));
@@ -2512,6 +2537,8 @@ typedef struct PDMDEVHLPR3
* @param pfnLoadPrep Prepare load callback, optional.
* @param pfnLoadExec Execute load callback, optional.
* @param pfnLoadDone Done load callback, optional.
+ * @remarks Caller enters the device critical section prior to invoking the
+ * registered callback methods.
*/
DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
@@ -2530,6 +2557,8 @@ typedef struct PDMDEVHLPR3
* @param pszDesc Pointer to description string which must stay around
* until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
* @param ppTimer Where to store the timer on success.
+ * @remarks Caller enters the device critical section prior to invoking the
+ * callback.
*/
DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
@@ -2797,6 +2826,22 @@ typedef struct PDMDEVHLPR3
DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler));
/**
+ * Registers a set of registers for a device.
+ *
+ * The @a pvUser argument of the getter and setter callbacks will be
+ * @a pDevIns. The register names will be prefixed by the device name followed
+ * immediately by the instance number.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param paRegisters The register descriptors.
+ *
+ * @remarks The device critical section is NOT entered prior to working the
+ * callbacks registered via this helper!
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDBGFRegRegister,(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters));
+
+ /**
* Gets the trace buffer handle.
*
* This is used by the macros found in VBox/vmm/dbgftrace.h and is not
@@ -2861,22 +2906,6 @@ typedef struct PDMDEVHLPR3
STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args));
/**
- * Reads data via bus mastering, if enabled. If no bus mastering is available,
- * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
- *
- * @return IPRT status code.
- */
- DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
-
- /**
- * Writes data via bus mastering, if enabled. If no bus mastering is available,
- * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
- *
- * @return IPRT status code.
- */
- DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
-
- /**
* Registers the device with the default PCI bus.
*
* @returns VBox status code.
@@ -2907,8 +2936,11 @@ typedef struct PDMDEVHLPR3
* @param cbRegion Size of the region.
* @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
* @param pfnCallback Callback for doing the mapping.
+ * @remarks The callback will be invoked holding the PDM lock. The device lock
+ * is NOT take because that is very likely be a lock order violation.
*/
- DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
+ DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion,
+ PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
/**
* Register PCI configuration space read/write callbacks.
@@ -2924,12 +2956,40 @@ typedef struct PDMDEVHLPR3
* @param pfnWriteOld Pointer to function pointer which will receive the old (default)
* PCI config write function. This way, user can decide when (and if)
* to call default PCI config write function. Can be NULL.
+ * @remarks The callbacks will be invoked holding the PDM lock. The device lock
+ * is NOT take because that is very likely be a lock order violation.
* @thread EMT
*/
DECLR3CALLBACKMEMBER(void, pfnPCISetConfigCallbacks,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
/**
+ * Bus master physical memory read.
+ *
+ * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
+ * VERR_EM_MEMORY. The informational status shall NOT be propagated!
+ * @param pDevIns The device instance.
+ * @param GCPhys Physical address start reading from.
+ * @param pvBuf Where to put the read bits.
+ * @param cbRead How many bytes to read.
+ * @thread Any thread, but the call may involve the emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
+
+ /**
+ * Bus master physical memory write.
+ *
+ * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
+ * VERR_EM_MEMORY. The informational status shall NOT be propagated!
+ * @param pDevIns The device instance.
+ * @param GCPhys Physical address to write to.
+ * @param pvBuf What to write.
+ * @param cbWrite How many bytes to write.
+ * @thread Any thread, but the call may involve the emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
+
+ /**
* Set the IRQ for a PCI device.
*
* @param pDevIns The device instance.
@@ -2985,7 +3045,8 @@ typedef struct PDMDEVHLPR3
* @param pszDesc Pointer to a string describing the LUN. This string must remain valid
* for the live of the device instance.
*/
- DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc));
+ DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface,
+ PPDMIBASE *ppBaseInterface, const char *pszDesc));
/**
* Create a queue.
@@ -3002,6 +3063,9 @@ typedef struct PDMDEVHLPR3
* appended automatically.
* @param ppQueue Where to store the queue handle on success.
* @thread The emulation thread.
+ * @remarks The device critical section will NOT be entered before calling the
+ * callback. No locks will be held, but for now it's safe to assume
+ * that only one EMT will do queue callbacks at any one time.
*/
DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue));
@@ -3075,6 +3139,8 @@ typedef struct PDMDEVHLPR3
* @param cbStack See RTThreadCreate.
* @param enmType See RTThreadCreate.
* @param pszName See RTThreadCreate.
+ * @remarks The device critical section will NOT be entered prior to invoking
+ * the function pointers.
*/
DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
@@ -3089,6 +3155,8 @@ typedef struct PDMDEVHLPR3
* @param pDevIns The device instance.
* @param pfnAsyncNotify The callback.
* @thread EMT(0)
+ * @remarks The caller will enter the device critical section prior to invoking
+ * the callback.
*/
DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify));
@@ -3372,6 +3440,25 @@ typedef struct PDMDEVHLPR3
*/
DECLR3CALLBACKMEMBER(int, pfnCallR0,(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg));
+ /**
+ * Gets the reason for the most recent VM suspend.
+ *
+ * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no
+ * suspend has been made or if the pDevIns is invalid.
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the reason for the most recent VM resume.
+ *
+ * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no
+ * resume has been made or if the pDevIns is invalid.
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMDEVINS pDevIns));
+
+
/** Space reserved for future members.
* @{ */
DECLR3CALLBACKMEMBER(void, pfnReserved1,(void));
@@ -3381,9 +3468,9 @@ typedef struct PDMDEVHLPR3
DECLR3CALLBACKMEMBER(void, pfnReserved5,(void));
DECLR3CALLBACKMEMBER(void, pfnReserved6,(void));
DECLR3CALLBACKMEMBER(void, pfnReserved7,(void));
- DECLR3CALLBACKMEMBER(void, pfnReserved8,(void));
- DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));
- DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));
+ /*DECLR3CALLBACKMEMBER(void, pfnReserved8,(void));
+ DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));*/
+ /*DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));*/
/** @} */
@@ -3394,8 +3481,17 @@ typedef struct PDMDEVHLPR3
*
* @{
*/
+
/**
- * Gets the VM handle. Restricted API.
+ * Gets the user mode VM handle. Restricted API.
+ *
+ * @returns User mode VM Handle.
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(PUVM, pfnGetUVM,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the global VM handle. Restricted API.
*
* @returns VM Handle.
* @param pDevIns The device instance.
@@ -3527,6 +3623,16 @@ typedef struct PDMDEVHLPR3
*/
DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
+ /**
+ * Gets the support driver session.
+ *
+ * This is intended for working with the semaphore API.
+ *
+ * @returns Support driver session handle.
+ * @param pDrvIns The driver instance.
+ */
+ DECLR3CALLBACKMEMBER(PSUPDRVSESSION, pfnGetSupDrvSession,(PPDMDEVINS pDevIns));
+
/** @} */
/** Just a safety precaution. (PDM_DEVHLPR3_VERSION) */
@@ -3539,7 +3645,7 @@ typedef R3PTRTYPE(struct PDMDEVHLPR3 *) PPDMDEVHLPR3;
typedef R3PTRTYPE(const struct PDMDEVHLPR3 *) PCPDMDEVHLPR3;
/** Current PDMDEVHLPR3 version number. */
-#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE(0xffe7, 9, 0)
+#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE(0xffe7, 12, 1)
/**
@@ -3551,20 +3657,30 @@ typedef struct PDMDEVHLPRC
uint32_t u32Version;
/**
- * Reads data via bus mastering, if enabled. If no bus mastering is available,
- * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
+ * Bus master physical memory read.
*
- * @return IPRT status code.
+ * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
+ * VERR_EM_MEMORY. The informational status shall NOT be propagated!
+ * @param pDevIns The device instance.
+ * @param GCPhys Physical address start reading from.
+ * @param pvBuf Where to put the read bits.
+ * @param cbRead How many bytes to read.
+ * @thread Any thread, but the call may involve the emulation thread.
*/
- DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
+ DECLRCCALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
/**
- * Writes data via bus mastering, if enabled. If no bus mastering is available,
- * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
+ * Bus master physical memory write.
*
- * @return IPRT status code.
+ * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
+ * VERR_EM_MEMORY. The informational status shall NOT be propagated!
+ * @param pDevIns The device instance.
+ * @param GCPhys Physical address to write to.
+ * @param pvBuf What to write.
+ * @param cbWrite How many bytes to write.
+ * @thread Any thread, but the call may involve the emulation thread.
*/
- DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
+ DECLRCCALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
/**
* Set the IRQ for a PCI device.
@@ -3746,7 +3862,7 @@ typedef RCPTRTYPE(struct PDMDEVHLPRC *) PPDMDEVHLPRC;
typedef RCPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC;
/** Current PDMDEVHLP version number. */
-#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 3, 0)
+#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 3, 1)
/**
@@ -3758,18 +3874,28 @@ typedef struct PDMDEVHLPR0
uint32_t u32Version;
/**
- * Reads data via bus mastering, if enabled. If no bus mastering is available,
- * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
+ * Bus master physical memory read.
*
- * @return IPRT status code.
+ * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe
+ * VERR_EM_MEMORY.
+ * @param pDevIns The device instance.
+ * @param GCPhys Physical address start reading from.
+ * @param pvBuf Where to put the read bits.
+ * @param cbRead How many bytes to read.
+ * @thread Any thread, but the call may involve the emulation thread.
*/
DECLR0CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
/**
- * Writes data via bus mastering, if enabled. If no bus mastering is available,
- * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
+ * Bus master physical memory write.
*
- * @return IPRT status code.
+ * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe
+ * VERR_EM_MEMORY.
+ * @param pDevIns The device instance.
+ * @param GCPhys Physical address to write to.
+ * @param pvBuf What to write.
+ * @param cbWrite How many bytes to write.
+ * @thread Any thread, but the call may involve the emulation thread.
*/
DECLR0CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
@@ -3961,7 +4087,7 @@ typedef R0PTRTYPE(struct PDMDEVHLPR0 *) PPDMDEVHLPR0;
typedef R0PTRTYPE(const struct PDMDEVHLPR0 *) PCPDMDEVHLPR0;
/** Current PDMDEVHLP version number. */
-#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 3, 0)
+#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 3, 1)
@@ -4621,6 +4747,14 @@ DECLINLINE(int) PDMDevHlpDBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszNam
}
/**
+ * @copydoc PDMDEVHLPR3::pfnDBGFRegRegister
+ */
+DECLINLINE(int) PDMDevHlpDBGFRegRegister(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters)
+{
+ return pDevIns->pHlpR3->pfnDBGFRegRegister(pDevIns, paRegisters);
+}
+
+/**
* @copydoc PDMDEVHLPR3::pfnSTAMRegister
*/
DECLINLINE(void) PDMDevHlpSTAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
@@ -4673,56 +4807,24 @@ DECLINLINE(void) PDMDevHlpPCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE p
pDevIns->pHlpR3->pfnPCISetConfigCallbacks(pDevIns, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld);
}
+#endif /* IN_RING3 */
+
/**
- * Reads data via bus mastering, if enabled. If no bus mastering is available,
- * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
- *
- * @return IPRT status code.
+ * @copydoc PDMDEVHLPR3::pfnPCIPhysRead
*/
-DECLINLINE(int) PDMDevHlpPCIDevPhysRead(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
+DECLINLINE(int) PDMDevHlpPCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
{
- AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
- AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
- AssertReturn(cbRead, VERR_INVALID_PARAMETER);
-
- if (!PCIDevIsBusmaster(pPciDev))
- {
-#ifdef DEBUG
- Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping read %p (%z)\n", __FUNCTION__,
- PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbRead));
-#endif
- return VINF_PDM_PCI_PHYS_READ_BM_DISABLED;
- }
-
- return PDMDevHlpPhysRead(pPciDev->pDevIns, GCPhys, pvBuf, cbRead);
+ return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
}
/**
- * Writes data via bus mastering, if enabled. If no bus mastering is available,
- * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
- *
- * @return IPRT status code.
+ * @copydoc PDMDEVHLPR3::pfnPCIPhysWrite
*/
-DECLINLINE(int) PDMDevHlpPCIDevPhysWrite(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
+DECLINLINE(int) PDMDevHlpPCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
{
- AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
- AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
- AssertReturn(cbWrite, VERR_INVALID_PARAMETER);
-
- if (!PCIDevIsBusmaster(pPciDev))
- {
-#ifdef DEBUG
- Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping write %p (%z)\n", __FUNCTION__,
- PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbWrite));
-#endif
- return VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED;
- }
-
- return PDMDevHlpPhysWrite(pPciDev->pDevIns, GCPhys, pvBuf, cbWrite);
+ return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
}
-#endif /* IN_RING3 */
-
/**
* @copydoc PDMDEVHLPR3::pfnPCISetIrq
*/
@@ -4999,6 +5101,30 @@ DECLINLINE(int) PDMDevHlpCallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_
return pDevIns->pHlpR3->pfnCallR0(pDevIns, uOperation, u64Arg);
}
+/**
+ * @copydoc PDMDEVHLP::pfnVMGetSuspendReason
+ */
+DECLINLINE(VMSUSPENDREASON) PDMDevHlpVMGetSuspendReason(PPDMDEVINS pDevIns)
+{
+ return pDevIns->pHlpR3->pfnVMGetSuspendReason(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLP::pfnVMGetResumeReason
+ */
+DECLINLINE(VMRESUMEREASON) PDMDevHlpVMGetResumeReason(PPDMDEVINS pDevIns)
+{
+ return pDevIns->pHlpR3->pfnVMGetResumeReason(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnGetUVM
+ */
+DECLINLINE(PUVM) PDMDevHlpGetUVM(PPDMDEVINS pDevIns)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnGetUVM(pDevIns);
+}
+
#endif /* IN_RING3 */
/**
@@ -5111,6 +5237,14 @@ DECLINLINE(void) PDMDevHlpGetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t
pDevIns->pHlpR3->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx);
}
+/**
+ * @copydoc PDMDEVHLPR3::pfnGetSupDrvSession
+ */
+DECLINLINE(PSUPDRVSESSION) PDMDevHlpGetSupDrvSession(PPDMDEVINS pDevIns)
+{
+ return pDevIns->pHlpR3->pfnGetSupDrvSession(pDevIns);
+}
+
#endif /* IN_RING3 */
#ifdef IN_RING0
diff --git a/include/VBox/vmm/pdmdrv.h b/include/VBox/vmm/pdmdrv.h
index d830ea69..57dbe960 100644
--- a/include/VBox/vmm/pdmdrv.h
+++ b/include/VBox/vmm/pdmdrv.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -1297,12 +1297,43 @@ typedef struct PDMDRVHLPR3
PFNPDMBLKCACHEXFERENQUEUEDRV pfnXferEnqueue,
PFNPDMBLKCACHEXFERENQUEUEDISCARDDRV pfnXferEnqueueDiscard,
const char *pcszId));
+ /**
+ * Gets the reason for the most recent VM suspend.
+ *
+ * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no
+ * suspend has been made or if the pDrvIns is invalid.
+ * @param pDrvIns The driver instance.
+ */
+ DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMDRVINS pDrvIns));
+
+ /**
+ * Gets the reason for the most recent VM resume.
+ *
+ * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no
+ * resume has been made or if the pDrvIns is invalid.
+ * @param pDrvIns The driver instance.
+ */
+ DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMDRVINS pDrvIns));
+
+ /** @name Space reserved for minor interface changes.
+ * @{ */
+ DECLR3CALLBACKMEMBER(void, pfnReserved0,(PPDMDRVINS pDrvIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved1,(PPDMDRVINS pDrvIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved2,(PPDMDRVINS pDrvIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved3,(PPDMDRVINS pDrvIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved4,(PPDMDRVINS pDrvIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved5,(PPDMDRVINS pDrvIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved6,(PPDMDRVINS pDrvIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved7,(PPDMDRVINS pDrvIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved8,(PPDMDRVINS pDrvIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved9,(PPDMDRVINS pDrvIns));
+ /** @} */
/** Just a safety precaution. */
uint32_t u32TheEnd;
} PDMDRVHLPR3;
/** Current DRVHLP version number. */
-#define PDM_DRVHLPR3_VERSION PDM_VERSION_MAKE(0xf0fb, 2, 0)
+#define PDM_DRVHLPR3_VERSION PDM_VERSION_MAKE(0xf0fb, 3, 0)
#endif /* IN_RING3 */
@@ -1777,6 +1808,23 @@ DECLINLINE(int) PDMDrvHlpBlkCacheRetain(PPDMDRVINS pDrvIns, PPPDMBLKCACHE ppBlkC
return pDrvIns->pHlpR3->pfnBlkCacheRetain(pDrvIns, ppBlkCache, pfnXferComplete, pfnXferEnqueue, pfnXferEnqueueDiscard, pcszId);
}
+/**
+ * @copydoc PDMDRVHLP::pfnVMGetSuspendReason
+ */
+DECLINLINE(VMSUSPENDREASON) PDMDrvHlpVMGetSuspendReason(PPDMDRVINS pDrvIns)
+{
+ return pDrvIns->pHlpR3->pfnVMGetSuspendReason(pDrvIns);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnVMGetResumeReason
+ */
+DECLINLINE(VMRESUMEREASON) PDMDrvHlpVMGetResumeReason(PPDMDRVINS pDrvIns)
+{
+ return pDrvIns->pHlpR3->pfnVMGetResumeReason(pDrvIns);
+}
+
+
/** Pointer to callbacks provided to the VBoxDriverRegister() call. */
typedef struct PDMDRVREGCB *PPDMDRVREGCB;
/** Pointer to const callbacks provided to the VBoxDriverRegister() call. */
diff --git a/include/VBox/vmm/pdmifs.h b/include/VBox/vmm/pdmifs.h
index 17dba105..913c0dc2 100644
--- a/include/VBox/vmm/pdmifs.h
+++ b/include/VBox/vmm/pdmifs.h
@@ -296,14 +296,16 @@ typedef struct PDMIMOUSEPORT
* @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the
* event now and want it to be repeated at a later point.
*
- * @param pInterface Pointer to this interface structure.
- * @param iDeltaX The X delta.
- * @param iDeltaY The Y delta.
- * @param iDeltaZ The Z delta.
- * @param iDeltaW The W (horizontal scroll button) delta.
- * @param fButtonStates The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines.
+ * @param pInterface Pointer to this interface structure.
+ * @param dx The X delta.
+ * @param dy The Y delta.
+ * @param dz The Z delta.
+ * @param dw The W (horizontal scroll button) delta.
+ * @param fButtons The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines.
*/
- DECLR3CALLBACKMEMBER(int, pfnPutEvent,(PPDMIMOUSEPORT pInterface, int32_t iDeltaX, int32_t iDeltaY, int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtonStates));
+ DECLR3CALLBACKMEMBER(int, pfnPutEvent,(PPDMIMOUSEPORT pInterface,
+ int32_t dx, int32_t dy, int32_t dz,
+ int32_t dw, uint32_t fButtons));
/**
* Puts an absolute mouse event.
*
@@ -313,17 +315,45 @@ typedef struct PDMIMOUSEPORT
* @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the
* event now and want it to be repeated at a later point.
*
- * @param pInterface Pointer to this interface structure.
- * @param uX The X value, in the range 0 to 0xffff.
- * @param uY The Y value, in the range 0 to 0xffff.
- * @param iDeltaZ The Z delta.
- * @param iDeltaW The W (horizontal scroll button) delta.
- * @param fButtonStates The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines.
+ * @param pInterface Pointer to this interface structure.
+ * @param x The X value, in the range 0 to 0xffff.
+ * @param z The Y value, in the range 0 to 0xffff.
+ * @param dz The Z delta.
+ * @param dw The W (horizontal scroll button) delta.
+ * @param fButtons The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines.
*/
- DECLR3CALLBACKMEMBER(int, pfnPutEventAbs,(PPDMIMOUSEPORT pInterface, uint32_t uX, uint32_t uY, int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtonStates));
+ DECLR3CALLBACKMEMBER(int, pfnPutEventAbs,(PPDMIMOUSEPORT pInterface,
+ uint32_t x, uint32_t z,
+ int32_t dz, int32_t dw,
+ uint32_t fButtons));
+ /**
+ * Puts a multi-touch event.
+ *
+ * @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the
+ * event now and want it to be repeated at a later point.
+ *
+ * @param pInterface Pointer to this interface structure.
+ * @param cContacts How many touch contacts in this event.
+ * @param pau64Contacts Pointer to array of packed contact information.
+ * Each 64bit element contains:
+ * Bits 0..15: X coordinate in pixels (signed).
+ * Bits 16..31: Y coordinate in pixels (signed).
+ * Bits 32..39: contact identifier.
+ * Bit 40: "in contact" flag, which indicates that
+ * there is a contact with the touch surface.
+ * Bit 41: "in range" flag, the contact is close enough
+ * to the touch surface.
+ * All other bits are reserved for future use and must be set to 0.
+ * @param u32ScanTime Timestamp of this event in milliseconds. Only relative
+ * time between event is important.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPutEventMultiTouch,(PPDMIMOUSEPORT pInterface,
+ uint8_t cContacts,
+ const uint64_t *pau64Contacts,
+ uint32_t u32ScanTime));
} PDMIMOUSEPORT;
/** PDMIMOUSEPORT interface ID. */
-#define PDMIMOUSEPORT_IID "442136fe-6f3c-49ec-9964-259b378ffa64"
+#define PDMIMOUSEPORT_IID "359364f0-9fa3-4490-a6b4-7ed771901c93"
/** Mouse button defines for PDMIMOUSEPORT::pfnPutEvent.
* @{ */
@@ -350,8 +380,9 @@ typedef struct PDMIMOUSECONNECTOR
* @param pInterface Pointer to the this interface.
* @param fRelative Whether relative mode is currently supported.
* @param fAbsolute Whether absolute mode is currently supported.
+ * @param fAbsolute Whether multi-touch mode is currently supported.
*/
- DECLR3CALLBACKMEMBER(void, pfnReportModes,(PPDMIMOUSECONNECTOR pInterface, bool fRelative, bool fAbsolute));
+ DECLR3CALLBACKMEMBER(void, pfnReportModes,(PPDMIMOUSECONNECTOR pInterface, bool fRelative, bool fAbsolute, bool fMultiTouch));
} PDMIMOUSECONNECTOR;
/** PDMIMOUSECONNECTOR interface ID. */
@@ -598,8 +629,11 @@ typedef struct VBVAHOSTFLAGS *PVBVAHOSTFLAGS;
typedef struct VBOXVDMACMD_CHROMIUM_CMD *PVBOXVDMACMD_CHROMIUM_CMD; /* <- chromium [hgsmi] command */
typedef struct VBOXVDMACMD_CHROMIUM_CTL *PVBOXVDMACMD_CHROMIUM_CTL; /* <- chromium [hgsmi] command */
+
/** Pointer to a display connector interface. */
typedef struct PDMIDISPLAYCONNECTOR *PPDMIDISPLAYCONNECTOR;
+struct VBOXCRCMDCTL;
+typedef DECLCALLBACKPTR(void, PFNCRCTLCOMPLETION)(struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, int rc, void *pvCompletion);
/**
* Display connector interface (up).
* Pair with PDMIDISPLAYPORT.
@@ -703,9 +737,12 @@ typedef struct PDMIDISPLAYCONNECTOR
*
* @param pInterface Pointer to this interface.
* @param pCmd Video HW Acceleration Command to be processed.
+ * @returns VINF_SUCCESS - command is completed,
+ * VINF_CALLBACK_RETURN - command will by asynchronously completed via complete callback
+ * VERR_INVALID_STATE - the command could not be processed (most likely because the framebuffer was disconnected) - the post should be retried later
* @thread The emulation thread.
*/
- DECLR3CALLBACKMEMBER(void, pfnVHWACommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCmd));
+ DECLR3CALLBACKMEMBER(int, pfnVHWACommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCmd));
/**
* Process the guest chromium command.
@@ -725,6 +762,17 @@ typedef struct PDMIDISPLAYCONNECTOR
*/
DECLR3CALLBACKMEMBER(void, pfnCrHgsmiControlProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCtl));
+ /**
+ * Process the guest chromium control command.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pCmd Video HW Acceleration Command to be processed.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCrHgcmCtlSubmit, (PPDMIDISPLAYCONNECTOR pInterface,
+ struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
+ PFNCRCTLCOMPLETION pfnCompletion,
+ void *pvCompletion));
/**
* The specified screen enters VBVA mode.
@@ -835,7 +883,7 @@ typedef struct PDMIDISPLAYCONNECTOR
/** @} */
} PDMIDISPLAYCONNECTOR;
/** PDMIDISPLAYCONNECTOR interface ID. */
-#define PDMIDISPLAYCONNECTOR_IID "c7a1b36d-8dfc-421d-b71f-3a0eeaf733e6"
+#define PDMIDISPLAYCONNECTOR_IID "05ba9649-302e-43dd-b9ff-60b6fb311d97"
/** Pointer to a block port interface. */
@@ -892,6 +940,12 @@ typedef enum PDMBLOCKTYPE
PDMBLOCKTYPE_FLOPPY_1_44,
/** 2.88MB 3 1/2" floppy drive. */
PDMBLOCKTYPE_FLOPPY_2_88,
+ /** Fake drive that can take up to 15.6 MB images.
+ * C=255, H=2, S=63. */
+ PDMBLOCKTYPE_FLOPPY_FAKE_15_6,
+ /** Fake drive that can take up to 63.5 MB images.
+ * C=255, H=2, S=255. */
+ PDMBLOCKTYPE_FLOPPY_FAKE_63_5,
/** CDROM drive. */
PDMBLOCKTYPE_CDROM,
/** DVD drive. */
@@ -900,6 +954,8 @@ typedef enum PDMBLOCKTYPE
PDMBLOCKTYPE_HARD_DISK
} PDMBLOCKTYPE;
+/** Check if the given block type is a floppy. */
+#define PDMBLOCKTYPE_IS_FLOPPY(a_enmType) ( (a_enmType) >= PDMBLOCKTYPE_FLOPPY_360 && (a_enmType) <= PDMBLOCKTYPE_FLOPPY_2_88 )
/**
* Block raw command data transfer direction.
@@ -1000,6 +1056,15 @@ typedef struct PDMIBLOCK
DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize,(PPDMIBLOCK pInterface));
/**
+ * Gets the media sector size in bytes.
+ *
+ * @returns Media sector size in bytes.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(uint32_t, pfnGetSectorSize,(PPDMIBLOCK pInterface));
+
+ /**
* Gets the block drive type.
*
* @returns block drive type.
@@ -1245,6 +1310,15 @@ typedef struct PDMIMEDIA
DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize,(PPDMIMEDIA pInterface));
/**
+ * Gets the media sector size in bytes.
+ *
+ * @returns Media sector size in bytes.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(uint32_t, pfnGetSectorSize,(PPDMIMEDIA pInterface));
+
+ /**
* Check if the media is readonly or not.
*
* @returns true if readonly.
@@ -2065,8 +2139,19 @@ typedef struct PDMIVMMDEVPORT
* @param cy Vertical pixel resolution (0 = do not change).
* @param cBits Bits per pixel (0 = do not change).
* @param idxDisplay The display index.
+ * @param xOrigin The X coordinate of the lower left
+ * corner of the secondary display with
+ * ID = idxDisplay
+ * @param yOrigin The Y coordinate of the lower left
+ * corner of the secondary display with
+ * ID = idxDisplay
+ * @param fEnabled Whether the display is enabled or not. (Guessing
+ * again.)
+ * @param fChangeOrigin Whether the display origin point changed. (Guess)
*/
- DECLR3CALLBACKMEMBER(int, pfnRequestDisplayChange,(PPDMIVMMDEVPORT pInterface, uint32_t cx, uint32_t cy, uint32_t cBits, uint32_t idxDisplay));
+ DECLR3CALLBACKMEMBER(int, pfnRequestDisplayChange,(PPDMIVMMDEVPORT pInterface, uint32_t cx,
+ uint32_t cy, uint32_t cBits, uint32_t idxDisplay,
+ int32_t xOrigin, int32_t yOrigin, bool fEnabled, bool fChangeOrigin));
/**
* Pass credentials to guest.
@@ -2237,6 +2322,23 @@ typedef struct PDMIVMMDEVCONNECTOR
uint32_t fFlags, PCRTTIMESPEC pTimeSpecTS));
/**
+ * Updates a guest user state.
+ *
+ * Called in response to VMMDevReq_ReportGuestUserState.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pszUser Guest user name to update status for.
+ * @param pszDomain Domain the guest user is bound to. Optional.
+ * @param uState New guest user state to notify host about.
+ * @param puDetails Pointer to optional state data.
+ * @param cbDetails Size (in bytes) of optional state data.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUpdateGuestUserState,(PPDMIVMMDEVCONNECTOR pInterface, const char *pszUser, const char *pszDomain,
+ uint32_t uState,
+ const uint8_t *puDetails, uint32_t cbDetails));
+
+ /**
* Reports the guest API and OS version.
* Called whenever the Additions issue a guest info report request.
*
@@ -2966,6 +3068,11 @@ typedef struct PDMIDISPLAYVBVACALLBACKS
DECLR3CALLBACKMEMBER(int, pfnCrHgsmiControlCompleteAsync, (PPDMIDISPLAYVBVACALLBACKS pInterface,
PVBOXVDMACMD_CHROMIUM_CTL pCmd, int rc));
+
+ DECLR3CALLBACKMEMBER(int, pfnCrCtlSubmit, (PPDMIDISPLAYVBVACALLBACKS pInterface,
+ struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
+ PFNCRCTLCOMPLETION pfnCompletion,
+ void *pvCompletion));
} PDMIDISPLAYVBVACALLBACKS;
/** PDMIDISPLAYVBVACALLBACKS */
#define PDMIDISPLAYVBVACALLBACKS_IID "b78b81d2-c821-4e66-96ff-dbafa76343a5"
diff --git a/include/VBox/vmm/pdmnetinline.h b/include/VBox/vmm/pdmnetinline.h
index 66c3078f..ac2bb6f7 100644
--- a/include/VBox/vmm/pdmnetinline.h
+++ b/include/VBox/vmm/pdmnetinline.h
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2010-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/include/VBox/vmm/pdmnetshaper.h b/include/VBox/vmm/pdmnetshaper.h
index b2aa5bab..d3610564 100644
--- a/include/VBox/vmm/pdmnetshaper.h
+++ b/include/VBox/vmm/pdmnetshaper.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2011-2012 Oracle Corporation
+ * Copyright (C) 2011-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -33,84 +33,43 @@
#include <iprt/sg.h>
-#define PDM_NETSHAPER_MIN_BUCKET_SIZE 65536 /* bytes */
-#define PDM_NETSHAPER_MAX_LATENCY 100 /* milliseconds */
+/** @defgroup grp_pdm_net_shaper The PDM Network Shaper API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+
+#define PDM_NETSHAPER_MIN_BUCKET_SIZE UINT32_C(65536) /**< bytes */
+#define PDM_NETSHAPER_MAX_LATENCY UINT32_C(100) /**< milliseconds */
RT_C_DECLS_BEGIN
typedef struct PDMNSFILTER
{
- /** [R3] Pointer to the next group in the list. */
- struct PDMNSFILTER *pNext;
- /** [R3] Pointer to the bandwidth group. */
- struct PDMNSBWGROUP *pBwGroupR3;
- /** [R0] Pointer to the bandwidth group. */
- R0PTRTYPE(struct PDMNSBWGROUP *) pBwGroupR0;
- /** Becomes true when filter fails to obtain bandwidth. */
- bool fChoked;
- /** [R3] The driver this filter is aggregated into. */
- PPDMINETWORKDOWN pIDrvNet;
+ /** Pointer to the next group in the list (ring-3). */
+ R3PTRTYPE(struct PDMNSFILTER *) pNextR3;
+ /** Pointer to the bandwidth group (ring-3). */
+ R3PTRTYPE(struct PDMNSBWGROUP *) pBwGroupR3;
+ /** Pointer to the bandwidth group (ring-0). */
+ R0PTRTYPE(struct PDMNSBWGROUP *) pBwGroupR0;
+ /** Set when the filter fails to obtain bandwidth. */
+ bool fChoked;
+ /** Aligment padding. */
+ bool afPadding[HC_ARCH_BITS == 32 ? 3 : 7];
+ /** The driver this filter is aggregated into (ring-3). */
+ R3PTRTYPE(PPDMINETWORKDOWN) pIDrvNetR3;
} PDMNSFILTER;
-/** @defgroup grp_pdm_net_shaper The PDM Network Shaper API
- * @ingroup grp_pdm
- * @{
- */
-
/** Pointer to a PDM filter handle. */
typedef struct PDMNSFILTER *PPDMNSFILTER;
/** Pointer to a network shaper. */
typedef struct PDMNETSHAPER *PPDMNETSHAPER;
-/**
- * Obtain bandwidth in a bandwidth group (R0 version).
- *
- * @returns VBox status code.
- * @param pFilter Pointer to the filter that allocates bandwidth.
- * @param cbTransfer Number of bytes to allocate.
- */
-VMMR0DECL(bool) PDMR0NsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer);
-
-/**
- * Obtain bandwidth in a bandwidth group.
- *
- * @returns VBox status code.
- * @param pFilter Pointer to the filter that allocates bandwidth.
- * @param cbTransfer Number of bytes to allocate.
- */
-VMMR3DECL(bool) PDMR3NsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer);
-
-/**
- * Attach network filter driver from bandwidth group.
- *
- * @returns VBox status code.
- * @param pVM Handle of VM.
- * @param pDrvIns The driver instance.
- * @param pcszBwGroup Name of the bandwidth group to attach to.
- * @param pFilter Pointer to the filter we attach.
- */
-VMMR3DECL(int) PDMR3NsAttach(PVM pVM, PPDMDRVINS pDrvIns, const char *pcszBwGroup, PPDMNSFILTER pFilter);
-
-/**
- * Detach network filter driver from bandwidth group.
- *
- * @returns VBox status code.
- * @param pVM Handle of VM.
- * @param pDrvIns The driver instance.
- * @param pFilter Pointer to the filter we detach.
- */
-VMMR3DECL(int) PDMR3NsDetach(PVM pVM, PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter);
-
-/**
- * Adjusts the maximum rate for the bandwidth group.
- *
- * @returns VBox status code.
- * @param pVM Handle of VM.
- * @param pcszBwGroup Name of the bandwidth group to attach to.
- * @param cbTransferPerSecMax Maximum number of bytes per second to be transmitted.
- */
-VMMR3DECL(int) PDMR3NsBwGroupSetLimit(PVM pVM, const char *pcszBwGroup, uint64_t cbTransferPerSecMax);
+VMMDECL(bool) PDMNsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer);
+VMMR3_INT_DECL(int) PDMR3NsAttach(PUVM pUVM, PPDMDRVINS pDrvIns, const char *pcszBwGroup, PPDMNSFILTER pFilter);
+VMMR3_INT_DECL(int) PDMR3NsDetach(PUVM pUVM, PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter);
+VMMR3DECL(int) PDMR3NsBwGroupSetLimit(PUVM pUVM, const char *pszBwGroup, uint64_t cbPerSecMax);
/** @} */
diff --git a/include/VBox/vmm/pdmnetshaperint.h b/include/VBox/vmm/pdmnetshaperint.h
deleted file mode 100644
index 3bbfcda7..00000000
--- a/include/VBox/vmm/pdmnetshaperint.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* $Id: pdmnetshaperint.h $ */
-/** @file
- * PDM Network Shaper - Internal data structures and functions common for both
- * R0 and R3 parts.
- */
-
-/*
- * Copyright (C) 2011-2012 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * The contents of this file may alternatively be used under the terms
- * of the Common Development and Distribution License Version 1.0
- * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
- * VirtualBox OSE distribution, in which case the provisions of the
- * CDDL are applicable instead of those of the GPL.
- *
- * You may elect to license modified versions of this file under the
- * terms and conditions of either the GPL or the CDDL or both.
- */
-
-/**
- * Bandwidth group instance data
- */
-typedef struct PDMNSBWGROUP
-{
- /** Pointer to the next group in the list. */
- struct PDMNSBWGROUP *pNext;
- /** Pointer to the shared UVM structure. */
- struct PDMNETSHAPER *pShaper;
- /** Critical section protecting all members below. */
- PDMCRITSECT cs;
- /** Pointer to the first filter attached to this group. */
- struct PDMNSFILTER *pFiltersHead;
- /** Bandwidth group name. */
- char *pszName;
- /** Maximum number of bytes filters are allowed to transfer. */
- volatile uint64_t cbTransferPerSecMax;
- /** Number of bytes we are allowed to transfer in one burst. */
- volatile uint32_t cbBucketSize;
- /** Number of bytes we were allowed to transfer at the last update. */
- volatile uint32_t cbTokensLast;
- /** Timestamp of the last update */
- volatile uint64_t tsUpdatedLast;
- /** Reference counter - How many filters are associated with this group. */
- volatile uint32_t cRefs;
-} PDMNSBWGROUP;
-/** Pointer to a bandwidth group. */
-typedef PDMNSBWGROUP *PPDMNSBWGROUP;
-
-DECLINLINE(bool) pdmNsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer)
-{
- AssertPtrReturn(pFilter, true);
- if (!VALID_PTR(pFilter->CTX_SUFF(pBwGroup)))
- return true;
-
- PPDMNSBWGROUP pBwGroup = ASMAtomicReadPtrT(&pFilter->CTX_SUFF(pBwGroup), PPDMNSBWGROUP);
- int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc);
- if (RT_UNLIKELY(rc == VERR_SEM_BUSY))
- return true;
- bool fAllowed = true;
- if (pBwGroup->cbTransferPerSecMax)
- {
- /* Re-fill the bucket first */
- uint64_t tsNow = RTTimeSystemNanoTS();
- uint32_t uTokensAdded = (tsNow - pBwGroup->tsUpdatedLast)*pBwGroup->cbTransferPerSecMax/(1000*1000*1000);
- uint32_t uTokens = RT_MIN(pBwGroup->cbBucketSize, uTokensAdded + pBwGroup->cbTokensLast);
-
- if (cbTransfer > uTokens)
- {
- fAllowed = false;
- ASMAtomicWriteBool(&pFilter->fChoked, true);
- }
- else
- {
- pBwGroup->tsUpdatedLast = tsNow;
- pBwGroup->cbTokensLast = uTokens - (uint32_t)cbTransfer;
- }
- Log2((LOG_FN_FMT "BwGroup=%#p{%s} cbTransfer=%u uTokens=%u uTokensAdded=%u fAllowed=%RTbool\n",
- __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, cbTransfer, uTokens, uTokensAdded, fAllowed));
- }
- else
- Log2((LOG_FN_FMT "BwGroup=%#p{%s} disabled fAllowed=%RTbool\n",
- __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, fAllowed));
-
- rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc);
- return fAllowed;
-}
diff --git a/include/VBox/vmm/pdmnvram.h b/include/VBox/vmm/pdmnvram.h
index 10c1abc4..03967dff 100644
--- a/include/VBox/vmm/pdmnvram.h
+++ b/include/VBox/vmm/pdmnvram.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2012 Oracle Corporation
+ * Copyright (C) 2012-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -36,35 +36,85 @@ RT_C_DECLS_BEGIN
* @{
*/
-typedef struct PDMINVRAM *PPDMINVRAM;
+/** Pointer to NVRAM interface provided by the driver. */
+typedef struct PDMINVRAMCONNECTOR *PPDMINVRAMCONNECTOR;
-typedef struct PDMINVRAM
+/**
+ * Non-volatile RAM storage interface provided by the driver (up).
+ *
+ * @note The variable indexes used here 0-based, sequential and without gaps.
+ */
+typedef struct PDMINVRAMCONNECTOR
{
/**
- * This method flushes all values in the storage.
+ * Query a variable by variable index.
+ *
+ * @returns VBox status code.
+ * @retval VERR_NOT_FOUND if the variable was not found. This indicates that
+ * there are not variables with a higher index.
+ *
+ * @param idxVariable The variable index. By starting @a idxVariable at 0
+ * and increasing it with each call, this can be used
+ * to enumerate all available variables.
+ * @param pVendorUuid The vendor UUID of the variable.
+ * @param pszName The variable name buffer.
+ * @param pcchName On input this hold the name buffer size (including
+ * the space for the terminator char). On successful
+ * return it holds the strlen() value for @a pszName.
+ * @param pfAttributes Where to return the value attributes.
+ * @param pbValue The value buffer.
+ * @param pcbValue On input the size of the value buffer, on output the
+ * actual number of bytes returned.
*/
- DECLR3CALLBACKMEMBER(int, pfnFlushNvramStorage, (PPDMINVRAM pInterface));
+ DECLR3CALLBACKMEMBER(int, pfnVarQueryByIndex,(PPDMINVRAMCONNECTOR pInterface, uint32_t idxVariable,
+ PRTUUID pVendorUuid, char *pszName, uint32_t *pcchName,
+ uint32_t *pfAttributes, uint8_t *pbValue, uint32_t *pcbValue));
/**
- * This method store NVRAM variable to storage
+ * Begins variable store sequence.
+ *
+ * @returns VBox status code.
+ * @param pInterance Pointer to this interface structure.
+ * @param cVariables The number of variables.
*/
- DECLR3CALLBACKMEMBER(int, pfnStoreNvramValue, (PPDMINVRAM pInterface, int idxVariable, RTUUID *pVendorUuid, const char *pcszVariableName, size_t cbVariableName, uint8_t *pu8Value, size_t cbValue));
+ DECLR3CALLBACKMEMBER(int, pfnVarStoreSeqBegin,(PPDMINVRAMCONNECTOR pInterface, uint32_t cVariables));
/**
- * This method load NVRAM variable to storage
+ * Puts the next variable in the store sequence.
+ *
+ * @returns VBox status code.
+ * @param idxVariable The variable index. This will start at 0 and advance
+ * up to @a cVariables - 1.
+ * @param pVendorUuid The vendor UUID of the variable.
+ * @param pszName The variable name buffer.
+ * @param pcchName On input this hold the name buffer size (including
+ * the space for the terminator char). On successful
+ * return it holds the strlen() value for @a pszName.
+ * @param fAttributes The value attributes.
+ * @param pbValue The value buffer.
+ * @param pcbValue On input the size of the value buffer, on output the
+ * actual number of bytes returned.
*/
- DECLR3CALLBACKMEMBER(int, pfnLoadNvramValue, (PPDMINVRAM pInterface, int idxVariable, RTUUID *pVendorUuid, char *pcszVariableName, size_t *pcbVariableName, uint8_t *pu8Value, size_t *pcbValue));
-
-} PDMINVRAM;
+ DECLR3CALLBACKMEMBER(int, pfnVarStoreSeqPut,(PPDMINVRAMCONNECTOR pInterface, int idxVariable,
+ PCRTUUID pVendorUuid, const char *pszName, size_t cchName,
+ uint32_t fAttributes, uint8_t const *pbValue, size_t cbValue));
+ /**
+ * Ends a variable store sequence.
+ *
+ * @returns VBox status code, @a rc on success.
+ * @param pInterance Pointer to this interface structure.
+ * @param rc The VBox status code for the whole store operation.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVarStoreSeqEnd,(PPDMINVRAMCONNECTOR pInterface, int rc));
-#define PDMINVRAM_IID "11226408-CB4C-4369-9218-1EE0092FB9F8"
+} PDMINVRAMCONNECTOR;
+/** PDMINVRAMCONNECTOR interface ID. */
+#define PDMINVRAMCONNECTOR_IID "057bc5c9-8022-43a8-9a41-0b106f97a89f"
/** @} */
RT_C_DECLS_END
-
#endif
-
diff --git a/include/VBox/vmm/pdmqueue.h b/include/VBox/vmm/pdmqueue.h
index 3445c85a..4edf16c3 100644
--- a/include/VBox/vmm/pdmqueue.h
+++ b/include/VBox/vmm/pdmqueue.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -65,6 +65,9 @@ typedef struct PDMQUEUEITEMCORE
* If false the item will not be removed and the flushing will stop.
* @param pDevIns The device instance.
* @param pItem The item to consume. Upon return this item will be freed.
+ * @remarks The device critical section will NOT be entered before calling the
+ * callback. No locks will be held, but for now it's safe to assume
+ * that only one EMT will do queue callbacks at any one time.
*/
typedef DECLCALLBACK(bool) FNPDMQUEUEDEV(PPDMDEVINS pDevIns, PPDMQUEUEITEMCORE pItem);
/** Pointer to a FNPDMQUEUEDEV(). */
@@ -77,6 +80,8 @@ typedef FNPDMQUEUEDEV *PFNPDMQUEUEDEV;
* If false the item will not be removed and the flushing will stop.
* @param pDevIns The USB device instance.
* @param pItem The item to consume. Upon return this item will be freed.
+ * @remarks No locks will be held, but for now it's safe to assume that only one
+ * EMT will do queue callbacks at any one time.
*/
typedef DECLCALLBACK(bool) FNPDMQUEUEUSB(PPDMUSBINS pUsbIns, PPDMQUEUEITEMCORE pItem);
/** Pointer to a FNPDMQUEUEUSB(). */
@@ -89,6 +94,8 @@ typedef FNPDMQUEUEUSB *PFNPDMQUEUEUSB;
* If false the item will not be removed and the flushing will stop.
* @param pDrvIns The driver instance.
* @param pItem The item to consume. Upon return this item will be freed.
+ * @remarks No locks will be held, but for now it's safe to assume that only one
+ * EMT will do queue callbacks at any one time.
*/
typedef DECLCALLBACK(bool) FNPDMQUEUEDRV(PPDMDRVINS pDrvIns, PPDMQUEUEITEMCORE pItem);
/** Pointer to a FNPDMQUEUEDRV(). */
@@ -101,6 +108,8 @@ typedef FNPDMQUEUEDRV *PFNPDMQUEUEDRV;
* If false the item will not be removed and the flushing will stop.
* @param pVM The VM handle.
* @param pItem The item to consume. Upon return this item will be freed.
+ * @remarks No locks will be held, but for now it's safe to assume that only one
+ * EMT will do queue callbacks at any one time.
*/
typedef DECLCALLBACK(bool) FNPDMQUEUEINT(PVM pVM, PPDMQUEUEITEMCORE pItem);
/** Pointer to a FNPDMQUEUEINT(). */
@@ -113,6 +122,8 @@ typedef FNPDMQUEUEINT *PFNPDMQUEUEINT;
* If false the item will not be removed and the flushing will stop.
* @param pvUser User argument.
* @param pItem The item to consume. Upon return this item will be freed.
+ * @remarks No locks will be held, but for now it's safe to assume that only one
+ * EMT will do queue callbacks at any one time.
*/
typedef DECLCALLBACK(bool) FNPDMQUEUEEXT(void *pvUser, PPDMQUEUEITEMCORE pItem);
/** Pointer to a FNPDMQUEUEEXT(). */
diff --git a/include/VBox/vmm/pdmusb.h b/include/VBox/vmm/pdmusb.h
index ae3f5cfb..6abe2a14 100644
--- a/include/VBox/vmm/pdmusb.h
+++ b/include/VBox/vmm/pdmusb.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -113,6 +113,11 @@ typedef PDMUSBDESCCACHE *PPDMUSBDESCCACHE;
typedef const PDMUSBDESCCACHE *PCPDMUSBDESCCACHE;
+/** PDM Device Flags.
+ * @{ */
+/** A high-speed capable USB 2.0 device (also required to support full-speed). */
+#define PDM_USBREG_HIGHSPEED_CAPABLE RT_BIT(0)
+/** @} */
/** PDM USB Device Registration Structure,
*
@@ -164,7 +169,7 @@ typedef struct PDMUSBREG
* Most VM resources are freed by the VM. This callback is provided so that any non-VM
* resources can be freed correctly.
*
- * This method will be called regardless of the pfnConstruc result to avoid
+ * This method will be called regardless of the pfnConstruct result to avoid
* complicated failure paths.
*
* @param pUsbIns The USB device instance data.
@@ -672,6 +677,38 @@ typedef struct PDMUSBHLP
*/
DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMUSBINS pUsbIns));
+ /**
+ * Gets the reason for the most recent VM suspend.
+ *
+ * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no
+ * suspend has been made or if the pUsbIns is invalid.
+ * @param pUsbIns The driver instance.
+ */
+ DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMUSBINS pUsbIns));
+
+ /**
+ * Gets the reason for the most recent VM resume.
+ *
+ * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no
+ * resume has been made or if the pUsbIns is invalid.
+ * @param pUsbIns The driver instance.
+ */
+ DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMUSBINS pUsbIns));
+
+ /** @name Space reserved for minor interface changes.
+ * @{ */
+ DECLR3CALLBACKMEMBER(void, pfnReserved0,(PPDMUSBINS pUsbIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved1,(PPDMUSBINS pUsbIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved2,(PPDMUSBINS pUsbIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved3,(PPDMUSBINS pUsbIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved4,(PPDMUSBINS pUsbIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved5,(PPDMUSBINS pUsbIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved6,(PPDMUSBINS pUsbIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved7,(PPDMUSBINS pUsbIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved8,(PPDMUSBINS pUsbIns));
+ DECLR3CALLBACKMEMBER(void, pfnReserved9,(PPDMUSBINS pUsbIns));
+ /** @} */
+
/** Just a safety precaution. */
uint32_t u32TheEnd;
} PDMUSBHLP;
@@ -681,7 +718,7 @@ typedef PDMUSBHLP *PPDMUSBHLP;
typedef const PDMUSBHLP *PCPDMUSBHLP;
/** Current USBHLP version number. */
-#define PDM_USBHLP_VERSION PDM_VERSION_MAKE(0xeefe, 2, 0)
+#define PDM_USBHLP_VERSION PDM_VERSION_MAKE(0xeefe, 3, 0)
#endif /* IN_RING3 */
@@ -732,9 +769,12 @@ typedef struct PDMUSBINS
uint32_t fTracing;
/** The tracing ID of this device. */
uint32_t idTracing;
+ /** The USB version of the hub this device is attached to. Used to
+ * determine whether the device communicates at high-speed or full-/low-speed. */
+ uint32_t iUsbHubVersion;
/** Padding to make achInstanceData aligned at 32 byte boundary. */
- uint32_t au32Padding[HC_ARCH_BITS == 32 ? 3 : 4];
+ uint32_t au32Padding[HC_ARCH_BITS == 32 ? 2 : 3];
/** Device instance data. The size of this area is defined
* in the PDMUSBREG::cbInstanceData field. */
@@ -991,10 +1031,11 @@ typedef struct PDMUSBREGCB
*/
typedef DECLCALLBACK(int) FNPDMVBOXUSBREGISTER(PCPDMUSBREGCB pCallbacks, uint32_t u32Version);
-VMMR3DECL(int) PDMR3USBCreateProxyDevice(PVM pVM, PCRTUUID pUuid, bool fRemote, const char *pszAddress, void *pvBackend,
+VMMR3DECL(int) PDMR3UsbCreateEmulatedDevice(PUVM pUVM, const char *pszDeviceName, PCFGMNODE pDeviceNode, PCRTUUID pUuid);
+VMMR3DECL(int) PDMR3UsbCreateProxyDevice(PUVM pUVM, PCRTUUID pUuid, bool fRemote, const char *pszAddress, void *pvBackend,
uint32_t iUsbVersion, uint32_t fMaskedIfs);
-VMMR3DECL(int) PDMR3USBDetachDevice(PVM pVM, PCRTUUID pUuid);
-VMMR3DECL(bool) PDMR3USBHasHub(PVM pVM);
+VMMR3DECL(int) PDMR3UsbDetachDevice(PUVM pUVM, PCRTUUID pUuid);
+VMMR3DECL(bool) PDMR3UsbHasHub(PUVM pUVM);
/** @} */
diff --git a/include/VBox/vmm/pdmwebcaminfs.h b/include/VBox/vmm/pdmwebcaminfs.h
new file mode 100644
index 00000000..40b01614
--- /dev/null
+++ b/include/VBox/vmm/pdmwebcaminfs.h
@@ -0,0 +1,133 @@
+/* $Id: pdmwebcaminfs.h $ */
+
+/** @file
+ * webcaminfs - interfaces between dev and driver.
+ */
+
+/*
+ * Copyright (C) 2011-2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_vmm_pdmwebcaminfs_h
+#define ___VBox_vmm_pdmwebcaminfs_h
+
+
+typedef struct PDMIWEBCAM_DEVICEDESC PDMIWEBCAM_DEVICEDESC;
+typedef struct PDMIWEBCAM_CTRLHDR PDMIWEBCAM_CTRLHDR;
+typedef struct PDMIWEBCAM_FRAMEHDR PDMIWEBCAM_FRAMEHDR;
+
+
+#define PDMIWEBCAMDOWN_IID "0d29b9a1-f4cd-4719-a564-38d5634ba9f8"
+typedef struct PDMIWEBCAMDOWN *PPDMIWEBCAMDOWN;
+typedef struct PDMIWEBCAMDOWN
+{
+ /*
+ * The PDM device is ready to get webcam notifications.
+ *
+ * @param pInterface Pointer to the interface.
+ * @param fReady Whether the device is ready.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnWebcamDownReady, (PPDMIWEBCAMDOWN pInterface,
+ bool fReady));
+
+ /*
+ * Send a control request to the webcam.
+ * Async response will be returned by pfnWebcamUpControl callback.
+ *
+ * @param pInterface Pointer to the interface.
+ * @param pvUser The callers context.
+ * @param u64DeviceId Unique id for the reported webcam assigned by the driver.
+ * @param pCtrl The control data.
+ * @param cbCtrl The size of the control data.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWebcamDownControl, (PPDMIWEBCAMDOWN pInterface,
+ void *pvUser,
+ uint64_t u64DeviceId,
+ const PDMIWEBCAM_CTRLHDR *pCtrl,
+ uint32_t cbCtrl));
+} PDMIWEBCAMDOWN;
+
+
+#define PDMIWEBCAMUP_IID "6ac03e3c-f56c-4a35-80af-c13ce47a9dd7"
+typedef struct PDMIWEBCAMUP *PPDMIWEBCAMUP;
+typedef struct PDMIWEBCAMUP
+{
+ /*
+ * A webcam is available.
+ *
+ * @param pInterface Pointer to the interface.
+ * @param u64DeviceId Unique id for the reported webcam assigned by the driver.
+ * @param pDeviceDesc The device description.
+ * @param cbDeviceDesc The size of the device description.
+ * @param u32Version The remote video input protocol version.
+ * @param fu32Capabilities The remote video input protocol capabilities.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWebcamUpAttached,(PPDMIWEBCAMUP pInterface,
+ uint64_t u64DeviceId,
+ const PDMIWEBCAM_DEVICEDESC *pDeviceDesc,
+ uint32_t cbDeviceDesc,
+ uint32_t u32Version,
+ uint32_t fu32Capabilities));
+
+ /*
+ * The webcam is not available anymore.
+ *
+ * @param pInterface Pointer to the interface.
+ * @param u64DeviceId Unique id for the reported webcam assigned by the driver.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnWebcamUpDetached,(PPDMIWEBCAMUP pInterface,
+ uint64_t u64DeviceId));
+
+ /*
+ * There is a control response or a control change for the webcam.
+ *
+ * @param pInterface Pointer to the interface.
+ * @param fResponse True if this is a response for a previous pfnWebcamDownControl call.
+ * @param pvUser The pvUser parameter of the pfnWebcamDownControl call. Undefined if fResponse == false.
+ * @param u64DeviceId Unique id for the reported webcam assigned by the driver.
+ * @param pCtrl The control data.
+ * @param cbCtrl The size of the control data.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnWebcamUpControl,(PPDMIWEBCAMUP pInterface,
+ bool fResponse,
+ void *pvUser,
+ uint64_t u64DeviceId,
+ const PDMIWEBCAM_CTRLHDR *pCtrl,
+ uint32_t cbCtrl));
+
+ /*
+ * A new frame.
+ *
+ * @param pInterface Pointer to the interface.
+ * @param u64DeviceId Unique id for the reported webcam assigned by the driver.
+ * @param pHeader Payload header.
+ * @param cbHeader Size of the payload header.
+ * @param pvFrame Frame (image) data.
+ * @param cbFrame Size of the image data.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnWebcamUpFrame,(PPDMIWEBCAMUP pInterface,
+ uint64_t u64DeviceId,
+ PDMIWEBCAM_FRAMEHDR *pHeader,
+ uint32_t cbHeader,
+ const void *pvFrame,
+ uint32_t cbFrame));
+} PDMIWEBCAMUP;
+
+#endif
diff --git a/include/VBox/vmm/pgm.h b/include/VBox/vmm/pgm.h
index 5d8b5f0d..7e397b2a 100644
--- a/include/VBox/vmm/pgm.h
+++ b/include/VBox/vmm/pgm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -333,13 +333,14 @@ VMMDECL(bool) PGMGstIsPagePresent(PVMCPU pVCpu, RTGCPTR GCPtr);
VMMDECL(int) PGMGstSetPage(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags);
VMMDECL(int) PGMGstModifyPage(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask);
VMM_INT_DECL(int) PGMGstGetPaePdpes(PVMCPU pVCpu, PX86PDPE paPdpes);
-VMM_INT_DECL(int) PGMGstUpdatePaePdpes(PVMCPU pVCpu, PCX86PDPE paPdpes);
+VMM_INT_DECL(void) PGMGstUpdatePaePdpes(PVMCPU pVCpu, PCX86PDPE paPdpes);
VMMDECL(int) PGMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCPtrPage);
VMMDECL(int) PGMFlushTLB(PVMCPU pVCpu, uint64_t cr3, bool fGlobal);
VMMDECL(int) PGMSyncCR3(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal);
VMMDECL(int) PGMUpdateCR3(PVMCPU pVCpu, uint64_t cr3);
VMMDECL(int) PGMChangeMode(PVMCPU pVCpu, uint64_t cr0, uint64_t cr4, uint64_t efer);
+VMMDECL(void) PGMCr0WpEnabled(PVMCPU pVCpu);
VMMDECL(PGMMODE) PGMGetGuestMode(PVMCPU pVCpu);
VMMDECL(PGMMODE) PGMGetShadowMode(PVMCPU pVCpu);
VMMDECL(PGMMODE) PGMGetHostMode(PVM pVM);
@@ -383,7 +384,9 @@ VMMDECL(int) PGMPhysSimpleDirtyWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst,
VMMDECL(int) PGMPhysInterpretedRead(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
VMMDECL(int) PGMPhysInterpretedReadNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCUINTPTR GCPtrSrc, size_t cb, bool fRaiseTrap);
VMMDECL(int) PGMPhysInterpretedWriteNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, bool fRaiseTrap);
-VMM_INT_DECL(int) PGMPhysIemGCPhys2Ptr(PVM pVM, RTGCPHYS GCPhys, bool fWritable, bool fByPassHandlers, void **ppv, PPGMPAGEMAPLOCK pLock);
+VMM_INT_DECL(int) PGMPhysIemGCPhys2Ptr(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, bool fWritable, bool fByPassHandlers, void **ppv, PPGMPAGEMAPLOCK pLock);
+VMM_INT_DECL(int) PGMPhysIemQueryAccess(PVM pVM, RTGCPHYS GCPhys, bool fWritable, bool fByPassHandlers);
+
#ifdef VBOX_STRICT
VMMDECL(unsigned) PGMAssertHandlerAndFlagsInSync(PVM pVM);
VMMDECL(unsigned) PGMAssertNoMappingConflicts(PVM pVM);
@@ -455,8 +458,9 @@ VMMR3DECL(int) PGMR3InitDynMap(PVM pVM);
VMMR3DECL(int) PGMR3InitFinalize(PVM pVM);
VMMR3_INT_DECL(int) PGMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
VMMR3DECL(void) PGMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
-VMMR3DECL(void) PGMR3ResetUnpluggedCpu(PVM pVM, PVMCPU pVCpu);
-VMMR3DECL(void) PGMR3Reset(PVM pVM);
+VMMR3DECL(void) PGMR3ResetCpu(PVM pVM, PVMCPU pVCpu);
+VMMR3_INT_DECL(void) PGMR3Reset(PVM pVM);
+VMMR3_INT_DECL(void) PGMR3MemSetup(PVM pVM, bool fReset);
VMMR3DECL(int) PGMR3Term(PVM pVM);
VMMR3DECL(int) PGMR3LockCall(PVM pVM);
VMMR3DECL(int) PGMR3ChangeMode(PVM pVM, PVMCPU pVCpu, PGMMODE enmGuestMode);
@@ -468,8 +472,8 @@ VMMR3DECL(int) PGMR3PhysEnumDirtyFTPages(PVM pVM, PFNPGMENUMDIRTYFTPAGES pf
VMMR3DECL(uint32_t) PGMR3PhysGetRamRangeCount(PVM pVM);
VMMR3DECL(int) PGMR3PhysGetRange(PVM pVM, uint32_t iRange, PRTGCPHYS pGCPhysStart, PRTGCPHYS pGCPhysLast,
const char **ppszDesc, bool *pfIsMmio);
-VMMR3DECL(int) PGMR3QueryMemoryStats(PVM pVM, uint64_t *pcbTotalMem, uint64_t *pcbPrivateMem, uint64_t *pcbSharedMem, uint64_t *pcbZeroMem);
-VMMR3DECL(int) PGMR3QueryGlobalMemoryStats(PVM pVM, uint64_t *pcbAllocMem, uint64_t *pcbFreeMem, uint64_t *pcbBallonedMem, uint64_t *pcbSharedMem);
+VMMR3DECL(int) PGMR3QueryMemoryStats(PUVM pUVM, uint64_t *pcbTotalMem, uint64_t *pcbPrivateMem, uint64_t *pcbSharedMem, uint64_t *pcbZeroMem);
+VMMR3DECL(int) PGMR3QueryGlobalMemoryStats(PUVM pUVM, uint64_t *pcbAllocMem, uint64_t *pcbFreeMem, uint64_t *pcbBallonedMem, uint64_t *pcbSharedMem);
VMMR3DECL(int) PGMR3PhysMMIORegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3, RTR3PTR pvUserR3,
@@ -507,12 +511,13 @@ VMMDECL(void) PGMR3PhysSetA20(PVMCPU pVCpu, bool fEnable);
VMMR3DECL(int) PGMR3MapPT(PVM pVM, RTGCPTR GCPtr, uint32_t cb, uint32_t fFlags, PFNPGMRELOCATE pfnRelocate, void *pvUser, const char *pszDesc);
VMMR3DECL(int) PGMR3UnmapPT(PVM pVM, RTGCPTR GCPtr);
VMMR3DECL(int) PGMR3FinalizeMappings(PVM pVM);
-VMMR3DECL(int) PGMR3MappingsDisable(PVM pVM);
VMMR3DECL(int) PGMR3MappingsSize(PVM pVM, uint32_t *pcb);
VMMR3DECL(int) PGMR3MappingsFix(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb);
VMMR3DECL(int) PGMR3MappingsUnfix(PVM pVM);
VMMR3DECL(bool) PGMR3MappingsNeedReFixing(PVM pVM);
+#if defined(VBOX_WITH_RAW_MODE) || (HC_ARCH_BITS != 64 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL))
VMMR3DECL(int) PGMR3MapIntermediate(PVM pVM, RTUINTPTR Addr, RTHCPHYS HCPhys, unsigned cbPages);
+#endif
VMMR3DECL(int) PGMR3MapRead(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
VMMR3DECL(int) PGMR3HandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,
@@ -552,15 +557,15 @@ VMMR3DECL(int) PGMR3PhysAllocateLargeHandyPage(PVM pVM, RTGCPHYS GCPhys);
VMMR3DECL(int) PGMR3CheckIntegrity(PVM pVM);
-VMMR3DECL(int) PGMR3DbgR3Ptr2GCPhys(PVM pVM, RTR3PTR R3Ptr, PRTGCPHYS pGCPhys);
-VMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PVM pVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys);
-VMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PVM pVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys);
-VMMR3DECL(int) PGMR3DbgReadGCPhys(PVM pVM, void *pvDst, RTGCPHYS GCPhysSrc, size_t cb, uint32_t fFlags, size_t *pcbRead);
-VMMR3DECL(int) PGMR3DbgWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten);
-VMMR3DECL(int) PGMR3DbgReadGCPtr(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb, uint32_t fFlags, size_t *pcbRead);
-VMMR3DECL(int) PGMR3DbgWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten);
-VMMR3DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, RTGCPHYS GCPhysAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCPHYS pGCPhysHit);
-VMMR3DECL(int) PGMR3DbgScanVirtual(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, RTGCPTR cbRange, RTGCPTR GCPtrAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPhysHit);
+VMMR3DECL(int) PGMR3DbgR3Ptr2GCPhys(PUVM pUVM, RTR3PTR R3Ptr, PRTGCPHYS pGCPhys);
+VMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PUVM pUVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys);
+VMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PUVM pUVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys);
+VMMR3_INT_DECL(int) PGMR3DbgReadGCPhys(PVM pVM, void *pvDst, RTGCPHYS GCPhysSrc, size_t cb, uint32_t fFlags, size_t *pcbRead);
+VMMR3_INT_DECL(int) PGMR3DbgWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten);
+VMMR3_INT_DECL(int) PGMR3DbgReadGCPtr(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb, uint32_t fFlags, size_t *pcbRead);
+VMMR3_INT_DECL(int) PGMR3DbgWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten);
+VMMR3_INT_DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, RTGCPHYS GCPhysAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCPHYS pGCPhysHit);
+VMMR3_INT_DECL(int) PGMR3DbgScanVirtual(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, RTGCPTR cbRange, RTGCPTR GCPtrAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPhysHit);
VMMR3_INT_DECL(int) PGMR3DumpHierarchyShw(PVM pVM, uint64_t cr3, uint32_t fFlags, uint64_t u64FirstAddr, uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
VMMR3_INT_DECL(int) PGMR3DumpHierarchyGst(PVM pVM, uint64_t cr3, uint32_t fFlags, RTGCPTR FirstAddr, RTGCPTR LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
diff --git a/include/VBox/vmm/rem.h b/include/VBox/vmm/rem.h
index 79a18810..bda6e29a 100644
--- a/include/VBox/vmm/rem.h
+++ b/include/VBox/vmm/rem.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/include/VBox/vmm/selm.h b/include/VBox/vmm/selm.h
index 763d0acf..7503e734 100644
--- a/include/VBox/vmm/selm.h
+++ b/include/VBox/vmm/selm.h
@@ -41,7 +41,6 @@ RT_C_DECLS_BEGIN
VMMDECL(RTSEL) SELMGetTrap8Selector(PVM pVM);
VMMDECL(void) SELMSetTrap8EIP(PVM pVM, uint32_t u32EIP);
VMMDECL(int) SELMGetRing1Stack(PVM pVM, uint32_t *pSS, PRTGCPTR32 pEsp);
-VMMDECL(RTGCPTR) SELMGetGuestTSS(PVM pVM);
VMMDECL(RTSEL) SELMGetHyperCS(PVM pVM);
VMMDECL(RTSEL) SELMGetHyperCS64(PVM pVM);
VMMDECL(RTSEL) SELMGetHyperDS(PVM pVM);
@@ -94,11 +93,12 @@ VMMR3DECL(int) SELMR3InitFinalize(PVM pVM);
VMMR3DECL(void) SELMR3Relocate(PVM pVM);
VMMR3DECL(int) SELMR3Term(PVM pVM);
VMMR3DECL(void) SELMR3Reset(PVM pVM);
+# ifdef VBOX_WITH_RAW_MODE
VMMR3DECL(VBOXSTRICTRC) SELMR3UpdateFromCPUM(PVM pVM, PVMCPU pVCpu);
VMMR3DECL(int) SELMR3SyncTSS(PVM pVM, PVMCPU pVCpu);
+# endif
VMMR3DECL(int) SELMR3GetSelectorInfo(PVM pVM, PVMCPU pVCpu, RTSEL Sel, PDBGFSELINFO pSelInfo);
VMMR3DECL(int) SELMR3GetShadowSelectorInfo(PVM pVM, RTSEL Sel, PDBGFSELINFO pSelInfo);
-VMMR3DECL(void) SELMR3DisableMonitoring(PVM pVM);
VMMR3DECL(void) SELMR3DumpDescriptor(X86DESC Desc, RTSEL Sel, const char *pszMsg);
VMMR3DECL(void) SELMR3DumpHyperGDT(PVM pVM);
VMMR3DECL(void) SELMR3DumpHyperLDT(PVM pVM);
@@ -106,6 +106,10 @@ VMMR3DECL(void) SELMR3DumpGuestGDT(PVM pVM);
VMMR3DECL(void) SELMR3DumpGuestLDT(PVM pVM);
VMMR3DECL(bool) SELMR3CheckTSS(PVM pVM);
VMMR3DECL(int) SELMR3DebugCheck(PVM pVM);
+# ifdef VBOX_WITH_SAFE_STR
+VMMR3DECL(bool) SELMR3CheckShadowTR(PVM pVM);
+# endif
+
/** @def SELMR3_DEBUG_CHECK
* Invokes SELMR3DebugCheck in stricts builds. */
# ifdef VBOX_STRICT
diff --git a/include/VBox/vmm/ssm.h b/include/VBox/vmm/ssm.h
index 427e0796..8218930f 100644
--- a/include/VBox/vmm/ssm.h
+++ b/include/VBox/vmm/ssm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -377,7 +377,11 @@ typedef struct SSMFIELD
#define SSMSTRUCT_FLAGS_DONT_IGNORE RT_BIT_32(2)
/** Saved using SSMR3PutMem, don't be too strict. */
#define SSMSTRUCT_FLAGS_SAVED_AS_MEM RT_BIT_32(3)
-/** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host pointers. */
+/** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host pointers.
+ * @remarks This type is normally only used up to the first changes to the
+ * structures take place in order to make sure the conversion from
+ * SSMR3PutMem to field descriptors went smoothly. Replace with
+ * SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED when changing the structure. */
#define SSMSTRUCT_FLAGS_MEM_BAND_AID ( SSMSTRUCT_FLAGS_DONT_IGNORE | SSMSTRUCT_FLAGS_FULL_STRUCT \
| SSMSTRUCT_FLAGS_NO_MARKERS | SSMSTRUCT_FLAGS_SAVED_AS_MEM)
/** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host
@@ -399,6 +403,7 @@ typedef struct SSMFIELD
* @returns VBox status code.
* @param pDevIns Device instance of the device which registered the data unit.
* @param pSSM SSM operation handle.
+ * @remarks The caller enters the device critical section prior to the call.
* @thread Any.
*/
typedef DECLCALLBACK(int) FNSSMDEVLIVEPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
@@ -415,6 +420,7 @@ typedef FNSSMDEVLIVEPREP *PFNSSMDEVLIVEPREP;
* @param pDevIns Device instance of the device which registered the data unit.
* @param pSSM SSM operation handle.
* @param uPass The pass.
+ * @remarks The caller enters the device critical section prior to the call.
* @thread Any.
*/
typedef DECLCALLBACK(int) FNSSMDEVLIVEEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass);
@@ -437,6 +443,7 @@ typedef FNSSMDEVLIVEEXEC *PFNSSMDEVLIVEEXEC;
* @param pDevIns Device instance of the device which registered the data unit.
* @param pSSM SSM operation handle.
* @param uPass The data pass.
+ * @remarks The caller enters the device critical section prior to the call.
* @thread Any.
*/
typedef DECLCALLBACK(int) FNSSMDEVLIVEVOTE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass);
@@ -449,6 +456,7 @@ typedef FNSSMDEVLIVEVOTE *PFNSSMDEVLIVEVOTE;
* @returns VBox status code.
* @param pDevIns Device instance of the device which registered the data unit.
* @param pSSM SSM operation handle.
+ * @remarks The caller enters the device critical section prior to the call.
*/
typedef DECLCALLBACK(int) FNSSMDEVSAVEPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
/** Pointer to a FNSSMDEVSAVEPREP() function. */
@@ -460,6 +468,7 @@ typedef FNSSMDEVSAVEPREP *PFNSSMDEVSAVEPREP;
* @returns VBox status code.
* @param pDevIns Device instance of the device which registered the data unit.
* @param pSSM SSM operation handle.
+ * @remarks The caller enters the device critical section prior to the call.
*/
typedef DECLCALLBACK(int) FNSSMDEVSAVEEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
/** Pointer to a FNSSMDEVSAVEEXEC() function. */
@@ -471,6 +480,7 @@ typedef FNSSMDEVSAVEEXEC *PFNSSMDEVSAVEEXEC;
* @returns VBox status code.
* @param pDevIns Device instance of the device which registered the data unit.
* @param pSSM SSM operation handle.
+ * @remarks The caller enters the device critical section prior to the call.
*/
typedef DECLCALLBACK(int) FNSSMDEVSAVEDONE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
/** Pointer to a FNSSMDEVSAVEDONE() function. */
@@ -482,6 +492,7 @@ typedef FNSSMDEVSAVEDONE *PFNSSMDEVSAVEDONE;
* @returns VBox status code.
* @param pDevIns Device instance of the device which registered the data unit.
* @param pSSM SSM operation handle.
+ * @remarks The caller enters the device critical section prior to the call.
*/
typedef DECLCALLBACK(int) FNSSMDEVLOADPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
/** Pointer to a FNSSMDEVLOADPREP() function. */
@@ -496,6 +507,7 @@ typedef FNSSMDEVLOADPREP *PFNSSMDEVLOADPREP;
* @param uVersion Data layout version.
* @param uPass The pass. This is always SSM_PASS_FINAL for units
* that doesn't specify a pfnSaveLive callback.
+ * @remarks The caller enters the device critical section prior to the call.
*/
typedef DECLCALLBACK(int) FNSSMDEVLOADEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
/** Pointer to a FNSSMDEVLOADEXEC() function. */
@@ -507,6 +519,7 @@ typedef FNSSMDEVLOADEXEC *PFNSSMDEVLOADEXEC;
* @returns VBox load code.
* @param pDevIns Device instance of the device which registered the data unit.
* @param pSSM SSM operation handle.
+ * @remarks The caller enters the device critical section prior to the call.
*/
typedef DECLCALLBACK(int) FNSSMDEVLOADDONE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
/** Pointer to a FNSSMDEVLOADDONE() function. */
@@ -1131,22 +1144,28 @@ typedef struct SSMSTRMOPS
VMMR3_INT_DECL(void) SSMR3Term(PVM pVM);
-VMMR3DECL(int) SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
- PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
- PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
- PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone);
-VMMR3DECL(int) SSMR3RegisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess,
- PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote,
- PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone,
- PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone);
-VMMR3DECL(int) SSMR3RegisterInternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess,
- PFNSSMINTLIVEPREP pfnLivePrep, PFNSSMINTLIVEEXEC pfnLiveExec, PFNSSMINTLIVEVOTE pfnLiveVote,
- PFNSSMINTSAVEPREP pfnSavePrep, PFNSSMINTSAVEEXEC pfnSaveExec, PFNSSMINTSAVEDONE pfnSaveDone,
- PFNSSMINTLOADPREP pfnLoadPrep, PFNSSMINTLOADEXEC pfnLoadExec, PFNSSMINTLOADDONE pfnLoadDone);
-VMMR3DECL(int) SSMR3RegisterExternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess,
- PFNSSMEXTLIVEPREP pfnLivePrep, PFNSSMEXTLIVEEXEC pfnLiveExec, PFNSSMEXTLIVEVOTE pfnLiveVote,
- PFNSSMEXTSAVEPREP pfnSavePrep, PFNSSMEXTSAVEEXEC pfnSaveExec, PFNSSMEXTSAVEDONE pfnSaveDone,
- PFNSSMEXTLOADPREP pfnLoadPrep, PFNSSMEXTLOADEXEC pfnLoadExec, PFNSSMEXTLOADDONE pfnLoadDone, void *pvUser);
+VMMR3_INT_DECL(int)
+SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance, uint32_t uVersion,
+ size_t cbGuess, const char *pszBefore,
+ PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
+ PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
+ PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone);
+VMMR3_INT_DECL(int)
+SSMR3RegisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess,
+ PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote,
+ PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone,
+ PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone);
+VMMR3DECL(int)
+SSMR3RegisterInternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess,
+ PFNSSMINTLIVEPREP pfnLivePrep, PFNSSMINTLIVEEXEC pfnLiveExec, PFNSSMINTLIVEVOTE pfnLiveVote,
+ PFNSSMINTSAVEPREP pfnSavePrep, PFNSSMINTSAVEEXEC pfnSaveExec, PFNSSMINTSAVEDONE pfnSaveDone,
+ PFNSSMINTLOADPREP pfnLoadPrep, PFNSSMINTLOADEXEC pfnLoadExec, PFNSSMINTLOADDONE pfnLoadDone);
+VMMR3DECL(int)
+SSMR3RegisterExternal(PUVM pUVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess,
+ PFNSSMEXTLIVEPREP pfnLivePrep, PFNSSMEXTLIVEEXEC pfnLiveExec, PFNSSMEXTLIVEVOTE pfnLiveVote,
+ PFNSSMEXTSAVEPREP pfnSavePrep, PFNSSMEXTSAVEEXEC pfnSaveExec, PFNSSMEXTSAVEDONE pfnSaveDone,
+ PFNSSMEXTLOADPREP pfnLoadPrep, PFNSSMEXTLOADEXEC pfnLoadExec, PFNSSMEXTLOADDONE pfnLoadDone, void *pvUser);
+VMMR3DECL(int) SSMR3RegisterStub(PVM pVM, const char *pszName, uint32_t uInstance);
VMMR3_INT_DECL(int) SSMR3DeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance);
VMMR3_INT_DECL(int) SSMR3DeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance);
VMMR3DECL(int) SSMR3DeregisterInternal(PVM pVM, const char *pszName);
@@ -1176,7 +1195,7 @@ VMMR3DECL(uint32_t) SSMR3HandleVersion(PSSMHANDLE pSSM);
VMMR3DECL(const char *) SSMR3HandleHostOSAndArch(PSSMHANDLE pSSM);
VMMR3_INT_DECL(int) SSMR3HandleSetGCPtrSize(PSSMHANDLE pSSM, unsigned cbGCPtr);
VMMR3DECL(void) SSMR3HandleReportLivePercent(PSSMHANDLE pSSM, unsigned uPercent);
-VMMR3DECL(int) SSMR3Cancel(PVM pVM);
+VMMR3DECL(int) SSMR3Cancel(PUVM pUVM);
/** Save operations.
diff --git a/include/VBox/vmm/stam.h b/include/VBox/vmm/stam.h
index c25c606f..e7f2c556 100644
--- a/include/VBox/vmm/stam.h
+++ b/include/VBox/vmm/stam.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -1200,38 +1200,17 @@ VMMR3DECL(int) STAMR3RegisterCallback(PVM pVM, void *pvSample, STAMVISIBILITY e
VMMR3DECL(int) STAMR3RegisterCallbackV(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint,
const char *pszDesc, const char *pszName, va_list args);
-VMMR3DECL(int) STAMR3DeregisterU(PUVM pUVM, void *pvSample);
-VMMR3DECL(int) STAMR3Deregister(PVM pVM, void *pvSample);
-
-/** @def STAM_REL_DEREG
- * Deregisters a statistics sample if statistics are enabled.
- *
- * @param pVM VM Handle.
- * @param pvSample Pointer to the sample.
- */
-#define STAM_REL_DEREG(pVM, pvSample) \
- STAM_REL_STATS({ int rcStam = STAMR3Deregister(pVM, pvSample); AssertRC(rcStam); })
-/** @def STAM_DEREG
- * Deregisters a statistics sample if statistics are enabled.
- *
- * @param pVM VM Handle.
- * @param pvSample Pointer to the sample.
- */
-#define STAM_DEREG(pVM, pvSample) \
- STAM_STATS({ STAM_REL_DEREG(pVM, pvSample); })
-
-VMMR3DECL(int) STAMR3ResetU(PUVM pUVM, const char *pszPat);
-VMMR3DECL(int) STAMR3Reset(PVM pVM, const char *pszPat);
-VMMR3DECL(int) STAMR3SnapshotU(PUVM pUVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc);
-VMMR3DECL(int) STAMR3Snapshot(PVM pVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc);
-VMMR3DECL(int) STAMR3SnapshotFreeU(PUVM pUVM, char *pszSnapshot);
-VMMR3DECL(int) STAMR3SnapshotFree(PVM pVM, char *pszSnapshot);
-VMMR3DECL(int) STAMR3DumpU(PUVM pUVM, const char *pszPat);
-VMMR3DECL(int) STAMR3Dump(PVM pVM, const char *pszPat);
-VMMR3DECL(int) STAMR3DumpToReleaseLogU(PUVM pUVM, const char *pszPat);
-VMMR3DECL(int) STAMR3DumpToReleaseLog(PVM pVM, const char *pszPat);
-VMMR3DECL(int) STAMR3PrintU(PUVM pUVM, const char *pszPat);
-VMMR3DECL(int) STAMR3Print(PVM pVM, const char *pszPat);
+VMMR3DECL(int) STAMR3Deregister(PUVM pUVM, const char *pszPat);
+VMMR3DECL(int) STAMR3DeregisterF(PUVM pUVM, const char *pszPatFmt, ...);
+VMMR3DECL(int) STAMR3DeregisterV(PUVM pUVM, const char *pszPatFmt, va_list va);
+VMMR3DECL(int) STAMR3DeregisterByAddr(PUVM pUVM, void *pvSample);
+
+VMMR3DECL(int) STAMR3Reset(PUVM pUVM, const char *pszPat);
+VMMR3DECL(int) STAMR3Snapshot(PUVM pUVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc);
+VMMR3DECL(int) STAMR3SnapshotFree(PUVM pUVM, char *pszSnapshot);
+VMMR3DECL(int) STAMR3Dump(PUVM pUVM, const char *pszPat);
+VMMR3DECL(int) STAMR3DumpToReleaseLog(PUVM pUVM, const char *pszPat);
+VMMR3DECL(int) STAMR3Print(PUVM pUVM, const char *pszPat);
/**
* Callback function for STAMR3Enum().
@@ -1251,8 +1230,7 @@ typedef DECLCALLBACK(int) FNSTAMR3ENUM(const char *pszName, STAMTYPE enmType, vo
/** Pointer to a FNSTAMR3ENUM(). */
typedef FNSTAMR3ENUM *PFNSTAMR3ENUM;
-VMMR3DECL(int) STAMR3EnumU(PUVM pUVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser);
-VMMR3DECL(int) STAMR3Enum(PVM pVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser);
+VMMR3DECL(int) STAMR3Enum(PUVM pUVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser);
VMMR3DECL(const char *) STAMR3GetUnit(STAMUNIT enmUnit);
/** @} */
diff --git a/include/VBox/vmm/tm.h b/include/VBox/vmm/tm.h
index be328b1c..8f857a4c 100644
--- a/include/VBox/vmm/tm.h
+++ b/include/VBox/vmm/tm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -87,9 +87,9 @@ VMM_INT_DECL(void) TMNotifyEndOfHalt(PVMCPU pVCpu);
#ifdef IN_RING3
VMMR3DECL(int) TMR3NotifySuspend(PVM pVM, PVMCPU pVCpu);
VMMR3DECL(int) TMR3NotifyResume(PVM pVM, PVMCPU pVCpu);
-VMMR3DECL(int) TMR3SetWarpDrive(PVM pVM, uint32_t u32Percent);
+VMMR3DECL(int) TMR3SetWarpDrive(PUVM pUVM, uint32_t u32Percent);
+VMMR3DECL(uint32_t) TMR3GetWarpDrive(PUVM pUVM);
#endif
-VMMDECL(uint32_t) TMGetWarpDrive(PVM pVM);
VMM_INT_DECL(uint32_t) TMCalcHostTimerFrequency(PVM pVM, PVMCPU pVCpu);
#ifdef IN_RING3
VMMR3DECL(int) TMR3GetCpuLoadTimes(PVM pVM, VMCPUID idCpu, uint64_t *pcNsTotal, uint64_t *pcNsExecuting,
diff --git a/include/VBox/vmm/trpm.h b/include/VBox/vmm/trpm.h
index 0cdfc153..7dc436c6 100644
--- a/include/VBox/vmm/trpm.h
+++ b/include/VBox/vmm/trpm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -68,17 +68,20 @@ typedef TRPMEVENT const *PCTRPMEVENT;
*/
#define TRPM_INVALID_HANDLER 0
-VMMDECL(int) TRPMQueryTrap(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType);
+VMMDECL(int) TRPMQueryTrap(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT penmType);
VMMDECL(uint8_t) TRPMGetTrapNo(PVMCPU pVCpu);
VMMDECL(RTGCUINT) TRPMGetErrorCode(PVMCPU pVCpu);
VMMDECL(RTGCUINTPTR) TRPMGetFaultAddress(PVMCPU pVCpu);
+VMMDECL(uint8_t) TRPMGetInstrLength(PVMCPU pVCpu);
VMMDECL(int) TRPMResetTrap(PVMCPU pVCpu);
VMMDECL(int) TRPMAssertTrap(PVMCPU pVCpu, uint8_t u8TrapNo, TRPMEVENT enmType);
+VMMDECL(int) TRPMAssertXcptPF(PVMCPU pVCpu, RTGCUINTPTR uCR2, RTGCUINT uErrorCode);
VMMDECL(void) TRPMSetErrorCode(PVMCPU pVCpu, RTGCUINT uErrorCode);
VMMDECL(void) TRPMSetFaultAddress(PVMCPU pVCpu, RTGCUINTPTR uCR2);
+VMMDECL(void) TRPMSetInstrLength(PVMCPU pVCpu, uint8_t cbInstr);
VMMDECL(bool) TRPMIsSoftwareInterrupt(PVMCPU pVCpu);
VMMDECL(bool) TRPMHasTrap(PVMCPU pVCpu);
-VMMDECL(int) TRPMQueryTrapAll(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType, PRTGCUINT puErrorCode, PRTGCUINTPTR puCR2);
+VMMDECL(int) TRPMQueryTrapAll(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType, PRTGCUINT puErrorCode, PRTGCUINTPTR puCR2, uint8_t *pcbInstr);
VMMDECL(void) TRPMSaveTrap(PVMCPU pVCpu);
VMMDECL(void) TRPMRestoreTrap(PVMCPU pVCpu);
VMMDECL(int) TRPMForwardTrap(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t iGate, uint32_t cbInstr, TRPMERRORCODE enmError, TRPMEVENT enmType, int32_t iOrgTrap);
@@ -96,16 +99,17 @@ VMMR3DECL(int) TRPMR3Init(PVM pVM);
VMMR3DECL(void) TRPMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
VMMR3DECL(void) TRPMR3ResetCpu(PVMCPU pVCpu);
VMMR3DECL(void) TRPMR3Reset(PVM pVM);
-VMMR3_INT_DECL(int) TRPMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue);
VMMR3DECL(int) TRPMR3Term(PVM pVM);
-VMMR3DECL(int) TRPMR3EnableGuestTrapHandler(PVM pVM, unsigned iTrap);
-VMMR3DECL(int) TRPMR3SetGuestTrapHandler(PVM pVM, unsigned iTrap, RTRCPTR pHandler);
-VMMR3DECL(RTRCPTR) TRPMR3GetGuestTrapHandler(PVM pVM, unsigned iTrap);
-VMMR3DECL(void) TRPMR3DisableMonitoring(PVM pVM);
+VMMR3DECL(int) TRPMR3InjectEvent(PVM pVM, PVMCPU pVCpu, TRPMEVENT enmEvent);
+# ifdef VBOX_WITH_RAW_MODE
+VMMR3_INT_DECL(int) TRPMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue);
VMMR3DECL(int) TRPMR3SyncIDT(PVM pVM, PVMCPU pVCpu);
VMMR3DECL(bool) TRPMR3IsGateHandler(PVM pVM, RTRCPTR GCPtr);
VMMR3DECL(uint32_t) TRPMR3QueryGateByHandler(PVM pVM, RTRCPTR GCPtr);
-VMMR3DECL(int) TRPMR3InjectEvent(PVM pVM, PVMCPU pVCpu, TRPMEVENT enmEvent);
+VMMR3DECL(int) TRPMR3EnableGuestTrapHandler(PVM pVM, unsigned iTrap);
+VMMR3DECL(int) TRPMR3SetGuestTrapHandler(PVM pVM, unsigned iTrap, RTRCPTR pHandler);
+VMMR3DECL(RTRCPTR) TRPMR3GetGuestTrapHandler(PVM pVM, unsigned iTrap);
+# endif
/** @} */
#endif
diff --git a/include/VBox/vmm/uvm.h b/include/VBox/vmm/uvm.h
index 10b8e49b..37087752 100644
--- a/include/VBox/vmm/uvm.h
+++ b/include/VBox/vmm/uvm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2007-2010 Oracle Corporation
+ * Copyright (C) 2007-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -55,6 +55,16 @@ typedef struct UVMCPU
#endif
uint8_t padding[512];
} vm;
+
+ /** The DBGF data. */
+ union
+ {
+#ifdef ___DBGFInternal_h
+ struct DBGFUSERPERVMCPU s;
+#endif
+ uint8_t padding[64];
+ } dbgf;
+
} UVMCPU;
AssertCompileMemberAlignment(UVMCPU, vm, 32);
@@ -114,7 +124,7 @@ typedef struct UVM
#ifdef ___PDMInternal_h
struct PDMUSERPERVM s;
#endif
- uint8_t padding[128];
+ uint8_t padding[256];
} pdm;
/** The STAM data. */
@@ -123,9 +133,18 @@ typedef struct UVM
#ifdef ___STAMInternal_h
struct STAMUSERPERVM s;
#endif
- uint8_t padding[6624];
+ uint8_t padding[6880];
} stam;
+ /** The DBGF data. */
+ union
+ {
+#ifdef ___DBGFInternal_h
+ struct DBGFUSERPERVM s;
+#endif
+ uint8_t padding[256];
+ } dbgf;
+
/** Per virtual CPU data. */
UVMCPU aCpus[1];
} UVM;
diff --git a/include/VBox/vmm/vm.h b/include/VBox/vmm/vm.h
index ef713127..bebb9836 100644
--- a/include/VBox/vmm/vm.h
+++ b/include/VBox/vmm/vm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -68,7 +68,9 @@ typedef enum VMCPUSTATE
/** CPU started. */
VMCPUSTATE_STARTED,
- /** Executing guest code and can be poked. */
+ /** CPU started in HM context. */
+ VMCPUSTATE_STARTED_HM,
+ /** Executing guest code and can be poked (RC or STI bits of HM). */
VMCPUSTATE_STARTED_EXEC,
/** Executing guest code in the recompiler. */
VMCPUSTATE_STARTED_EXEC_REM,
@@ -84,7 +86,9 @@ typedef enum VMCPUSTATE
/**
- * Per virtual CPU data.
+ * The cross context virtual CPU structure.
+ *
+ * Run 'kmk run-struct-tests' (from src/VBox/VMM if you like) after updating!
*/
typedef struct VMCPU
{
@@ -110,7 +114,7 @@ typedef struct VMCPU
/** The native R0 thread handle. (different from the R3 handle!) */
RTNATIVETHREAD hNativeThreadR0; /* 48 / 32 */
/** Which host CPU ID is this EMT running on.
- * Only valid when in RC or HWACCMR0 with scheduling disabled. */
+ * Only valid when in RC or HMR0 with scheduling disabled. */
RTCPUID volatile idHostCpu; /* 56 / 36 */
/** Trace groups enable flags. */
@@ -138,14 +142,14 @@ typedef struct VMCPU
uint8_t padding[3584]; /* multiple of 64 */
} cpum;
- /** HWACCM part. */
+ /** HM part. */
union
{
-#ifdef ___HWACCMInternal_h
- struct HWACCMCPU s;
+#ifdef ___HMInternal_h
+ struct HMCPU s;
#endif
- uint8_t padding[5376]; /* multiple of 64 */
- } hwaccm;
+ uint8_t padding[5568]; /* multiple of 64 */
+ } hm;
/** EM part. */
union
@@ -189,7 +193,7 @@ typedef struct VMCPU
#ifdef ___VMMInternal_h
struct VMMCPU s;
#endif
- uint8_t padding[640]; /* multiple of 64 */
+ uint8_t padding[704]; /* multiple of 64 */
} vmm;
/** PDM part. */
@@ -198,7 +202,7 @@ typedef struct VMCPU
#ifdef ___PDMInternal_h
struct PDMCPU s;
#endif
- uint8_t padding[128]; /* multiple of 64 */
+ uint8_t padding[256]; /* multiple of 64 */
} pdm;
/** IOM part. */
@@ -221,7 +225,7 @@ typedef struct VMCPU
} dbgf;
/** Align the following members on page boundary. */
- uint8_t abAlignment2[1024 - 320 - 128];
+ uint8_t abAlignment2[192];
/** PGM part. */
union
@@ -271,6 +275,16 @@ typedef struct VMCPU
/** The name of the Ring 0 Context VMM Core module. */
#define VMMR0_MAIN_MODULE_NAME "VMMR0.r0"
+/**
+ * Wrapper macro for avoiding too much \#ifdef VBOX_WITH_RAW_MODE.
+ */
+#ifdef VBOX_WITH_RAW_MODE
+# define VM_WHEN_RAW_MODE(a_WithExpr, a_WithoutExpr) a_WithExpr
+#else
+# define VM_WHEN_RAW_MODE(a_WithExpr, a_WithoutExpr) a_WithoutExpr
+#endif
+
+
/** VM Forced Action Flags.
*
* Use the VM_FF_SET() and VM_FF_CLEAR() macros to change the force
@@ -347,6 +361,12 @@ typedef struct VMCPU
/** This action forces the VM to service pending requests from other
* thread or requests which must be executed in another context. */
#define VMCPU_FF_REQUEST RT_BIT_32(9)
+/** This action forces the VM to service any pending updates to CR3 (used only
+ * by HM). */
+#define VMCPU_FF_HM_UPDATE_CR3 RT_BIT_32(12)
+/** This action forces the VM to service any pending updates to PAE PDPEs (used
+ * only by HM). */
+#define VMCPU_FF_HM_UPDATE_PAE_PDPES RT_BIT_32(13)
/** This action forces the VM to resync the page tables before going
* back to execute guest code. (GLOBAL FLUSH) */
#define VMCPU_FF_PGM_SYNC_CR3 RT_BIT_32(16)
@@ -354,29 +374,33 @@ typedef struct VMCPU
* (NON-GLOBAL FLUSH) */
#define VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL RT_BIT_32(17)
/** Check for pending TLB shootdown actions.
- * Consumer: HWACCM
- * @todo rename to VMCPU_FF_HWACCM_TLB_SHOOTDOWN */
+ * Consumer: HM
+ * @todo rename to VMCPU_FF_HM_TLB_SHOOTDOWN */
#define VMCPU_FF_TLB_SHOOTDOWN RT_BIT_32(18)
/** Check for pending TLB flush action.
- * Consumer: HWACCM
- * @todo rename to VMCPU_FF_HWACCM_TLB_FLUSH */
+ * Consumer: HM
+ * @todo rename to VMCPU_FF_HM_TLB_FLUSH */
#define VMCPU_FF_TLB_FLUSH RT_BIT_32(VMCPU_FF_TLB_FLUSH_BIT)
/** The bit number for VMCPU_FF_TLB_FLUSH. */
#define VMCPU_FF_TLB_FLUSH_BIT 19
+#ifdef VBOX_WITH_RAW_MODE
/** Check the interrupt and trap gates */
-#define VMCPU_FF_TRPM_SYNC_IDT RT_BIT_32(20)
+# define VMCPU_FF_TRPM_SYNC_IDT RT_BIT_32(20)
/** Check Guest's TSS ring 0 stack */
-#define VMCPU_FF_SELM_SYNC_TSS RT_BIT_32(21)
+# define VMCPU_FF_SELM_SYNC_TSS RT_BIT_32(21)
/** Check Guest's GDT table */
-#define VMCPU_FF_SELM_SYNC_GDT RT_BIT_32(22)
+# define VMCPU_FF_SELM_SYNC_GDT RT_BIT_32(22)
/** Check Guest's LDT table */
-#define VMCPU_FF_SELM_SYNC_LDT RT_BIT_32(23)
+# define VMCPU_FF_SELM_SYNC_LDT RT_BIT_32(23)
+#endif /* VBOX_WITH_RAW_MODE */
/** Inhibit interrupts pending. See EMGetInhibitInterruptsPC(). */
#define VMCPU_FF_INHIBIT_INTERRUPTS RT_BIT_32(24)
+#ifdef VBOX_WITH_RAW_MODE
/** CSAM needs to scan the page that's being executed */
-#define VMCPU_FF_CSAM_SCAN_PAGE RT_BIT_32(26)
+# define VMCPU_FF_CSAM_SCAN_PAGE RT_BIT_32(26)
/** CSAM needs to do some homework. */
-#define VMCPU_FF_CSAM_PENDING_ACTION RT_BIT_32(27)
+# define VMCPU_FF_CSAM_PENDING_ACTION RT_BIT_32(27)
+#endif /* VBOX_WITH_RAW_MODE */
/** Force return to Ring-3. */
#define VMCPU_FF_TO_R3 RT_BIT_32(28)
@@ -389,45 +413,67 @@ typedef struct VMCPU
#define VM_FF_EXTERNAL_HALTED_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_REQUEST \
| VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_EMT_RENDEZVOUS)
/** Externally forced VMCPU actions. Used to quit the idle/wait loop. */
-#define VMCPU_FF_EXTERNAL_HALTED_MASK (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_REQUEST | VMCPU_FF_TIMER)
+#define VMCPU_FF_EXTERNAL_HALTED_MASK ( VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_REQUEST \
+ | VMCPU_FF_TIMER)
/** High priority VM pre-execution actions. */
#define VM_FF_HIGH_PRIORITY_PRE_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_TM_VIRTUAL_SYNC \
- | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS)
+ | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY \
+ | VM_FF_EMT_RENDEZVOUS)
/** High priority VMCPU pre-execution actions. */
-#define 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_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \
- | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_INHIBIT_INTERRUPTS)
+#define 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 ) )
/** High priority VM pre raw-mode execution mask. */
#define VM_FF_HIGH_PRIORITY_PRE_RAW_MASK (VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY)
/** High priority VMCPU pre raw-mode execution mask. */
-#define VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK ( VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \
- | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_INHIBIT_INTERRUPTS)
+#define VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK ( 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) )
/** High priority post-execution actions. */
#define VM_FF_HIGH_PRIORITY_POST_MASK (VM_FF_PGM_NO_MEMORY)
/** High priority post-execution actions. */
-#define VMCPU_FF_HIGH_PRIORITY_POST_MASK (VMCPU_FF_PDM_CRITSECT|VMCPU_FF_CSAM_PENDING_ACTION)
+#define VMCPU_FF_HIGH_PRIORITY_POST_MASK ( VMCPU_FF_PDM_CRITSECT | VM_WHEN_RAW_MODE(VMCPU_FF_CSAM_PENDING_ACTION, 0) \
+ | VMCPU_FF_HM_UPDATE_CR3 | VMCPU_FF_HM_UPDATE_PAE_PDPES)
/** Normal priority VM post-execution actions. */
#define 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)
/** Normal priority VMCPU post-execution actions. */
-#define VMCPU_FF_NORMAL_PRIORITY_POST_MASK (VMCPU_FF_CSAM_SCAN_PAGE)
+#define VMCPU_FF_NORMAL_PRIORITY_POST_MASK VM_WHEN_RAW_MODE(VMCPU_FF_CSAM_SCAN_PAGE, 0)
/** Normal priority VM actions. */
-#define 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)
+#define 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)
/** Normal priority VMCPU actions. */
#define VMCPU_FF_NORMAL_PRIORITY_MASK (VMCPU_FF_REQUEST)
/** Flags to clear before resuming guest execution. */
#define VMCPU_FF_RESUME_GUEST_MASK (VMCPU_FF_TO_R3)
-/** VM Flags that cause the HWACCM loops to go back to ring-3. */
-#define VM_FF_HWACCM_TO_R3_MASK (VM_FF_TM_VIRTUAL_SYNC | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_PDM_QUEUES | VM_FF_EMT_RENDEZVOUS)
-/** VMCPU Flags that cause the HWACCM loops to go back to ring-3. */
-#define VMCPU_FF_HWACCM_TO_R3_MASK (VMCPU_FF_TO_R3 | VMCPU_FF_TIMER | VMCPU_FF_PDM_CRITSECT)
+/** VM Flags that cause the HM loops to go back to ring-3. */
+#define VM_FF_HM_TO_R3_MASK ( VM_FF_TM_VIRTUAL_SYNC | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY \
+ | VM_FF_PDM_QUEUES | VM_FF_EMT_RENDEZVOUS)
+/** VMCPU Flags that cause the HM loops to go back to ring-3. */
+#define VMCPU_FF_HM_TO_R3_MASK (VMCPU_FF_TO_R3 | VMCPU_FF_TIMER | VMCPU_FF_PDM_CRITSECT)
+
+/** High priority ring-0 VM pre HM-mode execution mask. */
+#define VM_FF_HP_R0_PRE_HM_MASK (VM_FF_HM_TO_R3_MASK | VM_FF_REQUEST | VM_FF_PGM_POOL_FLUSH_PENDING | VM_FF_PDM_DMA)
+/** High priority ring-0 VMCPU pre HM-mode execution mask. */
+#define VMCPU_FF_HP_R0_PRE_HM_MASK ( VMCPU_FF_HM_TO_R3_MASK | VMCPU_FF_PGM_SYNC_CR3 \
+ | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_REQUEST)
+/** High priority ring-0 VM pre HM-mode execution mask, single stepping. */
+#define VM_FF_HP_R0_PRE_HM_STEP_MASK (VM_FF_HP_R0_PRE_HM_MASK & ~( VM_FF_TM_VIRTUAL_SYNC | VM_FF_PDM_QUEUES \
+ | VM_FF_EMT_RENDEZVOUS | VM_FF_REQUEST \
+ | VM_FF_PDM_DMA) )
+/** High priority ring-0 VMCPU pre HM-mode execution mask, single stepping. */
+#define VMCPU_FF_HP_R0_PRE_HM_STEP_MASK (VMCPU_FF_HP_R0_PRE_HM_MASK & ~( VMCPU_FF_TO_R3 | VMCPU_FF_TIMER \
+ | VMCPU_FF_PDM_CRITSECT | VMCPU_FF_REQUEST) )
/** All the forced VM flags. */
#define VM_FF_ALL_MASK (~0U)
@@ -439,14 +485,15 @@ typedef struct VMCPU
#define VM_FF_ALL_REM_MASK (~(VM_FF_HIGH_PRIORITY_PRE_RAW_MASK) | VM_FF_PGM_NO_MEMORY)
/** All the forced VMCPU flags except those related to raw-mode and hardware
* assisted execution. */
-#define VMCPU_FF_ALL_REM_MASK (~(VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK | VMCPU_FF_CSAM_PENDING_ACTION | VMCPU_FF_PDM_CRITSECT | VMCPU_FF_TLB_FLUSH | VMCPU_FF_TLB_SHOOTDOWN))
-
+#define VMCPU_FF_ALL_REM_MASK (~( VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK | VMCPU_FF_PDM_CRITSECT \
+ | VMCPU_FF_TLB_FLUSH | VMCPU_FF_TLB_SHOOTDOWN \
+ | VM_WHEN_RAW_MODE(VMCPU_FF_CSAM_PENDING_ACTION, 0) ))
/** @} */
/** @def VM_FF_SET
* Sets a force action flag.
*
- * @param pVM VM Handle.
+ * @param pVM Pointer to the VM.
* @param fFlag The flag to set.
*/
#if 1
@@ -461,15 +508,15 @@ typedef struct VMCPU
/** @def VMCPU_FF_SET
* Sets a force action flag for the given VCPU.
*
- * @param pVCpu VMCPU Handle.
+ * @param pVCpu Pointer to the VMCPU.
* @param fFlag The flag to set.
*/
-#define VMCPU_FF_SET(pVCpu, fFlag) ASMAtomicOrU32(&(pVCpu)->fLocalForcedActions, (fFlag))
+#define VMCPU_FF_SET(pVCpu, fFlag) ASMAtomicOrU32(&(pVCpu)->fLocalForcedActions, (fFlag))
/** @def VM_FF_CLEAR
* Clears a force action flag.
*
- * @param pVM VM Handle.
+ * @param pVM Pointer to the VM.
* @param fFlag The flag to clear.
*/
#if 1
@@ -484,80 +531,68 @@ typedef struct VMCPU
/** @def VMCPU_FF_CLEAR
* Clears a force action flag for the given VCPU.
*
- * @param pVCpu VMCPU Handle.
+ * @param pVCpu Pointer to the VMCPU.
* @param fFlag The flag to clear.
*/
-#define VMCPU_FF_CLEAR(pVCpu, fFlag) ASMAtomicAndU32(&(pVCpu)->fLocalForcedActions, ~(fFlag))
+#define VMCPU_FF_CLEAR(pVCpu, fFlag) ASMAtomicAndU32(&(pVCpu)->fLocalForcedActions, ~(fFlag))
-/** @def VM_FF_ISSET
+/** @def VM_FF_IS_SET
* Checks if a force action flag is set.
*
- * @param pVM VM Handle.
+ * @param pVM Pointer to the VM.
* @param fFlag The flag to check.
*/
#define VM_FF_IS_SET(pVM, fFlag) (((pVM)->fGlobalForcedActions & (fFlag)) == (fFlag))
-/** @deprecated */
-#define VM_FF_ISSET(pVM, fFlag) VM_FF_IS_SET(pVM, fFlag)
-/** @def VMCPU_FF_ISSET
+/** @def VMCPU_FF_IS_SET
* Checks if a force action flag is set for the given VCPU.
*
- * @param pVCpu VMCPU Handle.
+ * @param pVCpu Pointer to the VMCPU.
* @param fFlag The flag to check.
*/
#define VMCPU_FF_IS_SET(pVCpu, fFlag) (((pVCpu)->fLocalForcedActions & (fFlag)) == (fFlag))
-/** @deprecated */
-#define VMCPU_FF_ISSET(pVCpu, fFlag) VMCPU_FF_IS_SET(pVCpu, fFlag)
-/** @def VM_FF_ISPENDING
+/** @def VM_FF_IS_PENDING
* Checks if one or more force action in the specified set is pending.
*
- * @param pVM VM Handle.
+ * @param pVM Pointer to the VM.
* @param fFlags The flags to check for.
*/
-#define VM_FF_IS_PENDING(pVM, fFlags) ((pVM)->fGlobalForcedActions & (fFlags))
-/** @deprecated */
-#define VM_FF_ISPENDING(pVM, fFlags) VM_FF_IS_PENDING(pVM, fFlags)
+#define VM_FF_IS_PENDING(pVM, fFlags) RT_BOOL((pVM)->fGlobalForcedActions & (fFlags))
/** @def VM_FF_TESTANDCLEAR
* Checks if one (!) force action in the specified set is pending and clears it atomically
*
* @returns true if the bit was set.
* @returns false if the bit was clear.
- * @param pVM VM Handle.
+ * @param pVM Pointer to the VM.
* @param iBit Bit position to check and clear
*/
#define VM_FF_TEST_AND_CLEAR(pVM, iBit) (ASMAtomicBitTestAndClear(&(pVM)->fGlobalForcedActions, iBit##_BIT))
-/** @deprecated */
-#define VM_FF_TESTANDCLEAR(pVM, iBit) (ASMAtomicBitTestAndClear(&(pVM)->fGlobalForcedActions, iBit##_BIT))
/** @def VMCPU_FF_TESTANDCLEAR
* Checks if one (!) force action in the specified set is pending and clears it atomically
*
* @returns true if the bit was set.
* @returns false if the bit was clear.
- * @param pVCpu VMCPU Handle.
+ * @param pVCpu Pointer to the VMCPU.
* @param iBit Bit position to check and clear
*/
#define VMCPU_FF_TEST_AND_CLEAR(pVCpu, iBit) (ASMAtomicBitTestAndClear(&(pVCpu)->fLocalForcedActions, iBit##_BIT))
-/** @deprecated */
-#define VMCPU_FF_TESTANDCLEAR(pVCpu, iBit) (ASMAtomicBitTestAndClear(&(pVCpu)->fLocalForcedActions, iBit##_BIT))
-/** @def VMCPU_FF_ISPENDING
+/** @def VMCPU_FF_IS_PENDING
* Checks if one or more force action in the specified set is pending for the given VCPU.
*
- * @param pVCpu VMCPU Handle.
+ * @param pVCpu Pointer to the VMCPU.
* @param fFlags The flags to check for.
*/
-#define VMCPU_FF_IS_PENDING(pVCpu, fFlags) ((pVCpu)->fLocalForcedActions & (fFlags))
-/** @deprecated */
-#define VMCPU_FF_ISPENDING(pVCpu, fFlags) VMCPU_FF_IS_PENDING(pVCpu, fFlags)
+#define VMCPU_FF_IS_PENDING(pVCpu, fFlags) RT_BOOL((pVCpu)->fLocalForcedActions & (fFlags))
-/** @def VM_FF_ISPENDING
+/** @def VM_FF_IS_PENDING_EXCEPT
* Checks if one or more force action in the specified set is pending while one
* or more other ones are not.
*
- * @param pVM VM Handle.
+ * @param pVM Pointer to the VM.
* @param fFlags The flags to check for.
* @param fExcpt The flags that should not be set.
*/
@@ -567,7 +602,7 @@ typedef struct VMCPU
* Checks if one or more force action in the specified set is pending for the given
* VCPU while one or more other ones are not.
*
- * @param pVCpu VMCPU Handle.
+ * @param pVCpu Pointer to the VMCPU.
* @param fFlags The flags to check for.
* @param fExcpt The flags that should not be set.
*/
@@ -615,7 +650,10 @@ typedef struct VMCPU
#ifdef IN_RC
# define VMCPU_ASSERT_EMT(pVCpu) Assert(VMCPU_IS_EMT(pVCpu))
#elif defined(IN_RING0)
-# define VMCPU_ASSERT_EMT(pVCpu) Assert(VMCPU_IS_EMT(pVCpu))
+# define VMCPU_ASSERT_EMT(pVCpu) AssertMsg(VMCPU_IS_EMT(pVCpu), \
+ ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd idCpu=%u\n", \
+ RTThreadNativeSelf(), (pVCpu) ? (pVCpu)->hNativeThreadR0 : 0, \
+ (pVCpu) ? (pVCpu)->idCpu : 0))
#else
# define VMCPU_ASSERT_EMT(pVCpu) \
AssertMsg(VMCPU_IS_EMT(pVCpu), \
@@ -723,15 +761,21 @@ typedef struct VMCPU
("state %s, expected %s\n", VMGetStateName((pVM)->enmVMState), VMGetStateName(_enmState)), \
(rc))
+/** @def VM_IS_VALID_EXT
+ * Asserts a the VM handle is valid for external access, i.e. not being destroy
+ * or terminated. */
+#define VM_IS_VALID_EXT(pVM) \
+ ( RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE) \
+ && ( (unsigned)(pVM)->enmVMState < (unsigned)VMSTATE_DESTROYING \
+ || ( (unsigned)(pVM)->enmVMState == (unsigned)VMSTATE_DESTROYING \
+ && VM_IS_EMT(pVM))) )
+
/** @def VM_ASSERT_VALID_EXT_RETURN
* Asserts a the VM handle is valid for external access, i.e. not being
* destroy or terminated.
*/
#define VM_ASSERT_VALID_EXT_RETURN(pVM, rc) \
- AssertMsgReturn( RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE) \
- && ( (unsigned)(pVM)->enmVMState < (unsigned)VMSTATE_DESTROYING \
- || ( (unsigned)(pVM)->enmVMState == (unsigned)VMSTATE_DESTROYING \
- && VM_IS_EMT(pVM))), \
+ AssertMsgReturn(VM_IS_VALID_EXT(pVM), \
("pVM=%p state %s\n", (pVM), RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE) \
? VMGetStateName(pVM->enmVMState) : ""), \
(rc))
@@ -753,17 +797,17 @@ typedef struct VMCPU
-/** This is the VM structure.
+/**
+ * The cross context VM structure.
*
- * It contains (nearly?) all the VM data which have to be available in all
- * contexts. Even if it contains all the data the idea is to use APIs not
- * to modify all the members all around the place. Therefore we make use of
- * unions to hide everything which isn't local to the current source module.
- * This means we'll have to pay a little bit of attention when adding new
- * members to structures in the unions and make sure to keep the padding sizes
- * up to date.
+ * It contains all the VM data which have to be available in all contexts.
+ * Even if it contains all the data the idea is to use APIs not to modify all
+ * the members all around the place. Therefore we make use of unions to hide
+ * everything which isn't local to the current source module. This means we'll
+ * have to pay a little bit of attention when adding new members to structures
+ * in the unions and make sure to keep the padding sizes up to date.
*
- * Run tstVMStructSize after update!
+ * Run 'kmk run-struct-tests' (from src/VBox/VMM if you like) after updating!
*/
typedef struct VM
{
@@ -835,6 +879,8 @@ typedef struct VM
bool fRecompileUser;
/** Whether to recompile supervisor mode code or run it raw/hm. */
bool fRecompileSupervisor;
+ /** Whether raw mode supports ring-1 code or not. */
+ bool fRawRing1Enabled;
/** PATM enabled flag.
* This is placed here for performance reasons. */
bool fPATMEnabled;
@@ -842,19 +888,26 @@ typedef struct VM
* This is placed here for performance reasons. */
bool fCSAMEnabled;
/** Hardware VM support is available and enabled.
+ * Determined very early during init.
* This is placed here for performance reasons. */
- bool fHWACCMEnabled;
- /** Hardware VM support is required and non-optional.
- * This is initialized together with the rest of the VM structure. */
- bool fHwVirtExtForced;
- /** Set when this VM is the master FT node. */
+ bool fHMEnabled;
+ /** For asserting on fHMEnable usage. */
+ bool fHMEnabledFixed;
+ /** Hardware VM support requires a minimal raw-mode context.
+ * This is never set on 64-bit hosts, only 32-bit hosts requires it. */
+ bool fHMNeedRawModeCtx;
+ /** Set when this VM is the master FT node.
+ * @todo This doesn't need to be here, FTM should store it in it's own
+ * structures instead. */
bool fFaultTolerantMaster;
- /** Large page enabled flag. */
+ /** Large page enabled flag.
+ * @todo This doesn't need to be here, PGM should store it in it's own
+ * structures instead. */
bool fUseLargePages;
/** @} */
/** Alignment padding.. */
- uint32_t uPadding1;
+ uint8_t uPadding1[2];
/** @name Debugging
* @{ */
@@ -929,14 +982,14 @@ typedef struct VM
uint8_t padding[4096*2+6080]; /* multiple of 64 */
} pgm;
- /** HWACCM part. */
+ /** HM part. */
union
{
-#ifdef ___HWACCMInternal_h
- struct HWACCM s;
+#ifdef ___HMInternal_h
+ struct HM s;
#endif
- uint8_t padding[5376]; /* multiple of 64 */
- } hwaccm;
+ uint8_t padding[5440]; /* multiple of 64 */
+ } hm;
/** TRPM part. */
union
@@ -980,7 +1033,7 @@ typedef struct VM
#ifdef ___IOMInternal_h
struct IOM s;
#endif
- uint8_t padding[832]; /* multiple of 64 */
+ uint8_t padding[896]; /* multiple of 64 */
} iom;
/** PATM part. */
@@ -1077,7 +1130,7 @@ typedef struct VM
/** Padding for aligning the cpu array on a page boundary. */
- uint8_t abAlignment2[542];
+ uint8_t abAlignment2[414];
/* ---- end small stuff ---- */
diff --git a/include/VBox/vmm/vm.mac b/include/VBox/vmm/vm.mac
index 6d65b0c9..2a1be76b 100644
--- a/include/VBox/vmm/vm.mac
+++ b/include/VBox/vmm/vm.mac
@@ -3,7 +3,7 @@
;
;
-; Copyright (C) 2006-2012 Oracle Corporation
+; Copyright (C) 2006-2013 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
@@ -58,14 +58,16 @@ struc VM
.pfnVMMRCToHostAsmNoReturn resd 1
.fRecompileUser resb 1
.fRecompileSupervisor resb 1
+ .fRawRing1Enabled resb 1
.fPATMEnabled resb 1
.fCSAMEnabled resb 1
- .fHWACCMEnabled resb 1
- .fHwVirtExtForced resb 1
+ .fHMEnabled resb 1
+ .fHMEnabledFixed resb 1
+ .fHMNeedRawModeCtx resb 1
.fFaultTolerantMaster resb 1
.fUseLargePages resb 1
- .uPadding1 resd 1
+ .uPadding1 resb 2
.hTraceBufRC RTRCPTR_RES 1
.hTraceBufR3 RTR3PTR_RES 1
@@ -132,13 +134,13 @@ struc VMCPU
alignb 64
.cpum resb 3584
- .hwaccm resb 5376
+ .hm resb 5568
.em resb 1472
.iem resb 3072
.trpm resb 128
.tm resb 384
- .vmm resb 640
- .pdm resb 128
+ .vmm resb 704
+ .pdm resb 256
.iom resb 512
.dbgf resb 64
alignb 4096
diff --git a/include/VBox/vmm/vmapi.h b/include/VBox/vmm/vmapi.h
index b15fc7f6..d19ac645 100644
--- a/include/VBox/vmm/vmapi.h
+++ b/include/VBox/vmm/vmapi.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -92,20 +92,20 @@ RT_C_DECLS_BEGIN
/**
* VM error callback function.
*
- * @param pVM The VM handle. Can be NULL if an error occurred before
- * successfully creating a VM.
+ * @param pUVM The user mode VM handle. Can be NULL if an error
+ * occurred before successfully creating a VM.
* @param pvUser The user argument.
* @param rc VBox status code.
* @param RT_SRC_POS_DECL The source position arguments. See RT_SRC_POS and RT_SRC_POS_ARGS.
* @param pszFormat Error message format string.
* @param args Error message arguments.
*/
-typedef DECLCALLBACK(void) FNVMATERROR(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszError, va_list args);
+typedef DECLCALLBACK(void) FNVMATERROR(PUVM pUVM, void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszError, va_list args);
/** Pointer to a VM error callback. */
typedef FNVMATERROR *PFNVMATERROR;
-VMMDECL(int) VMSetError(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
-VMMDECL(int) VMSetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args);
+VMMDECL(int) VMSetError(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
+VMMDECL(int) VMSetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args);
/** @def VM_SET_ERROR
* Macro for setting a simple VM error message.
@@ -122,20 +122,35 @@ VMMDECL(int) VMSetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat
*/
#define VM_SET_ERROR(pVM, rc, pszMessage) (VMSetError(pVM, rc, RT_SRC_POS, pszMessage))
+/** @def VM_SET_ERROR
+ * Macro for setting a simple VM error message.
+ * Don't use '%' in the message!
+ *
+ * @returns rc. Meaning you can do:
+ * @code
+ * return VM_SET_ERROR(pVM, VERR_OF_YOUR_CHOICE, "descriptive message");
+ * @endcode
+ * @param pVM VM handle.
+ * @param rc VBox status code.
+ * @param pszMessage Error message string.
+ * @thread Any
+ */
+#define VM_SET_ERROR_U(a_pUVM, a_rc, a_pszMessage) (VMR3SetError(a_pUVM, a_rc, RT_SRC_POS, a_pszMessage))
+
/**
* VM runtime error callback function.
*
* See VMSetRuntimeError for the detailed description of parameters.
*
- * @param pVM The VM handle.
+ * @param pUVM The user mode VM handle.
* @param pvUser The user argument.
* @param fFlags The error flags.
* @param pszErrorId Error ID string.
* @param pszFormat Error message format string.
* @param va Error message arguments.
*/
-typedef DECLCALLBACK(void) FNVMATRUNTIMEERROR(PVM pVM, void *pvUser, uint32_t fFlags, const char *pszErrorId,
+typedef DECLCALLBACK(void) FNVMATRUNTIMEERROR(PUVM pUVM, void *pvUser, uint32_t fFlags, const char *pszErrorId,
const char *pszFormat, va_list va);
/** Pointer to a VM runtime error callback. */
typedef FNVMATRUNTIMEERROR *PFNVMATRUNTIMEERROR;
@@ -163,17 +178,17 @@ VMMDECL(int) VMSetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId
/** @} */
/**
- * VM state callback function.
+ * VM state change callback function.
*
* You are not allowed to call any function which changes the VM state from a
* state callback, except VMR3Destroy().
*
- * @param pVM The VM handle.
+ * @param pUVM The user mode VM handle.
* @param enmState The new state.
* @param enmOldState The old state.
* @param pvUser The user argument.
*/
-typedef DECLCALLBACK(void) FNVMATSTATE(PVM pVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser);
+typedef DECLCALLBACK(void) FNVMATSTATE(PUVM pUVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser);
/** Pointer to a VM state callback. */
typedef FNVMATSTATE *PFNVMATSTATE;
@@ -309,45 +324,102 @@ typedef enum VMINITCOMPLETED
/** The ring-0 init is completed. */
VMINITCOMPLETED_RING0,
/** The hardware accelerated virtualization init is completed.
- * Used to make decisision depending on whether HWACCMIsEnabled(). */
- VMINITCOMPLETED_HWACCM,
- /** The GC init is completed. */
- VMINITCOMPLETED_GC
+ * Used to make decisision depending on HM* bits being completely
+ * initialized. */
+ VMINITCOMPLETED_HM,
+ /** The RC init is completed. */
+ VMINITCOMPLETED_RC
} VMINITCOMPLETED;
-VMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVm2UserCbs,
- PFNVMATERROR pfnVMAtError, void *pvUserVM,
- PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM,
- PVM *ppVM);
-VMMR3DECL(int) VMR3PowerOn(PVM pVM);
-VMMR3DECL(int) VMR3Suspend(PVM pVM);
-VMMR3DECL(int) VMR3Resume(PVM pVM);
-VMMR3DECL(int) VMR3Reset(PVM pVM);
+/** Reason for VM resume. */
+typedef enum VMRESUMEREASON
+{
+ VMRESUMEREASON_INVALID = 0,
+ /** User decided to do so. */
+ VMRESUMEREASON_USER,
+ /** VM reconfiguration (like changing DVD). */
+ VMRESUMEREASON_RECONFIG,
+ /** The host resumed. */
+ VMRESUMEREASON_HOST_RESUME,
+ /** Restored state. */
+ VMRESUMEREASON_STATE_RESTORED,
+ /** Snapshot / saved state. */
+ VMRESUMEREASON_STATE_SAVED,
+ /** Teleported to a new box / instance. */
+ VMRESUMEREASON_TELEPORTED,
+ /** Teleportation failed. */
+ VMRESUMEREASON_TELEPORT_FAILED,
+ /** FTM temporarily suspended the VM. */
+ VMRESUMEREASON_FTM_SYNC,
+ /** End of valid reasons. */
+ VMRESUMEREASON_END,
+ /** Blow the type up to 32-bits. */
+ VMRESUMEREASON_32BIT_HACK = 0x7fffffff
+} VMRESUMEREASON;
+
+/** Reason for VM suspend. */
+typedef enum VMSUSPENDREASON
+{
+ VMSUSPENDREASON_INVALID = 0,
+ /** User decided to do so. */
+ VMSUSPENDREASON_USER,
+ /** VM reconfiguration (like changing DVD). */
+ VMSUSPENDREASON_RECONFIG,
+ /** The VM is suspending itself. */
+ VMSUSPENDREASON_VM,
+ /** The Vm is suspending because of a runtime error. */
+ VMSUSPENDREASON_RUNTIME_ERROR,
+ /** The host was suspended. */
+ VMSUSPENDREASON_HOST_SUSPEND,
+ /** The host is running low on battery power. */
+ VMSUSPENDREASON_HOST_BATTERY_LOW,
+ /** FTM is temporarily suspending the VM. */
+ VMSUSPENDREASON_FTM_SYNC,
+ /** End of valid reasons. */
+ VMSUSPENDREASON_END,
+ /** Blow the type up to 32-bits. */
+ VMSUSPENDREASON_32BIT_HACK = 0x7fffffff
+} VMSUSPENDREASON;
+
/**
* Progress callback.
+ *
* This will report the completion percentage of an operation.
*
* @returns VINF_SUCCESS.
* @returns Error code to cancel the operation with.
- * @param pVM The VM handle.
+ * @param pUVM The user mode VM handle.
* @param uPercent Completion percentage (0-100).
* @param pvUser User specified argument.
*/
-typedef DECLCALLBACK(int) FNVMPROGRESS(PVM pVM, unsigned uPercent, void *pvUser);
+typedef DECLCALLBACK(int) FNVMPROGRESS(PUVM pUVM, unsigned uPercent, void *pvUser);
/** Pointer to a FNVMPROGRESS function. */
typedef FNVMPROGRESS *PFNVMPROGRESS;
-VMMR3DECL(int) VMR3Save(PVM pVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser, bool *pfSuspended);
-VMMR3DECL(int) VMR3Teleport(PVM pVM, uint32_t cMsDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended);
-VMMR3DECL(int) VMR3LoadFromFile(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser);
-VMMR3DECL(int) VMR3LoadFromStream(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
- PFNVMPROGRESS pfnProgress, void *pvProgressUser);
-VMMR3DECL(int) VMR3PowerOff(PVM pVM);
-VMMR3DECL(int) VMR3Destroy(PVM pVM);
-VMMR3DECL(void) VMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
-VMMR3DECL(PVM) VMR3EnumVMs(PVM pVMPrev);
+
+VMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVm2UserCbs,
+ PFNVMATERROR pfnVMAtError, void *pvUserVM,
+ PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM,
+ PVM *ppVM, PUVM *ppUVM);
+VMMR3DECL(int) VMR3PowerOn(PUVM pUVM);
+VMMR3DECL(int) VMR3Suspend(PUVM pUVM, VMSUSPENDREASON enmReason);
+VMMR3DECL(VMSUSPENDREASON) VMR3GetSuspendReason(PUVM);
+VMMR3DECL(int) VMR3Resume(PUVM pUVM, VMRESUMEREASON enmReason);
+VMMR3DECL(VMRESUMEREASON) VMR3GetResumeReason(PUVM);
+VMMR3DECL(int) VMR3Reset(PUVM pUVM);
+VMMR3DECL(int) VMR3Save(PUVM pUVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser, bool *pfSuspended);
+VMMR3_INT_DECL(int) VMR3SaveFT(PUVM pUVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended, bool fSkipStateChanges);
+VMMR3DECL(int) VMR3Teleport(PUVM pUVM, uint32_t cMsDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended);
+VMMR3DECL(int) VMR3LoadFromFile(PUVM pUVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser);
+VMMR3DECL(int) VMR3LoadFromStream(PUVM pUVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
+ PFNVMPROGRESS pfnProgress, void *pvProgressUser);
+VMMR3_INT_DECL(int) VMR3LoadFromStreamFT(PUVM pUVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser);
+
+VMMR3DECL(int) VMR3PowerOff(PUVM pUVM);
+VMMR3DECL(int) VMR3Destroy(PUVM pUVM);
+VMMR3_INT_DECL(void) VMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
VMMR3DECL(PVM) VMR3GetVM(PUVM pUVM);
VMMR3DECL(PUVM) VMR3GetUVM(PVM pVM);
@@ -358,48 +430,38 @@ VMMR3DECL(PRTUUID) VMR3GetUuid(PUVM pUVM, PRTUUID pUuid);
VMMR3DECL(VMSTATE) VMR3GetState(PVM pVM);
VMMR3DECL(VMSTATE) VMR3GetStateU(PUVM pUVM);
VMMR3DECL(const char *) VMR3GetStateName(VMSTATE enmState);
+VMMR3DECL(int) VMR3AtStateRegister(PUVM pUVM, PFNVMATSTATE pfnAtState, void *pvUser);
+VMMR3DECL(int) VMR3AtStateDeregister(PUVM pUVM, PFNVMATSTATE pfnAtState, void *pvUser);
+VMMR3_INT_DECL(bool) VMR3TeleportedAndNotFullyResumedYet(PVM pVM);
+VMMR3DECL(int) VMR3AtErrorRegister(PUVM pUVM, PFNVMATERROR pfnAtError, void *pvUser);
+VMMR3DECL(int) VMR3AtErrorDeregister(PUVM pUVM, PFNVMATERROR pfnAtError, void *pvUser);
+VMMR3DECL(int) VMR3SetError(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
+VMMR3DECL(int) VMR3SetErrorV(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);
+VMMR3_INT_DECL(void) VMR3SetErrorWorker(PVM pVM);
+VMMR3_INT_DECL(uint32_t) VMR3GetErrorCount(PUVM pUVM);
+VMMR3DECL(int) VMR3AtRuntimeErrorRegister(PUVM pUVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser);
+VMMR3DECL(int) VMR3AtRuntimeErrorDeregister(PUVM pUVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser);
+VMMR3_INT_DECL(int) VMR3SetRuntimeErrorWorker(PVM pVM);
+VMMR3_INT_DECL(uint32_t) VMR3GetRuntimeErrorCount(PUVM pUVM);
+
+VMMR3DECL(int) VMR3ReqCallU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqCallVU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
+VMMR3_INT_DECL(int) VMR3ReqCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqCallWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqCallNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqCallNoWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3_INT_DECL(int) VMR3ReqCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqCallVoidWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqCallVoidNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqPriorityCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqPriorityCallWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqPriorityCallVoidWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqAlloc(PUVM pUVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu);
+VMMR3DECL(int) VMR3ReqFree(PVMREQ pReq);
+VMMR3DECL(int) VMR3ReqQueue(PVMREQ pReq, RTMSINTERVAL cMillies);
+VMMR3DECL(int) VMR3ReqWait(PVMREQ pReq, RTMSINTERVAL cMillies);
+VMMR3_INT_DECL(int) VMR3ReqProcessU(PUVM pUVM, VMCPUID idDstCpu, bool fPriorityOnly);
-/**
- * VM destruction callback.
- * @param pVM The VM which is about to be destroyed.
- * @param pvUser The user parameter specified at registration.
- */
-typedef DECLCALLBACK(void) FNVMATDTOR(PVM pVM, void *pvUser);
-/** Pointer to a VM destruction callback. */
-typedef FNVMATDTOR *PFNVMATDTOR;
-
-VMMR3DECL(int) VMR3AtDtorRegister(PFNVMATDTOR pfnAtDtor, void *pvUser);
-VMMR3DECL(int) VMR3AtDtorDeregister(PFNVMATDTOR pfnAtDtor);
-VMMR3DECL(int) VMR3AtStateRegister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser);
-VMMR3DECL(int) VMR3AtStateDeregister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser);
-VMMR3DECL(bool) VMR3TeleportedAndNotFullyResumedYet(PVM pVM);
-VMMR3DECL(int) VMR3AtErrorRegister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser);
-VMMR3DECL(int) VMR3AtErrorRegisterU(PUVM pVM, PFNVMATERROR pfnAtError, void *pvUser);
-VMMR3DECL(int) VMR3AtErrorDeregister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser);
-VMMR3DECL(void) VMR3SetErrorWorker(PVM pVM);
-VMMR3DECL(uint32_t) VMR3GetErrorCount(PVM pVM);
-VMMR3DECL(uint32_t) VMR3GetErrorCountU(PUVM pUVM);
-VMMR3DECL(int) VMR3AtRuntimeErrorRegister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser);
-VMMR3DECL(int) VMR3AtRuntimeErrorDeregister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser);
-VMMR3DECL(int) VMR3SetRuntimeErrorWorker(PVM pVM);
-VMMR3DECL(uint32_t) VMR3GetRuntimeErrorCount(PVM pVM);
-VMMR3DECL(int) VMR3ReqCall(PVM pVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
-VMMR3DECL(int) VMR3ReqCallU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
-VMMR3DECL(int) VMR3ReqCallVU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
-VMMR3DECL(int) VMR3ReqCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
-VMMR3DECL(int) VMR3ReqCallNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
-VMMR3DECL(int) VMR3ReqCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
-VMMR3DECL(int) VMR3ReqCallVoidNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
-VMMR3DECL(int) VMR3ReqPriorityCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
-VMMR3DECL(int) VMR3ReqPriorityCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
-VMMR3DECL(int) VMR3ReqAlloc(PVM pVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu);
-VMMR3DECL(int) VMR3ReqAllocU(PUVM pUVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu);
-VMMR3DECL(int) VMR3ReqFree(PVMREQ pReq);
-VMMR3DECL(int) VMR3ReqQueue(PVMREQ pReq, RTMSINTERVAL cMillies);
-VMMR3DECL(int) VMR3ReqWait(PVMREQ pReq, RTMSINTERVAL cMillies);
-VMMR3DECL(int) VMR3ReqProcessU(PUVM pUVM, VMCPUID idDstCpu, bool fPriorityOnly);
-VMMR3DECL(void) VMR3NotifyGlobalFFU(PUVM pUVM, uint32_t fFlags);
-VMMR3DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags);
/** @name Flags for VMR3NotifyCpuFFU and VMR3NotifyGlobalFFU.
* @{ */
/** Whether we've done REM or not. */
@@ -407,20 +469,21 @@ VMMR3DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags);
/** Whether we should poke the CPU if it's executing guest code. */
#define VMNOTIFYFF_FLAGS_POKE RT_BIT_32(1)
/** @} */
-
-VMMR3DECL(int) VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts);
-VMMR3DECL(int) VMR3WaitU(PUVMCPU pUVMCpu);
+VMMR3_INT_DECL(void) VMR3NotifyGlobalFFU(PUVM pUVM, uint32_t fFlags);
+VMMR3_INT_DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags);
+VMMR3_INT_DECL(int) VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts);
+VMMR3_INT_DECL(int) VMR3WaitU(PUVMCPU pUVMCpu);
VMMR3_INT_DECL(int) VMR3AsyncPdmNotificationWaitU(PUVMCPU pUVCpu);
VMMR3_INT_DECL(void) VMR3AsyncPdmNotificationWakeupU(PUVM pUVM);
-VMMR3DECL(RTCPUID) VMR3GetVMCPUId(PVM pVM);
-VMMR3DECL(RTTHREAD) VMR3GetVMCPUThread(PVM pVM);
-VMMR3DECL(RTTHREAD) VMR3GetVMCPUThreadU(PUVM pUVM);
+VMMR3_INT_DECL(RTCPUID) VMR3GetVMCPUId(PVM pVM);
+VMMR3DECL(RTTHREAD) VMR3GetVMCPUThread(PUVM pUVM);
VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThread(PVM pVM);
VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThreadU(PUVM pUVM);
-VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage);
-VMMR3DECL(int) VMR3HotUnplugCpu(PVM pVM, VMCPUID idCpu);
-VMMR3DECL(int) VMR3HotPlugCpu(PVM pVM, VMCPUID idCpu);
-VMMR3DECL(int) VMR3SetCpuExecutionCap(PVM pVM, uint32_t uCpuExecutionCap);
+VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PUVM pUVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage);
+VMMR3DECL(int) VMR3HotUnplugCpu(PUVM pUVM, VMCPUID idCpu);
+VMMR3DECL(int) VMR3HotPlugCpu(PUVM pUVM, VMCPUID idCpu);
+VMMR3DECL(int) VMR3SetCpuExecutionCap(PUVM pUVM, uint32_t uCpuExecutionCap);
+VMMR3DECL(int) VMR3SetPowerOffInsteadOfReset(PUVM pUVM, bool fPowerOffInsteadOfReset);
/** @} */
#endif /* IN_RING3 */
diff --git a/include/VBox/vmm/vmm.h b/include/VBox/vmm/vmm.h
index e3af0c29..bd3cee05 100644
--- a/include/VBox/vmm/vmm.h
+++ b/include/VBox/vmm/vmm.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -31,6 +31,7 @@
#include <VBox/sup.h>
#include <VBox/log.h>
#include <iprt/stdarg.h>
+#include <iprt/thread.h>
RT_C_DECLS_BEGIN
@@ -63,6 +64,10 @@ typedef enum VMMSWITCHER
VMMSWITCHER_AMD64_TO_PAE,
/** Switcher for AMD64 host paging to AMD64 shadow paging. */
VMMSWITCHER_AMD64_TO_AMD64,
+ /** Stub switcher for 32-bit and PAE. */
+ VMMSWITCHER_X86_STUB,
+ /** Stub switcher for AMD64. */
+ VMMSWITCHER_AMD64_STUB,
/** Used to make a count for array declarations and suchlike. */
VMMSWITCHER_MAX,
/** The usual 32-bit paranoia. */
@@ -81,6 +86,10 @@ typedef enum VMMCALLRING3
VMMCALLRING3_PDM_LOCK,
/** Acquire the critical section specified as argument. */
VMMCALLRING3_PDM_CRIT_SECT_ENTER,
+ /** Enter the R/W critical section (in argument) exclusively. */
+ VMMCALLRING3_PDM_CRIT_SECT_RW_ENTER_EXCL,
+ /** Enter the R/W critical section (in argument) shared. */
+ VMMCALLRING3_PDM_CRIT_SECT_RW_ENTER_SHARED,
/** Acquire the PGM lock. */
VMMCALLRING3_PGM_LOCK,
/** Grow the PGM shadow page pool. */
@@ -103,7 +112,8 @@ typedef enum VMMCALLRING3
VMMCALLRING3_VM_SET_RUNTIME_ERROR,
/** Signal a ring 0 assertion. */
VMMCALLRING3_VM_R0_ASSERTION,
- /** Ring switch to force preemption. */
+ /** Ring switch to force preemption. This is also used by PDMCritSect to
+ * handle VERR_INTERRUPTED in kernel context. */
VMMCALLRING3_VM_R0_PREEMPT,
/** Sync the FTM state with the standby node. */
VMMCALLRING3_FTM_SET_CHECKPOINT,
@@ -112,17 +122,16 @@ typedef enum VMMCALLRING3
} VMMCALLRING3;
/**
- * VMMR3AtomicExecuteHandler callback function.
+ * VMMRZCallRing3 notification callback.
*
* @returns VBox status code.
- * @param pVM Pointer to the shared VM structure.
- * @param pvUser User specified argument
- *
- * @todo missing prefix.
+ * @param pVCpu Pointer to the VMCPU.
+ * @param enmOperation The operation causing the ring-3 jump.
+ * @param pvUser The user argument.
*/
-typedef DECLCALLBACK(int) FNATOMICHANDLER(PVM pVM, void *pvUser);
-/** Pointer to a FNMMATOMICHANDLER(). */
-typedef FNATOMICHANDLER *PFNATOMICHANDLER;
+typedef DECLCALLBACK(int) FNVMMR0CALLRING3NOTIFICATION(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser);
+/** Pointer to a FNRTMPNOTIFICATION(). */
+typedef FNVMMR0CALLRING3NOTIFICATION *PFNVMMR0CALLRING3NOTIFICATION;
/**
* Rendezvous callback.
@@ -213,6 +222,16 @@ typedef struct VMM2USERMETHODS
*/
DECLR3CALLBACKMEMBER(void, pfnNotifyPdmtTerm,(PCVMM2USERMETHODS pThis, PUVM pUVM));
+ /**
+ * Notification callback that that a VM reset will be turned into a power off.
+ *
+ * @param pThis Pointer to the callback method table.
+ * @param pUVM The user mode VM handle.
+ *
+ * @remarks This is optional and shall be set to NULL if not wanted.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnNotifyResetTurnedIntoPowerOff,(PCVMM2USERMETHODS pThis, PUVM pUVM));
+
/** Magic value (VMM2USERMETHODS_MAGIC) marking the end of the structure. */
uint32_t u32EndMagic;
} VMM2USERMETHODS;
@@ -220,28 +239,34 @@ typedef struct VMM2USERMETHODS
/** Magic value of the VMM2USERMETHODS (Franz Kafka). */
#define VMM2USERMETHODS_MAGIC UINT32_C(0x18830703)
/** The VMM2USERMETHODS structure version. */
-#define VMM2USERMETHODS_VERSION UINT32_C(0x00020000)
+#define VMM2USERMETHODS_VERSION UINT32_C(0x00020001)
-VMMDECL(RTRCPTR) VMMGetStackRC(PVMCPU pVCpu);
-VMMDECL(VMCPUID) VMMGetCpuId(PVM pVM);
-VMMDECL(PVMCPU) VMMGetCpu(PVM pVM);
-VMMDECL(PVMCPU) VMMGetCpu0(PVM pVM);
-VMMDECL(PVMCPU) VMMGetCpuById(PVM pVM, VMCPUID idCpu);
-VMMDECL(uint32_t) VMMGetSvnRev(void);
-VMMDECL(VMMSWITCHER) VMMGetSwitcher(PVM pVM);
-VMMDECL(void) VMMTrashVolatileXMMRegs(void);
-
-/** @def VMMIsHwVirtExtForced
- * Checks if forced to use the hardware assisted virtualization extensions.
- *
- * This is intended for making setup decisions where we can save resources when
- * using hardware assisted virtualization.
+/**
+ * Checks whether we've armed the ring-0 long jump machinery.
*
- * @returns true / false.
- * @param pVM Pointer to the shared VM structure.
+ * @returns @c true / @c false
+ * @param pVCpu The caller's cross context virtual CPU structure.
+ * @thread EMT
+ * @sa VMMR0IsLongJumpArmed
*/
-#define VMMIsHwVirtExtForced(pVM) ((pVM)->fHwVirtExtForced)
+#ifdef IN_RING0
+# define VMMIsLongJumpArmed(a_pVCpu) VMMR0IsLongJumpArmed(a_pVCpu)
+#else
+# define VMMIsLongJumpArmed(a_pVCpu) (false)
+#endif
+
+
+VMM_INT_DECL(RTRCPTR) VMMGetStackRC(PVMCPU pVCpu);
+VMMDECL(VMCPUID) VMMGetCpuId(PVM pVM);
+VMMDECL(PVMCPU) VMMGetCpu(PVM pVM);
+VMMDECL(PVMCPU) VMMGetCpu0(PVM pVM);
+VMMDECL(PVMCPU) VMMGetCpuById(PVM pVM, VMCPUID idCpu);
+VMMR3DECL(PVMCPU) VMMR3GetCpuByIdU(PUVM pVM, VMCPUID idCpu);
+VMM_INT_DECL(uint32_t) VMMGetSvnRev(void);
+VMM_INT_DECL(VMMSWITCHER) VMMGetSwitcher(PVM pVM);
+VMM_INT_DECL(bool) VMMIsInRing3Call(PVMCPU pVCpu);
+VMM_INT_DECL(void) VMMTrashVolatileXMMRegs(void);
#ifdef IN_RING3
@@ -251,23 +276,26 @@ VMMDECL(void) VMMTrashVolatileXMMRegs(void);
*/
VMMR3_INT_DECL(int) VMMR3Init(PVM pVM);
VMMR3_INT_DECL(int) VMMR3InitR0(PVM pVM);
+# ifdef VBOX_WITH_RAW_MODE
VMMR3_INT_DECL(int) VMMR3InitRC(PVM pVM);
+# endif
VMMR3_INT_DECL(int) VMMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
VMMR3_INT_DECL(int) VMMR3Term(PVM pVM);
VMMR3_INT_DECL(void) VMMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
VMMR3_INT_DECL(int) VMMR3UpdateLoggers(PVM pVM);
VMMR3DECL(const char *) VMMR3GetRZAssertMsg1(PVM pVM);
VMMR3DECL(const char *) VMMR3GetRZAssertMsg2(PVM pVM);
-VMMR3_INT_DECL(int) VMMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue);
VMMR3_INT_DECL(int) VMMR3SelectSwitcher(PVM pVM, VMMSWITCHER enmSwitcher);
-VMMR3_INT_DECL(int) VMMR3DisableSwitcher(PVM pVM);
VMMR3_INT_DECL(RTR0PTR) VMMR3GetHostToGuestSwitcher(PVM pVM, VMMSWITCHER enmSwitcher);
+VMMR3_INT_DECL(int) VMMR3HmRunGC(PVM pVM, PVMCPU pVCpu);
+# ifdef VBOX_WITH_RAW_MODE
VMMR3_INT_DECL(int) VMMR3RawRunGC(PVM pVM, PVMCPU pVCpu);
-VMMR3_INT_DECL(int) VMMR3HwAccRunGC(PVM pVM, PVMCPU pVCpu);
+VMMR3DECL(int) VMMR3ResumeHyper(PVM pVM, PVMCPU pVCpu);
+VMMR3_INT_DECL(int) VMMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue);
VMMR3DECL(int) VMMR3CallRC(PVM pVM, RTRCPTR RCPtrEntry, unsigned cArgs, ...);
VMMR3DECL(int) VMMR3CallRCV(PVM pVM, RTRCPTR RCPtrEntry, unsigned cArgs, va_list args);
+# endif
VMMR3DECL(int) VMMR3CallR0(PVM pVM, uint32_t uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr);
-VMMR3DECL(int) VMMR3ResumeHyper(PVM pVM, PVMCPU pVCpu);
VMMR3DECL(void) VMMR3FatalDump(PVM pVM, PVMCPU pVCpu, int rcErr);
VMMR3_INT_DECL(void) VMMR3YieldSuspend(PVM pVM);
VMMR3_INT_DECL(void) VMMR3YieldStop(PVM pVM);
@@ -320,7 +348,7 @@ typedef enum VMMR0OPERATION
/** Run guest context. */
VMMR0_DO_RAW_RUN = SUP_VMMR0_DO_RAW_RUN,
/** Run guest code using the available hardware acceleration technology. */
- VMMR0_DO_HWACC_RUN = SUP_VMMR0_DO_HWACC_RUN,
+ VMMR0_DO_HM_RUN = SUP_VMMR0_DO_HM_RUN,
/** Official NOP that we use for profiling. */
VMMR0_DO_NOP = SUP_VMMR0_DO_NOP,
/** Official slow iocl NOP that we use for profiling. */
@@ -352,9 +380,9 @@ typedef enum VMMR0OPERATION
/** Call VMMR0 Per VM Termination. */
VMMR0_DO_VMMR0_TERM,
/** Setup the hardware accelerated raw-mode session. */
- VMMR0_DO_HWACC_SETUP_VM,
+ VMMR0_DO_HM_SETUP_VM,
/** Attempt to enable or disable hardware accelerated raw-mode. */
- VMMR0_DO_HWACC_ENABLE,
+ VMMR0_DO_HM_ENABLE,
/** Calls function in the hypervisor.
* The caller must setup the hypervisor context so the call will be performed.
* The difference between VMMR0_DO_RUN_GC and this one is the handling of
@@ -475,18 +503,30 @@ typedef struct GCFGMVALUEREQ
*/
typedef GCFGMVALUEREQ *PGCFGMVALUEREQ;
-VMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg);
-VMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation);
-VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION);
-VMMR0DECL(int) VMMR0TermVM(PVM pVM, PGVM pGVM);
-
-#ifdef LOG_ENABLED
-VMMR0DECL(void) VMMR0LogFlushDisable(PVMCPU pVCpu);
-VMMR0DECL(void) VMMR0LogFlushEnable(PVMCPU pVCpu);
-#else
-#define VMMR0LogFlushDisable(pVCpu) do { } while(0)
-#define VMMR0LogFlushEnable(pVCpu) do { } while(0)
-#endif
+#ifdef IN_RING0
+VMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg);
+VMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation);
+VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION);
+VMMR0DECL(int) VMMR0TermVM(PVM pVM, PGVM pGVM);
+VMMR0_INT_DECL(bool) VMMR0IsLongJumpArmed(PVMCPU pVCpu);
+VMMR0_INT_DECL(bool) VMMR0IsInRing3LongJump(PVMCPU pVCpu);
+VMMR0DECL(int) VMMR0ThreadCtxHooksCreate(PVMCPU pVCpu);
+VMMR0DECL(void) VMMR0ThreadCtxHooksRelease(PVMCPU pVCpu);
+VMMR0DECL(bool) VMMR0ThreadCtxHooksAreCreated(PVMCPU pVCpu);
+VMMR0DECL(int) VMMR0ThreadCtxHooksRegister(PVMCPU pVCpu, PFNRTTHREADCTXHOOK pfnHook);
+VMMR0DECL(int) VMMR0ThreadCtxHooksDeregister(PVMCPU pVCpu);
+VMMR0DECL(bool) VMMR0ThreadCtxHooksAreRegistered(PVMCPU pVCpu);
+
+# ifdef LOG_ENABLED
+VMMR0DECL(void) VMMR0LogFlushDisable(PVMCPU pVCpu);
+VMMR0DECL(void) VMMR0LogFlushEnable(PVMCPU pVCpu);
+VMMR0DECL(bool) VMMR0IsLogFlushDisabled(PVMCPU pVCpu);
+# else
+# define VMMR0LogFlushDisable(pVCpu) do { } while(0)
+# define VMMR0LogFlushEnable(pVCpu) do { } while(0)
+# define VMMR0IsLogFlushDisabled(pVCpu) (true)
+# endif /* LOG_ENABLED */
+#endif /* IN_RING0 */
/** @} */
@@ -512,6 +552,9 @@ VMMRZDECL(int) VMMRZCallRing3NoCpu(PVM pVM, VMMCALLRING3 enmOperation, uint
VMMRZDECL(void) VMMRZCallRing3Disable(PVMCPU pVCpu);
VMMRZDECL(void) VMMRZCallRing3Enable(PVMCPU pVCpu);
VMMRZDECL(bool) VMMRZCallRing3IsEnabled(PVMCPU pVCpu);
+VMMRZDECL(int) VMMRZCallRing3SetNotification(PVMCPU pVCpu, R0PTRTYPE(PFNVMMR0CALLRING3NOTIFICATION) pfnCallback, RTR0PTR pvUser);
+VMMRZDECL(void) VMMRZCallRing3RemoveNotification(PVMCPU pVCpu);
+VMMRZDECL(bool) VMMRZCallRing3IsNotificationSet(PVMCPU pVCpu);
/** @} */
#endif