Index: trunk/src/VBox/VMM/Makefile.kmk
===================================================================
--- trunk/src/VBox/VMM/Makefile.kmk	(revision 43379)
+++ trunk/src/VBox/VMM/Makefile.kmk	(revision 43387)
@@ -120,5 +120,5 @@
 	VMMR3/EM.cpp \
 	VMMR3/EMRaw.cpp \
-	VMMR3/EMHwaccm.cpp \
+	VMMR3/EMHM.cpp \
 	VMMR3/FTM.cpp \
 	VMMR3/IEMR3.cpp \
@@ -160,5 +160,5 @@
 	VMMR3/VMMSwitcher.cpp \
 	VMMR3/VMMTests.cpp \
-	VMMR3/HWACCM.cpp \
+	VMMR3/HM.cpp \
 	VMMR3/CSAM.cpp \
 	VMMR3/PATM.cpp \
@@ -170,5 +170,5 @@
 	VMMAll/CPUMStack.cpp \
 	VMMAll/DBGFAll.cpp \
-	VMMAll/HWACCMAll.cpp \
+	VMMAll/HMAll.cpp \
 	VMMAll/IOMAll.cpp \
 	VMMAll/IOMAllMMIO.cpp \
@@ -390,5 +390,5 @@
  	VMMRC/VMMRC.cpp \
  	VMMRC/VMMRCA.asm \
- 	VMMRC/HWACCMRCA.asm \
+ 	VMMRC/HMRCA.asm \
  	VMMRC/CSAMRC.cpp \
  	VMMRC/PATMRC.cpp \
@@ -488,6 +488,6 @@
  	VMMR0/GMMR0.cpp \
  	VMMR0/GVMMR0.cpp \
- 	VMMR0/HWACCMR0.cpp \
- 	VMMR0/HWACCMR0A.asm \
+ 	VMMR0/HMR0.cpp \
+ 	VMMR0/HMR0A.asm \
  	VMMR0/HWSVMR0.cpp \
  	VMMR0/HWVMXR0.cpp \
@@ -508,5 +508,5 @@
  	VMMAll/EMAllA.asm \
  	VMMAll/FTMAll.cpp \
- 	VMMAll/HWACCMAll.cpp \
+ 	VMMAll/HMAll.cpp \
  	VMMAll/IOMAll.cpp \
  	VMMAll/IOMAllMMIO.cpp \
Index: trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 43387)
@@ -35,5 +35,5 @@
 #include <VBox/dis.h>
 #include <VBox/log.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <VBox/vmm/tm.h>
 #include <iprt/assert.h>
@@ -89,5 +89,5 @@
 {
     Assert(!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
-    Assert(!HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)));
+    Assert(!HMIsEnabled(pVCpu->CTX_SUFF(pVM)));
     Assert((uintptr_t)(pSReg - &pVCpu->cpum.s.Guest.es) < X86_SREG_COUNT);
 
@@ -545,5 +545,5 @@
 #ifdef VBOX_WITH_IEM
 # ifdef VBOX_WITH_RAW_MODE_NOT_R0
-    if (!HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)))
+    if (!HMIsEnabled(pVCpu->CTX_SUFF(pVM)))
         VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
 # endif
@@ -559,5 +559,5 @@
 #ifdef VBOX_WITH_IEM
 # ifdef VBOX_WITH_RAW_MODE_NOT_R0
-    if (!HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)))
+    if (!HMIsEnabled(pVCpu->CTX_SUFF(pVM)))
         VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
 # endif
@@ -573,5 +573,5 @@
 #ifdef VBOX_WITH_IEM
 # ifdef VBOX_WITH_RAW_MODE_NOT_R0
-    if (!HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)))
+    if (!HMIsEnabled(pVCpu->CTX_SUFF(pVM)))
         VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
 # endif
@@ -588,5 +588,5 @@
     if (   (   ldtr != 0
             || pVCpu->cpum.s.Guest.ldtr.Sel != 0)
-        && !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)))
+        && !HMIsEnabled(pVCpu->CTX_SUFF(pVM)))
         VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
 # endif
@@ -1236,5 +1236,5 @@
             {
                 /// @todo PGMFlushTLB(pVCpu, cr3, true /*fGlobal*/);
-                HWACCMFlushTLB(pVCpu);
+                HMFlushTLB(pVCpu);
 
                 /* Notify PGM about NXE changes. */
Index: trunk/src/VBox/VMM/VMMAll/EMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/EMAll.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMAll/EMAll.cpp	(revision 43387)
@@ -34,5 +34,5 @@
 #include <VBox/vmm/vm.h>
 #include <VBox/vmm/vmm.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <VBox/vmm/tm.h>
 #include <VBox/vmm/pdmapi.h>
@@ -378,7 +378,7 @@
                     if (rc == VERR_PAGE_TABLE_NOT_PRESENT || rc == VERR_PAGE_NOT_PRESENT)
                     {
-                        HWACCMInvalidatePage(pVCpu, uSrcAddr);
+                        HMInvalidatePage(pVCpu, uSrcAddr);
                         if (((uSrcAddr + cbToRead - 1) >> PAGE_SHIFT) !=  (uSrcAddr >> PAGE_SHIFT))
-                            HWACCMInvalidatePage(pVCpu, uSrcAddr + cbToRead - 1);
+                            HMInvalidatePage(pVCpu, uSrcAddr + cbToRead - 1);
                     }
 #endif
@@ -2926,5 +2926,5 @@
 
 
-#ifdef IN_RC /** @todo test+enable for HWACCM as well. */
+#ifdef IN_RC /** @todo test+enable for HM as well. */
 /**
  * [LOCK] XADD emulation.
Index: trunk/src/VBox/VMM/VMMAll/HMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/HMAll.cpp	(revision 43387)
+++ trunk/src/VBox/VMM/VMMAll/HMAll.cpp	(revision 43387)
@@ -0,0 +1,339 @@
+/* $Id$ */
+/** @file
+ * HM - All contexts.
+ */
+
+/*
+ * 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;
+ * 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.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_HM
+#include <VBox/vmm/hm.h>
+#include <VBox/vmm/pgm.h>
+#include "HMInternal.h"
+#include <VBox/vmm/vm.h>
+#include <VBox/vmm/hm_vmx.h>
+#include <VBox/vmm/hm_svm.h>
+#include <VBox/err.h>
+#include <VBox/log.h>
+#include <iprt/param.h>
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/string.h>
+#include <iprt/x86.h>
+
+
+/**
+ * Queues a page for invalidation
+ *
+ * @returns VBox status code.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   GCVirt      Page to invalidate
+ */
+static void hmQueueInvlPage(PVMCPU pVCpu, RTGCPTR GCVirt)
+{
+    /* Nothing to do if a TLB flush is already pending */
+    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH))
+        return;
+#if 1
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
+    NOREF(GCVirt);
+#else
+    Be very careful when activating this code!
+    if (iPage == RT_ELEMENTS(pVCpu->hm.s.TlbShootdown.aPages))
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
+    else
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_SHOOTDOWN);
+#endif
+}
+
+/**
+ * Invalidates a guest page
+ *
+ * @returns VBox status code.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   GCVirt      Page to invalidate
+ */
+VMMDECL(int) HMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCVirt)
+{
+    STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushPageManual);
+#ifdef IN_RING0
+    PVM pVM = pVCpu->CTX_SUFF(pVM);
+    if (pVM->hm.s.vmx.fSupported)
+        return VMXR0InvalidatePage(pVM, pVCpu, GCVirt);
+
+    Assert(pVM->hm.s.svm.fSupported);
+    return SVMR0InvalidatePage(pVM, pVCpu, GCVirt);
+
+#else
+    hmQueueInvlPage(pVCpu, GCVirt);
+    return VINF_SUCCESS;
+#endif
+}
+
+/**
+ * Flushes the guest TLB
+ *
+ * @returns VBox status code.
+ * @param   pVCpu       Pointer to the VMCPU.
+ */
+VMMDECL(int) HMFlushTLB(PVMCPU pVCpu)
+{
+    LogFlow(("HMFlushTLB\n"));
+
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
+    STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTLBManual);
+    return VINF_SUCCESS;
+}
+
+#ifdef IN_RING0
+
+/**
+ * Dummy RTMpOnSpecific handler since RTMpPokeCpu couldn't be used.
+ *
+ */
+static DECLCALLBACK(void) hmFlushHandler(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+    NOREF(idCpu); NOREF(pvUser1); NOREF(pvUser2);
+    return;
+}
+
+/**
+ * Wrapper for RTMpPokeCpu to deal with VERR_NOT_SUPPORTED.
+ */
+static void hmR0PokeCpu(PVMCPU pVCpu, RTCPUID idHostCpu)
+{
+    uint32_t cWorldSwitchExits = ASMAtomicUoReadU32(&pVCpu->hm.s.cWorldSwitchExits);
+
+    STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatPoke, x);
+    int rc = RTMpPokeCpu(idHostCpu);
+    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatPoke, x);
+
+    /* Not implemented on some platforms (Darwin, Linux kernel < 2.6.19); fall
+       back to a less efficient implementation (broadcast). */
+    if (rc == VERR_NOT_SUPPORTED)
+    {
+        STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatSpinPoke, z);
+        /* synchronous. */
+        RTMpOnSpecific(idHostCpu, hmFlushHandler, 0, 0);
+        STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatSpinPoke, z);
+    }
+    else
+    {
+        if (rc == VINF_SUCCESS)
+            STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatSpinPoke, z);
+        else
+            STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatSpinPokeFailed, z);
+
+/** @todo If more than one CPU is going to be poked, we could optimize this
+ *        operation by poking them first and wait afterwards.  Would require
+ *        recording who to poke and their current cWorldSwitchExits values,
+ *        that's something not suitable for stack... So, pVCpu->hm.s.something
+ *        then. */
+        /* Spin until the VCPU has switched back (poking is async). */
+        while (   ASMAtomicUoReadBool(&pVCpu->hm.s.fCheckedTLBFlush)
+               && cWorldSwitchExits == ASMAtomicUoReadU32(&pVCpu->hm.s.cWorldSwitchExits))
+            ASMNopPause();
+
+        if (rc == VINF_SUCCESS)
+            STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatSpinPoke, z);
+        else
+            STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatSpinPokeFailed, z);
+    }
+}
+
+#endif /* IN_RING0 */
+#ifndef IN_RC
+
+/**
+ * Poke an EMT so it can perform the appropriate TLB shootdowns.
+ *
+ * @param   pVCpu               The handle of the virtual CPU to poke.
+ * @param   fAccountFlushStat   Whether to account the call to
+ *                              StatTlbShootdownFlush or StatTlbShootdown.
+ */
+static void hmPokeCpuForTlbFlush(PVMCPU pVCpu, bool fAccountFlushStat)
+{
+    if (ASMAtomicUoReadBool(&pVCpu->hm.s.fCheckedTLBFlush))
+    {
+        if (fAccountFlushStat)
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatTlbShootdownFlush);
+        else
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatTlbShootdown);
+#ifdef IN_RING0
+        RTCPUID idHostCpu = pVCpu->hm.s.idEnteredCpu;
+        if (idHostCpu != NIL_RTCPUID)
+            hmR0PokeCpu(pVCpu, idHostCpu);
+#else
+        VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_POKE);
+#endif
+    }
+    else
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushPageManual);
+}
+
+
+/**
+ * Invalidates a guest page on all VCPUs.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   GCVirt      Page to invalidate
+ */
+VMMDECL(int) HMInvalidatePageOnAllVCpus(PVM pVM, RTGCPTR GCPtr)
+{
+    VMCPUID idCurCpu = VMMGetCpuId(pVM);
+    STAM_COUNTER_INC(&pVM->aCpus[idCurCpu].hm.s.StatFlushPage);
+
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+        /* Nothing to do if a TLB flush is already pending; the VCPU should
+           have already been poked if it were active. */
+        if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH))
+            continue;
+
+        if (pVCpu->idCpu == idCurCpu)
+            HMInvalidatePage(pVCpu, GCPtr);
+        else
+        {
+            hmQueueInvlPage(pVCpu, GCPtr);
+            hmPokeCpuForTlbFlush(pVCpu, false /*fAccountFlushStat*/);
+        }
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Flush the TLBs of all VCPUs
+ *
+ * @returns VBox status code.
+ * @param   pVM       Pointer to the VM.
+ */
+VMMDECL(int) HMFlushTLBOnAllVCpus(PVM pVM)
+{
+    if (pVM->cCpus == 1)
+        return HMFlushTLB(&pVM->aCpus[0]);
+
+    VMCPUID idThisCpu = VMMGetCpuId(pVM);
+
+    STAM_COUNTER_INC(&pVM->aCpus[idThisCpu].hm.s.StatFlushTLB);
+
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+        /* Nothing to do if a TLB flush is already pending; the VCPU should
+           have already been poked if it were active. */
+        if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH))
+        {
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
+            if (idThisCpu != idCpu)
+                hmPokeCpuForTlbFlush(pVCpu, true /*fAccountFlushStat*/);
+        }
+    }
+
+    return VINF_SUCCESS;
+}
+
+#endif /* !IN_RC */
+
+/**
+ * Checks if nested paging is enabled
+ *
+ * @returns boolean
+ * @param   pVM         Pointer to the VM.
+ */
+VMMDECL(bool) HMIsNestedPagingActive(PVM pVM)
+{
+    return HMIsEnabled(pVM) && pVM->hm.s.fNestedPaging;
+}
+
+/**
+ * Return the shadow paging mode for nested paging/ept
+ *
+ * @returns shadow paging mode
+ * @param   pVM         Pointer to the VM.
+ */
+VMMDECL(PGMMODE) HMGetShwPagingMode(PVM pVM)
+{
+    Assert(HMIsNestedPagingActive(pVM));
+    if (pVM->hm.s.svm.fSupported)
+        return PGMMODE_NESTED;
+
+    Assert(pVM->hm.s.vmx.fSupported);
+    return PGMMODE_EPT;
+}
+
+/**
+ * Invalidates a guest page by physical address
+ *
+ * NOTE: Assumes the current instruction references this physical page though a virtual address!!
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   GCPhys      Page to invalidate
+ */
+VMMDECL(int) HMInvalidatePhysPage(PVM pVM, RTGCPHYS GCPhys)
+{
+    if (!HMIsNestedPagingActive(pVM))
+        return VINF_SUCCESS;
+
+#ifdef IN_RING0
+    if (pVM->hm.s.vmx.fSupported)
+    {
+        VMCPUID idThisCpu = VMMGetCpuId(pVM);
+
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+            if (idThisCpu == idCpu)
+                VMXR0InvalidatePhysPage(pVM, pVCpu, GCPhys);
+            else
+            {
+                VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
+                hmPokeCpuForTlbFlush(pVCpu, true /*fAccountFlushStat*/);
+            }
+        }
+        return VINF_SUCCESS;
+    }
+
+    /* AMD-V doesn't support invalidation with guest physical addresses; see
+       comment in SVMR0InvalidatePhysPage. */
+    Assert(pVM->hm.s.svm.fSupported);
+#else
+    NOREF(GCPhys);
+#endif
+
+    HMFlushTLBOnAllVCpus(pVM);
+    return VINF_SUCCESS;
+}
+
+/**
+ * Checks if an interrupt event is currently pending.
+ *
+ * @returns Interrupt event pending state.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMDECL(bool) HMHasPendingIrq(PVM pVM)
+{
+    PVMCPU pVCpu = VMMGetCpu(pVM);
+    return !!pVCpu->hm.s.Event.fPending;
+}
+
Index: trunk/src/VBox/VMM/VMMAll/HWACCMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/HWACCMAll.cpp	(revision 43379)
+++ 	(revision )
@@ -1,339 +1,0 @@
-/* $Id$ */
-/** @file
- * HWACCM - All contexts.
- */
-
-/*
- * 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;
- * 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.
- */
-
-
-/*******************************************************************************
-*   Header Files                                                               *
-*******************************************************************************/
-#define LOG_GROUP LOG_GROUP_HWACCM
-#include <VBox/vmm/hwaccm.h>
-#include <VBox/vmm/pgm.h>
-#include "HWACCMInternal.h"
-#include <VBox/vmm/vm.h>
-#include <VBox/vmm/hwacc_vmx.h>
-#include <VBox/vmm/hwacc_svm.h>
-#include <VBox/err.h>
-#include <VBox/log.h>
-#include <iprt/param.h>
-#include <iprt/assert.h>
-#include <iprt/asm.h>
-#include <iprt/string.h>
-#include <iprt/x86.h>
-
-
-/**
- * Queues a page for invalidation
- *
- * @returns VBox status code.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   GCVirt      Page to invalidate
- */
-static void hwaccmQueueInvlPage(PVMCPU pVCpu, RTGCPTR GCVirt)
-{
-    /* Nothing to do if a TLB flush is already pending */
-    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH))
-        return;
-#if 1
-    VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
-    NOREF(GCVirt);
-#else
-    Be very careful when activating this code!
-    if (iPage == RT_ELEMENTS(pVCpu->hwaccm.s.TlbShootdown.aPages))
-        VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
-    else
-        VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_SHOOTDOWN);
-#endif
-}
-
-/**
- * Invalidates a guest page
- *
- * @returns VBox status code.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   GCVirt      Page to invalidate
- */
-VMMDECL(int) HWACCMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCVirt)
-{
-    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushPageManual);
-#ifdef IN_RING0
-    PVM pVM = pVCpu->CTX_SUFF(pVM);
-    if (pVM->hwaccm.s.vmx.fSupported)
-        return VMXR0InvalidatePage(pVM, pVCpu, GCVirt);
-
-    Assert(pVM->hwaccm.s.svm.fSupported);
-    return SVMR0InvalidatePage(pVM, pVCpu, GCVirt);
-
-#else
-    hwaccmQueueInvlPage(pVCpu, GCVirt);
-    return VINF_SUCCESS;
-#endif
-}
-
-/**
- * Flushes the guest TLB
- *
- * @returns VBox status code.
- * @param   pVCpu       Pointer to the VMCPU.
- */
-VMMDECL(int) HWACCMFlushTLB(PVMCPU pVCpu)
-{
-    LogFlow(("HWACCMFlushTLB\n"));
-
-    VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
-    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushTLBManual);
-    return VINF_SUCCESS;
-}
-
-#ifdef IN_RING0
-
-/**
- * Dummy RTMpOnSpecific handler since RTMpPokeCpu couldn't be used.
- *
- */
-static DECLCALLBACK(void) hwaccmFlushHandler(RTCPUID idCpu, void *pvUser1, void *pvUser2)
-{
-    NOREF(idCpu); NOREF(pvUser1); NOREF(pvUser2);
-    return;
-}
-
-/**
- * Wrapper for RTMpPokeCpu to deal with VERR_NOT_SUPPORTED.
- */
-static void hmR0PokeCpu(PVMCPU pVCpu, RTCPUID idHostCpu)
-{
-    uint32_t cWorldSwitchExits = ASMAtomicUoReadU32(&pVCpu->hwaccm.s.cWorldSwitchExits);
-
-    STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatPoke, x);
-    int rc = RTMpPokeCpu(idHostCpu);
-    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatPoke, x);
-
-    /* Not implemented on some platforms (Darwin, Linux kernel < 2.6.19); fall
-       back to a less efficient implementation (broadcast). */
-    if (rc == VERR_NOT_SUPPORTED)
-    {
-        STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatSpinPoke, z);
-        /* synchronous. */
-        RTMpOnSpecific(idHostCpu, hwaccmFlushHandler, 0, 0);
-        STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatSpinPoke, z);
-    }
-    else
-    {
-        if (rc == VINF_SUCCESS)
-            STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatSpinPoke, z);
-        else
-            STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatSpinPokeFailed, z);
-
-/** @todo If more than one CPU is going to be poked, we could optimize this
- *        operation by poking them first and wait afterwards.  Would require
- *        recording who to poke and their current cWorldSwitchExits values,
- *        that's something not suitable for stack... So, pVCpu->hm.s.something
- *        then. */
-        /* Spin until the VCPU has switched back (poking is async). */
-        while (   ASMAtomicUoReadBool(&pVCpu->hwaccm.s.fCheckedTLBFlush)
-               && cWorldSwitchExits == ASMAtomicUoReadU32(&pVCpu->hwaccm.s.cWorldSwitchExits))
-            ASMNopPause();
-
-        if (rc == VINF_SUCCESS)
-            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatSpinPoke, z);
-        else
-            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatSpinPokeFailed, z);
-    }
-}
-
-#endif /* IN_RING0 */
-#ifndef IN_RC
-
-/**
- * Poke an EMT so it can perform the appropriate TLB shootdowns.
- *
- * @param   pVCpu               The handle of the virtual CPU to poke.
- * @param   fAccountFlushStat   Whether to account the call to
- *                              StatTlbShootdownFlush or StatTlbShootdown.
- */
-static void hmPokeCpuForTlbFlush(PVMCPU pVCpu, bool fAccountFlushStat)
-{
-    if (ASMAtomicUoReadBool(&pVCpu->hwaccm.s.fCheckedTLBFlush))
-    {
-        if (fAccountFlushStat)
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdownFlush);
-        else
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdown);
-#ifdef IN_RING0
-        RTCPUID idHostCpu = pVCpu->hwaccm.s.idEnteredCpu;
-        if (idHostCpu != NIL_RTCPUID)
-            hmR0PokeCpu(pVCpu, idHostCpu);
-#else
-        VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_POKE);
-#endif
-    }
-    else
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushPageManual);
-}
-
-
-/**
- * Invalidates a guest page on all VCPUs.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   GCVirt      Page to invalidate
- */
-VMMDECL(int) HWACCMInvalidatePageOnAllVCpus(PVM pVM, RTGCPTR GCPtr)
-{
-    VMCPUID idCurCpu = VMMGetCpuId(pVM);
-    STAM_COUNTER_INC(&pVM->aCpus[idCurCpu].hwaccm.s.StatFlushPage);
-
-    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
-
-        /* Nothing to do if a TLB flush is already pending; the VCPU should
-           have already been poked if it were active. */
-        if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH))
-            continue;
-
-        if (pVCpu->idCpu == idCurCpu)
-            HWACCMInvalidatePage(pVCpu, GCPtr);
-        else
-        {
-            hwaccmQueueInvlPage(pVCpu, GCPtr);
-            hmPokeCpuForTlbFlush(pVCpu, false /*fAccountFlushStat*/);
-        }
-    }
-
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Flush the TLBs of all VCPUs
- *
- * @returns VBox status code.
- * @param   pVM       Pointer to the VM.
- */
-VMMDECL(int) HWACCMFlushTLBOnAllVCpus(PVM pVM)
-{
-    if (pVM->cCpus == 1)
-        return HWACCMFlushTLB(&pVM->aCpus[0]);
-
-    VMCPUID idThisCpu = VMMGetCpuId(pVM);
-
-    STAM_COUNTER_INC(&pVM->aCpus[idThisCpu].hwaccm.s.StatFlushTLB);
-
-    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
-
-        /* Nothing to do if a TLB flush is already pending; the VCPU should
-           have already been poked if it were active. */
-        if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH))
-        {
-            VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
-            if (idThisCpu != idCpu)
-                hmPokeCpuForTlbFlush(pVCpu, true /*fAccountFlushStat*/);
-        }
-    }
-
-    return VINF_SUCCESS;
-}
-
-#endif /* !IN_RC */
-
-/**
- * Checks if nested paging is enabled
- *
- * @returns boolean
- * @param   pVM         Pointer to the VM.
- */
-VMMDECL(bool) HWACCMIsNestedPagingActive(PVM pVM)
-{
-    return HWACCMIsEnabled(pVM) && pVM->hwaccm.s.fNestedPaging;
-}
-
-/**
- * Return the shadow paging mode for nested paging/ept
- *
- * @returns shadow paging mode
- * @param   pVM         Pointer to the VM.
- */
-VMMDECL(PGMMODE) HWACCMGetShwPagingMode(PVM pVM)
-{
-    Assert(HWACCMIsNestedPagingActive(pVM));
-    if (pVM->hwaccm.s.svm.fSupported)
-        return PGMMODE_NESTED;
-
-    Assert(pVM->hwaccm.s.vmx.fSupported);
-    return PGMMODE_EPT;
-}
-
-/**
- * Invalidates a guest page by physical address
- *
- * NOTE: Assumes the current instruction references this physical page though a virtual address!!
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   GCPhys      Page to invalidate
- */
-VMMDECL(int) HWACCMInvalidatePhysPage(PVM pVM, RTGCPHYS GCPhys)
-{
-    if (!HWACCMIsNestedPagingActive(pVM))
-        return VINF_SUCCESS;
-
-#ifdef IN_RING0
-    if (pVM->hwaccm.s.vmx.fSupported)
-    {
-        VMCPUID idThisCpu = VMMGetCpuId(pVM);
-
-        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-        {
-            PVMCPU pVCpu = &pVM->aCpus[idCpu];
-
-            if (idThisCpu == idCpu)
-                VMXR0InvalidatePhysPage(pVM, pVCpu, GCPhys);
-            else
-            {
-                VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
-                hmPokeCpuForTlbFlush(pVCpu, true /*fAccountFlushStat*/);
-            }
-        }
-        return VINF_SUCCESS;
-    }
-
-    /* AMD-V doesn't support invalidation with guest physical addresses; see
-       comment in SVMR0InvalidatePhysPage. */
-    Assert(pVM->hwaccm.s.svm.fSupported);
-#else
-    NOREF(GCPhys);
-#endif
-
-    HWACCMFlushTLBOnAllVCpus(pVM);
-    return VINF_SUCCESS;
-}
-
-/**
- * Checks if an interrupt event is currently pending.
- *
- * @returns Interrupt event pending state.
- * @param   pVM         Pointer to the VM.
- */
-VMMDECL(bool) HWACCMHasPendingIrq(PVM pVM)
-{
-    PVMCPU pVCpu = VMMGetCpu(pVM);
-    return !!pVCpu->hwaccm.s.Event.fPending;
-}
-
Index: trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp	(revision 43387)
@@ -35,5 +35,5 @@
 #include <VBox/vmm/vm.h>
 #include <VBox/vmm/vmm.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include "IOMInline.h"
 
@@ -2360,7 +2360,7 @@
 
     /* This currently only works in real mode, protected mode without paging or with nested paging. */
-    if (    !HWACCMIsEnabled(pVM)       /* useless without VT-x/AMD-V */
+    if (    !HMIsEnabled(pVM)       /* useless without VT-x/AMD-V */
         ||  (   CPUMIsGuestInPagedProtectedMode(pVCpu)
-             && !HWACCMIsNestedPagingActive(pVM)))
+             && !HMIsNestedPagingActive(pVM)))
         return VINF_SUCCESS;    /* ignore */
 
@@ -2429,5 +2429,5 @@
 
     AssertReturn(fPageFlags == (X86_PTE_RW | X86_PTE_P), VERR_INVALID_PARAMETER);
-    Assert(HWACCMIsEnabled(pVM));
+    Assert(HMIsEnabled(pVM));
 
     PVMCPU pVCpu = VMMGetCpu(pVM);
@@ -2481,7 +2481,7 @@
 
     /* This currently only works in real mode, protected mode without paging or with nested paging. */
-    if (    !HWACCMIsEnabled(pVM)       /* useless without VT-x/AMD-V */
+    if (    !HMIsEnabled(pVM)       /* useless without VT-x/AMD-V */
         ||  (   CPUMIsGuestInPagedProtectedMode(pVCpu)
-             && !HWACCMIsNestedPagingActive(pVM)))
+             && !HMIsNestedPagingActive(pVM)))
         return VINF_SUCCESS;    /* ignore */
 
Index: trunk/src/VBox/VMM/VMMAll/MMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/MMAll.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMAll/MMAll.cpp	(revision 43387)
@@ -640,5 +640,5 @@
         TAG2STR(VMM);
 
-        TAG2STR(HWACCM);
+        TAG2STR(HM);
 
         #undef TAG2STR
Index: trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 43387)
@@ -27,5 +27,5 @@
 #include <VBox/vmm/vm.h>
 #include <VBox/err.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 
 #include <VBox/log.h>
@@ -254,5 +254,5 @@
     {
         /*
-         * Leave HWACCM context while waiting if necessary.
+         * Leave HM context while waiting if necessary.
          */
         int rc;
@@ -267,5 +267,5 @@
             PVM     pVM   = pCritSect->s.CTX_SUFF(pVM);
             PVMCPU  pVCpu = VMMGetCpu(pVM);
-            HWACCMR0Leave(pVM, pVCpu);
+            HMR0Leave(pVM, pVCpu);
             RTThreadPreemptRestore(NIL_RTTHREAD, ????);
 
@@ -273,5 +273,5 @@
 
             RTThreadPreemptDisable(NIL_RTTHREAD, ????);
-            HWACCMR0Enter(pVM, pVCpu);
+            HMR0Enter(pVM, pVCpu);
         }
         return rc;
Index: trunk/src/VBox/VMM/VMMAll/PGMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAll.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMAll/PGMAll.cpp	(revision 43387)
@@ -34,6 +34,6 @@
 #endif
 #include <VBox/vmm/em.h>
-#include <VBox/vmm/hwaccm.h>
-#include <VBox/vmm/hwacc_vmx.h>
+#include <VBox/vmm/hm.h>
+#include <VBox/vmm/hm_vmx.h>
 #include "PGMInternal.h"
 #include <VBox/vmm/vm.h>
@@ -958,5 +958,5 @@
                      * No need to monitor anything in this case.
                      */
-                    Assert(!HWACCMIsEnabled(pVM));
+                    Assert(!HMIsEnabled(pVM));
 
                     GCPdPt  = uGstPdpe & X86_PDPE_PG_MASK;
Index: trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 43379)
+++ trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 43387)
@@ -1017,5 +1017,5 @@
                 */
 #   if PGM_SHW_TYPE == PGM_TYPE_EPT
-                HWACCMInvalidatePhysPage(pVM, (RTGCPHYS)pvFault);
+                HMInvalidatePhysPage(pVM, (RTGCPHYS)pvFault);
 #   else
                 PGM_INVL_PG(pVCpu, pvFault);
Index: trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp	(revision 43387)
@@ -437,5 +437,5 @@
         PGM_INVL_VCPU_TLBS(VMMGetCpu0(pVM));
 # else
-    HWACCMFlushTLBOnAllVCpus(pVM);
+    HMFlushTLBOnAllVCpus(pVM);
 # endif
 
Index: trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 43387)
@@ -32,5 +32,5 @@
 #include "PGMInline.h"
 #include <VBox/disopcode.h>
-#include <VBox/vmm/hwacc_vmx.h>
+#include <VBox/vmm/hm_vmx.h>
 
 #include <VBox/log.h>
@@ -742,5 +742,5 @@
 #ifndef IN_RC
     /** @todo could make this general, faulting close to rsp should be a safe reuse heuristic. */
-    if (   HWACCMHasPendingIrq(pVM)
+    if (   HMHasPendingIrq(pVM)
         && (pRegFrame->rsp - pvFault) < 32)
     {
Index: trunk/src/VBox/VMM/VMMAll/PGMAllShw.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAllShw.h	(revision 43379)
+++ trunk/src/VBox/VMM/VMMAll/PGMAllShw.h	(revision 43387)
@@ -479,5 +479,5 @@
                 SHW_PTE_ATOMIC_SET2(pPT->a[iPTE], NewPte);
 # if PGM_SHW_TYPE == PGM_TYPE_EPT
-                HWACCMInvalidatePhysPage(pVM, (RTGCPHYS)GCPtr);
+                HMInvalidatePhysPage(pVM, (RTGCPHYS)GCPtr);
 # else
                 PGM_INVL_PG_ALL_VCPU(pVM, GCPtr);
Index: trunk/src/VBox/VMM/VMMAll/SELMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/SELMAll.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMAll/SELMAll.cpp	(revision 43387)
@@ -25,5 +25,5 @@
 #include <VBox/vmm/mm.h>
 #include <VBox/vmm/pgm.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include "SELMInternal.h"
 #include <VBox/vmm/vm.h>
@@ -786,8 +786,8 @@
 
     /* Undo ring compression. */
-    if ((SelCPL & X86_SEL_RPL) == 1 && !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)))
+    if ((SelCPL & X86_SEL_RPL) == 1 && !HMIsEnabled(pVCpu->CTX_SUFF(pVM)))
         SelCPL &= ~X86_SEL_RPL;
     Assert(pSRegCS->Sel == SelCS);
-    if ((SelCS  & X86_SEL_RPL) == 1 && !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM)))
+    if ((SelCS  & X86_SEL_RPL) == 1 && !HMIsEnabled(pVCpu->CTX_SUFF(pVM)))
         SelCS  &= ~X86_SEL_RPL;
 #else
Index: trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp	(revision 43387)
@@ -26,5 +26,5 @@
 #include <VBox/err.h>
 #include <VBox/log.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <iprt/assert.h>
 #include <iprt/asm-amd64-x86.h>
@@ -407,5 +407,5 @@
         if (!(pVCpu->cpum.s.fUseFlags & CPUM_SYNC_FPU_STATE))
         {
-            HWACCMR0SaveFPUState(pVM, pVCpu, pCtx);
+            HMR0SaveFPUState(pVM, pVCpu, pCtx);
             cpumR0RestoreHostFPUState(&pVCpu->cpum.s);
         }
@@ -493,5 +493,5 @@
             uint64_t dr6 = pCtx->dr[6];
 
-            HWACCMR0SaveDebugState(pVM, pVCpu, pCtx);
+            HMR0SaveDebugState(pVM, pVCpu, pCtx);
             if (!fDR6) /* dr6 was already up-to-date */
                 pCtx->dr[6] = dr6;
Index: trunk/src/VBox/VMM/VMMR0/HMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HMR0.cpp	(revision 43387)
+++ trunk/src/VBox/VMM/VMMR0/HMR0.cpp	(revision 43387)
@@ -0,0 +1,2057 @@
+/* $Id$ */
+/** @file
+ * Hardware Assisted Virtualization Manager (HM) - Host Context Ring-0.
+ */
+
+/*
+ * 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;
+ * 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.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_HM
+#include <VBox/vmm/hm.h>
+#include <VBox/vmm/pgm.h>
+#include "HMInternal.h"
+#include <VBox/vmm/vm.h>
+#include <VBox/vmm/hm_vmx.h>
+#include <VBox/vmm/hm_svm.h>
+#include <VBox/err.h>
+#include <VBox/log.h>
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/asm-amd64-x86.h>
+#include <iprt/cpuset.h>
+#include <iprt/mem.h>
+#include <iprt/memobj.h>
+#include <iprt/once.h>
+#include <iprt/param.h>
+#include <iprt/power.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+#include <iprt/x86.h>
+#include "HWVMXR0.h"
+#include "HWSVMR0.h"
+
+
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
+static DECLCALLBACK(void) hmR0EnableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2);
+static DECLCALLBACK(void) hmR0DisableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2);
+static DECLCALLBACK(void) hmR0InitIntelCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2);
+static DECLCALLBACK(void) hmR0InitAmdCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2);
+static DECLCALLBACK(void) hmR0PowerCallback(RTPOWEREVENT enmEvent, void *pvUser);
+static DECLCALLBACK(void) hmR0MpEventCallback(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvData);
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/**
+ * This is used to manage the status code of a RTMpOnAll in HM.
+ */
+typedef struct HMR0FIRSTRC
+{
+    /** The status code. */
+    int32_t volatile    rc;
+    /** The ID of the CPU reporting the first failure. */
+    RTCPUID volatile    idCpu;
+} HMR0FIRSTRC;
+/** Pointer to a first return code structure. */
+typedef HMR0FIRSTRC *PHMR0FIRSTRC;
+
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+/**
+ * Global data.
+ */
+static struct
+{
+    /** Per CPU globals. */
+    HMGLOBLCPUINFO                  aCpuInfo[RTCPUSET_MAX_CPUS];
+
+    /** @name Ring-0 method table for AMD-V and VT-x specific operations.
+     * @{ */
+    DECLR0CALLBACKMEMBER(int, pfnEnterSession,(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu));
+    DECLR0CALLBACKMEMBER(int, pfnLeaveSession,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx));
+    DECLR0CALLBACKMEMBER(int, pfnSaveHostState,(PVM pVM, PVMCPU pVCpu));
+    DECLR0CALLBACKMEMBER(int, pfnLoadGuestState,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx));
+    DECLR0CALLBACKMEMBER(int, pfnRunGuestCode,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx));
+    DECLR0CALLBACKMEMBER(int, pfnEnableCpu,(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage,
+                                            bool fEnabledByHost));
+    DECLR0CALLBACKMEMBER(int, pfnDisableCpu,(PHMGLOBLCPUINFO pCpu, void *pvCpuPage, RTHCPHYS HCPhysCpuPage));
+    DECLR0CALLBACKMEMBER(int, pfnInitVM,(PVM pVM));
+    DECLR0CALLBACKMEMBER(int, pfnTermVM,(PVM pVM));
+    DECLR0CALLBACKMEMBER(int, pfnSetupVM,(PVM pVM));
+    /** @} */
+
+    /** Maximum ASID allowed. */
+    uint32_t                        uMaxASID;
+
+    /** VT-x data. */
+    struct
+    {
+        /** Set to by us to indicate VMX is supported by the CPU. */
+        bool                        fSupported;
+        /** Whether we're using SUPR0EnableVTx or not. */
+        bool                        fUsingSUPR0EnableVTx;
+        /** Whether we're using the preemption timer or not. */
+        bool                        fUsePreemptTimer;
+        /** The shift mask employed by the VMX-Preemption timer. */
+        uint8_t                     cPreemptTimerShift;
+
+        /** Host CR4 value (set by ring-0 VMX init) */
+        uint64_t                    hostCR4;
+
+        /** Host EFER value (set by ring-0 VMX init) */
+        uint64_t                    hostEFER;
+
+        /** VMX MSR values */
+        struct
+        {
+            uint64_t                feature_ctrl;
+            uint64_t                vmx_basic_info;
+            VMX_CAPABILITY          vmx_pin_ctls;
+            VMX_CAPABILITY          vmx_proc_ctls;
+            VMX_CAPABILITY          vmx_proc_ctls2;
+            VMX_CAPABILITY          vmx_exit;
+            VMX_CAPABILITY          vmx_entry;
+            uint64_t                vmx_misc;
+            uint64_t                vmx_cr0_fixed0;
+            uint64_t                vmx_cr0_fixed1;
+            uint64_t                vmx_cr4_fixed0;
+            uint64_t                vmx_cr4_fixed1;
+            uint64_t                vmx_vmcs_enum;
+            uint64_t                vmx_eptcaps;
+        } msr;
+        /* Last instruction error */
+        uint32_t                    ulLastInstrError;
+    } vmx;
+
+    /** AMD-V information. */
+    struct
+    {
+        /* HWCR msr (for diagnostics) */
+        uint64_t                    msrHWCR;
+
+        /** SVM revision. */
+        uint32_t                    u32Rev;
+
+        /** SVM feature bits from cpuid 0x8000000a */
+        uint32_t                    u32Features;
+
+        /** Set by us to indicate SVM is supported by the CPU. */
+        bool                        fSupported;
+    } svm;
+    /** Saved error from detection */
+    int32_t         lLastError;
+
+    struct
+    {
+        uint32_t                    u32AMDFeatureECX;
+        uint32_t                    u32AMDFeatureEDX;
+    } cpuid;
+
+    /** If set, VT-x/AMD-V is enabled globally at init time, otherwise it's
+     * enabled and disabled each time it's used to execute guest code. */
+    bool                            fGlobalInit;
+    /** Indicates whether the host is suspending or not.  We'll refuse a few
+     *  actions when the host is being suspended to speed up the suspending and
+     *  avoid trouble. */
+    volatile        bool            fSuspended;
+
+    /** Whether we've already initialized all CPUs.
+     * @remarks We could check the EnableAllCpusOnce state, but this is
+     *          simpler and hopefully easier to understand. */
+    bool                            fEnabled;
+    /** Serialize initialization in HMR0EnableAllCpus. */
+    RTONCE                          EnableAllCpusOnce;
+} g_HvmR0;
+
+
+
+/**
+ * Initializes a first return code structure.
+ *
+ * @param   pFirstRc            The structure to init.
+ */
+static void hmR0FirstRcInit(PHMR0FIRSTRC pFirstRc)
+{
+    pFirstRc->rc    = VINF_SUCCESS;
+    pFirstRc->idCpu = NIL_RTCPUID;
+}
+
+
+/**
+ * Try se the status code (success ignored).
+ *
+ * @param   pFirstRc            The first return code structure.
+ * @param   rc                  The status code.
+ */
+static void     hmR0FirstRcSetStatus(PHMR0FIRSTRC pFirstRc, int rc)
+{
+    if (   RT_FAILURE(rc)
+        && ASMAtomicCmpXchgS32(&pFirstRc->rc, rc, VINF_SUCCESS))
+        pFirstRc->idCpu = RTMpCpuId();
+}
+
+
+/**
+ * Get the status code of a first return code structure.
+ *
+ * @returns The status code; VINF_SUCCESS or error status, no informational or
+ *          warning errors.
+ * @param   pFirstRc            The first return code structure.
+ */
+static int hmR0FirstRcGetStatus(PHMR0FIRSTRC pFirstRc)
+{
+    return pFirstRc->rc;
+}
+
+
+#ifdef VBOX_STRICT
+/**
+ * Get the CPU ID on which the failure status code was reported.
+ *
+ * @returns The CPU ID, NIL_RTCPUID if no failure was reported.
+ * @param   pFirstRc            The first return code structure.
+ */
+static RTCPUID hmR0FirstRcGetCpuId(PHMR0FIRSTRC pFirstRc)
+{
+    return pFirstRc->idCpu;
+}
+#endif /* VBOX_STRICT */
+
+
+/** @name Dummy callback handlers.
+ * @{ */
+
+static DECLCALLBACK(int) hmR0DummyEnter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu)
+{
+    NOREF(pVM); NOREF(pVCpu); NOREF(pCpu);
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) hmR0DummyLeave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+    NOREF(pVM); NOREF(pVCpu); NOREF(pCtx);
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) hmR0DummyEnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage,
+                                            bool fEnabledBySystem)
+{
+    NOREF(pCpu); NOREF(pVM); NOREF(pvCpuPage); NOREF(HCPhysCpuPage); NOREF(fEnabledBySystem);
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) hmR0DummyDisableCpu(PHMGLOBLCPUINFO pCpu, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
+{
+    NOREF(pCpu);  NOREF(pvCpuPage); NOREF(HCPhysCpuPage);
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) hmR0DummyInitVM(PVM pVM)
+{
+    NOREF(pVM);
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) hmR0DummyTermVM(PVM pVM)
+{
+    NOREF(pVM);
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) hmR0DummySetupVM(PVM pVM)
+{
+    NOREF(pVM);
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) hmR0DummyRunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+    NOREF(pVM); NOREF(pVCpu); NOREF(pCtx);
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) hmR0DummySaveHostState(PVM pVM, PVMCPU pVCpu)
+{
+    NOREF(pVM); NOREF(pVCpu);
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) hmR0DummyLoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+    NOREF(pVM); NOREF(pVCpu); NOREF(pCtx);
+    return VINF_SUCCESS;
+}
+
+/** @} */
+
+
+/**
+ * Checks if the CPU is subject to the "VMX-Preemption Timer Does Not Count
+ * Down at the Rate Specified" erratum.
+ *
+ * Errata names and related steppings:
+ *      - BA86   - D0.
+ *      - AAX65  - C2.
+ *      - AAU65  - C2, K0.
+ *      - AAO95  - B1.
+ *      - AAT59  - C2.
+ *      - AAK139 - D0.
+ *      - AAM126 - C0, C1, D0.
+ *      - AAN92  - B1.
+ *      - AAJ124 - C0, D0.
+ *
+ *      - AAP86  - B1.
+ *
+ * Steppings: B1, C0, C1, C2, D0, K0.
+ *
+ * @returns true if subject to it, false if not.
+ */
+static bool hmR0InitIntelIsSubjectToVmxPreemptionTimerErratum(void)
+{
+    uint32_t u = ASMCpuId_EAX(1);
+    u &= ~(RT_BIT_32(14) | RT_BIT_32(15) | RT_BIT_32(28) | RT_BIT_32(29) | RT_BIT_32(30) | RT_BIT_32(31));
+    if (   u == UINT32_C(0x000206E6) /* 323344.pdf - BA86   - D0 - Intel Xeon Processor 7500 Series */
+        || u == UINT32_C(0x00020652) /* 323056.pdf - AAX65  - C2 - Intel Xeon Processor L3406 */
+        || u == UINT32_C(0x00020652) /* 322814.pdf - AAT59  - C2 - Intel CoreTM i7-600, i5-500, i5-400 and i3-300 Mobile Processor Series */
+        || u == UINT32_C(0x00020652) /* 322911.pdf - AAU65  - C2 - Intel CoreTM i5-600, i3-500 Desktop Processor Series and Intel Pentium Processor G6950 */
+        || u == UINT32_C(0x00020655) /* 322911.pdf - AAU65  - K0 - Intel CoreTM i5-600, i3-500 Desktop Processor Series and Intel Pentium Processor G6950 */
+        || u == UINT32_C(0x000106E5) /* 322373.pdf - AAO95  - B1 - Intel Xeon Processor 3400 Series */
+        || u == UINT32_C(0x000106E5) /* 322166.pdf - AAN92  - B1 - Intel CoreTM i7-800 and i5-700 Desktop Processor Series */
+        || u == UINT32_C(0x000106E5) /* 320767.pdf - AAP86  - B1 - Intel Core i7-900 Mobile Processor Extreme Edition Series, Intel Core i7-800 and i7-700 Mobile Processor Series */
+        || u == UINT32_C(0x000106A0) /*?321333.pdf - AAM126 - C0 - Intel Xeon Processor 3500 Series Specification */
+        || u == UINT32_C(0x000106A1) /*?321333.pdf - AAM126 - C1 - Intel Xeon Processor 3500 Series Specification */
+        || u == UINT32_C(0x000106A4) /* 320836.pdf - AAJ124 - C0 - Intel Core i7-900 Desktop Processor Extreme Edition Series and Intel Core i7-900 Desktop Processor Series */
+        || u == UINT32_C(0x000106A5) /* 321333.pdf - AAM126 - D0 - Intel Xeon Processor 3500 Series Specification */
+        || u == UINT32_C(0x000106A5) /* 321324.pdf - AAK139 - D0 - Intel Xeon Processor 5500 Series Specification */
+        || u == UINT32_C(0x000106A5) /* 320836.pdf - AAJ124 - D0 - Intel Core i7-900 Desktop Processor Extreme Edition Series and Intel Core i7-900 Desktop Processor Series */
+        )
+        return true;
+    return false;
+}
+
+
+/**
+ * Intel specific initialization code.
+ *
+ * @returns VBox status code (will only fail if out of memory).
+ */
+static int hmR0InitIntel(uint32_t u32FeaturesECX, uint32_t u32FeaturesEDX)
+{
+    /*
+     * Check that all the required VT-x features are present.
+     * We also assume all VT-x-enabled CPUs support fxsave/fxrstor.
+     */
+    if (    (u32FeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
+         && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
+         && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
+       )
+    {
+        /** @todo move this into a separate function. */
+        g_HvmR0.vmx.msr.feature_ctrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+
+        /*
+         * First try use native kernel API for controlling VT-x.
+         * (This is only supported by some Mac OS X kernels atm.)
+         */
+        int rc = g_HvmR0.lLastError = SUPR0EnableVTx(true /* fEnable */);
+        g_HvmR0.vmx.fUsingSUPR0EnableVTx = rc != VERR_NOT_SUPPORTED;
+        if (g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+        {
+            AssertLogRelMsg(rc == VINF_SUCCESS || rc == VERR_VMX_IN_VMX_ROOT_MODE || rc == VERR_VMX_NO_VMX, ("%Rrc\n", rc));
+            if (RT_SUCCESS(rc))
+            {
+                g_HvmR0.vmx.fSupported = true;
+                rc = SUPR0EnableVTx(false /* fEnable */);
+                AssertLogRelRC(rc);
+            }
+        }
+        else
+        {
+            /* We need to check if VT-x has been properly initialized on all
+               CPUs. Some BIOSes do a lousy job. */
+            HMR0FIRSTRC FirstRc;
+            hmR0FirstRcInit(&FirstRc);
+            g_HvmR0.lLastError = RTMpOnAll(hmR0InitIntelCpu, &FirstRc, NULL);
+            if (RT_SUCCESS(g_HvmR0.lLastError))
+                g_HvmR0.lLastError = hmR0FirstRcGetStatus(&FirstRc);
+        }
+        if (RT_SUCCESS(g_HvmR0.lLastError))
+        {
+            /* Reread in case we've changed it. */
+            g_HvmR0.vmx.msr.feature_ctrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+
+            if (   (g_HvmR0.vmx.msr.feature_ctrl & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+                ==                                 (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+            {
+                /*
+                 * Read all relevant MSR.
+                 */
+                g_HvmR0.vmx.msr.vmx_basic_info  = ASMRdMsr(MSR_IA32_VMX_BASIC_INFO);
+                g_HvmR0.vmx.msr.vmx_pin_ctls.u  = ASMRdMsr(MSR_IA32_VMX_PINBASED_CTLS);
+                g_HvmR0.vmx.msr.vmx_proc_ctls.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS);
+                g_HvmR0.vmx.msr.vmx_exit.u      = ASMRdMsr(MSR_IA32_VMX_EXIT_CTLS);
+                g_HvmR0.vmx.msr.vmx_entry.u     = ASMRdMsr(MSR_IA32_VMX_ENTRY_CTLS);
+                g_HvmR0.vmx.msr.vmx_misc        = ASMRdMsr(MSR_IA32_VMX_MISC);
+                g_HvmR0.vmx.msr.vmx_cr0_fixed0  = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED0);
+                g_HvmR0.vmx.msr.vmx_cr0_fixed1  = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED1);
+                g_HvmR0.vmx.msr.vmx_cr4_fixed0  = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED0);
+                g_HvmR0.vmx.msr.vmx_cr4_fixed1  = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED1);
+                g_HvmR0.vmx.msr.vmx_vmcs_enum   = ASMRdMsr(MSR_IA32_VMX_VMCS_ENUM);
+                g_HvmR0.vmx.hostCR4             = ASMGetCR4();
+                g_HvmR0.vmx.hostEFER            = ASMRdMsr(MSR_K6_EFER);
+                /* VPID 16 bits ASID. */
+                g_HvmR0.uMaxASID                = 0x10000; /* exclusive */
+
+                if (g_HvmR0.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
+                {
+                    g_HvmR0.vmx.msr.vmx_proc_ctls2.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS2);
+                    if (  g_HvmR0.vmx.msr.vmx_proc_ctls2.n.allowed1
+                        & (VMX_VMCS_CTRL_PROC_EXEC2_EPT | VMX_VMCS_CTRL_PROC_EXEC2_VPID))
+                        g_HvmR0.vmx.msr.vmx_eptcaps = ASMRdMsr(MSR_IA32_VMX_EPT_CAPS);
+                }
+
+                if (!g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+                {
+                    /*
+                     * Enter root mode
+                     */
+                    RTR0MEMOBJ hScatchMemObj;
+                    rc = RTR0MemObjAllocCont(&hScatchMemObj, PAGE_SIZE, true /*fExecutable*/);
+                    if (RT_FAILURE(rc))
+                    {
+                        LogRel(("hmR0InitIntel: RTR0MemObjAllocCont(,PAGE_SIZE,true) -> %Rrc\n", rc));
+                        return rc;
+                    }
+
+                    void      *pvScatchPage      = RTR0MemObjAddress(hScatchMemObj);
+                    RTHCPHYS   HCPhysScratchPage = RTR0MemObjGetPagePhysAddr(hScatchMemObj, 0);
+                    ASMMemZeroPage(pvScatchPage);
+
+                    /* Set revision dword at the beginning of the structure. */
+                    *(uint32_t *)pvScatchPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(g_HvmR0.vmx.msr.vmx_basic_info);
+
+                    /* Make sure we don't get rescheduled to another cpu during this probe. */
+                    RTCCUINTREG fFlags = ASMIntDisableFlags();
+
+                    /*
+                     * Check CR4.VMXE
+                     */
+                    g_HvmR0.vmx.hostCR4 = ASMGetCR4();
+                    if (!(g_HvmR0.vmx.hostCR4 & X86_CR4_VMXE))
+                    {
+                        /* In theory this bit could be cleared behind our back.  Which would cause
+                           #UD faults when we try to execute the VMX instructions... */
+                        ASMSetCR4(g_HvmR0.vmx.hostCR4 | X86_CR4_VMXE);
+                    }
+
+                    /* Enter VMX Root Mode */
+                    rc = VMXEnable(HCPhysScratchPage);
+                    if (RT_SUCCESS(rc))
+                    {
+                        g_HvmR0.vmx.fSupported = true;
+                        VMXDisable();
+                    }
+                    else
+                    {
+                        /*
+                         * KVM leaves the CPU in VMX root mode. Not only is  this not allowed,
+                         * it will crash the host when we enter raw mode, because:
+                         *
+                         *   (a) clearing X86_CR4_VMXE in CR4 causes a #GP (we no longer modify
+                         *       this bit), and
+                         *   (b) turning off paging causes a #GP  (unavoidable when switching
+                         *       from long to 32 bits mode or 32 bits to PAE).
+                         *
+                         * They should fix their code, but until they do we simply refuse to run.
+                         */
+                        g_HvmR0.lLastError = VERR_VMX_IN_VMX_ROOT_MODE;
+                    }
+
+                    /* Restore CR4 again; don't leave the X86_CR4_VMXE flag set
+                       if it wasn't so before (some software could incorrectly
+                       think it's in VMX mode). */
+                    ASMSetCR4(g_HvmR0.vmx.hostCR4);
+                    ASMSetFlags(fFlags);
+
+                    RTR0MemObjFree(hScatchMemObj, false);
+                }
+            }
+            else
+            {
+                AssertFailed(); /* can't hit this case anymore */
+                g_HvmR0.lLastError = VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR;
+            }
+
+            if (g_HvmR0.vmx.fSupported)
+            {
+                /*
+                 * Install the VT-x methods.
+                 */
+                g_HvmR0.pfnEnterSession     = VMXR0Enter;
+                g_HvmR0.pfnLeaveSession     = VMXR0Leave;
+                g_HvmR0.pfnSaveHostState    = VMXR0SaveHostState;
+                g_HvmR0.pfnLoadGuestState   = VMXR0LoadGuestState;
+                g_HvmR0.pfnRunGuestCode     = VMXR0RunGuestCode;
+                g_HvmR0.pfnEnableCpu        = VMXR0EnableCpu;
+                g_HvmR0.pfnDisableCpu       = VMXR0DisableCpu;
+                g_HvmR0.pfnInitVM           = VMXR0InitVM;
+                g_HvmR0.pfnTermVM           = VMXR0TermVM;
+                g_HvmR0.pfnSetupVM          = VMXR0SetupVM;
+
+                /*
+                 * Check for the VMX-Preemption Timer and adjust for the * "VMX-Preemption
+                 * Timer Does Not Count Down at the Rate Specified" erratum.
+                 */
+                if (  g_HvmR0.vmx.msr.vmx_pin_ctls.n.allowed1
+                    & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
+                {
+                    g_HvmR0.vmx.fUsePreemptTimer   = true;
+                    g_HvmR0.vmx.cPreemptTimerShift = MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(g_HvmR0.vmx.msr.vmx_misc);
+                    if (hmR0InitIntelIsSubjectToVmxPreemptionTimerErratum())
+                        g_HvmR0.vmx.cPreemptTimerShift = 0; /* This is about right most of the time here. */
+                }
+            }
+        }
+#ifdef LOG_ENABLED
+        else
+            SUPR0Printf("hmR0InitIntelCpu failed with rc=%d\n", g_HvmR0.lLastError);
+#endif
+    }
+    else
+        g_HvmR0.lLastError = VERR_VMX_NO_VMX;
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * AMD-specific initialization code.
+ */
+static void hmR0InitAmd(uint32_t u32FeaturesEDX)
+{
+    /*
+     * Read all SVM MSRs if SVM is available. (same goes for RDMSR/WRMSR)
+     * We also assume all SVM-enabled CPUs support fxsave/fxrstor.
+     */
+    if (   (g_HvmR0.cpuid.u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM)
+        && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
+        && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
+       )
+    {
+        g_HvmR0.pfnEnterSession     = SVMR0Enter;
+        g_HvmR0.pfnLeaveSession     = SVMR0Leave;
+        g_HvmR0.pfnSaveHostState    = SVMR0SaveHostState;
+        g_HvmR0.pfnLoadGuestState   = SVMR0LoadGuestState;
+        g_HvmR0.pfnRunGuestCode     = SVMR0RunGuestCode;
+        g_HvmR0.pfnEnableCpu        = SVMR0EnableCpu;
+        g_HvmR0.pfnDisableCpu       = SVMR0DisableCpu;
+        g_HvmR0.pfnInitVM           = SVMR0InitVM;
+        g_HvmR0.pfnTermVM           = SVMR0TermVM;
+        g_HvmR0.pfnSetupVM          = SVMR0SetupVM;
+
+        /* Query AMD features. */
+        uint32_t u32Dummy;
+        ASMCpuId(0x8000000A, &g_HvmR0.svm.u32Rev, &g_HvmR0.uMaxASID,
+                 &u32Dummy, &g_HvmR0.svm.u32Features);
+
+        /*
+         * We need to check if AMD-V has been properly initialized on all CPUs.
+         * Some BIOSes might do a poor job.
+         */
+        HMR0FIRSTRC FirstRc;
+        hmR0FirstRcInit(&FirstRc);
+        int rc = RTMpOnAll(hmR0InitAmdCpu, &FirstRc, NULL);
+        AssertRC(rc);
+        if (RT_SUCCESS(rc))
+            rc = hmR0FirstRcGetStatus(&FirstRc);
+#ifndef DEBUG_bird
+        AssertMsg(rc == VINF_SUCCESS || rc == VERR_SVM_IN_USE,
+                  ("hmR0InitAmdCpu failed for cpu %d with rc=%Rrc\n", hmR0FirstRcGetCpuId(&FirstRc), rc));
+#endif
+        if (RT_SUCCESS(rc))
+        {
+            /* Read the HWCR msr for diagnostics. */
+            g_HvmR0.svm.msrHWCR    = ASMRdMsr(MSR_K8_HWCR);
+            g_HvmR0.svm.fSupported = true;
+        }
+        else
+            g_HvmR0.lLastError = rc;
+    }
+    else
+        g_HvmR0.lLastError = VERR_SVM_NO_SVM;
+}
+
+
+/**
+ * Does global Ring-0 HM initialization (at module init).
+ *
+ * @returns VBox status code.
+ */
+VMMR0DECL(int) HMR0Init(void)
+{
+    /*
+     * Initialize the globals.
+     */
+    g_HvmR0.fEnabled = false;
+    static RTONCE s_OnceInit = RTONCE_INITIALIZER;
+    g_HvmR0.EnableAllCpusOnce = s_OnceInit;
+    for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
+        g_HvmR0.aCpuInfo[i].hMemObj = NIL_RTR0MEMOBJ;
+
+    /* Fill in all callbacks with placeholders. */
+    g_HvmR0.pfnEnterSession     = hmR0DummyEnter;
+    g_HvmR0.pfnLeaveSession     = hmR0DummyLeave;
+    g_HvmR0.pfnSaveHostState    = hmR0DummySaveHostState;
+    g_HvmR0.pfnLoadGuestState   = hmR0DummyLoadGuestState;
+    g_HvmR0.pfnRunGuestCode     = hmR0DummyRunGuestCode;
+    g_HvmR0.pfnEnableCpu        = hmR0DummyEnableCpu;
+    g_HvmR0.pfnDisableCpu       = hmR0DummyDisableCpu;
+    g_HvmR0.pfnInitVM           = hmR0DummyInitVM;
+    g_HvmR0.pfnTermVM           = hmR0DummyTermVM;
+    g_HvmR0.pfnSetupVM          = hmR0DummySetupVM;
+
+    /* Default is global VT-x/AMD-V init. */
+    g_HvmR0.fGlobalInit         = true;
+
+    /*
+     * Make sure aCpuInfo is big enough for all the CPUs on this system.
+     */
+    if (RTMpGetArraySize() > RT_ELEMENTS(g_HvmR0.aCpuInfo))
+    {
+        LogRel(("HM: Too many real CPUs/cores/threads - %u, max %u\n", RTMpGetArraySize(), RT_ELEMENTS(g_HvmR0.aCpuInfo)));
+        return VERR_TOO_MANY_CPUS;
+    }
+
+    /*
+     * Check for VT-x and AMD-V capabilities.
+     */
+    int rc;
+    if (ASMHasCpuId())
+    {
+        uint32_t u32FeaturesECX, u32FeaturesEDX;
+        uint32_t u32VendorEBX, u32VendorECX, u32VendorEDX;
+        uint32_t u32Dummy;
+
+        /* Standard features. */
+        ASMCpuId(0, &u32Dummy, &u32VendorEBX, &u32VendorECX, &u32VendorEDX);
+        ASMCpuId(1, &u32Dummy, &u32Dummy, &u32FeaturesECX, &u32FeaturesEDX);
+
+        /* Query AMD features. */
+        ASMCpuId(0x80000001, &u32Dummy, &u32Dummy,
+                 &g_HvmR0.cpuid.u32AMDFeatureECX,
+                 &g_HvmR0.cpuid.u32AMDFeatureEDX);
+
+        /* Go to CPU specific initialization code. */
+        if (   (   u32VendorEBX == X86_CPUID_VENDOR_INTEL_EBX
+                && u32VendorECX == X86_CPUID_VENDOR_INTEL_ECX
+                && u32VendorEDX == X86_CPUID_VENDOR_INTEL_EDX)
+            || (   u32VendorEBX == X86_CPUID_VENDOR_VIA_EBX
+                && u32VendorECX == X86_CPUID_VENDOR_VIA_ECX
+                && u32VendorEDX == X86_CPUID_VENDOR_VIA_EDX))
+        {
+            rc = hmR0InitIntel(u32FeaturesECX, u32FeaturesEDX);
+            if (RT_FAILURE(rc))
+                return rc;
+        }
+        else if (   u32VendorEBX == X86_CPUID_VENDOR_AMD_EBX
+                 && u32VendorECX == X86_CPUID_VENDOR_AMD_ECX
+                 && u32VendorEDX == X86_CPUID_VENDOR_AMD_EDX)
+            hmR0InitAmd(u32FeaturesEDX);
+        else
+            g_HvmR0.lLastError = VERR_HM_UNKNOWN_CPU;
+    }
+    else
+        g_HvmR0.lLastError = VERR_HM_NO_CPUID;
+
+    /*
+     * Register notification callbacks that we can use to disable/enable CPUs
+     * when brought offline/online or suspending/resuming.
+     */
+    if (!g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+    {
+        rc = RTMpNotificationRegister(hmR0MpEventCallback, NULL);
+        AssertRC(rc);
+
+        rc = RTPowerNotificationRegister(hmR0PowerCallback, NULL);
+        AssertRC(rc);
+    }
+
+    /* We return success here because module init shall not fail if HM
+       fails to initialize. */
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Does global Ring-0 HM termination (at module termination).
+ *
+ * @returns VBox status code.
+ */
+VMMR0DECL(int) HMR0Term(void)
+{
+    int rc;
+    if (   g_HvmR0.vmx.fSupported
+        && g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+    {
+        /*
+         * Simple if the host OS manages VT-x.
+         */
+        Assert(g_HvmR0.fGlobalInit);
+        rc = SUPR0EnableVTx(false /* fEnable */);
+
+        for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo); iCpu++)
+        {
+            g_HvmR0.aCpuInfo[iCpu].fConfigured = false;
+            Assert(g_HvmR0.aCpuInfo[iCpu].hMemObj == NIL_RTR0MEMOBJ);
+        }
+    }
+    else
+    {
+        Assert(!g_HvmR0.vmx.fUsingSUPR0EnableVTx);
+        if (!g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+        {
+            /* Doesn't really matter if this fails. */
+            rc = RTMpNotificationDeregister(hmR0MpEventCallback, NULL);  AssertRC(rc);
+            rc = RTPowerNotificationDeregister(hmR0PowerCallback, NULL); AssertRC(rc);
+        }
+        else
+            rc = VINF_SUCCESS;
+
+        /*
+         * Disable VT-x/AMD-V on all CPUs if we enabled it before.
+         */
+        if (g_HvmR0.fGlobalInit)
+        {
+            HMR0FIRSTRC FirstRc;
+            hmR0FirstRcInit(&FirstRc);
+            rc = RTMpOnAll(hmR0DisableCpuCallback, NULL, &FirstRc);
+            Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
+            if (RT_SUCCESS(rc))
+            {
+                rc = hmR0FirstRcGetStatus(&FirstRc);
+                AssertMsgRC(rc, ("%u: %Rrc\n", hmR0FirstRcGetCpuId(&FirstRc), rc));
+            }
+        }
+
+        /*
+         * Free the per-cpu pages used for VT-x and AMD-V.
+         */
+        for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
+        {
+            if (g_HvmR0.aCpuInfo[i].hMemObj != NIL_RTR0MEMOBJ)
+            {
+                RTR0MemObjFree(g_HvmR0.aCpuInfo[i].hMemObj, false);
+                g_HvmR0.aCpuInfo[i].hMemObj = NIL_RTR0MEMOBJ;
+            }
+        }
+    }
+    return rc;
+}
+
+
+/**
+ * Worker function used by hmR0PowerCallback  and HMR0Init to initalize
+ * VT-x on a CPU.
+ *
+ * @param   idCpu       The identifier for the CPU the function is called on.
+ * @param   pvUser1     Pointer to the first RC structure.
+ * @param   pvUser2     Ignored.
+ */
+static DECLCALLBACK(void) hmR0InitIntelCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+    PHMR0FIRSTRC pFirstRc = (PHMR0FIRSTRC)pvUser1;
+    Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
+    NOREF(pvUser2);
+
+    /*
+     * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP.
+     * Once the lock bit is set, this MSR can no longer be modified.
+     */
+    uint64_t fFC = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+    if (   !(fFC    & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+        || (   (fFC & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+            == MSR_IA32_FEATURE_CONTROL_VMXON ) /* Some BIOSes forget to set the locked bit. */
+       )
+    {
+        /* MSR is not yet locked; we can change it ourselves here. */
+        ASMWrMsr(MSR_IA32_FEATURE_CONTROL,
+                 g_HvmR0.vmx.msr.feature_ctrl | MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK);
+        fFC = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
+    }
+
+    int rc;
+    if (   (fFC & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+        == (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
+        rc = VINF_SUCCESS;
+    else
+        rc = VERR_VMX_MSR_LOCKED_OR_DISABLED;
+
+    hmR0FirstRcSetStatus(pFirstRc, rc);
+}
+
+
+/**
+ * Worker function used by hmR0PowerCallback  and HMR0Init to initalize
+ * VT-x / AMD-V on a CPU.
+ *
+ * @param   idCpu       The identifier for the CPU the function is called on.
+ * @param   pvUser1     Pointer to the first RC structure.
+ * @param   pvUser2     Ignored.
+ */
+static DECLCALLBACK(void) hmR0InitAmdCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+    PHMR0FIRSTRC pFirstRc = (PHMR0FIRSTRC)pvUser1;
+    Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
+    NOREF(pvUser2);
+
+    /* Check if SVM is disabled. */
+    int rc;
+    uint64_t fVmCr = ASMRdMsr(MSR_K8_VM_CR);
+    if (!(fVmCr & MSR_K8_VM_CR_SVM_DISABLE))
+    {
+        /* Turn on SVM in the EFER MSR. */
+        uint64_t fEfer = ASMRdMsr(MSR_K6_EFER);
+        if (fEfer & MSR_K6_EFER_SVME)
+            rc = VERR_SVM_IN_USE;
+        else
+        {
+            ASMWrMsr(MSR_K6_EFER, fEfer | MSR_K6_EFER_SVME);
+
+            /* Paranoia. */
+            fEfer = ASMRdMsr(MSR_K6_EFER);
+            if (fEfer & MSR_K6_EFER_SVME)
+            {
+                /* Restore previous value. */
+                ASMWrMsr(MSR_K6_EFER, fEfer & ~MSR_K6_EFER_SVME);
+                rc = VINF_SUCCESS;
+            }
+            else
+                rc = VERR_SVM_ILLEGAL_EFER_MSR;
+        }
+    }
+    else
+        rc = VERR_SVM_DISABLED;
+
+    hmR0FirstRcSetStatus(pFirstRc, rc);
+}
+
+
+
+/**
+ * Disable VT-x or AMD-V on the current CPU
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM (can be 0).
+ * @param   idCpu       The identifier for the CPU the function is called on.
+ */
+static int hmR0EnableCpu(PVM pVM, RTCPUID idCpu)
+{
+    PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[idCpu];
+
+    Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
+    Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
+    Assert(!pCpu->fConfigured);
+    Assert(!g_HvmR0.fGlobalInit || ASMAtomicReadBool(&pCpu->fInUse) == false);
+
+    pCpu->idCpu         = idCpu;
+    pCpu->uCurrentASID  = 0;    /* we'll aways increment this the first time (host uses ASID 0) */
+    /* Do NOT reset cTLBFlushes here, see @bugref{6255}. */
+
+    int rc;
+    if (g_HvmR0.vmx.fSupported && g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+        rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, NULL, NIL_RTHCPHYS, true);
+    else
+    {
+        AssertLogRelMsgReturn(pCpu->hMemObj != NIL_RTR0MEMOBJ, ("hmR0EnableCpu failed idCpu=%u.\n", idCpu), VERR_HM_IPE_1);
+        void    *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
+        RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
+        rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage, false);
+    }
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+        pCpu->fConfigured = true;
+
+    return rc;
+}
+
+
+/**
+ * Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that
+ * is to be called on the target cpus.
+ *
+ * @param   idCpu       The identifier for the CPU the function is called on.
+ * @param   pvUser1     The 1st user argument.
+ * @param   pvUser2     The 2nd user argument.
+ */
+static DECLCALLBACK(void) hmR0EnableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+    PVM             pVM      = (PVM)pvUser1;     /* can be NULL! */
+    PHMR0FIRSTRC    pFirstRc = (PHMR0FIRSTRC)pvUser2;
+    AssertReturnVoid(g_HvmR0.fGlobalInit);
+    hmR0FirstRcSetStatus(pFirstRc, hmR0EnableCpu(pVM, idCpu));
+}
+
+
+/**
+ * RTOnce callback employed by HMR0EnableAllCpus.
+ *
+ * @returns VBox status code.
+ * @param   pvUser          Pointer to the VM.
+ * @param   pvUserIgnore    NULL, ignored.
+ */
+static DECLCALLBACK(int32_t) hmR0EnableAllCpuOnce(void *pvUser, void *pvUserIgnore)
+{
+    PVM pVM = (PVM)pvUser;
+    NOREF(pvUserIgnore);
+
+    /*
+     * Indicate that we've initialized.
+     *
+     * Note! There is a potential race between this function and the suspend
+     *       notification.  Kind of unlikely though, so ignored for now.
+     */
+    AssertReturn(!g_HvmR0.fEnabled, VERR_HM_ALREADY_ENABLED_IPE);
+    ASMAtomicWriteBool(&g_HvmR0.fEnabled, true);
+
+    /*
+     * The global init variable is set by the first VM.
+     */
+    g_HvmR0.fGlobalInit = pVM->hm.s.fGlobalInit;
+
+    for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
+    {
+        Assert(g_HvmR0.aCpuInfo[i].hMemObj == NIL_RTR0MEMOBJ);
+        g_HvmR0.aCpuInfo[i].fConfigured = false;
+        g_HvmR0.aCpuInfo[i].cTLBFlushes = 0;
+    }
+
+    int rc;
+    if (   g_HvmR0.vmx.fSupported
+        && g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+    {
+        /*
+         * Global VT-x initialization API (only darwin for now).
+         */
+        rc = SUPR0EnableVTx(true /* fEnable */);
+        if (RT_SUCCESS(rc))
+            /* If the host provides a VT-x init API, then we'll rely on that for global init. */
+            g_HvmR0.fGlobalInit = pVM->hm.s.fGlobalInit = true;
+        else
+            AssertMsgFailed(("hmR0EnableAllCpuOnce/SUPR0EnableVTx: rc=%Rrc\n", rc));
+    }
+    else
+    {
+        /*
+         * We're doing the job ourselves.
+         */
+        /* Allocate one page per cpu for the global vt-x and amd-v pages */
+        for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
+        {
+            Assert(g_HvmR0.aCpuInfo[i].hMemObj == NIL_RTR0MEMOBJ);
+
+            if (RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(i)))
+            {
+                rc = RTR0MemObjAllocCont(&g_HvmR0.aCpuInfo[i].hMemObj, PAGE_SIZE, true /* executable R0 mapping */);
+                AssertLogRelRCReturn(rc, rc);
+
+                void *pvR0 = RTR0MemObjAddress(g_HvmR0.aCpuInfo[i].hMemObj); Assert(pvR0);
+                ASMMemZeroPage(pvR0);
+            }
+        }
+
+        rc = VINF_SUCCESS;
+    }
+
+    if (RT_SUCCESS(rc) && g_HvmR0.fGlobalInit)
+    {
+        /* First time, so initialize each cpu/core. */
+        HMR0FIRSTRC FirstRc;
+        hmR0FirstRcInit(&FirstRc);
+        rc = RTMpOnAll(hmR0EnableCpuCallback, (void *)pVM, &FirstRc);
+        if (RT_SUCCESS(rc))
+            rc = hmR0FirstRcGetStatus(&FirstRc);
+        AssertMsgRC(rc, ("hmR0EnableAllCpuOnce failed for cpu %d with rc=%d\n", hmR0FirstRcGetCpuId(&FirstRc), rc));
+    }
+
+    return rc;
+}
+
+
+/**
+ * Sets up HM on all cpus.
+ *
+ * @returns VBox status code.
+ * @param   pVM                 Pointer to the VM.
+ */
+VMMR0DECL(int) HMR0EnableAllCpus(PVM pVM)
+{
+    /* Make sure we don't touch hm after we've disabled hm in
+       preparation of a suspend. */
+    if (ASMAtomicReadBool(&g_HvmR0.fSuspended))
+        return VERR_HM_SUSPEND_PENDING;
+
+    return RTOnce(&g_HvmR0.EnableAllCpusOnce, hmR0EnableAllCpuOnce, pVM, NULL);
+}
+
+
+/**
+ * Disable VT-x or AMD-V on the current CPU.
+ *
+ * @returns VBox status code.
+ * @param   idCpu       The identifier for the CPU the function is called on.
+ */
+static int hmR0DisableCpu(RTCPUID idCpu)
+{
+    PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[idCpu];
+
+    Assert(!g_HvmR0.vmx.fSupported || !g_HvmR0.vmx.fUsingSUPR0EnableVTx);
+    Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
+    Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
+    Assert(!g_HvmR0.fGlobalInit || ASMAtomicReadBool(&pCpu->fInUse) == false);
+    Assert(!pCpu->fConfigured || pCpu->hMemObj != NIL_RTR0MEMOBJ);
+
+    if (pCpu->hMemObj == NIL_RTR0MEMOBJ)
+        return pCpu->fConfigured ? VERR_NO_MEMORY : VINF_SUCCESS /* not initialized. */;
+
+    int rc;
+    if (pCpu->fConfigured)
+    {
+        void    *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
+        RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
+        if (idCpu == RTMpCpuId())
+        {
+            rc = g_HvmR0.pfnDisableCpu(pCpu, pvCpuPage, HCPhysCpuPage);
+            AssertRC(rc);
+        }
+        else
+        {
+            pCpu->fIgnoreAMDVInUseError = true;
+            rc = VINF_SUCCESS;
+        }
+
+        pCpu->fConfigured = false;
+    }
+    else
+        rc = VINF_SUCCESS; /* nothing to do */
+
+    pCpu->uCurrentASID = 0;
+    return rc;
+}
+
+
+/**
+ * Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that
+ * is to be called on the target cpus.
+ *
+ * @param   idCpu       The identifier for the CPU the function is called on.
+ * @param   pvUser1     The 1st user argument.
+ * @param   pvUser2     The 2nd user argument.
+ */
+static DECLCALLBACK(void) hmR0DisableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+{
+    PHMR0FIRSTRC pFirstRc = (PHMR0FIRSTRC)pvUser2; NOREF(pvUser1);
+    AssertReturnVoid(g_HvmR0.fGlobalInit);
+    hmR0FirstRcSetStatus(pFirstRc, hmR0DisableCpu(idCpu));
+}
+
+
+/**
+ * Callback function invoked when a cpu goes online or offline.
+ *
+ * @param   enmEvent            The Mp event.
+ * @param   idCpu               The identifier for the CPU the function is called on.
+ * @param   pvData              Opaque data (PVM pointer).
+ */
+static DECLCALLBACK(void) hmR0MpEventCallback(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvData)
+{
+    NOREF(pvData);
+
+    /*
+     * We only care about uninitializing a CPU that is going offline. When a
+     * CPU comes online, the initialization is done lazily in HMR0Enter().
+     */
+    Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+    switch (enmEvent)
+    {
+        case RTMPEVENT_OFFLINE:
+        {
+            int rc = hmR0DisableCpu(idCpu);
+            AssertRC(rc);
+            break;
+        }
+
+        default:
+            break;
+    }
+}
+
+
+/**
+ * Called whenever a system power state change occurs.
+ *
+ * @param   enmEvent        The Power event.
+ * @param   pvUser          User argument.
+ */
+static DECLCALLBACK(void) hmR0PowerCallback(RTPOWEREVENT enmEvent, void *pvUser)
+{
+    NOREF(pvUser);
+    Assert(!g_HvmR0.vmx.fSupported || !g_HvmR0.vmx.fUsingSUPR0EnableVTx);
+
+#ifdef LOG_ENABLED
+    if (enmEvent == RTPOWEREVENT_SUSPEND)
+        SUPR0Printf("hmR0PowerCallback RTPOWEREVENT_SUSPEND\n");
+    else
+        SUPR0Printf("hmR0PowerCallback RTPOWEREVENT_RESUME\n");
+#endif
+
+    if (enmEvent == RTPOWEREVENT_SUSPEND)
+        ASMAtomicWriteBool(&g_HvmR0.fSuspended, true);
+
+    if (g_HvmR0.fEnabled)
+    {
+        int         rc;
+        HMR0FIRSTRC FirstRc;
+        hmR0FirstRcInit(&FirstRc);
+
+        if (enmEvent == RTPOWEREVENT_SUSPEND)
+        {
+            if (g_HvmR0.fGlobalInit)
+            {
+                /* Turn off VT-x or AMD-V on all CPUs. */
+                rc = RTMpOnAll(hmR0DisableCpuCallback, NULL, &FirstRc);
+                Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
+            }
+            /* else nothing to do here for the local init case */
+        }
+        else
+        {
+            /* Reinit the CPUs from scratch as the suspend state might have
+               messed with the MSRs. (lousy BIOSes as usual) */
+            if (g_HvmR0.vmx.fSupported)
+                rc = RTMpOnAll(hmR0InitIntelCpu, &FirstRc, NULL);
+            else
+                rc = RTMpOnAll(hmR0InitAmdCpu, &FirstRc, NULL);
+            Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
+            if (RT_SUCCESS(rc))
+                rc = hmR0FirstRcGetStatus(&FirstRc);
+#ifdef LOG_ENABLED
+            if (RT_FAILURE(rc))
+                SUPR0Printf("hmR0PowerCallback hmR0InitXxxCpu failed with %Rc\n", rc);
+#endif
+            if (g_HvmR0.fGlobalInit)
+            {
+                /* Turn VT-x or AMD-V back on on all CPUs. */
+                rc = RTMpOnAll(hmR0EnableCpuCallback, NULL, &FirstRc /* output ignored */);
+                Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
+            }
+            /* else nothing to do here for the local init case */
+        }
+    }
+
+    if (enmEvent == RTPOWEREVENT_RESUME)
+        ASMAtomicWriteBool(&g_HvmR0.fSuspended, false);
+}
+
+
+/**
+ * Does Ring-0 per VM HM initialization.
+ *
+ * This will copy HM global into the VM structure and call the CPU specific
+ * init routine which will allocate resources for each virtual CPU and such.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR0DECL(int) HMR0InitVM(PVM pVM)
+{
+    AssertReturn(pVM, VERR_INVALID_PARAMETER);
+
+#ifdef LOG_ENABLED
+    SUPR0Printf("HMR0InitVM: %p\n", pVM);
+#endif
+
+    /* Make sure we don't touch hm after we've disabled hm in preparation of a suspend. */
+    if (ASMAtomicReadBool(&g_HvmR0.fSuspended))
+        return VERR_HM_SUSPEND_PENDING;
+
+    /*
+     * Copy globals to the VM structure.
+     */
+    pVM->hm.s.vmx.fSupported            = g_HvmR0.vmx.fSupported;
+    pVM->hm.s.svm.fSupported            = g_HvmR0.svm.fSupported;
+
+    pVM->hm.s.vmx.fUsePreemptTimer      = g_HvmR0.vmx.fUsePreemptTimer;
+    pVM->hm.s.vmx.cPreemptTimerShift    = g_HvmR0.vmx.cPreemptTimerShift;
+    pVM->hm.s.vmx.msr.feature_ctrl      = g_HvmR0.vmx.msr.feature_ctrl;
+    pVM->hm.s.vmx.hostCR4               = g_HvmR0.vmx.hostCR4;
+    pVM->hm.s.vmx.hostEFER              = g_HvmR0.vmx.hostEFER;
+    pVM->hm.s.vmx.msr.vmx_basic_info    = g_HvmR0.vmx.msr.vmx_basic_info;
+    pVM->hm.s.vmx.msr.vmx_pin_ctls      = g_HvmR0.vmx.msr.vmx_pin_ctls;
+    pVM->hm.s.vmx.msr.vmx_proc_ctls     = g_HvmR0.vmx.msr.vmx_proc_ctls;
+    pVM->hm.s.vmx.msr.vmx_proc_ctls2    = g_HvmR0.vmx.msr.vmx_proc_ctls2;
+    pVM->hm.s.vmx.msr.vmx_exit          = g_HvmR0.vmx.msr.vmx_exit;
+    pVM->hm.s.vmx.msr.vmx_entry         = g_HvmR0.vmx.msr.vmx_entry;
+    pVM->hm.s.vmx.msr.vmx_misc          = g_HvmR0.vmx.msr.vmx_misc;
+    pVM->hm.s.vmx.msr.vmx_cr0_fixed0    = g_HvmR0.vmx.msr.vmx_cr0_fixed0;
+    pVM->hm.s.vmx.msr.vmx_cr0_fixed1    = g_HvmR0.vmx.msr.vmx_cr0_fixed1;
+    pVM->hm.s.vmx.msr.vmx_cr4_fixed0    = g_HvmR0.vmx.msr.vmx_cr4_fixed0;
+    pVM->hm.s.vmx.msr.vmx_cr4_fixed1    = g_HvmR0.vmx.msr.vmx_cr4_fixed1;
+    pVM->hm.s.vmx.msr.vmx_vmcs_enum     = g_HvmR0.vmx.msr.vmx_vmcs_enum;
+    pVM->hm.s.vmx.msr.vmx_eptcaps       = g_HvmR0.vmx.msr.vmx_eptcaps;
+    pVM->hm.s.svm.msrHWCR               = g_HvmR0.svm.msrHWCR;
+    pVM->hm.s.svm.u32Rev                = g_HvmR0.svm.u32Rev;
+    pVM->hm.s.svm.u32Features           = g_HvmR0.svm.u32Features;
+    pVM->hm.s.cpuid.u32AMDFeatureECX    = g_HvmR0.cpuid.u32AMDFeatureECX;
+    pVM->hm.s.cpuid.u32AMDFeatureEDX    = g_HvmR0.cpuid.u32AMDFeatureEDX;
+    pVM->hm.s.lLastError                = g_HvmR0.lLastError;
+
+    pVM->hm.s.uMaxASID                  = g_HvmR0.uMaxASID;
+
+
+    if (!pVM->hm.s.cMaxResumeLoops) /* allow ring-3 overrides */
+    {
+        pVM->hm.s.cMaxResumeLoops       = 1024;
+#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
+        if (RTThreadPreemptIsPendingTrusty())
+            pVM->hm.s.cMaxResumeLoops   = 8192;
+#endif
+    }
+
+    /*
+     * Initialize some per CPU fields.
+     */
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+
+        pVCpu->hm.s.idEnteredCpu        = NIL_RTCPUID;
+
+        /* Invalidate the last cpu we were running on. */
+        pVCpu->hm.s.idLastCpu           = NIL_RTCPUID;
+
+        /* We'll aways increment this the first time (host uses ASID 0) */
+        pVCpu->hm.s.uCurrentASID        = 0;
+    }
+
+    /*
+     * Call the hardware specific initialization method.
+     *
+     * Note! The fInUse handling here isn't correct as we can we can be
+     *       rescheduled to a different cpu, but the fInUse case is mostly for
+     *       debugging...  Disabling preemption isn't an option when allocating
+     *       memory, so we'll let it slip for now.
+     */
+    RTCCUINTREG     fFlags = ASMIntDisableFlags();
+    PHMGLOBLCPUINFO pCpu   = HMR0GetCurrentCpu();
+    ASMAtomicWriteBool(&pCpu->fInUse, true);
+    ASMSetFlags(fFlags);
+
+    int rc = g_HvmR0.pfnInitVM(pVM);
+
+    ASMAtomicWriteBool(&pCpu->fInUse, false);
+    return rc;
+}
+
+
+/**
+ * Does Ring-0 per VM HM termination.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR0DECL(int) HMR0TermVM(PVM pVM)
+{
+    Log(("HMR0TermVM: %p\n", pVM));
+    AssertReturn(pVM, VERR_INVALID_PARAMETER);
+
+    /* Make sure we don't touch hm after we've disabled hm in preparation
+       of a suspend. */
+    /** @todo r=bird: This cannot be right, the termination functions are
+     *        just freeing memory and resetting pVM/pVCpu members...
+     *  ==> memory leak. */
+    AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HM_SUSPEND_PENDING);
+
+    /*
+     * Call the hardware specific method.
+     *
+     * Note! Not correct as we can be rescheduled to a different cpu, but the
+     *       fInUse case is mostly for debugging.
+     */
+    RTCCUINTREG     fFlags = ASMIntDisableFlags();
+    PHMGLOBLCPUINFO pCpu   = HMR0GetCurrentCpu();
+    ASMAtomicWriteBool(&pCpu->fInUse, true);
+    ASMSetFlags(fFlags);
+
+    int rc = g_HvmR0.pfnTermVM(pVM);
+
+    ASMAtomicWriteBool(&pCpu->fInUse, false);
+    return rc;
+}
+
+
+/**
+ * Sets up a VT-x or AMD-V session.
+ *
+ * This is mostly about setting up the hardware VM state.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR0DECL(int) HMR0SetupVM(PVM pVM)
+{
+    Log(("HMR0SetupVM: %p\n", pVM));
+    AssertReturn(pVM, VERR_INVALID_PARAMETER);
+
+    /* Make sure we don't touch hm after we've disabled hm in
+       preparation of a suspend. */
+    AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HM_SUSPEND_PENDING);
+
+
+    /*
+     * Call the hardware specific setup VM method.  This requires the CPU to be
+     * enabled for AMD-V/VT-x and preemption to be prevented.
+     */
+    RTCCUINTREG     fFlags = ASMIntDisableFlags();
+    RTCPUID         idCpu  = RTMpCpuId();
+    PHMGLOBLCPUINFO pCpu   = &g_HvmR0.aCpuInfo[idCpu];
+    ASMAtomicWriteBool(&pCpu->fInUse, true);
+
+    /* On first entry we'll sync everything. */
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+        pVM->aCpus[i].hm.s.fContextUseFlags = HM_CHANGED_ALL;
+
+    /* Enable VT-x or AMD-V if local init is required. */
+    int rc;
+    if (!g_HvmR0.fGlobalInit)
+    {
+        rc = hmR0EnableCpu(pVM, idCpu);
+        AssertReturnStmt(RT_SUCCESS_NP(rc), ASMSetFlags(fFlags), rc);
+    }
+
+    /* Setup VT-x or AMD-V. */
+    rc = g_HvmR0.pfnSetupVM(pVM);
+
+    /* Disable VT-x or AMD-V if local init was done before. */
+    if (!g_HvmR0.fGlobalInit)
+    {
+        int rc2 = hmR0DisableCpu(idCpu);
+        AssertRC(rc2);
+    }
+
+    ASMAtomicWriteBool(&pCpu->fInUse, false);
+    ASMSetFlags(fFlags);
+
+    return rc;
+}
+
+
+/**
+ * Enters the VT-x or AMD-V session.
+ *
+ * @returns VBox status code.
+ * @param   pVM        Pointer to the VM.
+ * @param   pVCpu      Pointer to the VMCPU.
+ *
+ * @remarks This is called with preemption disabled.
+ */
+VMMR0DECL(int) HMR0Enter(PVM pVM, PVMCPU pVCpu)
+{
+    RTCPUID         idCpu = RTMpCpuId();
+    PHMGLOBLCPUINFO pCpu  = &g_HvmR0.aCpuInfo[idCpu];
+
+    /* Make sure we can't enter a session after we've disabled HM in preparation of a suspend. */
+    AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HM_SUSPEND_PENDING);
+    ASMAtomicWriteBool(&pCpu->fInUse, true);
+
+    AssertMsg(pVCpu->hm.s.idEnteredCpu == NIL_RTCPUID, ("%d", (int)pVCpu->hm.s.idEnteredCpu));
+    pVCpu->hm.s.idEnteredCpu = idCpu;
+
+    PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
+
+    /* Always load the guest's FPU/XMM state on-demand. */
+    CPUMDeactivateGuestFPUState(pVCpu);
+
+    /* Always load the guest's debug state on-demand. */
+    CPUMDeactivateGuestDebugState(pVCpu);
+
+    /* Always reload the host context and the guest's CR0 register. (!!!!) */
+    pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR0 | HM_CHANGED_HOST_CONTEXT;
+
+    /* Setup the register and mask according to the current execution mode. */
+    if (pCtx->msrEFER & MSR_K6_EFER_LMA)
+        pVM->hm.s.u64RegisterMask = UINT64_C(0xFFFFFFFFFFFFFFFF);
+    else
+        pVM->hm.s.u64RegisterMask = UINT64_C(0xFFFFFFFF);
+
+    /* Enable VT-x or AMD-V if local init is required, or enable if it's a
+       freshly onlined CPU. */
+    int rc;
+    if (   !pCpu->fConfigured
+        || !g_HvmR0.fGlobalInit)
+    {
+        rc = hmR0EnableCpu(pVM, idCpu);
+        AssertRCReturn(rc, rc);
+    }
+
+#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
+    bool fStartedSet = PGMR0DynMapStartOrMigrateAutoSet(pVCpu);
+#endif
+
+    rc  = g_HvmR0.pfnEnterSession(pVM, pVCpu, pCpu);
+    AssertRC(rc);
+    /* We must save the host context here (VT-x) as we might be rescheduled on
+       a different cpu after a long jump back to ring 3. */
+    rc |= g_HvmR0.pfnSaveHostState(pVM, pVCpu);
+    AssertRC(rc);
+    rc |= g_HvmR0.pfnLoadGuestState(pVM, pVCpu, pCtx);
+    AssertRC(rc);
+
+#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
+    if (fStartedSet)
+        PGMRZDynMapReleaseAutoSet(pVCpu);
+#endif
+
+    /* Keep track of the CPU owning the VMCS for debugging scheduling weirdness
+       and ring-3 calls. */
+    if (RT_FAILURE(rc))
+        pVCpu->hm.s.idEnteredCpu = NIL_RTCPUID;
+    return rc;
+}
+
+
+/**
+ * Leaves the VT-x or AMD-V session.
+ *
+ * @returns VBox status code.
+ * @param   pVM        Pointer to the VM.
+ * @param   pVCpu      Pointer to the VMCPU.
+ *
+ * @remarks Called with preemption disabled just like HMR0Enter, our
+ *          counterpart.
+ */
+VMMR0DECL(int) HMR0Leave(PVM pVM, PVMCPU pVCpu)
+{
+    int             rc;
+    RTCPUID         idCpu = RTMpCpuId();
+    PHMGLOBLCPUINFO pCpu  = &g_HvmR0.aCpuInfo[idCpu];
+    PCPUMCTX        pCtx  = CPUMQueryGuestCtxPtr(pVCpu);
+
+    /** @todo r=bird: This can't be entirely right? */
+    AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HM_SUSPEND_PENDING);
+
+    /*
+     * Save the guest FPU and XMM state if necessary.
+     *
+     * Note! It's rather tricky with longjmps done by e.g. Log statements or
+     *       the page fault handler.  We must restore the host FPU here to make
+     *       absolutely sure we don't leave the guest FPU state active or trash
+     *       somebody else's FPU state.
+     */
+    if (CPUMIsGuestFPUStateActive(pVCpu))
+    {
+        Log2(("CPUMR0SaveGuestFPU\n"));
+        CPUMR0SaveGuestFPU(pVM, pVCpu, pCtx);
+
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR0;
+        Assert(!CPUMIsGuestFPUStateActive(pVCpu));
+    }
+
+    rc = g_HvmR0.pfnLeaveSession(pVM, pVCpu, pCtx);
+
+    /* We don't pass on invlpg information to the recompiler for nested paging
+       guests, so we must make sure the recompiler flushes its TLB the next
+       time it executes code. */
+    if (    pVM->hm.s.fNestedPaging
+        &&  CPUMIsGuestInPagedProtectedModeEx(pCtx))
+        CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_GLOBAL_TLB_FLUSH);
+
+    /* Keep track of the CPU owning the VMCS for debugging scheduling weirdness
+       and ring-3 calls. */
+    AssertMsgStmt(   pVCpu->hm.s.idEnteredCpu == idCpu
+                  || RT_FAILURE_NP(rc),
+                  ("Owner is %u, I'm %u", pVCpu->hm.s.idEnteredCpu, idCpu),
+                  rc = VERR_HM_WRONG_CPU_1);
+    pVCpu->hm.s.idEnteredCpu = NIL_RTCPUID;
+
+    /*
+     * Disable VT-x or AMD-V if local init was done before.
+     */
+    if (!g_HvmR0.fGlobalInit)
+    {
+        rc = hmR0DisableCpu(idCpu);
+        AssertRC(rc);
+
+        /* Reset these to force a TLB flush for the next entry. (-> EXPENSIVE) */
+        pVCpu->hm.s.idLastCpu    = NIL_RTCPUID;
+        pVCpu->hm.s.uCurrentASID = 0;
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
+    }
+
+    ASMAtomicWriteBool(&pCpu->fInUse, false);
+    return rc;
+}
+
+
+/**
+ * Runs guest code in a hardware accelerated VM.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ *
+ * @remarks Called with preemption disabled and after first having called
+ *          HMR0Enter.
+ */
+VMMR0DECL(int) HMR0RunGuestCode(PVM pVM, PVMCPU pVCpu)
+{
+#ifdef VBOX_STRICT
+    PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[RTMpCpuId()];
+    Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL));
+    Assert(pCpu->fConfigured);
+    AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HM_SUSPEND_PENDING);
+    Assert(ASMAtomicReadBool(&pCpu->fInUse) == true);
+#endif
+
+#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
+    PGMRZDynMapStartAutoSet(pVCpu);
+#endif
+
+    int rc = g_HvmR0.pfnRunGuestCode(pVM, pVCpu, CPUMQueryGuestCtxPtr(pVCpu));
+
+#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
+    PGMRZDynMapReleaseAutoSet(pVCpu);
+#endif
+    return rc;
+}
+
+#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+
+/**
+ * Save guest FPU/XMM state (64 bits guest mode & 32 bits host only)
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   pCtx        Pointer to the guest CPU context.
+ */
+VMMR0DECL(int)   HMR0SaveFPUState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+    STAM_COUNTER_INC(&pVCpu->hm.s.StatFpu64SwitchBack);
+    if (pVM->hm.s.vmx.fSupported)
+        return VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hm.s.pfnSaveGuestFPU64, 0, NULL);
+    return SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hm.s.pfnSaveGuestFPU64, 0, NULL);
+}
+
+
+/**
+ * Save guest debug state (64 bits guest mode & 32 bits host only)
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   pCtx        Pointer to the guest CPU context.
+ */
+VMMR0DECL(int)   HMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+    STAM_COUNTER_INC(&pVCpu->hm.s.StatDebug64SwitchBack);
+    if (pVM->hm.s.vmx.fSupported)
+        return VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hm.s.pfnSaveGuestDebug64, 0, NULL);
+    return SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hm.s.pfnSaveGuestDebug64, 0, NULL);
+}
+
+
+/**
+ * Test the 32->64 bits switcher.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR0DECL(int)   HMR0TestSwitcher3264(PVM pVM)
+{
+    PVMCPU   pVCpu = &pVM->aCpus[0];
+    PCPUMCTX pCtx  = CPUMQueryGuestCtxPtr(pVCpu);
+    uint32_t aParam[5] = {0, 1, 2, 3, 4};
+    int      rc;
+
+    STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatWorldSwitch3264, z);
+    if (pVM->hm.s.vmx.fSupported)
+        rc = VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hm.s.pfnTest64, 5, &aParam[0]);
+    else
+        rc = SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hm.s.pfnTest64, 5, &aParam[0]);
+    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatWorldSwitch3264, z);
+
+    return rc;
+}
+
+#endif /* HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL) */
+
+/**
+ * Returns suspend status of the host.
+ *
+ * @returns Suspend pending or not.
+ */
+VMMR0DECL(bool) HMR0SuspendPending(void)
+{
+    return ASMAtomicReadBool(&g_HvmR0.fSuspended);
+}
+
+
+/**
+ * Returns the cpu structure for the current cpu.
+ * Keep in mind that there is no guarantee it will stay the same (long jumps to ring 3!!!).
+ *
+ * @returns The cpu structure pointer.
+ */
+VMMR0DECL(PHMGLOBLCPUINFO) HMR0GetCurrentCpu(void)
+{
+    RTCPUID idCpu = RTMpCpuId();
+    Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
+    return &g_HvmR0.aCpuInfo[idCpu];
+}
+
+
+/**
+ * Returns the cpu structure for the current cpu.
+ * Keep in mind that there is no guarantee it will stay the same (long jumps to ring 3!!!).
+ *
+ * @returns The cpu structure pointer.
+ * @param   idCpu       id of the VCPU.
+ */
+VMMR0DECL(PHMGLOBLCPUINFO) HMR0GetCurrentCpuEx(RTCPUID idCpu)
+{
+    Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
+    return &g_HvmR0.aCpuInfo[idCpu];
+}
+
+
+/**
+ * Save a pending IO read.
+ *
+ * @param   pVCpu           Pointer to the VMCPU.
+ * @param   GCPtrRip        Address of IO instruction.
+ * @param   GCPtrRipNext    Address of the next instruction.
+ * @param   uPort           Port address.
+ * @param   uAndVal         AND mask for saving the result in eax.
+ * @param   cbSize          Read size.
+ */
+VMMR0DECL(void) HMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize)
+{
+    pVCpu->hm.s.PendingIO.enmType         = HMPENDINGIO_PORT_READ;
+    pVCpu->hm.s.PendingIO.GCPtrRip        = GCPtrRip;
+    pVCpu->hm.s.PendingIO.GCPtrRipNext    = GCPtrRipNext;
+    pVCpu->hm.s.PendingIO.s.Port.uPort    = uPort;
+    pVCpu->hm.s.PendingIO.s.Port.uAndVal  = uAndVal;
+    pVCpu->hm.s.PendingIO.s.Port.cbSize   = cbSize;
+    return;
+}
+
+
+/**
+ * Save a pending IO write.
+ *
+ * @param   pVCpu           Pointer to the VMCPU.
+ * @param   GCPtrRIP        Address of IO instruction.
+ * @param   uPort           Port address.
+ * @param   uAndVal         AND mask for fetching the result from eax.
+ * @param   cbSize          Read size.
+ */
+VMMR0DECL(void) HMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize)
+{
+    pVCpu->hm.s.PendingIO.enmType         = HMPENDINGIO_PORT_WRITE;
+    pVCpu->hm.s.PendingIO.GCPtrRip        = GCPtrRip;
+    pVCpu->hm.s.PendingIO.GCPtrRipNext    = GCPtrRipNext;
+    pVCpu->hm.s.PendingIO.s.Port.uPort    = uPort;
+    pVCpu->hm.s.PendingIO.s.Port.uAndVal  = uAndVal;
+    pVCpu->hm.s.PendingIO.s.Port.cbSize   = cbSize;
+    return;
+}
+
+
+/**
+ * Raw-mode switcher hook - disable VT-x if it's active *and* the current
+ * switcher turns off paging.
+ *
+ * @returns VBox status code.
+ * @param   pVM             Pointer to the VM.
+ * @param   enmSwitcher     The switcher we're about to use.
+ * @param   pfVTxDisabled   Where to store whether VT-x was disabled or not.
+ */
+VMMR0DECL(int) HMR0EnterSwitcher(PVM pVM, VMMSWITCHER enmSwitcher, bool *pfVTxDisabled)
+{
+    Assert(!(ASMGetFlags() & X86_EFL_IF) || !RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+
+    *pfVTxDisabled = false;
+
+    /* No such issues with AMD-V */
+    if (!g_HvmR0.vmx.fSupported)
+        return VINF_SUCCESS;
+
+    /* Check if the swithcing we're up to is safe. */
+    switch (enmSwitcher)
+    {
+        case VMMSWITCHER_32_TO_32:
+        case VMMSWITCHER_PAE_TO_PAE:
+            return VINF_SUCCESS;    /* safe switchers as they don't turn off paging */
+
+        case VMMSWITCHER_32_TO_PAE:
+        case VMMSWITCHER_PAE_TO_32: /* is this one actually used?? */
+        case VMMSWITCHER_AMD64_TO_32:
+        case VMMSWITCHER_AMD64_TO_PAE:
+            break;                  /* unsafe switchers */
+
+        default:
+            AssertFailedReturn(VERR_HM_WRONG_SWITCHER);
+    }
+
+    /* When using SUPR0EnableVTx we must let the host suspend and resume VT-x,
+       regardless of whether we're currently using VT-x or not. */
+    if (g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+    {
+        *pfVTxDisabled = SUPR0SuspendVTxOnCpu();
+        return VINF_SUCCESS;
+    }
+
+    /** @todo Check if this code is presumtive wrt other VT-x users on the
+    *        system... */
+
+    /* Nothing to do if we haven't enabled VT-x. */
+    if (!g_HvmR0.fEnabled)
+        return VINF_SUCCESS;
+
+    /* Local init implies the CPU is currently not in VMX root mode. */
+    if (!g_HvmR0.fGlobalInit)
+        return VINF_SUCCESS;
+
+    /* Ok, disable VT-x. */
+    PHMGLOBLCPUINFO pCpu = HMR0GetCurrentCpu();
+    AssertReturn(pCpu && pCpu->hMemObj != NIL_RTR0MEMOBJ, VERR_HM_IPE_2);
+
+    *pfVTxDisabled = true;
+    void    *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
+    RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
+    return VMXR0DisableCpu(pCpu, pvCpuPage, HCPhysCpuPage);
+}
+
+
+/**
+ * Raw-mode switcher hook - re-enable VT-x if was active *and* the current
+ * switcher turned off paging.
+ *
+ * @param   pVM             Pointer to the VM.
+ * @param   fVTxDisabled    Whether VT-x was disabled or not.
+ */
+VMMR0DECL(void) HMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled)
+{
+    Assert(!(ASMGetFlags() & X86_EFL_IF));
+
+    if (!fVTxDisabled)
+        return;         /* nothing to do */
+
+    Assert(g_HvmR0.vmx.fSupported);
+    if (g_HvmR0.vmx.fUsingSUPR0EnableVTx)
+        SUPR0ResumeVTxOnCpu(fVTxDisabled);
+    else
+    {
+        Assert(g_HvmR0.fEnabled);
+        Assert(g_HvmR0.fGlobalInit);
+
+        PHMGLOBLCPUINFO pCpu = HMR0GetCurrentCpu();
+        AssertReturnVoid(pCpu && pCpu->hMemObj != NIL_RTR0MEMOBJ);
+
+        void           *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
+        RTHCPHYS        HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
+        VMXR0EnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage, false);
+    }
+}
+
+#ifdef VBOX_STRICT
+
+/**
+ * Dumps a descriptor.
+ *
+ * @param   pDesc    Descriptor to dump.
+ * @param   Sel      Selector number.
+ * @param   pszMsg   Message to prepend the log entry with.
+ */
+VMMR0DECL(void) HMR0DumpDescriptor(PCX86DESCHC pDesc, RTSEL Sel, const char *pszMsg)
+{
+    /*
+     * Make variable description string.
+     */
+    static struct
+    {
+        unsigned    cch;
+        const char *psz;
+    } const s_aTypes[32] =
+    {
+# define STRENTRY(str) { sizeof(str) - 1, str }
+
+        /* system */
+# if HC_ARCH_BITS == 64
+        STRENTRY("Reserved0 "),                  /* 0x00 */
+        STRENTRY("Reserved1 "),                  /* 0x01 */
+        STRENTRY("LDT "),                        /* 0x02 */
+        STRENTRY("Reserved3 "),                  /* 0x03 */
+        STRENTRY("Reserved4 "),                  /* 0x04 */
+        STRENTRY("Reserved5 "),                  /* 0x05 */
+        STRENTRY("Reserved6 "),                  /* 0x06 */
+        STRENTRY("Reserved7 "),                  /* 0x07 */
+        STRENTRY("Reserved8 "),                  /* 0x08 */
+        STRENTRY("TSS64Avail "),                 /* 0x09 */
+        STRENTRY("ReservedA "),                  /* 0x0a */
+        STRENTRY("TSS64Busy "),                  /* 0x0b */
+        STRENTRY("Call64 "),                     /* 0x0c */
+        STRENTRY("ReservedD "),                  /* 0x0d */
+        STRENTRY("Int64 "),                      /* 0x0e */
+        STRENTRY("Trap64 "),                     /* 0x0f */
+# else
+        STRENTRY("Reserved0 "),                  /* 0x00 */
+        STRENTRY("TSS16Avail "),                 /* 0x01 */
+        STRENTRY("LDT "),                        /* 0x02 */
+        STRENTRY("TSS16Busy "),                  /* 0x03 */
+        STRENTRY("Call16 "),                     /* 0x04 */
+        STRENTRY("Task "),                       /* 0x05 */
+        STRENTRY("Int16 "),                      /* 0x06 */
+        STRENTRY("Trap16 "),                     /* 0x07 */
+        STRENTRY("Reserved8 "),                  /* 0x08 */
+        STRENTRY("TSS32Avail "),                 /* 0x09 */
+        STRENTRY("ReservedA "),                  /* 0x0a */
+        STRENTRY("TSS32Busy "),                  /* 0x0b */
+        STRENTRY("Call32 "),                     /* 0x0c */
+        STRENTRY("ReservedD "),                  /* 0x0d */
+        STRENTRY("Int32 "),                      /* 0x0e */
+        STRENTRY("Trap32 "),                     /* 0x0f */
+# endif
+        /* non system */
+        STRENTRY("DataRO "),                     /* 0x10 */
+        STRENTRY("DataRO Accessed "),            /* 0x11 */
+        STRENTRY("DataRW "),                     /* 0x12 */
+        STRENTRY("DataRW Accessed "),            /* 0x13 */
+        STRENTRY("DataDownRO "),                 /* 0x14 */
+        STRENTRY("DataDownRO Accessed "),        /* 0x15 */
+        STRENTRY("DataDownRW "),                 /* 0x16 */
+        STRENTRY("DataDownRW Accessed "),        /* 0x17 */
+        STRENTRY("CodeEO "),                     /* 0x18 */
+        STRENTRY("CodeEO Accessed "),            /* 0x19 */
+        STRENTRY("CodeER "),                     /* 0x1a */
+        STRENTRY("CodeER Accessed "),            /* 0x1b */
+        STRENTRY("CodeConfEO "),                 /* 0x1c */
+        STRENTRY("CodeConfEO Accessed "),        /* 0x1d */
+        STRENTRY("CodeConfER "),                 /* 0x1e */
+        STRENTRY("CodeConfER Accessed ")         /* 0x1f */
+# undef SYSENTRY
+    };
+# define ADD_STR(psz, pszAdd) do { strcpy(psz, pszAdd); psz += strlen(pszAdd); } while (0)
+    char        szMsg[128];
+    char       *psz = &szMsg[0];
+    unsigned    i = pDesc->Gen.u1DescType << 4 | pDesc->Gen.u4Type;
+    memcpy(psz, s_aTypes[i].psz, s_aTypes[i].cch);
+    psz += s_aTypes[i].cch;
+
+    if (pDesc->Gen.u1Present)
+        ADD_STR(psz, "Present ");
+    else
+        ADD_STR(psz, "Not-Present ");
+# if HC_ARCH_BITS == 64
+    if (pDesc->Gen.u1Long)
+        ADD_STR(psz, "64-bit ");
+    else
+        ADD_STR(psz, "Comp   ");
+# else
+    if (pDesc->Gen.u1Granularity)
+        ADD_STR(psz, "Page ");
+    if (pDesc->Gen.u1DefBig)
+        ADD_STR(psz, "32-bit ");
+    else
+        ADD_STR(psz, "16-bit ");
+# endif
+# undef ADD_STR
+    *psz = '\0';
+
+    /*
+     * Limit and Base and format the output.
+     */
+    uint32_t    u32Limit = X86DESC_LIMIT_G(pDesc);
+
+# if HC_ARCH_BITS == 64
+    uint64_t    u32Base  = X86DESC64_BASE(pDesc);
+
+    Log(("%s %04x - %RX64 %RX64 - base=%RX64 limit=%08x dpl=%d %s\n", pszMsg,
+         Sel, pDesc->au64[0], pDesc->au64[1], u32Base, u32Limit, pDesc->Gen.u2Dpl, szMsg));
+# else
+    uint32_t    u32Base  = X86DESC_BASE(pDesc);
+
+    Log(("%s %04x - %08x %08x - base=%08x limit=%08x dpl=%d %s\n", pszMsg,
+         Sel, pDesc->au32[0], pDesc->au32[1], u32Base, u32Limit, pDesc->Gen.u2Dpl, szMsg));
+# endif
+}
+
+
+/**
+ * Formats a full register dump.
+ *
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   pCtx        Pointer to the CPU context.
+ */
+VMMR0DECL(void) HMDumpRegs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+    NOREF(pVM);
+
+    /*
+     * Format the flags.
+     */
+    static struct
+    {
+        const char *pszSet; const char *pszClear; uint32_t fFlag;
+    } const s_aFlags[] =
+    {
+        { "vip",NULL, X86_EFL_VIP },
+        { "vif",NULL, X86_EFL_VIF },
+        { "ac", NULL, X86_EFL_AC },
+        { "vm", NULL, X86_EFL_VM },
+        { "rf", NULL, X86_EFL_RF },
+        { "nt", NULL, X86_EFL_NT },
+        { "ov", "nv", X86_EFL_OF },
+        { "dn", "up", X86_EFL_DF },
+        { "ei", "di", X86_EFL_IF },
+        { "tf", NULL, X86_EFL_TF },
+        { "nt", "pl", X86_EFL_SF },
+        { "nz", "zr", X86_EFL_ZF },
+        { "ac", "na", X86_EFL_AF },
+        { "po", "pe", X86_EFL_PF },
+        { "cy", "nc", X86_EFL_CF },
+    };
+    char szEFlags[80];
+    char *psz = szEFlags;
+    uint32_t efl = pCtx->eflags.u32;
+    for (unsigned i = 0; i < RT_ELEMENTS(s_aFlags); i++)
+    {
+        const char *pszAdd = s_aFlags[i].fFlag & efl ? s_aFlags[i].pszSet : s_aFlags[i].pszClear;
+        if (pszAdd)
+        {
+            strcpy(psz, pszAdd);
+            psz += strlen(pszAdd);
+            *psz++ = ' ';
+        }
+    }
+    psz[-1] = '\0';
+
+
+    /*
+     * Format the registers.
+     */
+    if (CPUMIsGuestIn64BitCode(pVCpu))
+    {
+        Log(("rax=%016RX64 rbx=%016RX64 rcx=%016RX64 rdx=%016RX64\n"
+             "rsi=%016RX64 rdi=%016RX64 r8 =%016RX64 r9 =%016RX64\n"
+             "r10=%016RX64 r11=%016RX64 r12=%016RX64 r13=%016RX64\n"
+             "r14=%016RX64 r15=%016RX64\n"
+             "rip=%016RX64 rsp=%016RX64 rbp=%016RX64 iopl=%d %*s\n"
+             "cs={%04x base=%016RX64 limit=%08x flags=%08x}\n"
+             "ds={%04x base=%016RX64 limit=%08x flags=%08x}\n"
+             "es={%04x base=%016RX64 limit=%08x flags=%08x}\n"
+             "fs={%04x base=%016RX64 limit=%08x flags=%08x}\n"
+             "gs={%04x base=%016RX64 limit=%08x flags=%08x}\n"
+             "ss={%04x base=%016RX64 limit=%08x flags=%08x}\n"
+             "cr0=%016RX64 cr2=%016RX64 cr3=%016RX64 cr4=%016RX64\n"
+             "dr0=%016RX64 dr1=%016RX64 dr2=%016RX64 dr3=%016RX64\n"
+             "dr4=%016RX64 dr5=%016RX64 dr6=%016RX64 dr7=%016RX64\n"
+             "gdtr=%016RX64:%04x  idtr=%016RX64:%04x  eflags=%08x\n"
+             "ldtr={%04x base=%08RX64 limit=%08x flags=%08x}\n"
+             "tr  ={%04x base=%08RX64 limit=%08x flags=%08x}\n"
+             "SysEnter={cs=%04llx eip=%08llx esp=%08llx}\n"
+             ,
+             pCtx->rax, pCtx->rbx, pCtx->rcx, pCtx->rdx, pCtx->rsi, pCtx->rdi,
+             pCtx->r8, pCtx->r9, pCtx->r10, pCtx->r11, pCtx->r12, pCtx->r13,
+             pCtx->r14, pCtx->r15,
+             pCtx->rip, pCtx->rsp, pCtx->rbp, X86_EFL_GET_IOPL(efl), 31, szEFlags,
+             pCtx->cs.Sel, pCtx->cs.u64Base, pCtx->cs.u32Limit, pCtx->cs.Attr.u,
+             pCtx->ds.Sel, pCtx->ds.u64Base, pCtx->ds.u32Limit, pCtx->ds.Attr.u,
+             pCtx->es.Sel, pCtx->es.u64Base, pCtx->es.u32Limit, pCtx->es.Attr.u,
+             pCtx->fs.Sel, pCtx->fs.u64Base, pCtx->fs.u32Limit, pCtx->fs.Attr.u,
+             pCtx->gs.Sel, pCtx->gs.u64Base, pCtx->gs.u32Limit, pCtx->gs.Attr.u,
+             pCtx->ss.Sel, pCtx->ss.u64Base, pCtx->ss.u32Limit, pCtx->ss.Attr.u,
+             pCtx->cr0,  pCtx->cr2, pCtx->cr3,  pCtx->cr4,
+             pCtx->dr[0],  pCtx->dr[1], pCtx->dr[2],  pCtx->dr[3],
+             pCtx->dr[4],  pCtx->dr[5], pCtx->dr[6],  pCtx->dr[7],
+             pCtx->gdtr.pGdt, pCtx->gdtr.cbGdt, pCtx->idtr.pIdt, pCtx->idtr.cbIdt, efl,
+             pCtx->ldtr.Sel, pCtx->ldtr.u64Base, pCtx->ldtr.u32Limit, pCtx->ldtr.Attr.u,
+             pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u,
+             pCtx->SysEnter.cs, pCtx->SysEnter.eip, pCtx->SysEnter.esp));
+    }
+    else
+        Log(("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n"
+             "eip=%08x esp=%08x ebp=%08x iopl=%d %*s\n"
+             "cs={%04x base=%016RX64 limit=%08x flags=%08x} dr0=%08RX64 dr1=%08RX64\n"
+             "ds={%04x base=%016RX64 limit=%08x flags=%08x} dr2=%08RX64 dr3=%08RX64\n"
+             "es={%04x base=%016RX64 limit=%08x flags=%08x} dr4=%08RX64 dr5=%08RX64\n"
+             "fs={%04x base=%016RX64 limit=%08x flags=%08x} dr6=%08RX64 dr7=%08RX64\n"
+             "gs={%04x base=%016RX64 limit=%08x flags=%08x} cr0=%08RX64 cr2=%08RX64\n"
+             "ss={%04x base=%016RX64 limit=%08x flags=%08x} cr3=%08RX64 cr4=%08RX64\n"
+             "gdtr=%016RX64:%04x  idtr=%016RX64:%04x  eflags=%08x\n"
+             "ldtr={%04x base=%08RX64 limit=%08x flags=%08x}\n"
+             "tr  ={%04x base=%08RX64 limit=%08x flags=%08x}\n"
+             "SysEnter={cs=%04llx eip=%08llx esp=%08llx}\n"
+             ,
+             pCtx->eax, pCtx->ebx, pCtx->ecx, pCtx->edx, pCtx->esi, pCtx->edi,
+             pCtx->eip, pCtx->esp, pCtx->ebp, X86_EFL_GET_IOPL(efl), 31, szEFlags,
+             pCtx->cs.Sel, pCtx->cs.u64Base, pCtx->cs.u32Limit, pCtx->cs.Attr.u, pCtx->dr[0],  pCtx->dr[1],
+             pCtx->ds.Sel, pCtx->ds.u64Base, pCtx->ds.u32Limit, pCtx->ds.Attr.u, pCtx->dr[2],  pCtx->dr[3],
+             pCtx->es.Sel, pCtx->es.u64Base, pCtx->es.u32Limit, pCtx->es.Attr.u, pCtx->dr[4],  pCtx->dr[5],
+             pCtx->fs.Sel, pCtx->fs.u64Base, pCtx->fs.u32Limit, pCtx->fs.Attr.u, pCtx->dr[6],  pCtx->dr[7],
+             pCtx->gs.Sel, pCtx->gs.u64Base, pCtx->gs.u32Limit, pCtx->gs.Attr.u, pCtx->cr0,  pCtx->cr2,
+             pCtx->ss.Sel, pCtx->ss.u64Base, pCtx->ss.u32Limit, pCtx->ss.Attr.u, pCtx->cr3,  pCtx->cr4,
+             pCtx->gdtr.pGdt, pCtx->gdtr.cbGdt, pCtx->idtr.pIdt, pCtx->idtr.cbIdt, efl,
+             pCtx->ldtr.Sel, pCtx->ldtr.u64Base, pCtx->ldtr.u32Limit, pCtx->ldtr.Attr.u,
+             pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u,
+             pCtx->SysEnter.cs, pCtx->SysEnter.eip, pCtx->SysEnter.esp));
+
+    Log(("FPU:\n"
+        "FCW=%04x FSW=%04x FTW=%02x\n"
+        "FOP=%04x FPUIP=%08x CS=%04x Rsrvd1=%04x\n"
+        "FPUDP=%04x DS=%04x Rsvrd2=%04x MXCSR=%08x MXCSR_MASK=%08x\n"
+        ,
+        pCtx->fpu.FCW, pCtx->fpu.FSW, pCtx->fpu.FTW,
+        pCtx->fpu.FOP, pCtx->fpu.FPUIP, pCtx->fpu.CS, pCtx->fpu.Rsrvd1,
+        pCtx->fpu.FPUDP, pCtx->fpu.DS, pCtx->fpu.Rsrvd2,
+        pCtx->fpu.MXCSR, pCtx->fpu.MXCSR_MASK));
+
+
+    Log(("MSR:\n"
+        "EFER         =%016RX64\n"
+        "PAT          =%016RX64\n"
+        "STAR         =%016RX64\n"
+        "CSTAR        =%016RX64\n"
+        "LSTAR        =%016RX64\n"
+        "SFMASK       =%016RX64\n"
+        "KERNELGSBASE =%016RX64\n",
+        pCtx->msrEFER,
+        pCtx->msrPAT,
+        pCtx->msrSTAR,
+        pCtx->msrCSTAR,
+        pCtx->msrLSTAR,
+        pCtx->msrSFMASK,
+        pCtx->msrKERNELGSBASE));
+
+}
+
+#endif /* VBOX_STRICT */
+
Index: trunk/src/VBox/VMM/VMMR0/HMR0A.asm
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HMR0A.asm	(revision 43387)
+++ trunk/src/VBox/VMM/VMMR0/HMR0A.asm	(revision 43387)
@@ -0,0 +1,1506 @@
+; $Id$
+;; @file
+; VMXM - R0 vmx helpers
+;
+
+;
+; Copyright (C) 2006-2007 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.
+;
+
+;*******************************************************************************
+;* Header Files                                                                *
+;*******************************************************************************
+%include "VBox/asmdefs.mac"
+%include "VBox/err.mac"
+%include "VBox/vmm/hm_vmx.mac"
+%include "VBox/vmm/cpum.mac"
+%include "iprt/x86.mac"
+%include "HMInternal.mac"
+
+%ifdef RT_OS_OS2 ;; @todo fix OMF support in yasm and kick nasm out completely.
+ %macro vmwrite 2,
+    int3
+ %endmacro
+ %define vmlaunch int3
+ %define vmresume int3
+ %define vmsave int3
+ %define vmload int3
+ %define vmrun int3
+ %define clgi int3
+ %define stgi int3
+ %macro invlpga 2,
+    int3
+ %endmacro
+%endif
+
+;*******************************************************************************
+;*  Defined Constants And Macros                                               *
+;*******************************************************************************
+%ifdef RT_ARCH_AMD64
+ %define MAYBE_64_BIT
+%endif
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ %define MAYBE_64_BIT
+%else
+ %ifdef RT_OS_DARWIN
+  %ifdef RT_ARCH_AMD64
+   ;;
+   ; Load the NULL selector into DS, ES, FS and GS on 64-bit darwin so we don't
+   ; risk loading a stale LDT value or something invalid.
+   %define HM_64_BIT_USE_NULL_SEL
+  %endif
+ %endif
+%endif
+
+;; The offset of the XMM registers in X86FXSTATE.
+; Use define because I'm too lazy to convert the struct.
+%define XMM_OFF_IN_X86FXSTATE   160
+
+
+;; This is too risky wrt. stability, performance and correctness.
+;%define VBOX_WITH_DR6_EXPERIMENT 1
+
+;; @def MYPUSHAD
+; Macro generating an equivalent to pushad
+
+;; @def MYPOPAD
+; Macro generating an equivalent to popad
+
+;; @def MYPUSHSEGS
+; Macro saving all segment registers on the stack.
+; @param 1  full width register name
+; @param 2  16-bit register name for \a 1.
+
+;; @def MYPOPSEGS
+; Macro restoring all segment registers on the stack
+; @param 1  full width register name
+; @param 2  16-bit register name for \a 1.
+
+%ifdef MAYBE_64_BIT
+  ; Save a host and load the corresponding guest MSR (trashes rdx & rcx)
+  %macro LOADGUESTMSR 2
+    mov     rcx, %1
+    rdmsr
+    push    rdx
+    push    rax
+    mov     edx, dword [xSI + %2 + 4]
+    mov     eax, dword [xSI + %2]
+    wrmsr
+  %endmacro
+
+  ; Save a guest and load the corresponding host MSR (trashes rdx & rcx)
+  ; Only really useful for gs kernel base as that one can be changed behind our back (swapgs)
+  %macro LOADHOSTMSREX 2
+    mov     rcx, %1
+    rdmsr
+    mov     dword [xSI + %2], eax
+    mov     dword [xSI + %2 + 4], edx
+    pop     rax
+    pop     rdx
+    wrmsr
+  %endmacro
+
+  ; Load the corresponding host MSR (trashes rdx & rcx)
+  %macro LOADHOSTMSR 1
+    mov     rcx, %1
+    pop     rax
+    pop     rdx
+    wrmsr
+  %endmacro
+%endif
+
+%ifdef ASM_CALL64_GCC
+ %macro MYPUSHAD64 0
+   push    r15
+   push    r14
+   push    r13
+   push    r12
+   push    rbx
+ %endmacro
+ %macro MYPOPAD64 0
+   pop     rbx
+   pop     r12
+   pop     r13
+   pop     r14
+   pop     r15
+ %endmacro
+
+%else ; ASM_CALL64_MSC
+ %macro MYPUSHAD64 0
+   push    r15
+   push    r14
+   push    r13
+   push    r12
+   push    rbx
+   push    rsi
+   push    rdi
+ %endmacro
+ %macro MYPOPAD64 0
+   pop     rdi
+   pop     rsi
+   pop     rbx
+   pop     r12
+   pop     r13
+   pop     r14
+   pop     r15
+ %endmacro
+%endif
+
+; trashes, rax, rdx & rcx
+%macro MYPUSHSEGS64 2
+ %ifndef HM_64_BIT_USE_NULL_SEL
+   mov     %2, es
+   push    %1
+   mov     %2, ds
+   push    %1
+ %endif
+
+   ; Special case for FS; Windows and Linux either don't use it or restore it when leaving kernel mode, Solaris OTOH doesn't and we must save it.
+   mov     ecx, MSR_K8_FS_BASE
+   rdmsr
+   push    rdx
+   push    rax
+ %ifndef HM_64_BIT_USE_NULL_SEL
+   push    fs
+ %endif
+
+   ; Special case for GS; OSes typically use swapgs to reset the hidden base register for GS on entry into the kernel. The same happens on exit
+   mov     ecx, MSR_K8_GS_BASE
+   rdmsr
+   push    rdx
+   push    rax
+ %ifndef HM_64_BIT_USE_NULL_SEL
+   push    gs
+ %endif
+%endmacro
+
+; trashes, rax, rdx & rcx
+%macro MYPOPSEGS64 2
+   ; Note: do not step through this code with a debugger!
+ %ifndef HM_64_BIT_USE_NULL_SEL
+   xor     eax, eax
+   mov     ds, ax
+   mov     es, ax
+   mov     fs, ax
+   mov     gs, ax
+ %endif
+
+ %ifndef HM_64_BIT_USE_NULL_SEL
+   pop     gs
+ %endif
+   pop     rax
+   pop     rdx
+   mov     ecx, MSR_K8_GS_BASE
+   wrmsr
+
+ %ifndef HM_64_BIT_USE_NULL_SEL
+   pop     fs
+ %endif
+   pop     rax
+   pop     rdx
+   mov     ecx, MSR_K8_FS_BASE
+   wrmsr
+   ; Now it's safe to step again
+
+ %ifndef HM_64_BIT_USE_NULL_SEL
+   pop     %1
+   mov     ds, %2
+   pop     %1
+   mov     es, %2
+ %endif
+%endmacro
+
+%macro MYPUSHAD32 0
+  pushad
+%endmacro
+%macro MYPOPAD32 0
+  popad
+%endmacro
+
+%macro MYPUSHSEGS32 2
+  push    ds
+  push    es
+  push    fs
+  push    gs
+%endmacro
+%macro MYPOPSEGS32 2
+  pop     gs
+  pop     fs
+  pop     es
+  pop     ds
+%endmacro
+
+
+;*******************************************************************************
+;* External Symbols                                                            *
+;*******************************************************************************
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+extern NAME(SUPR0AbsIs64bit)
+extern NAME(SUPR0Abs64bitKernelCS)
+extern NAME(SUPR0Abs64bitKernelSS)
+extern NAME(SUPR0Abs64bitKernelDS)
+extern NAME(SUPR0AbsKernelCS)
+%endif
+%ifdef VBOX_WITH_KERNEL_USING_XMM
+extern NAME(CPUMIsGuestFPUStateActive)
+%endif
+
+
+;*******************************************************************************
+;*  Global Variables                                                           *
+;*******************************************************************************
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+BEGINDATA
+;;
+; Store the SUPR0AbsIs64bit absolute value here so we can cmp/test without
+; needing to clobber a register. (This trick doesn't quite work for PE btw.
+; but that's not relevant atm.)
+GLOBALNAME g_fVMXIs64bitHost
+    dd  NAME(SUPR0AbsIs64bit)
+%endif
+
+
+BEGINCODE
+
+
+;/**
+; * Executes VMWRITE, 64-bit value.
+; *
+; * @returns VBox status code
+; * @param   idxField   x86: [ebp + 08h]  msc: rcx  gcc: rdi   VMCS index
+; * @param   u64Data    x86: [ebp + 0ch]  msc: rdx  gcc: rsi   VM field value
+; */
+ALIGNCODE(16)
+BEGINPROC VMXWriteVMCS64
+%ifdef RT_ARCH_AMD64
+ %ifdef ASM_CALL64_GCC
+    and         edi, 0ffffffffh
+    xor         rax, rax
+    vmwrite     rdi, rsi
+ %else
+    and         ecx, 0ffffffffh
+    xor         rax, rax
+    vmwrite     rcx, rdx
+ %endif
+%else  ; RT_ARCH_X86
+    mov         ecx, [esp + 4]          ; idxField
+    lea         edx, [esp + 8]          ; &u64Data
+ %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+    cmp         byte [NAME(g_fVMXIs64bitHost)], 0
+    jz          .legacy_mode
+    db          0xea                    ; jmp far .sixtyfourbit_mode
+    dd          .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.legacy_mode:
+ %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+    vmwrite     ecx, [edx]              ; low dword
+    jz          .done
+    jc          .done
+    inc         ecx
+    xor         eax, eax
+    vmwrite     ecx, [edx + 4]          ; high dword
+.done:
+%endif ; RT_ARCH_X86
+    jnc         .valid_vmcs
+    mov         eax, VERR_VMX_INVALID_VMCS_PTR
+    ret
+.valid_vmcs:
+    jnz         .the_end
+    mov         eax, VERR_VMX_INVALID_VMCS_FIELD
+.the_end:
+    ret
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    and     edx, 0ffffffffh
+    and     ecx, 0ffffffffh
+    xor     eax, eax
+    vmwrite rcx, [rdx]
+    mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
+    cmovz   eax, r8d
+    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
+    cmovc   eax, r9d
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+ENDPROC VMXWriteVMCS64
+
+
+;/**
+; * Executes VMREAD, 64-bit value
+; *
+; * @returns VBox status code
+; * @param   idxField        VMCS index
+; * @param   pData           Ptr to store VM field value
+; */
+;DECLASM(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData);
+ALIGNCODE(16)
+BEGINPROC VMXReadVMCS64
+%ifdef RT_ARCH_AMD64
+ %ifdef ASM_CALL64_GCC
+    and         edi, 0ffffffffh
+    xor         rax, rax
+    vmread      [rsi], rdi
+ %else
+    and         ecx, 0ffffffffh
+    xor         rax, rax
+    vmread      [rdx], rcx
+ %endif
+%else  ; RT_ARCH_X86
+    mov         ecx, [esp + 4]          ; idxField
+    mov         edx, [esp + 8]          ; pData
+ %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+    cmp         byte [NAME(g_fVMXIs64bitHost)], 0
+    jz          .legacy_mode
+    db          0xea                    ; jmp far .sixtyfourbit_mode
+    dd          .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.legacy_mode:
+ %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+    vmread      [edx], ecx              ; low dword
+    jz          .done
+    jc          .done
+    inc         ecx
+    xor         eax, eax
+    vmread      [edx + 4], ecx          ; high dword
+.done:
+%endif ; RT_ARCH_X86
+    jnc         .valid_vmcs
+    mov         eax, VERR_VMX_INVALID_VMCS_PTR
+    ret
+.valid_vmcs:
+    jnz         .the_end
+    mov         eax, VERR_VMX_INVALID_VMCS_FIELD
+.the_end:
+    ret
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    and     edx, 0ffffffffh
+    and     ecx, 0ffffffffh
+    xor     eax, eax
+    vmread  [rdx], rcx
+    mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
+    cmovz   eax, r8d
+    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
+    cmovc   eax, r9d
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+ENDPROC VMXReadVMCS64
+
+
+;/**
+; * Executes VMREAD, 32-bit value.
+; *
+; * @returns VBox status code
+; * @param   idxField        VMCS index
+; * @param   pu32Data        Ptr to store VM field value
+; */
+;DECLASM(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pu32Data);
+ALIGNCODE(16)
+BEGINPROC VMXReadVMCS32
+%ifdef RT_ARCH_AMD64
+ %ifdef ASM_CALL64_GCC
+    and     edi, 0ffffffffh
+    xor     rax, rax
+    vmread  r10, rdi
+    mov     [rsi], r10d
+ %else
+    and     ecx, 0ffffffffh
+    xor     rax, rax
+    vmread  r10, rcx
+    mov     [rdx], r10d
+ %endif
+%else  ; RT_ARCH_X86
+    mov     ecx, [esp + 4]              ; idxField
+    mov     edx, [esp + 8]              ; pu32Data
+ %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    jz      .legacy_mode
+    db      0xea                        ; jmp far .sixtyfourbit_mode
+    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.legacy_mode:
+ %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+    xor     eax, eax
+    vmread  [edx], ecx
+%endif ; RT_ARCH_X86
+    jnc     .valid_vmcs
+    mov     eax, VERR_VMX_INVALID_VMCS_PTR
+    ret
+.valid_vmcs:
+    jnz     .the_end
+    mov     eax, VERR_VMX_INVALID_VMCS_FIELD
+.the_end:
+    ret
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    and     edx, 0ffffffffh
+    and     ecx, 0ffffffffh
+    xor     eax, eax
+    vmread  r10, rcx
+    mov     [rdx], r10d
+    mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
+    cmovz   eax, r8d
+    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
+    cmovc   eax, r9d
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+ENDPROC VMXReadVMCS32
+
+
+;/**
+; * Executes VMWRITE, 32-bit value.
+; *
+; * @returns VBox status code
+; * @param   idxField        VMCS index
+; * @param   u32Data         Ptr to store VM field value
+; */
+;DECLASM(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Data);
+ALIGNCODE(16)
+BEGINPROC VMXWriteVMCS32
+%ifdef RT_ARCH_AMD64
+ %ifdef ASM_CALL64_GCC
+    and     edi, 0ffffffffh
+    and     esi, 0ffffffffh
+    xor     rax, rax
+    vmwrite rdi, rsi
+ %else
+    and     ecx, 0ffffffffh
+    and     edx, 0ffffffffh
+    xor     rax, rax
+    vmwrite rcx, rdx
+ %endif
+%else  ; RT_ARCH_X86
+    mov     ecx, [esp + 4]              ; idxField
+    mov     edx, [esp + 8]              ; u32Data
+ %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    jz      .legacy_mode
+    db      0xea                        ; jmp far .sixtyfourbit_mode
+    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.legacy_mode:
+ %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+    xor     eax, eax
+    vmwrite ecx, edx
+%endif ; RT_ARCH_X86
+    jnc     .valid_vmcs
+    mov     eax, VERR_VMX_INVALID_VMCS_PTR
+    ret
+.valid_vmcs:
+    jnz     .the_end
+    mov     eax, VERR_VMX_INVALID_VMCS_FIELD
+.the_end:
+    ret
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    and     edx, 0ffffffffh
+    and     ecx, 0ffffffffh
+    xor     eax, eax
+    vmwrite rcx, rdx
+    mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
+    cmovz   eax, r8d
+    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
+    cmovc   eax, r9d
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+ENDPROC VMXWriteVMCS32
+
+
+;/**
+; * Executes VMXON
+; *
+; * @returns VBox status code
+; * @param   HCPhysVMXOn      Physical address of VMXON structure
+; */
+;DECLASM(int) VMXEnable(RTHCPHYS HCPhysVMXOn);
+BEGINPROC VMXEnable
+%ifdef RT_ARCH_AMD64
+    xor     rax, rax
+ %ifdef ASM_CALL64_GCC
+    push    rdi
+ %else
+    push    rcx
+ %endif
+    vmxon   [rsp]
+%else  ; RT_ARCH_X86
+ %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    jz      .legacy_mode
+    db      0xea                        ; jmp far .sixtyfourbit_mode
+    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.legacy_mode:
+ %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+    xor     eax, eax
+    vmxon   [esp + 4]
+%endif ; RT_ARCH_X86
+    jnc     .good
+    mov     eax, VERR_VMX_INVALID_VMXON_PTR
+    jmp     .the_end
+
+.good:
+    jnz     .the_end
+    mov     eax, VERR_VMX_GENERIC
+
+.the_end:
+%ifdef RT_ARCH_AMD64
+    add     rsp, 8
+%endif
+    ret
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    lea     rdx, [rsp + 4]              ; &HCPhysVMXOn.
+    and     edx, 0ffffffffh
+    xor     eax, eax
+    vmxon   [rdx]
+    mov     r8d, VERR_INVALID_PARAMETER
+    cmovz   eax, r8d
+    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
+    cmovc   eax, r9d
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+ENDPROC VMXEnable
+
+
+;/**
+; * Executes VMXOFF
+; */
+;DECLASM(void) VMXDisable(void);
+BEGINPROC VMXDisable
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    jz      .legacy_mode
+    db      0xea                        ; jmp far .sixtyfourbit_mode
+    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.legacy_mode:
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+    vmxoff
+.the_end:
+    ret
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    vmxoff
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+ENDPROC VMXDisable
+
+
+;/**
+; * Executes VMCLEAR
+; *
+; * @returns VBox status code
+; * @param   HCPhysVMCS     Physical address of VM control structure
+; */
+;DECLASM(int) VMXClearVMCS(RTHCPHYS HCPhysVMCS);
+ALIGNCODE(16)
+BEGINPROC VMXClearVMCS
+%ifdef RT_ARCH_AMD64
+    xor     rax, rax
+ %ifdef ASM_CALL64_GCC
+    push    rdi
+ %else
+    push    rcx
+ %endif
+    vmclear [rsp]
+%else  ; RT_ARCH_X86
+ %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    jz      .legacy_mode
+    db      0xea                        ; jmp far .sixtyfourbit_mode
+    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.legacy_mode:
+ %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+    xor     eax, eax
+    vmclear [esp + 4]
+%endif ; RT_ARCH_X86
+    jnc     .the_end
+    mov     eax, VERR_VMX_INVALID_VMCS_PTR
+.the_end:
+%ifdef RT_ARCH_AMD64
+    add     rsp, 8
+%endif
+    ret
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    lea     rdx, [rsp + 4]              ; &HCPhysVMCS
+    and     edx, 0ffffffffh
+    xor     eax, eax
+    vmclear [rdx]
+    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
+    cmovc   eax, r9d
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+%endif
+ENDPROC VMXClearVMCS
+
+
+;/**
+; * Executes VMPTRLD
+; *
+; * @returns VBox status code
+; * @param   HCPhysVMCS     Physical address of VMCS structure
+; */
+;DECLASM(int) VMXActivateVMCS(RTHCPHYS HCPhysVMCS);
+ALIGNCODE(16)
+BEGINPROC VMXActivateVMCS
+%ifdef RT_ARCH_AMD64
+    xor     rax, rax
+ %ifdef ASM_CALL64_GCC
+    push    rdi
+ %else
+    push    rcx
+ %endif
+    vmptrld [rsp]
+%else
+ %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    jz      .legacy_mode
+    db      0xea                        ; jmp far .sixtyfourbit_mode
+    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.legacy_mode:
+ %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+    xor     eax, eax
+    vmptrld [esp + 4]
+%endif
+    jnc     .the_end
+    mov     eax, VERR_VMX_INVALID_VMCS_PTR
+.the_end:
+%ifdef RT_ARCH_AMD64
+    add     rsp, 8
+%endif
+    ret
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    lea     rdx, [rsp + 4]              ; &HCPhysVMCS
+    and     edx, 0ffffffffh
+    xor     eax, eax
+    vmptrld [rdx]
+    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
+    cmovc   eax, r9d
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+ENDPROC VMXActivateVMCS
+
+
+;/**
+; * Executes VMPTRST
+; *
+; * @returns VBox status code
+; * @param    [esp + 04h]  gcc:rdi  msc:rcx   Param 1 - First parameter - Address that will receive the current pointer
+; */
+;DECLASM(int) VMXGetActivateVMCS(RTHCPHYS *pVMCS);
+BEGINPROC VMXGetActivateVMCS
+%ifdef RT_OS_OS2
+    mov     eax, VERR_NOT_SUPPORTED
+    ret
+%else
+ %ifdef RT_ARCH_AMD64
+  %ifdef ASM_CALL64_GCC
+    vmptrst qword [rdi]
+  %else
+    vmptrst qword [rcx]
+  %endif
+ %else
+  %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    jz      .legacy_mode
+    db      0xea                        ; jmp far .sixtyfourbit_mode
+    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.legacy_mode:
+  %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+    vmptrst qword [esp+04h]
+ %endif
+    xor     eax, eax
+.the_end:
+    ret
+
+ %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    lea     rdx, [rsp + 4]              ; &HCPhysVMCS
+    and     edx, 0ffffffffh
+    vmptrst qword [rdx]
+    xor     eax, eax
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+ %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+%endif
+ENDPROC VMXGetActivateVMCS
+
+;/**
+; * Invalidate a page using invept
+; @param   enmFlush     msc:ecx  gcc:edi  x86:[esp+04]  Type of flush
+; @param   pDescriptor  msc:edx  gcc:esi  x86:[esp+08]  Descriptor pointer
+; */
+;DECLASM(int) VMXR0InvEPT(VMX_FLUSH enmFlush, uint64_t *pDescriptor);
+BEGINPROC VMXR0InvEPT
+%ifdef RT_ARCH_AMD64
+ %ifdef ASM_CALL64_GCC
+    and         edi, 0ffffffffh
+    xor         rax, rax
+;    invept      rdi, qword [rsi]
+    DB          0x66, 0x0F, 0x38, 0x80, 0x3E
+ %else
+    and         ecx, 0ffffffffh
+    xor         rax, rax
+;    invept      rcx, qword [rdx]
+    DB          0x66, 0x0F, 0x38, 0x80, 0xA
+ %endif
+%else
+ %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+    cmp         byte [NAME(g_fVMXIs64bitHost)], 0
+    jz          .legacy_mode
+    db          0xea                        ; jmp far .sixtyfourbit_mode
+    dd          .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.legacy_mode:
+ %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+    mov         ecx, [esp + 4]
+    mov         edx, [esp + 8]
+    xor         eax, eax
+;    invept      ecx, qword [edx]
+    DB          0x66, 0x0F, 0x38, 0x80, 0xA
+%endif
+    jnc         .valid_vmcs
+    mov         eax, VERR_VMX_INVALID_VMCS_PTR
+    ret
+.valid_vmcs:
+    jnz         .the_end
+    mov         eax, VERR_INVALID_PARAMETER
+.the_end:
+    ret
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    and     esp, 0ffffffffh
+    mov     ecx, [rsp + 4]              ; enmFlush
+    mov     edx, [rsp + 8]              ; pDescriptor
+    xor     eax, eax
+;    invept  rcx, qword [rdx]
+    DB      0x66, 0x0F, 0x38, 0x80, 0xA
+    mov     r8d, VERR_INVALID_PARAMETER
+    cmovz   eax, r8d
+    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
+    cmovc   eax, r9d
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+ENDPROC VMXR0InvEPT
+
+
+;/**
+; * Invalidate a page using invvpid
+; @param   enmFlush     msc:ecx  gcc:edi  x86:[esp+04]  Type of flush
+; @param   pDescriptor  msc:edx  gcc:esi  x86:[esp+08]  Descriptor pointer
+; */
+;DECLASM(int) VMXR0InvVPID(VMX_FLUSH enmFlush, uint64_t *pDescriptor);
+BEGINPROC VMXR0InvVPID
+%ifdef RT_ARCH_AMD64
+ %ifdef ASM_CALL64_GCC
+    and         edi, 0ffffffffh
+    xor         rax, rax
+;    invvpid     rdi, qword [rsi]
+    DB          0x66, 0x0F, 0x38, 0x81, 0x3E
+ %else
+    and         ecx, 0ffffffffh
+    xor         rax, rax
+;    invvpid     rcx, qword [rdx]
+    DB          0x66, 0x0F, 0x38, 0x81, 0xA
+ %endif
+%else
+ %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    jz      .legacy_mode
+    db      0xea                        ; jmp far .sixtyfourbit_mode
+    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.legacy_mode:
+ %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+    mov         ecx, [esp + 4]
+    mov         edx, [esp + 8]
+    xor         eax, eax
+;    invvpid     ecx, qword [edx]
+    DB          0x66, 0x0F, 0x38, 0x81, 0xA
+%endif
+    jnc         .valid_vmcs
+    mov         eax, VERR_VMX_INVALID_VMCS_PTR
+    ret
+.valid_vmcs:
+    jnz         .the_end
+    mov         eax, VERR_INVALID_PARAMETER
+.the_end:
+    ret
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    and     esp, 0ffffffffh
+    mov     ecx, [rsp + 4]              ; enmFlush
+    mov     edx, [rsp + 8]              ; pDescriptor
+    xor     eax, eax
+;    invvpid rcx, qword [rdx]
+    DB      0x66, 0x0F, 0x38, 0x81, 0xA
+    mov     r8d, VERR_INVALID_PARAMETER
+    cmovz   eax, r8d
+    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
+    cmovc   eax, r9d
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+ENDPROC VMXR0InvVPID
+
+
+%if GC_ARCH_BITS == 64
+;;
+; Executes INVLPGA
+;
+; @param   pPageGC  msc:rcx  gcc:rdi  x86:[esp+04]  Virtual page to invalidate
+; @param   uASID    msc:rdx  gcc:rsi  x86:[esp+0C]  Tagged TLB id
+;
+;DECLASM(void) SVMR0InvlpgA(RTGCPTR pPageGC, uint32_t uASID);
+BEGINPROC SVMR0InvlpgA
+%ifdef RT_ARCH_AMD64
+ %ifdef ASM_CALL64_GCC
+    mov     rax, rdi
+    mov     rcx, rsi
+ %else
+    mov     rax, rcx
+    mov     rcx, rdx
+ %endif
+%else
+    mov     eax, [esp + 4]
+    mov     ecx, [esp + 0Ch]
+%endif
+    invlpga [xAX], ecx
+    ret
+ENDPROC SVMR0InvlpgA
+
+%else ; GC_ARCH_BITS != 64
+;;
+; Executes INVLPGA
+;
+; @param   pPageGC  msc:ecx  gcc:edi  x86:[esp+04]  Virtual page to invalidate
+; @param   uASID    msc:edx  gcc:esi  x86:[esp+08]  Tagged TLB id
+;
+;DECLASM(void) SVMR0InvlpgA(RTGCPTR pPageGC, uint32_t uASID);
+BEGINPROC SVMR0InvlpgA
+%ifdef RT_ARCH_AMD64
+ %ifdef ASM_CALL64_GCC
+    movzx   rax, edi
+    mov     ecx, esi
+ %else
+    ; from http://www.cs.cmu.edu/~fp/courses/15213-s06/misc/asm64-handout.pdf:
+    ; ``Perhaps unexpectedly, instructions that move or generate 32-bit register
+    ;   values also set the upper 32 bits of the register to zero. Consequently
+    ;   there is no need for an instruction movzlq.''
+    mov     eax, ecx
+    mov     ecx, edx
+ %endif
+%else
+    mov     eax, [esp + 4]
+    mov     ecx, [esp + 8]
+%endif
+    invlpga [xAX], ecx
+    ret
+ENDPROC SVMR0InvlpgA
+
+%endif ; GC_ARCH_BITS != 64
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+
+;/**
+; * Gets 64-bit GDTR and IDTR on darwin.
+; * @param  pGdtr        Where to store the 64-bit GDTR.
+; * @param  pIdtr        Where to store the 64-bit IDTR.
+; */
+;DECLASM(void) hmR0Get64bitGDTRandIDTR(PX86XDTR64 pGdtr, PX86XDTR64 pIdtr);
+ALIGNCODE(16)
+BEGINPROC hmR0Get64bitGDTRandIDTR
+    db      0xea                        ; jmp far .sixtyfourbit_mode
+    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.the_end:
+    ret
+
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    and     esp, 0ffffffffh
+    mov     ecx, [rsp + 4]              ; pGdtr
+    mov     edx, [rsp + 8]              ; pIdtr
+    sgdt    [rcx]
+    sidt    [rdx]
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+ENDPROC   hmR0Get64bitGDTRandIDTR
+
+
+;/**
+; * Gets 64-bit CR3 on darwin.
+; * @returns CR3
+; */
+;DECLASM(uint64_t) hmR0Get64bitCR3(void);
+ALIGNCODE(16)
+BEGINPROC hmR0Get64bitCR3
+    db      0xea                        ; jmp far .sixtyfourbit_mode
+    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
+.the_end:
+    ret
+
+ALIGNCODE(16)
+BITS 64
+.sixtyfourbit_mode:
+    mov     rax, cr3
+    mov     rdx, rax
+    shr     rdx, 32
+    jmp far [.fpret wrt rip]
+.fpret:                                 ; 16:32 Pointer to .the_end.
+    dd      .the_end, NAME(SUPR0AbsKernelCS)
+BITS 32
+ENDPROC   hmR0Get64bitCR3
+
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
+
+%ifdef VBOX_WITH_KERNEL_USING_XMM
+
+;;
+; Wrapper around vmx.pfnStartVM that preserves host XMM registers and
+; load the guest ones when necessary.
+;
+; @cproto       DECLASM(int) hmR0VMXStartVMWrapXMM(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu, PFNHMVMXSTARTVM pfnStartVM);
+;
+; @returns      eax
+;
+; @param        fResumeVM       msc:rcx
+; @param        pCtx            msc:rdx
+; @param        pVMCSCache      msc:r8
+; @param        pVM             msc:r9
+; @param        pVCpu           msc:[rbp+30h]
+; @param        pfnStartVM      msc:[rbp+38h]
+;
+; @remarks      This is essentially the same code as hmR0SVMRunWrapXMM, only the parameters differ a little bit.
+;
+; ASSUMING 64-bit and windows for now.
+ALIGNCODE(16)
+BEGINPROC hmR0VMXStartVMWrapXMM
+        push    xBP
+        mov     xBP, xSP
+        sub     xSP, 0a0h + 040h        ; Don't bother optimizing the frame size.
+
+        ; spill input parameters.
+        mov     [xBP + 010h], rcx       ; fResumeVM
+        mov     [xBP + 018h], rdx       ; pCtx
+        mov     [xBP + 020h], r8        ; pVMCSCache
+        mov     [xBP + 028h], r9        ; pVM
+
+        ; Ask CPUM whether we've started using the FPU yet.
+        mov     rcx, [xBP + 30h]        ; pVCpu
+        call    NAME(CPUMIsGuestFPUStateActive)
+        test    al, al
+        jnz     .guest_fpu_state_active
+
+        ; No need to mess with XMM registers just call the start routine and return.
+        mov     r11, [xBP + 38h]        ; pfnStartVM
+        mov     r10, [xBP + 30h]        ; pVCpu
+        mov     [xSP + 020h], r10
+        mov     rcx, [xBP + 010h]       ; fResumeVM
+        mov     rdx, [xBP + 018h]       ; pCtx
+        mov     r8,  [xBP + 020h]       ; pVMCSCache
+        mov     r9,  [xBP + 028h]       ; pVM
+        call    r11
+
+        leave
+        ret
+
+ALIGNCODE(8)
+.guest_fpu_state_active:
+        ; Save the host XMM registers.
+        movdqa  [rsp + 040h + 000h], xmm6
+        movdqa  [rsp + 040h + 010h], xmm7
+        movdqa  [rsp + 040h + 020h], xmm8
+        movdqa  [rsp + 040h + 030h], xmm9
+        movdqa  [rsp + 040h + 040h], xmm10
+        movdqa  [rsp + 040h + 050h], xmm11
+        movdqa  [rsp + 040h + 060h], xmm12
+        movdqa  [rsp + 040h + 070h], xmm13
+        movdqa  [rsp + 040h + 080h], xmm14
+        movdqa  [rsp + 040h + 090h], xmm15
+
+        ; Load the full guest XMM register state.
+        mov     r10, [xBP + 018h]       ; pCtx
+        lea     r10, [r10 + XMM_OFF_IN_X86FXSTATE]
+        movdqa  xmm0,  [r10 + 000h]
+        movdqa  xmm1,  [r10 + 010h]
+        movdqa  xmm2,  [r10 + 020h]
+        movdqa  xmm3,  [r10 + 030h]
+        movdqa  xmm4,  [r10 + 040h]
+        movdqa  xmm5,  [r10 + 050h]
+        movdqa  xmm6,  [r10 + 060h]
+        movdqa  xmm7,  [r10 + 070h]
+        movdqa  xmm8,  [r10 + 080h]
+        movdqa  xmm9,  [r10 + 090h]
+        movdqa  xmm10, [r10 + 0a0h]
+        movdqa  xmm11, [r10 + 0b0h]
+        movdqa  xmm12, [r10 + 0c0h]
+        movdqa  xmm13, [r10 + 0d0h]
+        movdqa  xmm14, [r10 + 0e0h]
+        movdqa  xmm15, [r10 + 0f0h]
+
+        ; Make the call (same as in the other case ).
+        mov     r11, [xBP + 38h]        ; pfnStartVM
+        mov     r10, [xBP + 30h]        ; pVCpu
+        mov     [xSP + 020h], r10
+        mov     rcx, [xBP + 010h]       ; fResumeVM
+        mov     rdx, [xBP + 018h]       ; pCtx
+        mov     r8,  [xBP + 020h]       ; pVMCSCache
+        mov     r9,  [xBP + 028h]       ; pVM
+        call    r11
+
+        ; Save the guest XMM registers.
+        mov     r10, [xBP + 018h]       ; pCtx
+        lea     r10, [r10 + XMM_OFF_IN_X86FXSTATE]
+        movdqa  [r10 + 000h], xmm0
+        movdqa  [r10 + 010h], xmm1
+        movdqa  [r10 + 020h], xmm2
+        movdqa  [r10 + 030h], xmm3
+        movdqa  [r10 + 040h], xmm4
+        movdqa  [r10 + 050h], xmm5
+        movdqa  [r10 + 060h], xmm6
+        movdqa  [r10 + 070h], xmm7
+        movdqa  [r10 + 080h], xmm8
+        movdqa  [r10 + 090h], xmm9
+        movdqa  [r10 + 0a0h], xmm10
+        movdqa  [r10 + 0b0h], xmm11
+        movdqa  [r10 + 0c0h], xmm12
+        movdqa  [r10 + 0d0h], xmm13
+        movdqa  [r10 + 0e0h], xmm14
+        movdqa  [r10 + 0f0h], xmm15
+
+        ; Load the host XMM registers.
+        movdqa  xmm6,  [rsp + 040h + 000h]
+        movdqa  xmm7,  [rsp + 040h + 010h]
+        movdqa  xmm8,  [rsp + 040h + 020h]
+        movdqa  xmm9,  [rsp + 040h + 030h]
+        movdqa  xmm10, [rsp + 040h + 040h]
+        movdqa  xmm11, [rsp + 040h + 050h]
+        movdqa  xmm12, [rsp + 040h + 060h]
+        movdqa  xmm13, [rsp + 040h + 070h]
+        movdqa  xmm14, [rsp + 040h + 080h]
+        movdqa  xmm15, [rsp + 040h + 090h]
+        leave
+        ret
+ENDPROC   hmR0VMXStartVMWrapXMM
+
+;;
+; Wrapper around svm.pfnVMRun that preserves host XMM registers and
+; load the guest ones when necessary.
+;
+; @cproto       DECLASM(int) hmR0SVMRunWrapXMM(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu, PFNHMSVMVMRUN pfnVMRun);
+;
+; @returns      eax
+;
+; @param        pVMCBHostPhys   msc:rcx
+; @param        pVMCBPhys       msc:rdx
+; @param        pCtx            msc:r8
+; @param        pVM             msc:r9
+; @param        pVCpu           msc:[rbp+30h]
+; @param        pfnVMRun        msc:[rbp+38h]
+;
+; @remarks      This is essentially the same code as hmR0VMXStartVMWrapXMM, only the parameters differ a little bit.
+;
+; ASSUMING 64-bit and windows for now.
+ALIGNCODE(16)
+BEGINPROC hmR0SVMRunWrapXMM
+        push    xBP
+        mov     xBP, xSP
+        sub     xSP, 0a0h + 040h        ; Don't bother optimizing the frame size.
+
+        ; spill input parameters.
+        mov     [xBP + 010h], rcx       ; pVMCBHostPhys
+        mov     [xBP + 018h], rdx       ; pVMCBPhys
+        mov     [xBP + 020h], r8        ; pCtx
+        mov     [xBP + 028h], r9        ; pVM
+
+        ; Ask CPUM whether we've started using the FPU yet.
+        mov     rcx, [xBP + 30h]        ; pVCpu
+        call    NAME(CPUMIsGuestFPUStateActive)
+        test    al, al
+        jnz     .guest_fpu_state_active
+
+        ; No need to mess with XMM registers just call the start routine and return.
+        mov     r11, [xBP + 38h]        ; pfnVMRun
+        mov     r10, [xBP + 30h]        ; pVCpu
+        mov     [xSP + 020h], r10
+        mov     rcx, [xBP + 010h]       ; pVMCBHostPhys
+        mov     rdx, [xBP + 018h]       ; pVMCBPhys
+        mov     r8,  [xBP + 020h]       ; pCtx
+        mov     r9,  [xBP + 028h]       ; pVM
+        call    r11
+
+        leave
+        ret
+
+ALIGNCODE(8)
+.guest_fpu_state_active:
+        ; Save the host XMM registers.
+        movdqa  [rsp + 040h + 000h], xmm6
+        movdqa  [rsp + 040h + 010h], xmm7
+        movdqa  [rsp + 040h + 020h], xmm8
+        movdqa  [rsp + 040h + 030h], xmm9
+        movdqa  [rsp + 040h + 040h], xmm10
+        movdqa  [rsp + 040h + 050h], xmm11
+        movdqa  [rsp + 040h + 060h], xmm12
+        movdqa  [rsp + 040h + 070h], xmm13
+        movdqa  [rsp + 040h + 080h], xmm14
+        movdqa  [rsp + 040h + 090h], xmm15
+
+        ; Load the full guest XMM register state.
+        mov     r10, [xBP + 020h]       ; pCtx
+        lea     r10, [r10 + XMM_OFF_IN_X86FXSTATE]
+        movdqa  xmm0,  [r10 + 000h]
+        movdqa  xmm1,  [r10 + 010h]
+        movdqa  xmm2,  [r10 + 020h]
+        movdqa  xmm3,  [r10 + 030h]
+        movdqa  xmm4,  [r10 + 040h]
+        movdqa  xmm5,  [r10 + 050h]
+        movdqa  xmm6,  [r10 + 060h]
+        movdqa  xmm7,  [r10 + 070h]
+        movdqa  xmm8,  [r10 + 080h]
+        movdqa  xmm9,  [r10 + 090h]
+        movdqa  xmm10, [r10 + 0a0h]
+        movdqa  xmm11, [r10 + 0b0h]
+        movdqa  xmm12, [r10 + 0c0h]
+        movdqa  xmm13, [r10 + 0d0h]
+        movdqa  xmm14, [r10 + 0e0h]
+        movdqa  xmm15, [r10 + 0f0h]
+
+        ; Make the call (same as in the other case ).
+        mov     r11, [xBP + 38h]        ; pfnVMRun
+        mov     r10, [xBP + 30h]        ; pVCpu
+        mov     [xSP + 020h], r10
+        mov     rcx, [xBP + 010h]       ; pVMCBHostPhys
+        mov     rdx, [xBP + 018h]       ; pVMCBPhys
+        mov     r8,  [xBP + 020h]       ; pCtx
+        mov     r9,  [xBP + 028h]       ; pVM
+        call    r11
+
+        ; Save the guest XMM registers.
+        mov     r10, [xBP + 020h]       ; pCtx
+        lea     r10, [r10 + XMM_OFF_IN_X86FXSTATE]
+        movdqa  [r10 + 000h], xmm0
+        movdqa  [r10 + 010h], xmm1
+        movdqa  [r10 + 020h], xmm2
+        movdqa  [r10 + 030h], xmm3
+        movdqa  [r10 + 040h], xmm4
+        movdqa  [r10 + 050h], xmm5
+        movdqa  [r10 + 060h], xmm6
+        movdqa  [r10 + 070h], xmm7
+        movdqa  [r10 + 080h], xmm8
+        movdqa  [r10 + 090h], xmm9
+        movdqa  [r10 + 0a0h], xmm10
+        movdqa  [r10 + 0b0h], xmm11
+        movdqa  [r10 + 0c0h], xmm12
+        movdqa  [r10 + 0d0h], xmm13
+        movdqa  [r10 + 0e0h], xmm14
+        movdqa  [r10 + 0f0h], xmm15
+
+        ; Load the host XMM registers.
+        movdqa  xmm6,  [rsp + 040h + 000h]
+        movdqa  xmm7,  [rsp + 040h + 010h]
+        movdqa  xmm8,  [rsp + 040h + 020h]
+        movdqa  xmm9,  [rsp + 040h + 030h]
+        movdqa  xmm10, [rsp + 040h + 040h]
+        movdqa  xmm11, [rsp + 040h + 050h]
+        movdqa  xmm12, [rsp + 040h + 060h]
+        movdqa  xmm13, [rsp + 040h + 070h]
+        movdqa  xmm14, [rsp + 040h + 080h]
+        movdqa  xmm15, [rsp + 040h + 090h]
+        leave
+        ret
+ENDPROC   hmR0SVMRunWrapXMM
+
+%endif ; VBOX_WITH_KERNEL_USING_XMM
+
+;
+; The default setup of the StartVM routines.
+;
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ %define MY_NAME(name)   name %+ _32
+%else
+ %define MY_NAME(name)   name
+%endif
+%ifdef RT_ARCH_AMD64
+ %define MYPUSHAD       MYPUSHAD64
+ %define MYPOPAD        MYPOPAD64
+ %define MYPUSHSEGS     MYPUSHSEGS64
+ %define MYPOPSEGS      MYPOPSEGS64
+%else
+ %define MYPUSHAD       MYPUSHAD32
+ %define MYPOPAD        MYPOPAD32
+ %define MYPUSHSEGS     MYPUSHSEGS32
+ %define MYPOPSEGS      MYPOPSEGS32
+%endif
+
+%include "HMR0Mixed.mac"
+
+
+%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+ ;
+ ; Write the wrapper procedures.
+ ;
+ ; These routines are probably being too paranoid about selector
+ ; restoring, but better safe than sorry...
+ ;
+
+; DECLASM(int) VMXR0StartVM32(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache /*, PVM pVM, PVMCPU pVCpu*/);
+ALIGNCODE(16)
+BEGINPROC VMXR0StartVM32
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    je near NAME(VMXR0StartVM32_32)
+
+    ; stack frame
+    push    esi
+    push    edi
+    push    fs
+    push    gs
+
+    ; jmp far .thunk64
+    db      0xea
+    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
+
+ALIGNCODE(16)
+BITS 64
+.thunk64:
+    sub     esp, 20h
+    mov     edi, [rsp + 20h + 14h]      ; fResume
+    mov     esi, [rsp + 20h + 18h]      ; pCtx
+    mov     edx, [rsp + 20h + 1Ch]      ; pCache
+    call    NAME(VMXR0StartVM32_64)
+    add     esp, 20h
+    jmp far [.fpthunk32 wrt rip]
+.fpthunk32:                             ; 16:32 Pointer to .thunk32.
+    dd      .thunk32, NAME(SUPR0AbsKernelCS)
+
+BITS 32
+ALIGNCODE(16)
+.thunk32:
+    pop     gs
+    pop     fs
+    pop     edi
+    pop     esi
+    ret
+ENDPROC   VMXR0StartVM32
+
+
+; DECLASM(int) VMXR0StartVM64(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache /*, PVM pVM, PVMCPU pVCpu*/);
+ALIGNCODE(16)
+BEGINPROC VMXR0StartVM64
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    je      .not_in_long_mode
+
+    ; stack frame
+    push    esi
+    push    edi
+    push    fs
+    push    gs
+
+    ; jmp far .thunk64
+    db      0xea
+    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
+
+ALIGNCODE(16)
+BITS 64
+.thunk64:
+    sub     esp, 20h
+    mov     edi, [rsp + 20h + 14h]      ; fResume
+    mov     esi, [rsp + 20h + 18h]      ; pCtx
+    mov     edx, [rsp + 20h + 1Ch]      ; pCache
+    call    NAME(VMXR0StartVM64_64)
+    add     esp, 20h
+    jmp far [.fpthunk32 wrt rip]
+.fpthunk32:                             ; 16:32 Pointer to .thunk32.
+    dd      .thunk32, NAME(SUPR0AbsKernelCS)
+
+BITS 32
+ALIGNCODE(16)
+.thunk32:
+    pop     gs
+    pop     fs
+    pop     edi
+    pop     esi
+    ret
+
+.not_in_long_mode:
+    mov     eax, VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE
+    ret
+ENDPROC   VMXR0StartVM64
+
+;DECLASM(int) SVMR0VMRun(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx /*, PVM pVM, PVMCPU pVCpu*/);
+ALIGNCODE(16)
+BEGINPROC SVMR0VMRun
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    je near NAME(SVMR0VMRun_32)
+
+    ; stack frame
+    push    esi
+    push    edi
+    push    fs
+    push    gs
+
+    ; jmp far .thunk64
+    db      0xea
+    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
+
+ALIGNCODE(16)
+BITS 64
+.thunk64:
+    sub     esp, 20h
+    mov     rdi, [rsp + 20h + 14h]      ; pVMCBHostPhys
+    mov     rsi, [rsp + 20h + 1Ch]      ; pVMCBPhys
+    mov     edx, [rsp + 20h + 24h]      ; pCtx
+    call    NAME(SVMR0VMRun_64)
+    add     esp, 20h
+    jmp far [.fpthunk32 wrt rip]
+.fpthunk32:                             ; 16:32 Pointer to .thunk32.
+    dd      .thunk32, NAME(SUPR0AbsKernelCS)
+
+BITS 32
+ALIGNCODE(16)
+.thunk32:
+    pop     gs
+    pop     fs
+    pop     edi
+    pop     esi
+    ret
+ENDPROC   SVMR0VMRun
+
+
+; DECLASM(int) SVMR0VMRun64(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx /*, PVM pVM, PVMCPU pVCpu*/);
+ALIGNCODE(16)
+BEGINPROC SVMR0VMRun64
+    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
+    je      .not_in_long_mode
+
+    ; stack frame
+    push    esi
+    push    edi
+    push    fs
+    push    gs
+
+    ; jmp far .thunk64
+    db      0xea
+    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
+
+ALIGNCODE(16)
+BITS 64
+.thunk64:
+    sub     esp, 20h
+    mov     rdi, [rbp + 20h + 14h]      ; pVMCBHostPhys
+    mov     rsi, [rbp + 20h + 1Ch]      ; pVMCBPhys
+    mov     edx, [rbp + 20h + 24h]      ; pCtx
+    call    NAME(SVMR0VMRun64_64)
+    add     esp, 20h
+    jmp far [.fpthunk32 wrt rip]
+.fpthunk32:                             ; 16:32 Pointer to .thunk32.
+    dd      .thunk32, NAME(SUPR0AbsKernelCS)
+
+BITS 32
+ALIGNCODE(16)
+.thunk32:
+    pop     gs
+    pop     fs
+    pop     edi
+    pop     esi
+    ret
+
+.not_in_long_mode:
+    mov     eax, VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE
+    ret
+ENDPROC   SVMR0VMRun64
+
+ ;
+ ; Do it a second time pretending we're a 64-bit host.
+ ;
+ ; This *HAS* to be done at the very end of the file to avoid restoring
+ ; macros. So, add new code *BEFORE* this mess.
+ ;
+ BITS 64
+ %undef  RT_ARCH_X86
+ %define RT_ARCH_AMD64
+ %undef  ASM_CALL64_MSC
+ %define ASM_CALL64_GCC
+ %define xS             8
+ %define xSP            rsp
+ %define xBP            rbp
+ %define xAX            rax
+ %define xBX            rbx
+ %define xCX            rcx
+ %define xDX            rdx
+ %define xDI            rdi
+ %define xSI            rsi
+ %define MY_NAME(name)   name %+ _64
+ %define MYPUSHAD       MYPUSHAD64
+ %define MYPOPAD        MYPOPAD64
+ %define MYPUSHSEGS     MYPUSHSEGS64
+ %define MYPOPSEGS      MYPOPSEGS64
+
+ %include "HMR0Mixed.mac"
+%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
Index: trunk/src/VBox/VMM/VMMR0/HMR0Mixed.mac
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HMR0Mixed.mac	(revision 43387)
+++ trunk/src/VBox/VMM/VMMR0/HMR0Mixed.mac	(revision 43387)
@@ -0,0 +1,901 @@
+; $Id$
+;; @file
+; HMR0Mixed.mac - Stuff that darwin needs to build two versions of.
+;
+; Included by HMR0A.asm with RT_ARCH_AMD64 defined or or undefined.
+;
+
+;
+; 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;
+; 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.
+;
+
+
+;/**
+; * Prepares for and executes VMLAUNCH/VMRESUME (32 bits guest mode)
+; *
+; * @returns VBox status code
+; * @param   fResume    x86:[ebp+8], msc:rcx,gcc:rdi     vmlauch/vmresume
+; * @param   pCtx       x86:[ebp+c], msc:rdx,gcc:rsi     Guest context
+; * @param   pCache     x86:[esp+10],msc:r8, gcc:rdx     VMCS cache
+; */
+ALIGNCODE(16)
+BEGINPROC MY_NAME(VMXR0StartVM32)
+    push    xBP
+    mov     xBP, xSP
+
+    pushf
+    cli
+
+    ;/* Save all general purpose host registers. */
+    MYPUSHAD
+
+    ;/* First we have to save some final CPU context registers. */
+    mov     eax, VMX_VMCS_HOST_RIP
+%ifdef RT_ARCH_AMD64
+    lea     r10, [.vmlaunch_done wrt rip]
+    vmwrite rax, r10
+%else
+    mov     ecx, .vmlaunch_done
+    vmwrite eax, ecx
+%endif
+    ;/* Note: assumes success... */
+
+    ;/* Manual save and restore:
+    ; * - General purpose registers except RIP, RSP
+    ; *
+    ; * Trashed:
+    ; * - CR2 (we don't care)
+    ; * - LDTR (reset to 0)
+    ; * - DRx (presumably not changed at all)
+    ; * - DR7 (reset to 0x400)
+    ; * - EFLAGS (reset to RT_BIT(1); not relevant)
+    ; *
+    ; */
+
+    ;/* Save the Guest CPU context pointer. */
+%ifdef RT_ARCH_AMD64
+ %ifdef ASM_CALL64_GCC
+    ; fResume already in rdi
+    ; pCtx    already in rsi
+    mov     rbx, rdx        ; pCache
+ %else
+    mov     rdi, rcx        ; fResume
+    mov     rsi, rdx        ; pCtx
+    mov     rbx, r8         ; pCache
+ %endif
+%else
+    mov     edi, [ebp + 8]  ; fResume
+    mov     esi, [ebp + 12] ; pCtx
+    mov     ebx, [ebp + 16] ; pCache
+%endif
+
+    ;/* Save segment registers */
+    ; Note: MYPUSHSEGS trashes rdx & rcx, so we moved it here (msvc amd64 case)
+    MYPUSHSEGS xAX, ax
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    mov     ecx, [xBX + VMCSCACHE.Write.cValidEntries]
+    cmp     ecx, 0
+    je      .no_cached_writes
+    mov     edx, ecx
+    mov     ecx, 0
+    jmp     .cached_write
+
+ALIGN(16)
+.cached_write:
+    mov     eax, [xBX + VMCSCACHE.Write.aField + xCX*4]
+    vmwrite xAX, [xBX + VMCSCACHE.Write.aFieldVal + xCX*8]
+    inc     xCX
+    cmp     xCX, xDX
+    jl     .cached_write
+
+    mov     dword [xBX + VMCSCACHE.Write.cValidEntries], 0
+.no_cached_writes:
+
+    ; Save the pCache pointer
+    push    xBX
+%endif
+
+    ; Save the pCtx pointer
+    push    xSI
+
+    ; Save LDTR
+    xor     eax, eax
+    sldt    ax
+    push    xAX
+
+    ; The TR limit is reset to 0x67; restore it manually
+    str     eax
+    push    xAX
+
+    ; VMX only saves the base of the GDTR & IDTR and resets the limit to 0xffff; we must restore the limit correctly!
+    sub     xSP, xS*2
+    sgdt    [xSP]
+
+    sub     xSP, xS*2
+    sidt    [xSP]
+
+%ifdef VBOX_WITH_DR6_EXPERIMENT
+    ; Restore DR6 - experiment, not safe!
+    mov     xBX, [xSI + CPUMCTX.dr6]
+    mov     dr6, xBX
+%endif
+
+    ; Restore CR2
+    mov     ebx, [xSI + CPUMCTX.cr2]
+    mov     cr2, xBX
+
+    mov     eax, VMX_VMCS_HOST_RSP
+    vmwrite xAX, xSP
+    ;/* Note: assumes success... */
+    ;/* Don't mess with ESP anymore!! */
+
+    ;/* Restore Guest's general purpose registers. */
+    mov     eax, [xSI + CPUMCTX.eax]
+    mov     ebx, [xSI + CPUMCTX.ebx]
+    mov     ecx, [xSI + CPUMCTX.ecx]
+    mov     edx, [xSI + CPUMCTX.edx]
+    mov     ebp, [xSI + CPUMCTX.ebp]
+
+    ; resume or start?
+    cmp     xDI, 0                  ; fResume
+    je      .vmlauch_lauch
+
+    ;/* Restore edi & esi. */
+    mov     edi, [xSI + CPUMCTX.edi]
+    mov     esi, [xSI + CPUMCTX.esi]
+
+    vmresume
+    jmp     .vmlaunch_done;      ;/* here if vmresume detected a failure. */
+
+.vmlauch_lauch:
+    ;/* Restore edi & esi. */
+    mov     edi, [xSI + CPUMCTX.edi]
+    mov     esi, [xSI + CPUMCTX.esi]
+
+    vmlaunch
+    jmp     .vmlaunch_done;      ;/* here if vmlaunch detected a failure. */
+
+ALIGNCODE(16) ;; @todo YASM BUG - this alignment is wrong on darwin, it's 1 byte off.
+.vmlaunch_done:
+    jc      near .vmxstart_invalid_vmxon_ptr
+    jz      near .vmxstart_start_failed
+
+    ; Restore base and limit of the IDTR & GDTR
+    lidt    [xSP]
+    add     xSP, xS*2
+    lgdt    [xSP]
+    add     xSP, xS*2
+
+    push    xDI
+    mov     xDI, [xSP + xS * 3]         ; pCtx (*3 to skip the saved LDTR + TR)
+
+    mov     [ss:xDI + CPUMCTX.eax], eax
+    mov     [ss:xDI + CPUMCTX.ebx], ebx
+    mov     [ss:xDI + CPUMCTX.ecx], ecx
+    mov     [ss:xDI + CPUMCTX.edx], edx
+    mov     [ss:xDI + CPUMCTX.esi], esi
+    mov     [ss:xDI + CPUMCTX.ebp], ebp
+%ifdef RT_ARCH_AMD64
+    pop     xAX                                 ; the guest edi we pushed above
+    mov     dword [ss:xDI + CPUMCTX.edi], eax
+%else
+    pop     dword [ss:xDI + CPUMCTX.edi]        ; the guest edi we pushed above
+%endif
+
+%ifdef VBOX_WITH_DR6_EXPERIMENT
+    ; Save DR6 - experiment, not safe!
+    mov     xAX, dr6
+    mov     [ss:xDI + CPUMCTX.dr6], xAX
+%endif
+
+    ; Restore TSS selector; must mark it as not busy before using ltr (!)
+    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
+    ; @todo get rid of sgdt
+    pop     xBX         ; saved TR
+    sub     xSP, xS*2
+    sgdt    [xSP]
+    mov     xAX, xBX
+    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
+    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
+    and     dword [ss:xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
+    ltr     bx
+    add     xSP, xS*2
+
+    pop     xAX         ; saved LDTR
+    lldt    ax
+
+    add     xSP, xS      ; pCtx
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    pop     xDX         ; saved pCache
+
+    mov     ecx, [ss:xDX + VMCSCACHE.Read.cValidEntries]
+    cmp     ecx, 0  ; can't happen
+    je      .no_cached_reads
+    jmp     .cached_read
+
+ALIGN(16)
+.cached_read:
+    dec     xCX
+    mov     eax, [ss:xDX + VMCSCACHE.Read.aField + xCX*4]
+    vmread  [ss:xDX + VMCSCACHE.Read.aFieldVal + xCX*8], xAX
+    cmp     xCX, 0
+    jnz     .cached_read
+.no_cached_reads:
+
+    ; Save CR2 for EPT
+    mov     xAX, cr2
+    mov     [ss:xDX + VMCSCACHE.cr2], xAX
+%endif
+
+    ; Restore segment registers
+    MYPOPSEGS xAX, ax
+
+    ; Restore general purpose registers
+    MYPOPAD
+
+    mov     eax, VINF_SUCCESS
+
+.vmstart_end:
+    popf
+    pop     xBP
+    ret
+
+
+.vmxstart_invalid_vmxon_ptr:
+    ; Restore base and limit of the IDTR & GDTR
+    lidt    [xSP]
+    add     xSP, xS*2
+    lgdt    [xSP]
+    add     xSP, xS*2
+
+    ; Restore TSS selector; must mark it as not busy before using ltr (!)
+    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
+    ; @todo get rid of sgdt
+    pop     xBX         ; saved TR
+    sub     xSP, xS*2
+    sgdt    [xSP]
+    mov     xAX, xBX
+    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
+    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
+    and     dword [ss:xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
+    ltr     bx
+    add     xSP, xS*2
+
+    pop     xAX         ; saved LDTR
+    lldt    ax
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    add     xSP, xS*2   ; pCtx + pCache
+%else
+    add     xSP, xS     ; pCtx
+%endif
+
+    ; Restore segment registers
+    MYPOPSEGS xAX, ax
+
+    ; Restore all general purpose host registers.
+    MYPOPAD
+    mov     eax, VERR_VMX_INVALID_VMXON_PTR
+    jmp     .vmstart_end
+
+.vmxstart_start_failed:
+    ; Restore base and limit of the IDTR & GDTR
+    lidt    [xSP]
+    add     xSP, xS*2
+    lgdt    [xSP]
+    add     xSP, xS*2
+
+    ; Restore TSS selector; must mark it as not busy before using ltr (!)
+    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
+    ; @todo get rid of sgdt
+    pop     xBX         ; saved TR
+    sub     xSP, xS*2
+    sgdt    [xSP]
+    mov     xAX, xBX
+    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
+    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
+    and     dword [ss:xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
+    ltr     bx
+    add     xSP, xS*2
+
+    pop     xAX         ; saved LDTR
+    lldt    ax
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    add     xSP, xS*2   ; pCtx + pCache
+%else
+    add     xSP, xS     ; pCtx
+%endif
+
+    ; Restore segment registers
+    MYPOPSEGS xAX, ax
+
+    ; Restore all general purpose host registers.
+    MYPOPAD
+    mov     eax, VERR_VMX_UNABLE_TO_START_VM
+    jmp     .vmstart_end
+
+ENDPROC MY_NAME(VMXR0StartVM32)
+
+%ifdef RT_ARCH_AMD64
+;/**
+; * Prepares for and executes VMLAUNCH/VMRESUME (64 bits guest mode)
+; *
+; * @returns VBox status code
+; * @param   fResume    msc:rcx, gcc:rdi     vmlauch/vmresume
+; * @param   pCtx       msc:rdx, gcc:rsi     Guest context
+; * @param   pCache     msc:r8,  gcc:rdx     VMCS cache
+; */
+ALIGNCODE(16)
+BEGINPROC MY_NAME(VMXR0StartVM64)
+    push    xBP
+    mov     xBP, xSP
+
+    pushf
+    cli
+
+    ;/* Save all general purpose host registers. */
+    MYPUSHAD
+
+    ;/* First we have to save some final CPU context registers. */
+    lea     r10, [.vmlaunch64_done wrt rip]
+    mov     rax, VMX_VMCS_HOST_RIP  ;/* return address (too difficult to continue after VMLAUNCH?) */
+    vmwrite rax, r10
+    ;/* Note: assumes success... */
+
+    ;/* Manual save and restore:
+    ; * - General purpose registers except RIP, RSP
+    ; *
+    ; * Trashed:
+    ; * - CR2 (we don't care)
+    ; * - LDTR (reset to 0)
+    ; * - DRx (presumably not changed at all)
+    ; * - DR7 (reset to 0x400)
+    ; * - EFLAGS (reset to RT_BIT(1); not relevant)
+    ; *
+    ; */
+
+    ;/* Save the Guest CPU context pointer. */
+%ifdef ASM_CALL64_GCC
+    ; fResume already in rdi
+    ; pCtx    already in rsi
+    mov     rbx, rdx        ; pCache
+%else
+    mov     rdi, rcx        ; fResume
+    mov     rsi, rdx        ; pCtx
+    mov     rbx, r8         ; pCache
+%endif
+
+    ;/* Save segment registers */
+    ; Note: MYPUSHSEGS trashes rdx & rcx, so we moved it here (msvc amd64 case)
+    MYPUSHSEGS xAX, ax
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    mov     ecx, [xBX + VMCSCACHE.Write.cValidEntries]
+    cmp     ecx, 0
+    je      .no_cached_writes
+    mov     edx, ecx
+    mov     ecx, 0
+    jmp     .cached_write
+
+ALIGN(16)
+.cached_write:
+    mov     eax, [xBX + VMCSCACHE.Write.aField + xCX*4]
+    vmwrite xAX, [xBX + VMCSCACHE.Write.aFieldVal + xCX*8]
+    inc     xCX
+    cmp     xCX, xDX
+    jl     .cached_write
+
+    mov     dword [xBX + VMCSCACHE.Write.cValidEntries], 0
+.no_cached_writes:
+
+    ; Save the pCache pointer
+    push    xBX
+%endif
+
+%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
+    ; Save the host MSRs and load the guest MSRs
+    LOADGUESTMSR MSR_K8_LSTAR, CPUMCTX.msrLSTAR
+    LOADGUESTMSR MSR_K6_STAR, CPUMCTX.msrSTAR
+    LOADGUESTMSR MSR_K8_SF_MASK, CPUMCTX.msrSFMASK
+%endif
+    ; Kernel GS Base is special, we need to manually load/store it, see @bugref{6208}
+    LOADGUESTMSR MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
+
+    ; Save the pCtx pointer
+    push    xSI
+
+    ; Save LDTR
+    xor     eax, eax
+    sldt    ax
+    push    xAX
+
+    ; The TR limit is reset to 0x67; restore it manually
+    str     eax
+    push    xAX
+
+    ; VMX only saves the base of the GDTR & IDTR and resets the limit to 0xffff; we must restore the limit correctly!
+    sub     xSP, xS*2
+    sgdt    [xSP]
+
+    sub     xSP, xS*2
+    sidt    [xSP]
+
+%ifdef VBOX_WITH_DR6_EXPERIMENT
+    ; Restore DR6 - experiment, not safe!
+    mov     xBX, [xSI + CPUMCTX.dr6]
+    mov     dr6, xBX
+%endif
+
+    ; Restore CR2
+    mov     rbx, qword [xSI + CPUMCTX.cr2]
+    mov     cr2, rbx
+
+    mov     eax, VMX_VMCS_HOST_RSP
+    vmwrite xAX, xSP
+    ;/* Note: assumes success... */
+    ;/* Don't mess with ESP anymore!! */
+
+    ;/* Restore Guest's general purpose registers. */
+    mov     rax, qword [xSI + CPUMCTX.eax]
+    mov     rbx, qword [xSI + CPUMCTX.ebx]
+    mov     rcx, qword [xSI + CPUMCTX.ecx]
+    mov     rdx, qword [xSI + CPUMCTX.edx]
+    mov     rbp, qword [xSI + CPUMCTX.ebp]
+    mov     r8,  qword [xSI + CPUMCTX.r8]
+    mov     r9,  qword [xSI + CPUMCTX.r9]
+    mov     r10, qword [xSI + CPUMCTX.r10]
+    mov     r11, qword [xSI + CPUMCTX.r11]
+    mov     r12, qword [xSI + CPUMCTX.r12]
+    mov     r13, qword [xSI + CPUMCTX.r13]
+    mov     r14, qword [xSI + CPUMCTX.r14]
+    mov     r15, qword [xSI + CPUMCTX.r15]
+
+    ; resume or start?
+    cmp     xDI, 0                  ; fResume
+    je      .vmlauch64_lauch
+
+    ;/* Restore edi & esi. */
+    mov     rdi, qword [xSI + CPUMCTX.edi]
+    mov     rsi, qword [xSI + CPUMCTX.esi]
+
+    vmresume
+    jmp     .vmlaunch64_done;      ;/* here if vmresume detected a failure. */
+
+.vmlauch64_lauch:
+    ;/* Restore rdi & rsi. */
+    mov     rdi, qword [xSI + CPUMCTX.edi]
+    mov     rsi, qword [xSI + CPUMCTX.esi]
+
+    vmlaunch
+    jmp     .vmlaunch64_done;      ;/* here if vmlaunch detected a failure. */
+
+ALIGNCODE(16)
+.vmlaunch64_done:
+    jc      near .vmxstart64_invalid_vmxon_ptr
+    jz      near .vmxstart64_start_failed
+
+    ; Restore base and limit of the IDTR & GDTR
+    lidt    [xSP]
+    add     xSP, xS*2
+    lgdt    [xSP]
+    add     xSP, xS*2
+
+    push    xDI
+    mov     xDI, [xSP + xS * 3]         ; pCtx (*3 to skip the saved LDTR + TR)
+
+    mov     qword [xDI + CPUMCTX.eax], rax
+    mov     qword [xDI + CPUMCTX.ebx], rbx
+    mov     qword [xDI + CPUMCTX.ecx], rcx
+    mov     qword [xDI + CPUMCTX.edx], rdx
+    mov     qword [xDI + CPUMCTX.esi], rsi
+    mov     qword [xDI + CPUMCTX.ebp], rbp
+    mov     qword [xDI + CPUMCTX.r8],  r8
+    mov     qword [xDI + CPUMCTX.r9],  r9
+    mov     qword [xDI + CPUMCTX.r10], r10
+    mov     qword [xDI + CPUMCTX.r11], r11
+    mov     qword [xDI + CPUMCTX.r12], r12
+    mov     qword [xDI + CPUMCTX.r13], r13
+    mov     qword [xDI + CPUMCTX.r14], r14
+    mov     qword [xDI + CPUMCTX.r15], r15
+
+    pop     xAX                                 ; the guest edi we pushed above
+    mov     qword [xDI + CPUMCTX.edi], rax
+
+%ifdef VBOX_WITH_DR6_EXPERIMENT
+    ; Save DR6 - experiment, not safe!
+    mov     xAX, dr6
+    mov     [xDI + CPUMCTX.dr6], xAX
+%endif
+
+    ; Restore TSS selector; must mark it as not busy before using ltr (!)
+    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
+    ; @todo get rid of sgdt
+    pop     xBX         ; saved TR
+    sub     xSP, xS*2
+    sgdt    [xSP]
+    mov     xAX, xBX
+    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
+    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
+    and     dword [xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
+    ltr     bx
+    add     xSP, xS*2
+
+    pop     xAX         ; saved LDTR
+    lldt    ax
+
+    pop     xSI         ; pCtx (needed in rsi by the macros below)
+
+    ; Kernel GS Base is special, we need to manually load/store it, see @bugref{6208}.
+    LOADHOSTMSREX MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
+%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
+    ; Save the guest MSRs and load the host MSRs
+    LOADHOSTMSREX MSR_K8_SF_MASK, CPUMCTX.msrSFMASK
+    LOADHOSTMSREX MSR_K6_STAR, CPUMCTX.msrSTAR
+    LOADHOSTMSREX MSR_K8_LSTAR, CPUMCTX.msrLSTAR
+%endif
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    pop     xDX         ; saved pCache
+
+    mov     ecx, [xDX + VMCSCACHE.Read.cValidEntries]
+    cmp     ecx, 0  ; can't happen
+    je      .no_cached_reads
+    jmp     .cached_read
+
+ALIGN(16)
+.cached_read:
+    dec     xCX
+    mov     eax, [xDX + VMCSCACHE.Read.aField + xCX*4]
+    vmread  [xDX + VMCSCACHE.Read.aFieldVal + xCX*8], xAX
+    cmp      xCX, 0
+    jnz     .cached_read
+.no_cached_reads:
+
+    ; Save CR2 for EPT
+    mov     xAX, cr2
+    mov     [xDX + VMCSCACHE.cr2], xAX
+%endif
+
+    ; Restore segment registers
+    MYPOPSEGS xAX, ax
+
+    ; Restore general purpose registers
+    MYPOPAD
+
+    mov     eax, VINF_SUCCESS
+
+.vmstart64_end:
+    popf
+    pop     xBP
+    ret
+
+
+.vmxstart64_invalid_vmxon_ptr:
+    ; Restore base and limit of the IDTR & GDTR
+    lidt    [xSP]
+    add     xSP, xS*2
+    lgdt    [xSP]
+    add     xSP, xS*2
+
+    ; Restore TSS selector; must mark it as not busy before using ltr (!)
+    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
+    ; @todo get rid of sgdt
+    pop     xBX         ; saved TR
+    sub     xSP, xS*2
+    sgdt    [xSP]
+    mov     xAX, xBX
+    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
+    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
+    and     dword [xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
+    ltr     bx
+    add     xSP, xS*2
+
+    pop     xAX         ; saved LDTR
+    lldt    ax
+
+    pop     xSI         ; pCtx (needed in rsi by the macros below)
+
+    ; Kernel GS base is special, we need to manually load/store it See @bugref{6208}.
+    LOADHOSTMSREX MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
+%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
+    ; Load the host MSRs
+    LOADHOSTMSR MSR_K8_SF_MASK
+    LOADHOSTMSR MSR_K6_STAR
+    LOADHOSTMSR MSR_K8_LSTAR
+%endif
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    add     xSP, xS     ; pCache
+%endif
+
+    ; Restore segment registers
+    MYPOPSEGS xAX, ax
+
+    ; Restore all general purpose host registers.
+    MYPOPAD
+    mov     eax, VERR_VMX_INVALID_VMXON_PTR
+    jmp     .vmstart64_end
+
+.vmxstart64_start_failed:
+    ; Restore base and limit of the IDTR & GDTR
+    lidt    [xSP]
+    add     xSP, xS*2
+    lgdt    [xSP]
+    add     xSP, xS*2
+
+    ; Restore TSS selector; must mark it as not busy before using ltr (!)
+    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
+    ; @todo get rid of sgdt
+    pop     xBX         ; saved TR
+    sub     xSP, xS*2
+    sgdt    [xSP]
+    mov     xAX, xBX
+    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
+    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
+    and     dword [xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
+    ltr     bx
+    add     xSP, xS*2
+
+    pop     xAX         ; saved LDTR
+    lldt    ax
+
+    pop     xSI         ; pCtx (needed in rsi by the macros below)
+
+    ; Kernel GS base is special, load it manually. See @bugref{6208}.
+    LOADHOSTMSREX MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
+%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
+    ; Load the host MSRs
+    LOADHOSTMSR MSR_K8_SF_MASK
+    LOADHOSTMSR MSR_K6_STAR
+    LOADHOSTMSR MSR_K8_LSTAR
+%endif
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    add     xSP, xS     ; pCache
+%endif
+
+    ; Restore segment registers
+    MYPOPSEGS xAX, ax
+
+    ; Restore all general purpose host registers.
+    MYPOPAD
+    mov     eax, VERR_VMX_UNABLE_TO_START_VM
+    jmp     .vmstart64_end
+ENDPROC MY_NAME(VMXR0StartVM64)
+%endif ; RT_ARCH_AMD64
+
+
+;/**
+; * Prepares for and executes VMRUN (32 bits guests)
+; *
+; * @returns VBox status code
+; * @param   HCPhysVMCB     Physical address of host VMCB
+; * @param   HCPhysVMCB     Physical address of guest VMCB
+; * @param   pCtx           Guest context
+; */
+ALIGNCODE(16)
+BEGINPROC MY_NAME(SVMR0VMRun)
+%ifdef RT_ARCH_AMD64 ; fake a cdecl stack frame
+ %ifdef ASM_CALL64_GCC
+    push    rdx
+    push    rsi
+    push    rdi
+ %else
+    push    r8
+    push    rdx
+    push    rcx
+ %endif
+    push    0
+%endif
+    push    xBP
+    mov     xBP, xSP
+    pushf
+
+    ;/* Manual save and restore:
+    ; * - General purpose registers except RIP, RSP, RAX
+    ; *
+    ; * Trashed:
+    ; * - CR2 (we don't care)
+    ; * - LDTR (reset to 0)
+    ; * - DRx (presumably not changed at all)
+    ; * - DR7 (reset to 0x400)
+    ; */
+
+    ;/* Save all general purpose host registers. */
+    MYPUSHAD
+
+    ;/* Save the Guest CPU context pointer. */
+    mov     xSI, [xBP + xS*2 + RTHCPHYS_CB*2]   ; pCtx
+    push    xSI                     ; push for saving the state at the end
+
+    ; save host fs, gs, sysenter msr etc
+    mov     xAX, [xBP + xS*2]       ; pVMCBHostPhys (64 bits physical address; x86: take low dword only)
+    push    xAX                     ; save for the vmload after vmrun
+    vmsave
+
+    ; setup eax for VMLOAD
+    mov     xAX, [xBP + xS*2 + RTHCPHYS_CB]     ; pVMCBPhys (64 bits physical address; take low dword only)
+
+    ;/* Restore Guest's general purpose registers. */
+    ;/* EAX is loaded from the VMCB by VMRUN */
+    mov     ebx, [xSI + CPUMCTX.ebx]
+    mov     ecx, [xSI + CPUMCTX.ecx]
+    mov     edx, [xSI + CPUMCTX.edx]
+    mov     edi, [xSI + CPUMCTX.edi]
+    mov     ebp, [xSI + CPUMCTX.ebp]
+    mov     esi, [xSI + CPUMCTX.esi]
+
+    ; Clear the global interrupt flag & execute sti to make sure external interrupts cause a world switch
+    clgi
+    sti
+
+    ; load guest fs, gs, sysenter msr etc
+    vmload
+    ; run the VM
+    vmrun
+
+    ;/* EAX is in the VMCB already; we can use it here. */
+
+    ; save guest fs, gs, sysenter msr etc
+    vmsave
+
+    ; load host fs, gs, sysenter msr etc
+    pop     xAX                     ; pushed above
+    vmload
+
+    ; Set the global interrupt flag again, but execute cli to make sure IF=0.
+    cli
+    stgi
+
+    pop     xAX                     ; pCtx
+
+    mov     [ss:xAX + CPUMCTX.ebx], ebx
+    mov     [ss:xAX + CPUMCTX.ecx], ecx
+    mov     [ss:xAX + CPUMCTX.edx], edx
+    mov     [ss:xAX + CPUMCTX.esi], esi
+    mov     [ss:xAX + CPUMCTX.edi], edi
+    mov     [ss:xAX + CPUMCTX.ebp], ebp
+
+    ; Restore general purpose registers
+    MYPOPAD
+
+    mov     eax, VINF_SUCCESS
+
+    popf
+    pop     xBP
+%ifdef RT_ARCH_AMD64
+    add     xSP, 4*xS
+%endif
+    ret
+ENDPROC MY_NAME(SVMR0VMRun)
+
+%ifdef RT_ARCH_AMD64
+;/**
+; * Prepares for and executes VMRUN (64 bits guests)
+; *
+; * @returns VBox status code
+; * @param   HCPhysVMCB     Physical address of host VMCB
+; * @param   HCPhysVMCB     Physical address of guest VMCB
+; * @param   pCtx           Guest context
+; */
+ALIGNCODE(16)
+BEGINPROC MY_NAME(SVMR0VMRun64)
+    ; fake a cdecl stack frame
+ %ifdef ASM_CALL64_GCC
+    push    rdx
+    push    rsi
+    push    rdi
+ %else
+    push    r8
+    push    rdx
+    push    rcx
+ %endif
+    push    0
+    push    rbp
+    mov     rbp, rsp
+    pushf
+
+    ;/* Manual save and restore:
+    ; * - General purpose registers except RIP, RSP, RAX
+    ; *
+    ; * Trashed:
+    ; * - CR2 (we don't care)
+    ; * - LDTR (reset to 0)
+    ; * - DRx (presumably not changed at all)
+    ; * - DR7 (reset to 0x400)
+    ; */
+
+    ;/* Save all general purpose host registers. */
+    MYPUSHAD
+
+    ;/* Save the Guest CPU context pointer. */
+    mov     rsi, [rbp + xS*2 + RTHCPHYS_CB*2]   ; pCtx
+    push    rsi                     ; push for saving the state at the end
+
+    ; save host fs, gs, sysenter msr etc
+    mov     rax, [rbp + xS*2]       ; pVMCBHostPhys (64 bits physical address; x86: take low dword only)
+    push    rax                     ; save for the vmload after vmrun
+    vmsave
+
+    ; setup eax for VMLOAD
+    mov     rax, [rbp + xS*2 + RTHCPHYS_CB]     ; pVMCBPhys (64 bits physical address; take low dword only)
+
+    ;/* Restore Guest's general purpose registers. */
+    ;/* RAX is loaded from the VMCB by VMRUN */
+    mov     rbx, qword [xSI + CPUMCTX.ebx]
+    mov     rcx, qword [xSI + CPUMCTX.ecx]
+    mov     rdx, qword [xSI + CPUMCTX.edx]
+    mov     rdi, qword [xSI + CPUMCTX.edi]
+    mov     rbp, qword [xSI + CPUMCTX.ebp]
+    mov     r8,  qword [xSI + CPUMCTX.r8]
+    mov     r9,  qword [xSI + CPUMCTX.r9]
+    mov     r10, qword [xSI + CPUMCTX.r10]
+    mov     r11, qword [xSI + CPUMCTX.r11]
+    mov     r12, qword [xSI + CPUMCTX.r12]
+    mov     r13, qword [xSI + CPUMCTX.r13]
+    mov     r14, qword [xSI + CPUMCTX.r14]
+    mov     r15, qword [xSI + CPUMCTX.r15]
+    mov     rsi, qword [xSI + CPUMCTX.esi]
+
+    ; Clear the global interrupt flag & execute sti to make sure external interrupts cause a world switch
+    clgi
+    sti
+
+    ; load guest fs, gs, sysenter msr etc
+    vmload
+    ; run the VM
+    vmrun
+
+    ;/* RAX is in the VMCB already; we can use it here. */
+
+    ; save guest fs, gs, sysenter msr etc
+    vmsave
+
+    ; load host fs, gs, sysenter msr etc
+    pop     rax                     ; pushed above
+    vmload
+
+    ; Set the global interrupt flag again, but execute cli to make sure IF=0.
+    cli
+    stgi
+
+    pop     rax                     ; pCtx
+
+    mov     qword [rax + CPUMCTX.ebx], rbx
+    mov     qword [rax + CPUMCTX.ecx], rcx
+    mov     qword [rax + CPUMCTX.edx], rdx
+    mov     qword [rax + CPUMCTX.esi], rsi
+    mov     qword [rax + CPUMCTX.edi], rdi
+    mov     qword [rax + CPUMCTX.ebp], rbp
+    mov     qword [rax + CPUMCTX.r8],  r8
+    mov     qword [rax + CPUMCTX.r9],  r9
+    mov     qword [rax + CPUMCTX.r10], r10
+    mov     qword [rax + CPUMCTX.r11], r11
+    mov     qword [rax + CPUMCTX.r12], r12
+    mov     qword [rax + CPUMCTX.r13], r13
+    mov     qword [rax + CPUMCTX.r14], r14
+    mov     qword [rax + CPUMCTX.r15], r15
+
+    ; Restore general purpose registers
+    MYPOPAD
+
+    mov     eax, VINF_SUCCESS
+
+    popf
+    pop     rbp
+    add     rsp, 4*xS
+    ret
+ENDPROC MY_NAME(SVMR0VMRun64)
+%endif ; RT_ARCH_AMD64
+
Index: trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp	(revision 43379)
+++ 	(revision )
@@ -1,2057 +1,0 @@
-/* $Id$ */
-/** @file
- * Hardware Assisted Virtualization Manager (HM) - Host Context Ring-0.
- */
-
-/*
- * 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;
- * 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.
- */
-
-
-/*******************************************************************************
-*   Header Files                                                               *
-*******************************************************************************/
-#define LOG_GROUP LOG_GROUP_HWACCM
-#include <VBox/vmm/hwaccm.h>
-#include <VBox/vmm/pgm.h>
-#include "HWACCMInternal.h"
-#include <VBox/vmm/vm.h>
-#include <VBox/vmm/hwacc_vmx.h>
-#include <VBox/vmm/hwacc_svm.h>
-#include <VBox/err.h>
-#include <VBox/log.h>
-#include <iprt/assert.h>
-#include <iprt/asm.h>
-#include <iprt/asm-amd64-x86.h>
-#include <iprt/cpuset.h>
-#include <iprt/mem.h>
-#include <iprt/memobj.h>
-#include <iprt/once.h>
-#include <iprt/param.h>
-#include <iprt/power.h>
-#include <iprt/string.h>
-#include <iprt/thread.h>
-#include <iprt/x86.h>
-#include "HWVMXR0.h"
-#include "HWSVMR0.h"
-
-
-/*******************************************************************************
-*   Internal Functions                                                         *
-*******************************************************************************/
-static DECLCALLBACK(void) hmR0EnableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2);
-static DECLCALLBACK(void) hmR0DisableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2);
-static DECLCALLBACK(void) hmR0InitIntelCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2);
-static DECLCALLBACK(void) hmR0InitAmdCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2);
-static DECLCALLBACK(void) hmR0PowerCallback(RTPOWEREVENT enmEvent, void *pvUser);
-static DECLCALLBACK(void) hmR0MpEventCallback(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvData);
-
-
-/*******************************************************************************
-*   Structures and Typedefs                                                    *
-*******************************************************************************/
-/**
- * This is used to manage the status code of a RTMpOnAll in HM.
- */
-typedef struct HMR0FIRSTRC
-{
-    /** The status code. */
-    int32_t volatile    rc;
-    /** The ID of the CPU reporting the first failure. */
-    RTCPUID volatile    idCpu;
-} HMR0FIRSTRC;
-/** Pointer to a first return code structure. */
-typedef HMR0FIRSTRC *PHMR0FIRSTRC;
-
-
-/*******************************************************************************
-*   Global Variables                                                           *
-*******************************************************************************/
-/**
- * Global data.
- */
-static struct
-{
-    /** Per CPU globals. */
-    HMGLOBLCPUINFO                  aCpuInfo[RTCPUSET_MAX_CPUS];
-
-    /** @name Ring-0 method table for AMD-V and VT-x specific operations.
-     * @{ */
-    DECLR0CALLBACKMEMBER(int, pfnEnterSession,(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu));
-    DECLR0CALLBACKMEMBER(int, pfnLeaveSession,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx));
-    DECLR0CALLBACKMEMBER(int, pfnSaveHostState,(PVM pVM, PVMCPU pVCpu));
-    DECLR0CALLBACKMEMBER(int, pfnLoadGuestState,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx));
-    DECLR0CALLBACKMEMBER(int, pfnRunGuestCode,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx));
-    DECLR0CALLBACKMEMBER(int, pfnEnableCpu,(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage,
-                                            bool fEnabledByHost));
-    DECLR0CALLBACKMEMBER(int, pfnDisableCpu,(PHMGLOBLCPUINFO pCpu, void *pvCpuPage, RTHCPHYS HCPhysCpuPage));
-    DECLR0CALLBACKMEMBER(int, pfnInitVM,(PVM pVM));
-    DECLR0CALLBACKMEMBER(int, pfnTermVM,(PVM pVM));
-    DECLR0CALLBACKMEMBER(int, pfnSetupVM,(PVM pVM));
-    /** @} */
-
-    /** Maximum ASID allowed. */
-    uint32_t                        uMaxASID;
-
-    /** VT-x data. */
-    struct
-    {
-        /** Set to by us to indicate VMX is supported by the CPU. */
-        bool                        fSupported;
-        /** Whether we're using SUPR0EnableVTx or not. */
-        bool                        fUsingSUPR0EnableVTx;
-        /** Whether we're using the preemption timer or not. */
-        bool                        fUsePreemptTimer;
-        /** The shift mask employed by the VMX-Preemption timer. */
-        uint8_t                     cPreemptTimerShift;
-
-        /** Host CR4 value (set by ring-0 VMX init) */
-        uint64_t                    hostCR4;
-
-        /** Host EFER value (set by ring-0 VMX init) */
-        uint64_t                    hostEFER;
-
-        /** VMX MSR values */
-        struct
-        {
-            uint64_t                feature_ctrl;
-            uint64_t                vmx_basic_info;
-            VMX_CAPABILITY          vmx_pin_ctls;
-            VMX_CAPABILITY          vmx_proc_ctls;
-            VMX_CAPABILITY          vmx_proc_ctls2;
-            VMX_CAPABILITY          vmx_exit;
-            VMX_CAPABILITY          vmx_entry;
-            uint64_t                vmx_misc;
-            uint64_t                vmx_cr0_fixed0;
-            uint64_t                vmx_cr0_fixed1;
-            uint64_t                vmx_cr4_fixed0;
-            uint64_t                vmx_cr4_fixed1;
-            uint64_t                vmx_vmcs_enum;
-            uint64_t                vmx_eptcaps;
-        } msr;
-        /* Last instruction error */
-        uint32_t                    ulLastInstrError;
-    } vmx;
-
-    /** AMD-V information. */
-    struct
-    {
-        /* HWCR msr (for diagnostics) */
-        uint64_t                    msrHWCR;
-
-        /** SVM revision. */
-        uint32_t                    u32Rev;
-
-        /** SVM feature bits from cpuid 0x8000000a */
-        uint32_t                    u32Features;
-
-        /** Set by us to indicate SVM is supported by the CPU. */
-        bool                        fSupported;
-    } svm;
-    /** Saved error from detection */
-    int32_t         lLastError;
-
-    struct
-    {
-        uint32_t                    u32AMDFeatureECX;
-        uint32_t                    u32AMDFeatureEDX;
-    } cpuid;
-
-    /** If set, VT-x/AMD-V is enabled globally at init time, otherwise it's
-     * enabled and disabled each time it's used to execute guest code. */
-    bool                            fGlobalInit;
-    /** Indicates whether the host is suspending or not.  We'll refuse a few
-     *  actions when the host is being suspended to speed up the suspending and
-     *  avoid trouble. */
-    volatile        bool            fSuspended;
-
-    /** Whether we've already initialized all CPUs.
-     * @remarks We could check the EnableAllCpusOnce state, but this is
-     *          simpler and hopefully easier to understand. */
-    bool                            fEnabled;
-    /** Serialize initialization in HWACCMR0EnableAllCpus. */
-    RTONCE                          EnableAllCpusOnce;
-} g_HvmR0;
-
-
-
-/**
- * Initializes a first return code structure.
- *
- * @param   pFirstRc            The structure to init.
- */
-static void hmR0FirstRcInit(PHMR0FIRSTRC pFirstRc)
-{
-    pFirstRc->rc    = VINF_SUCCESS;
-    pFirstRc->idCpu = NIL_RTCPUID;
-}
-
-
-/**
- * Try se the status code (success ignored).
- *
- * @param   pFirstRc            The first return code structure.
- * @param   rc                  The status code.
- */
-static void     hmR0FirstRcSetStatus(PHMR0FIRSTRC pFirstRc, int rc)
-{
-    if (   RT_FAILURE(rc)
-        && ASMAtomicCmpXchgS32(&pFirstRc->rc, rc, VINF_SUCCESS))
-        pFirstRc->idCpu = RTMpCpuId();
-}
-
-
-/**
- * Get the status code of a first return code structure.
- *
- * @returns The status code; VINF_SUCCESS or error status, no informational or
- *          warning errors.
- * @param   pFirstRc            The first return code structure.
- */
-static int hmR0FirstRcGetStatus(PHMR0FIRSTRC pFirstRc)
-{
-    return pFirstRc->rc;
-}
-
-
-#ifdef VBOX_STRICT
-/**
- * Get the CPU ID on which the failure status code was reported.
- *
- * @returns The CPU ID, NIL_RTCPUID if no failure was reported.
- * @param   pFirstRc            The first return code structure.
- */
-static RTCPUID hmR0FirstRcGetCpuId(PHMR0FIRSTRC pFirstRc)
-{
-    return pFirstRc->idCpu;
-}
-#endif /* VBOX_STRICT */
-
-
-/** @name Dummy callback handlers.
- * @{ */
-
-static DECLCALLBACK(int) hmR0DummyEnter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu)
-{
-    NOREF(pVM); NOREF(pVCpu); NOREF(pCpu);
-    return VINF_SUCCESS;
-}
-
-static DECLCALLBACK(int) hmR0DummyLeave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
-    NOREF(pVM); NOREF(pVCpu); NOREF(pCtx);
-    return VINF_SUCCESS;
-}
-
-static DECLCALLBACK(int) hmR0DummyEnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage,
-                                            bool fEnabledBySystem)
-{
-    NOREF(pCpu); NOREF(pVM); NOREF(pvCpuPage); NOREF(HCPhysCpuPage); NOREF(fEnabledBySystem);
-    return VINF_SUCCESS;
-}
-
-static DECLCALLBACK(int) hmR0DummyDisableCpu(PHMGLOBLCPUINFO pCpu, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
-{
-    NOREF(pCpu);  NOREF(pvCpuPage); NOREF(HCPhysCpuPage);
-    return VINF_SUCCESS;
-}
-
-static DECLCALLBACK(int) hmR0DummyInitVM(PVM pVM)
-{
-    NOREF(pVM);
-    return VINF_SUCCESS;
-}
-
-static DECLCALLBACK(int) hmR0DummyTermVM(PVM pVM)
-{
-    NOREF(pVM);
-    return VINF_SUCCESS;
-}
-
-static DECLCALLBACK(int) hmR0DummySetupVM(PVM pVM)
-{
-    NOREF(pVM);
-    return VINF_SUCCESS;
-}
-
-static DECLCALLBACK(int) hmR0DummyRunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
-    NOREF(pVM); NOREF(pVCpu); NOREF(pCtx);
-    return VINF_SUCCESS;
-}
-
-static DECLCALLBACK(int) hmR0DummySaveHostState(PVM pVM, PVMCPU pVCpu)
-{
-    NOREF(pVM); NOREF(pVCpu);
-    return VINF_SUCCESS;
-}
-
-static DECLCALLBACK(int) hmR0DummyLoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
-    NOREF(pVM); NOREF(pVCpu); NOREF(pCtx);
-    return VINF_SUCCESS;
-}
-
-/** @} */
-
-
-/**
- * Checks if the CPU is subject to the "VMX-Preemption Timer Does Not Count
- * Down at the Rate Specified" erratum.
- *
- * Errata names and related steppings:
- *      - BA86   - D0.
- *      - AAX65  - C2.
- *      - AAU65  - C2, K0.
- *      - AAO95  - B1.
- *      - AAT59  - C2.
- *      - AAK139 - D0.
- *      - AAM126 - C0, C1, D0.
- *      - AAN92  - B1.
- *      - AAJ124 - C0, D0.
- *
- *      - AAP86  - B1.
- *
- * Steppings: B1, C0, C1, C2, D0, K0.
- *
- * @returns true if subject to it, false if not.
- */
-static bool hmR0InitIntelIsSubjectToVmxPreemptionTimerErratum(void)
-{
-    uint32_t u = ASMCpuId_EAX(1);
-    u &= ~(RT_BIT_32(14) | RT_BIT_32(15) | RT_BIT_32(28) | RT_BIT_32(29) | RT_BIT_32(30) | RT_BIT_32(31));
-    if (   u == UINT32_C(0x000206E6) /* 323344.pdf - BA86   - D0 - Intel Xeon Processor 7500 Series */
-        || u == UINT32_C(0x00020652) /* 323056.pdf - AAX65  - C2 - Intel Xeon Processor L3406 */
-        || u == UINT32_C(0x00020652) /* 322814.pdf - AAT59  - C2 - Intel CoreTM i7-600, i5-500, i5-400 and i3-300 Mobile Processor Series */
-        || u == UINT32_C(0x00020652) /* 322911.pdf - AAU65  - C2 - Intel CoreTM i5-600, i3-500 Desktop Processor Series and Intel Pentium Processor G6950 */
-        || u == UINT32_C(0x00020655) /* 322911.pdf - AAU65  - K0 - Intel CoreTM i5-600, i3-500 Desktop Processor Series and Intel Pentium Processor G6950 */
-        || u == UINT32_C(0x000106E5) /* 322373.pdf - AAO95  - B1 - Intel Xeon Processor 3400 Series */
-        || u == UINT32_C(0x000106E5) /* 322166.pdf - AAN92  - B1 - Intel CoreTM i7-800 and i5-700 Desktop Processor Series */
-        || u == UINT32_C(0x000106E5) /* 320767.pdf - AAP86  - B1 - Intel Core i7-900 Mobile Processor Extreme Edition Series, Intel Core i7-800 and i7-700 Mobile Processor Series */
-        || u == UINT32_C(0x000106A0) /*?321333.pdf - AAM126 - C0 - Intel Xeon Processor 3500 Series Specification */
-        || u == UINT32_C(0x000106A1) /*?321333.pdf - AAM126 - C1 - Intel Xeon Processor 3500 Series Specification */
-        || u == UINT32_C(0x000106A4) /* 320836.pdf - AAJ124 - C0 - Intel Core i7-900 Desktop Processor Extreme Edition Series and Intel Core i7-900 Desktop Processor Series */
-        || u == UINT32_C(0x000106A5) /* 321333.pdf - AAM126 - D0 - Intel Xeon Processor 3500 Series Specification */
-        || u == UINT32_C(0x000106A5) /* 321324.pdf - AAK139 - D0 - Intel Xeon Processor 5500 Series Specification */
-        || u == UINT32_C(0x000106A5) /* 320836.pdf - AAJ124 - D0 - Intel Core i7-900 Desktop Processor Extreme Edition Series and Intel Core i7-900 Desktop Processor Series */
-        )
-        return true;
-    return false;
-}
-
-
-/**
- * Intel specific initialization code.
- *
- * @returns VBox status code (will only fail if out of memory).
- */
-static int hmR0InitIntel(uint32_t u32FeaturesECX, uint32_t u32FeaturesEDX)
-{
-    /*
-     * Check that all the required VT-x features are present.
-     * We also assume all VT-x-enabled CPUs support fxsave/fxrstor.
-     */
-    if (    (u32FeaturesECX & X86_CPUID_FEATURE_ECX_VMX)
-         && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
-         && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
-       )
-    {
-        /** @todo move this into a separate function. */
-        g_HvmR0.vmx.msr.feature_ctrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
-
-        /*
-         * First try use native kernel API for controlling VT-x.
-         * (This is only supported by some Mac OS X kernels atm.)
-         */
-        int rc = g_HvmR0.lLastError = SUPR0EnableVTx(true /* fEnable */);
-        g_HvmR0.vmx.fUsingSUPR0EnableVTx = rc != VERR_NOT_SUPPORTED;
-        if (g_HvmR0.vmx.fUsingSUPR0EnableVTx)
-        {
-            AssertLogRelMsg(rc == VINF_SUCCESS || rc == VERR_VMX_IN_VMX_ROOT_MODE || rc == VERR_VMX_NO_VMX, ("%Rrc\n", rc));
-            if (RT_SUCCESS(rc))
-            {
-                g_HvmR0.vmx.fSupported = true;
-                rc = SUPR0EnableVTx(false /* fEnable */);
-                AssertLogRelRC(rc);
-            }
-        }
-        else
-        {
-            /* We need to check if VT-x has been properly initialized on all
-               CPUs. Some BIOSes do a lousy job. */
-            HMR0FIRSTRC FirstRc;
-            hmR0FirstRcInit(&FirstRc);
-            g_HvmR0.lLastError = RTMpOnAll(hmR0InitIntelCpu, &FirstRc, NULL);
-            if (RT_SUCCESS(g_HvmR0.lLastError))
-                g_HvmR0.lLastError = hmR0FirstRcGetStatus(&FirstRc);
-        }
-        if (RT_SUCCESS(g_HvmR0.lLastError))
-        {
-            /* Reread in case we've changed it. */
-            g_HvmR0.vmx.msr.feature_ctrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
-
-            if (   (g_HvmR0.vmx.msr.feature_ctrl & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
-                ==                                 (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
-            {
-                /*
-                 * Read all relevant MSR.
-                 */
-                g_HvmR0.vmx.msr.vmx_basic_info  = ASMRdMsr(MSR_IA32_VMX_BASIC_INFO);
-                g_HvmR0.vmx.msr.vmx_pin_ctls.u  = ASMRdMsr(MSR_IA32_VMX_PINBASED_CTLS);
-                g_HvmR0.vmx.msr.vmx_proc_ctls.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS);
-                g_HvmR0.vmx.msr.vmx_exit.u      = ASMRdMsr(MSR_IA32_VMX_EXIT_CTLS);
-                g_HvmR0.vmx.msr.vmx_entry.u     = ASMRdMsr(MSR_IA32_VMX_ENTRY_CTLS);
-                g_HvmR0.vmx.msr.vmx_misc        = ASMRdMsr(MSR_IA32_VMX_MISC);
-                g_HvmR0.vmx.msr.vmx_cr0_fixed0  = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED0);
-                g_HvmR0.vmx.msr.vmx_cr0_fixed1  = ASMRdMsr(MSR_IA32_VMX_CR0_FIXED1);
-                g_HvmR0.vmx.msr.vmx_cr4_fixed0  = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED0);
-                g_HvmR0.vmx.msr.vmx_cr4_fixed1  = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED1);
-                g_HvmR0.vmx.msr.vmx_vmcs_enum   = ASMRdMsr(MSR_IA32_VMX_VMCS_ENUM);
-                g_HvmR0.vmx.hostCR4             = ASMGetCR4();
-                g_HvmR0.vmx.hostEFER            = ASMRdMsr(MSR_K6_EFER);
-                /* VPID 16 bits ASID. */
-                g_HvmR0.uMaxASID                = 0x10000; /* exclusive */
-
-                if (g_HvmR0.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
-                {
-                    g_HvmR0.vmx.msr.vmx_proc_ctls2.u = ASMRdMsr(MSR_IA32_VMX_PROCBASED_CTLS2);
-                    if (  g_HvmR0.vmx.msr.vmx_proc_ctls2.n.allowed1
-                        & (VMX_VMCS_CTRL_PROC_EXEC2_EPT | VMX_VMCS_CTRL_PROC_EXEC2_VPID))
-                        g_HvmR0.vmx.msr.vmx_eptcaps = ASMRdMsr(MSR_IA32_VMX_EPT_CAPS);
-                }
-
-                if (!g_HvmR0.vmx.fUsingSUPR0EnableVTx)
-                {
-                    /*
-                     * Enter root mode
-                     */
-                    RTR0MEMOBJ hScatchMemObj;
-                    rc = RTR0MemObjAllocCont(&hScatchMemObj, PAGE_SIZE, true /*fExecutable*/);
-                    if (RT_FAILURE(rc))
-                    {
-                        LogRel(("hmR0InitIntel: RTR0MemObjAllocCont(,PAGE_SIZE,true) -> %Rrc\n", rc));
-                        return rc;
-                    }
-
-                    void      *pvScatchPage      = RTR0MemObjAddress(hScatchMemObj);
-                    RTHCPHYS   HCPhysScratchPage = RTR0MemObjGetPagePhysAddr(hScatchMemObj, 0);
-                    ASMMemZeroPage(pvScatchPage);
-
-                    /* Set revision dword at the beginning of the structure. */
-                    *(uint32_t *)pvScatchPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(g_HvmR0.vmx.msr.vmx_basic_info);
-
-                    /* Make sure we don't get rescheduled to another cpu during this probe. */
-                    RTCCUINTREG fFlags = ASMIntDisableFlags();
-
-                    /*
-                     * Check CR4.VMXE
-                     */
-                    g_HvmR0.vmx.hostCR4 = ASMGetCR4();
-                    if (!(g_HvmR0.vmx.hostCR4 & X86_CR4_VMXE))
-                    {
-                        /* In theory this bit could be cleared behind our back.  Which would cause
-                           #UD faults when we try to execute the VMX instructions... */
-                        ASMSetCR4(g_HvmR0.vmx.hostCR4 | X86_CR4_VMXE);
-                    }
-
-                    /* Enter VMX Root Mode */
-                    rc = VMXEnable(HCPhysScratchPage);
-                    if (RT_SUCCESS(rc))
-                    {
-                        g_HvmR0.vmx.fSupported = true;
-                        VMXDisable();
-                    }
-                    else
-                    {
-                        /*
-                         * KVM leaves the CPU in VMX root mode. Not only is  this not allowed,
-                         * it will crash the host when we enter raw mode, because:
-                         *
-                         *   (a) clearing X86_CR4_VMXE in CR4 causes a #GP (we no longer modify
-                         *       this bit), and
-                         *   (b) turning off paging causes a #GP  (unavoidable when switching
-                         *       from long to 32 bits mode or 32 bits to PAE).
-                         *
-                         * They should fix their code, but until they do we simply refuse to run.
-                         */
-                        g_HvmR0.lLastError = rc == VERR_VMX_GENERIC ? VERR_VMX_IN_VMX_ROOT_MODE : rc;
-                    }
-
-                    /* Restore CR4 again; don't leave the X86_CR4_VMXE flag set
-                       if it wasn't so before (some software could incorrectly
-                       think it's in VMX mode). */
-                    ASMSetCR4(g_HvmR0.vmx.hostCR4);
-                    ASMSetFlags(fFlags);
-
-                    RTR0MemObjFree(hScatchMemObj, false);
-                }
-            }
-            else
-            {
-                AssertFailed(); /* can't hit this case anymore */
-                g_HvmR0.lLastError = VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR;
-            }
-
-            if (g_HvmR0.vmx.fSupported)
-            {
-                /*
-                 * Install the VT-x methods.
-                 */
-                g_HvmR0.pfnEnterSession     = VMXR0Enter;
-                g_HvmR0.pfnLeaveSession     = VMXR0Leave;
-                g_HvmR0.pfnSaveHostState    = VMXR0SaveHostState;
-                g_HvmR0.pfnLoadGuestState   = VMXR0LoadGuestState;
-                g_HvmR0.pfnRunGuestCode     = VMXR0RunGuestCode;
-                g_HvmR0.pfnEnableCpu        = VMXR0EnableCpu;
-                g_HvmR0.pfnDisableCpu       = VMXR0DisableCpu;
-                g_HvmR0.pfnInitVM           = VMXR0InitVM;
-                g_HvmR0.pfnTermVM           = VMXR0TermVM;
-                g_HvmR0.pfnSetupVM          = VMXR0SetupVM;
-
-                /*
-                 * Check for the VMX-Preemption Timer and adjust for the * "VMX-Preemption
-                 * Timer Does Not Count Down at the Rate Specified" erratum.
-                 */
-                if (  g_HvmR0.vmx.msr.vmx_pin_ctls.n.allowed1
-                    & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
-                {
-                    g_HvmR0.vmx.fUsePreemptTimer   = true;
-                    g_HvmR0.vmx.cPreemptTimerShift = MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(g_HvmR0.vmx.msr.vmx_misc);
-                    if (hmR0InitIntelIsSubjectToVmxPreemptionTimerErratum())
-                        g_HvmR0.vmx.cPreemptTimerShift = 0; /* This is about right most of the time here. */
-                }
-            }
-        }
-#ifdef LOG_ENABLED
-        else
-            SUPR0Printf("hmR0InitIntelCpu failed with rc=%d\n", g_HvmR0.lLastError);
-#endif
-    }
-    else
-        g_HvmR0.lLastError = VERR_VMX_NO_VMX;
-    return VINF_SUCCESS;
-}
-
-
-/**
- * AMD-specific initialization code.
- */
-static void hmR0InitAmd(uint32_t u32FeaturesEDX)
-{
-    /*
-     * Read all SVM MSRs if SVM is available. (same goes for RDMSR/WRMSR)
-     * We also assume all SVM-enabled CPUs support fxsave/fxrstor.
-     */
-    if (   (g_HvmR0.cpuid.u32AMDFeatureECX & X86_CPUID_AMD_FEATURE_ECX_SVM)
-        && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_MSR)
-        && (u32FeaturesEDX & X86_CPUID_FEATURE_EDX_FXSR)
-       )
-    {
-        g_HvmR0.pfnEnterSession     = SVMR0Enter;
-        g_HvmR0.pfnLeaveSession     = SVMR0Leave;
-        g_HvmR0.pfnSaveHostState    = SVMR0SaveHostState;
-        g_HvmR0.pfnLoadGuestState   = SVMR0LoadGuestState;
-        g_HvmR0.pfnRunGuestCode     = SVMR0RunGuestCode;
-        g_HvmR0.pfnEnableCpu        = SVMR0EnableCpu;
-        g_HvmR0.pfnDisableCpu       = SVMR0DisableCpu;
-        g_HvmR0.pfnInitVM           = SVMR0InitVM;
-        g_HvmR0.pfnTermVM           = SVMR0TermVM;
-        g_HvmR0.pfnSetupVM          = SVMR0SetupVM;
-
-        /* Query AMD features. */
-        uint32_t u32Dummy;
-        ASMCpuId(0x8000000A, &g_HvmR0.svm.u32Rev, &g_HvmR0.uMaxASID,
-                 &u32Dummy, &g_HvmR0.svm.u32Features);
-
-        /*
-         * We need to check if AMD-V has been properly initialized on all CPUs.
-         * Some BIOSes might do a poor job.
-         */
-        HMR0FIRSTRC FirstRc;
-        hmR0FirstRcInit(&FirstRc);
-        int rc = RTMpOnAll(hmR0InitAmdCpu, &FirstRc, NULL);
-        AssertRC(rc);
-        if (RT_SUCCESS(rc))
-            rc = hmR0FirstRcGetStatus(&FirstRc);
-#ifndef DEBUG_bird
-        AssertMsg(rc == VINF_SUCCESS || rc == VERR_SVM_IN_USE,
-                  ("hmR0InitAmdCpu failed for cpu %d with rc=%Rrc\n", hmR0FirstRcGetCpuId(&FirstRc), rc));
-#endif
-        if (RT_SUCCESS(rc))
-        {
-            /* Read the HWCR msr for diagnostics. */
-            g_HvmR0.svm.msrHWCR    = ASMRdMsr(MSR_K8_HWCR);
-            g_HvmR0.svm.fSupported = true;
-        }
-        else
-            g_HvmR0.lLastError = rc;
-    }
-    else
-        g_HvmR0.lLastError = VERR_SVM_NO_SVM;
-}
-
-
-/**
- * Does global Ring-0 HM initialization (at module init).
- *
- * @returns VBox status code.
- */
-VMMR0DECL(int) HWACCMR0Init(void)
-{
-    /*
-     * Initialize the globals.
-     */
-    g_HvmR0.fEnabled = false;
-    static RTONCE s_OnceInit = RTONCE_INITIALIZER;
-    g_HvmR0.EnableAllCpusOnce = s_OnceInit;
-    for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
-        g_HvmR0.aCpuInfo[i].hMemObj = NIL_RTR0MEMOBJ;
-
-    /* Fill in all callbacks with placeholders. */
-    g_HvmR0.pfnEnterSession     = hmR0DummyEnter;
-    g_HvmR0.pfnLeaveSession     = hmR0DummyLeave;
-    g_HvmR0.pfnSaveHostState    = hmR0DummySaveHostState;
-    g_HvmR0.pfnLoadGuestState   = hmR0DummyLoadGuestState;
-    g_HvmR0.pfnRunGuestCode     = hmR0DummyRunGuestCode;
-    g_HvmR0.pfnEnableCpu        = hmR0DummyEnableCpu;
-    g_HvmR0.pfnDisableCpu       = hmR0DummyDisableCpu;
-    g_HvmR0.pfnInitVM           = hmR0DummyInitVM;
-    g_HvmR0.pfnTermVM           = hmR0DummyTermVM;
-    g_HvmR0.pfnSetupVM          = hmR0DummySetupVM;
-
-    /* Default is global VT-x/AMD-V init. */
-    g_HvmR0.fGlobalInit         = true;
-
-    /*
-     * Make sure aCpuInfo is big enough for all the CPUs on this system.
-     */
-    if (RTMpGetArraySize() > RT_ELEMENTS(g_HvmR0.aCpuInfo))
-    {
-        LogRel(("HM: Too many real CPUs/cores/threads - %u, max %u\n", RTMpGetArraySize(), RT_ELEMENTS(g_HvmR0.aCpuInfo)));
-        return VERR_TOO_MANY_CPUS;
-    }
-
-    /*
-     * Check for VT-x and AMD-V capabilities.
-     */
-    int rc;
-    if (ASMHasCpuId())
-    {
-        uint32_t u32FeaturesECX, u32FeaturesEDX;
-        uint32_t u32VendorEBX, u32VendorECX, u32VendorEDX;
-        uint32_t u32Dummy;
-
-        /* Standard features. */
-        ASMCpuId(0, &u32Dummy, &u32VendorEBX, &u32VendorECX, &u32VendorEDX);
-        ASMCpuId(1, &u32Dummy, &u32Dummy, &u32FeaturesECX, &u32FeaturesEDX);
-
-        /* Query AMD features. */
-        ASMCpuId(0x80000001, &u32Dummy, &u32Dummy,
-                 &g_HvmR0.cpuid.u32AMDFeatureECX,
-                 &g_HvmR0.cpuid.u32AMDFeatureEDX);
-
-        /* Go to CPU specific initialization code. */
-        if (   (   u32VendorEBX == X86_CPUID_VENDOR_INTEL_EBX
-                && u32VendorECX == X86_CPUID_VENDOR_INTEL_ECX
-                && u32VendorEDX == X86_CPUID_VENDOR_INTEL_EDX)
-            || (   u32VendorEBX == X86_CPUID_VENDOR_VIA_EBX
-                && u32VendorECX == X86_CPUID_VENDOR_VIA_ECX
-                && u32VendorEDX == X86_CPUID_VENDOR_VIA_EDX))
-        {
-            rc = hmR0InitIntel(u32FeaturesECX, u32FeaturesEDX);
-            if (RT_FAILURE(rc))
-                return rc;
-        }
-        else if (   u32VendorEBX == X86_CPUID_VENDOR_AMD_EBX
-                 && u32VendorECX == X86_CPUID_VENDOR_AMD_ECX
-                 && u32VendorEDX == X86_CPUID_VENDOR_AMD_EDX)
-            hmR0InitAmd(u32FeaturesEDX);
-        else
-            g_HvmR0.lLastError = VERR_HWACCM_UNKNOWN_CPU;
-    }
-    else
-        g_HvmR0.lLastError = VERR_HWACCM_NO_CPUID;
-
-    /*
-     * Register notification callbacks that we can use to disable/enable CPUs
-     * when brought offline/online or suspending/resuming.
-     */
-    if (!g_HvmR0.vmx.fUsingSUPR0EnableVTx)
-    {
-        rc = RTMpNotificationRegister(hmR0MpEventCallback, NULL);
-        AssertRC(rc);
-
-        rc = RTPowerNotificationRegister(hmR0PowerCallback, NULL);
-        AssertRC(rc);
-    }
-
-    /* We return success here because module init shall not fail if HM
-       fails to initialize. */
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Does global Ring-0 HM termination (at module termination).
- *
- * @returns VBox status code.
- */
-VMMR0DECL(int) HWACCMR0Term(void)
-{
-    int rc;
-    if (   g_HvmR0.vmx.fSupported
-        && g_HvmR0.vmx.fUsingSUPR0EnableVTx)
-    {
-        /*
-         * Simple if the host OS manages VT-x.
-         */
-        Assert(g_HvmR0.fGlobalInit);
-        rc = SUPR0EnableVTx(false /* fEnable */);
-
-        for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo); iCpu++)
-        {
-            g_HvmR0.aCpuInfo[iCpu].fConfigured = false;
-            Assert(g_HvmR0.aCpuInfo[iCpu].hMemObj == NIL_RTR0MEMOBJ);
-        }
-    }
-    else
-    {
-        Assert(!g_HvmR0.vmx.fUsingSUPR0EnableVTx);
-        if (!g_HvmR0.vmx.fUsingSUPR0EnableVTx)
-        {
-            /* Doesn't really matter if this fails. */
-            rc = RTMpNotificationDeregister(hmR0MpEventCallback, NULL);  AssertRC(rc);
-            rc = RTPowerNotificationDeregister(hmR0PowerCallback, NULL); AssertRC(rc);
-        }
-        else
-            rc = VINF_SUCCESS;
-
-        /*
-         * Disable VT-x/AMD-V on all CPUs if we enabled it before.
-         */
-        if (g_HvmR0.fGlobalInit)
-        {
-            HMR0FIRSTRC FirstRc;
-            hmR0FirstRcInit(&FirstRc);
-            rc = RTMpOnAll(hmR0DisableCpuCallback, NULL, &FirstRc);
-            Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
-            if (RT_SUCCESS(rc))
-            {
-                rc = hmR0FirstRcGetStatus(&FirstRc);
-                AssertMsgRC(rc, ("%u: %Rrc\n", hmR0FirstRcGetCpuId(&FirstRc), rc));
-            }
-        }
-
-        /*
-         * Free the per-cpu pages used for VT-x and AMD-V.
-         */
-        for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
-        {
-            if (g_HvmR0.aCpuInfo[i].hMemObj != NIL_RTR0MEMOBJ)
-            {
-                RTR0MemObjFree(g_HvmR0.aCpuInfo[i].hMemObj, false);
-                g_HvmR0.aCpuInfo[i].hMemObj = NIL_RTR0MEMOBJ;
-            }
-        }
-    }
-    return rc;
-}
-
-
-/**
- * Worker function used by hmR0PowerCallback  and HWACCMR0Init to initalize
- * VT-x on a CPU.
- *
- * @param   idCpu       The identifier for the CPU the function is called on.
- * @param   pvUser1     Pointer to the first RC structure.
- * @param   pvUser2     Ignored.
- */
-static DECLCALLBACK(void) hmR0InitIntelCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
-{
-    PHMR0FIRSTRC pFirstRc = (PHMR0FIRSTRC)pvUser1;
-    Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
-    NOREF(pvUser2);
-
-    /*
-     * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP.
-     * Once the lock bit is set, this MSR can no longer be modified.
-     */
-    uint64_t fFC = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
-    if (   !(fFC    & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
-        || (   (fFC & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
-            == MSR_IA32_FEATURE_CONTROL_VMXON ) /* Some BIOSes forget to set the locked bit. */
-       )
-    {
-        /* MSR is not yet locked; we can change it ourselves here. */
-        ASMWrMsr(MSR_IA32_FEATURE_CONTROL,
-                 g_HvmR0.vmx.msr.feature_ctrl | MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK);
-        fFC = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
-    }
-
-    int rc;
-    if (   (fFC & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
-        == (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
-        rc = VINF_SUCCESS;
-    else
-        rc = VERR_VMX_MSR_LOCKED_OR_DISABLED;
-
-    hmR0FirstRcSetStatus(pFirstRc, rc);
-}
-
-
-/**
- * Worker function used by hmR0PowerCallback  and HWACCMR0Init to initalize
- * VT-x / AMD-V on a CPU.
- *
- * @param   idCpu       The identifier for the CPU the function is called on.
- * @param   pvUser1     Pointer to the first RC structure.
- * @param   pvUser2     Ignored.
- */
-static DECLCALLBACK(void) hmR0InitAmdCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
-{
-    PHMR0FIRSTRC pFirstRc = (PHMR0FIRSTRC)pvUser1;
-    Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
-    NOREF(pvUser2);
-
-    /* Check if SVM is disabled. */
-    int rc;
-    uint64_t fVmCr = ASMRdMsr(MSR_K8_VM_CR);
-    if (!(fVmCr & MSR_K8_VM_CR_SVM_DISABLE))
-    {
-        /* Turn on SVM in the EFER MSR. */
-        uint64_t fEfer = ASMRdMsr(MSR_K6_EFER);
-        if (fEfer & MSR_K6_EFER_SVME)
-            rc = VERR_SVM_IN_USE;
-        else
-        {
-            ASMWrMsr(MSR_K6_EFER, fEfer | MSR_K6_EFER_SVME);
-
-            /* Paranoia. */
-            fEfer = ASMRdMsr(MSR_K6_EFER);
-            if (fEfer & MSR_K6_EFER_SVME)
-            {
-                /* Restore previous value. */
-                ASMWrMsr(MSR_K6_EFER, fEfer & ~MSR_K6_EFER_SVME);
-                rc = VINF_SUCCESS;
-            }
-            else
-                rc = VERR_SVM_ILLEGAL_EFER_MSR;
-        }
-    }
-    else
-        rc = VERR_SVM_DISABLED;
-
-    hmR0FirstRcSetStatus(pFirstRc, rc);
-}
-
-
-
-/**
- * Disable VT-x or AMD-V on the current CPU
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM (can be 0).
- * @param   idCpu       The identifier for the CPU the function is called on.
- */
-static int hmR0EnableCpu(PVM pVM, RTCPUID idCpu)
-{
-    PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[idCpu];
-
-    Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
-    Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
-    Assert(!pCpu->fConfigured);
-    Assert(!g_HvmR0.fGlobalInit || ASMAtomicReadBool(&pCpu->fInUse) == false);
-
-    pCpu->idCpu         = idCpu;
-    pCpu->uCurrentASID  = 0;    /* we'll aways increment this the first time (host uses ASID 0) */
-    /* Do NOT reset cTLBFlushes here, see @bugref{6255}. */
-
-    int rc;
-    if (g_HvmR0.vmx.fSupported && g_HvmR0.vmx.fUsingSUPR0EnableVTx)
-        rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, NULL, NIL_RTHCPHYS, true);
-    else
-    {
-        AssertLogRelMsgReturn(pCpu->hMemObj != NIL_RTR0MEMOBJ, ("hmR0EnableCpu failed idCpu=%u.\n", idCpu), VERR_HM_IPE_1);
-        void    *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
-        RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
-        rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage, false);
-    }
-    AssertRC(rc);
-    if (RT_SUCCESS(rc))
-        pCpu->fConfigured = true;
-
-    return rc;
-}
-
-
-/**
- * Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that
- * is to be called on the target cpus.
- *
- * @param   idCpu       The identifier for the CPU the function is called on.
- * @param   pvUser1     The 1st user argument.
- * @param   pvUser2     The 2nd user argument.
- */
-static DECLCALLBACK(void) hmR0EnableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2)
-{
-    PVM             pVM      = (PVM)pvUser1;     /* can be NULL! */
-    PHMR0FIRSTRC    pFirstRc = (PHMR0FIRSTRC)pvUser2;
-    AssertReturnVoid(g_HvmR0.fGlobalInit);
-    hmR0FirstRcSetStatus(pFirstRc, hmR0EnableCpu(pVM, idCpu));
-}
-
-
-/**
- * RTOnce callback employed by HWACCMR0EnableAllCpus.
- *
- * @returns VBox status code.
- * @param   pvUser          Pointer to the VM.
- * @param   pvUserIgnore    NULL, ignored.
- */
-static DECLCALLBACK(int32_t) hmR0EnableAllCpuOnce(void *pvUser, void *pvUserIgnore)
-{
-    PVM pVM = (PVM)pvUser;
-    NOREF(pvUserIgnore);
-
-    /*
-     * Indicate that we've initialized.
-     *
-     * Note! There is a potential race between this function and the suspend
-     *       notification.  Kind of unlikely though, so ignored for now.
-     */
-    AssertReturn(!g_HvmR0.fEnabled, VERR_HM_ALREADY_ENABLED_IPE);
-    ASMAtomicWriteBool(&g_HvmR0.fEnabled, true);
-
-    /*
-     * The global init variable is set by the first VM.
-     */
-    g_HvmR0.fGlobalInit = pVM->hwaccm.s.fGlobalInit;
-
-    for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
-    {
-        Assert(g_HvmR0.aCpuInfo[i].hMemObj == NIL_RTR0MEMOBJ);
-        g_HvmR0.aCpuInfo[i].fConfigured = false;
-        g_HvmR0.aCpuInfo[i].cTLBFlushes = 0;
-    }
-
-    int rc;
-    if (   g_HvmR0.vmx.fSupported
-        && g_HvmR0.vmx.fUsingSUPR0EnableVTx)
-    {
-        /*
-         * Global VT-x initialization API (only darwin for now).
-         */
-        rc = SUPR0EnableVTx(true /* fEnable */);
-        if (RT_SUCCESS(rc))
-            /* If the host provides a VT-x init API, then we'll rely on that for global init. */
-            g_HvmR0.fGlobalInit = pVM->hwaccm.s.fGlobalInit = true;
-        else
-            AssertMsgFailed(("hmR0EnableAllCpuOnce/SUPR0EnableVTx: rc=%Rrc\n", rc));
-    }
-    else
-    {
-        /*
-         * We're doing the job ourselves.
-         */
-        /* Allocate one page per cpu for the global vt-x and amd-v pages */
-        for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
-        {
-            Assert(g_HvmR0.aCpuInfo[i].hMemObj == NIL_RTR0MEMOBJ);
-
-            if (RTMpIsCpuPossible(RTMpCpuIdFromSetIndex(i)))
-            {
-                rc = RTR0MemObjAllocCont(&g_HvmR0.aCpuInfo[i].hMemObj, PAGE_SIZE, true /* executable R0 mapping */);
-                AssertLogRelRCReturn(rc, rc);
-
-                void *pvR0 = RTR0MemObjAddress(g_HvmR0.aCpuInfo[i].hMemObj); Assert(pvR0);
-                ASMMemZeroPage(pvR0);
-            }
-        }
-
-        rc = VINF_SUCCESS;
-    }
-
-    if (RT_SUCCESS(rc) && g_HvmR0.fGlobalInit)
-    {
-        /* First time, so initialize each cpu/core. */
-        HMR0FIRSTRC FirstRc;
-        hmR0FirstRcInit(&FirstRc);
-        rc = RTMpOnAll(hmR0EnableCpuCallback, (void *)pVM, &FirstRc);
-        if (RT_SUCCESS(rc))
-            rc = hmR0FirstRcGetStatus(&FirstRc);
-        AssertMsgRC(rc, ("hmR0EnableAllCpuOnce failed for cpu %d with rc=%d\n", hmR0FirstRcGetCpuId(&FirstRc), rc));
-    }
-
-    return rc;
-}
-
-
-/**
- * Sets up HWACCM on all cpus.
- *
- * @returns VBox status code.
- * @param   pVM                 Pointer to the VM.
- */
-VMMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM)
-{
-    /* Make sure we don't touch hwaccm after we've disabled hwaccm in
-       preparation of a suspend. */
-    if (ASMAtomicReadBool(&g_HvmR0.fSuspended))
-        return VERR_HWACCM_SUSPEND_PENDING;
-
-    return RTOnce(&g_HvmR0.EnableAllCpusOnce, hmR0EnableAllCpuOnce, pVM, NULL);
-}
-
-
-/**
- * Disable VT-x or AMD-V on the current CPU.
- *
- * @returns VBox status code.
- * @param   idCpu       The identifier for the CPU the function is called on.
- */
-static int hmR0DisableCpu(RTCPUID idCpu)
-{
-    PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[idCpu];
-
-    Assert(!g_HvmR0.vmx.fSupported || !g_HvmR0.vmx.fUsingSUPR0EnableVTx);
-    Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
-    Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
-    Assert(!g_HvmR0.fGlobalInit || ASMAtomicReadBool(&pCpu->fInUse) == false);
-    Assert(!pCpu->fConfigured || pCpu->hMemObj != NIL_RTR0MEMOBJ);
-
-    if (pCpu->hMemObj == NIL_RTR0MEMOBJ)
-        return pCpu->fConfigured ? VERR_NO_MEMORY : VINF_SUCCESS /* not initialized. */;
-
-    int rc;
-    if (pCpu->fConfigured)
-    {
-        void    *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
-        RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
-        if (idCpu == RTMpCpuId())
-        {
-            rc = g_HvmR0.pfnDisableCpu(pCpu, pvCpuPage, HCPhysCpuPage);
-            AssertRC(rc);
-        }
-        else
-        {
-            pCpu->fIgnoreAMDVInUseError = true;
-            rc = VINF_SUCCESS;
-        }
-
-        pCpu->fConfigured = false;
-    }
-    else
-        rc = VINF_SUCCESS; /* nothing to do */
-
-    pCpu->uCurrentASID = 0;
-    return rc;
-}
-
-
-/**
- * Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that
- * is to be called on the target cpus.
- *
- * @param   idCpu       The identifier for the CPU the function is called on.
- * @param   pvUser1     The 1st user argument.
- * @param   pvUser2     The 2nd user argument.
- */
-static DECLCALLBACK(void) hmR0DisableCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2)
-{
-    PHMR0FIRSTRC pFirstRc = (PHMR0FIRSTRC)pvUser2; NOREF(pvUser1);
-    AssertReturnVoid(g_HvmR0.fGlobalInit);
-    hmR0FirstRcSetStatus(pFirstRc, hmR0DisableCpu(idCpu));
-}
-
-
-/**
- * Callback function invoked when a cpu goes online or offline.
- *
- * @param   enmEvent            The Mp event.
- * @param   idCpu               The identifier for the CPU the function is called on.
- * @param   pvData              Opaque data (PVM pointer).
- */
-static DECLCALLBACK(void) hmR0MpEventCallback(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvData)
-{
-    NOREF(pvData);
-
-    /*
-     * We only care about uninitializing a CPU that is going offline. When a
-     * CPU comes online, the initialization is done lazily in HWACCMR0Enter().
-     */
-    Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
-    switch (enmEvent)
-    {
-        case RTMPEVENT_OFFLINE:
-        {
-            int rc = hmR0DisableCpu(idCpu);
-            AssertRC(rc);
-            break;
-        }
-
-        default:
-            break;
-    }
-}
-
-
-/**
- * Called whenever a system power state change occurs.
- *
- * @param   enmEvent        The Power event.
- * @param   pvUser          User argument.
- */
-static DECLCALLBACK(void) hmR0PowerCallback(RTPOWEREVENT enmEvent, void *pvUser)
-{
-    NOREF(pvUser);
-    Assert(!g_HvmR0.vmx.fSupported || !g_HvmR0.vmx.fUsingSUPR0EnableVTx);
-
-#ifdef LOG_ENABLED
-    if (enmEvent == RTPOWEREVENT_SUSPEND)
-        SUPR0Printf("hmR0PowerCallback RTPOWEREVENT_SUSPEND\n");
-    else
-        SUPR0Printf("hmR0PowerCallback RTPOWEREVENT_RESUME\n");
-#endif
-
-    if (enmEvent == RTPOWEREVENT_SUSPEND)
-        ASMAtomicWriteBool(&g_HvmR0.fSuspended, true);
-
-    if (g_HvmR0.fEnabled)
-    {
-        int         rc;
-        HMR0FIRSTRC FirstRc;
-        hmR0FirstRcInit(&FirstRc);
-
-        if (enmEvent == RTPOWEREVENT_SUSPEND)
-        {
-            if (g_HvmR0.fGlobalInit)
-            {
-                /* Turn off VT-x or AMD-V on all CPUs. */
-                rc = RTMpOnAll(hmR0DisableCpuCallback, NULL, &FirstRc);
-                Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
-            }
-            /* else nothing to do here for the local init case */
-        }
-        else
-        {
-            /* Reinit the CPUs from scratch as the suspend state might have
-               messed with the MSRs. (lousy BIOSes as usual) */
-            if (g_HvmR0.vmx.fSupported)
-                rc = RTMpOnAll(hmR0InitIntelCpu, &FirstRc, NULL);
-            else
-                rc = RTMpOnAll(hmR0InitAmdCpu, &FirstRc, NULL);
-            Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
-            if (RT_SUCCESS(rc))
-                rc = hmR0FirstRcGetStatus(&FirstRc);
-#ifdef LOG_ENABLED
-            if (RT_FAILURE(rc))
-                SUPR0Printf("hmR0PowerCallback hmR0InitXxxCpu failed with %Rc\n", rc);
-#endif
-            if (g_HvmR0.fGlobalInit)
-            {
-                /* Turn VT-x or AMD-V back on on all CPUs. */
-                rc = RTMpOnAll(hmR0EnableCpuCallback, NULL, &FirstRc /* output ignored */);
-                Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
-            }
-            /* else nothing to do here for the local init case */
-        }
-    }
-
-    if (enmEvent == RTPOWEREVENT_RESUME)
-        ASMAtomicWriteBool(&g_HvmR0.fSuspended, false);
-}
-
-
-/**
- * Does Ring-0 per VM HM initialization.
- *
- * This will copy HM global into the VM structure and call the CPU specific
- * init routine which will allocate resources for each virtual CPU and such.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- */
-VMMR0DECL(int) HWACCMR0InitVM(PVM pVM)
-{
-    AssertReturn(pVM, VERR_INVALID_PARAMETER);
-
-#ifdef LOG_ENABLED
-    SUPR0Printf("HWACCMR0InitVM: %p\n", pVM);
-#endif
-
-    /* Make sure we don't touch hwaccm after we've disabled hwaccm in preparation of a suspend. */
-    if (ASMAtomicReadBool(&g_HvmR0.fSuspended))
-        return VERR_HWACCM_SUSPEND_PENDING;
-
-    /*
-     * Copy globals to the VM structure.
-     */
-    pVM->hwaccm.s.vmx.fSupported            = g_HvmR0.vmx.fSupported;
-    pVM->hwaccm.s.svm.fSupported            = g_HvmR0.svm.fSupported;
-
-    pVM->hwaccm.s.vmx.fUsePreemptTimer      = g_HvmR0.vmx.fUsePreemptTimer;
-    pVM->hwaccm.s.vmx.cPreemptTimerShift    = g_HvmR0.vmx.cPreemptTimerShift;
-    pVM->hwaccm.s.vmx.msr.feature_ctrl      = g_HvmR0.vmx.msr.feature_ctrl;
-    pVM->hwaccm.s.vmx.hostCR4               = g_HvmR0.vmx.hostCR4;
-    pVM->hwaccm.s.vmx.hostEFER              = g_HvmR0.vmx.hostEFER;
-    pVM->hwaccm.s.vmx.msr.vmx_basic_info    = g_HvmR0.vmx.msr.vmx_basic_info;
-    pVM->hwaccm.s.vmx.msr.vmx_pin_ctls      = g_HvmR0.vmx.msr.vmx_pin_ctls;
-    pVM->hwaccm.s.vmx.msr.vmx_proc_ctls     = g_HvmR0.vmx.msr.vmx_proc_ctls;
-    pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2    = g_HvmR0.vmx.msr.vmx_proc_ctls2;
-    pVM->hwaccm.s.vmx.msr.vmx_exit          = g_HvmR0.vmx.msr.vmx_exit;
-    pVM->hwaccm.s.vmx.msr.vmx_entry         = g_HvmR0.vmx.msr.vmx_entry;
-    pVM->hwaccm.s.vmx.msr.vmx_misc          = g_HvmR0.vmx.msr.vmx_misc;
-    pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed0    = g_HvmR0.vmx.msr.vmx_cr0_fixed0;
-    pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed1    = g_HvmR0.vmx.msr.vmx_cr0_fixed1;
-    pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed0    = g_HvmR0.vmx.msr.vmx_cr4_fixed0;
-    pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed1    = g_HvmR0.vmx.msr.vmx_cr4_fixed1;
-    pVM->hwaccm.s.vmx.msr.vmx_vmcs_enum     = g_HvmR0.vmx.msr.vmx_vmcs_enum;
-    pVM->hwaccm.s.vmx.msr.vmx_eptcaps       = g_HvmR0.vmx.msr.vmx_eptcaps;
-    pVM->hwaccm.s.svm.msrHWCR               = g_HvmR0.svm.msrHWCR;
-    pVM->hwaccm.s.svm.u32Rev                = g_HvmR0.svm.u32Rev;
-    pVM->hwaccm.s.svm.u32Features           = g_HvmR0.svm.u32Features;
-    pVM->hwaccm.s.cpuid.u32AMDFeatureECX    = g_HvmR0.cpuid.u32AMDFeatureECX;
-    pVM->hwaccm.s.cpuid.u32AMDFeatureEDX    = g_HvmR0.cpuid.u32AMDFeatureEDX;
-    pVM->hwaccm.s.lLastError                = g_HvmR0.lLastError;
-
-    pVM->hwaccm.s.uMaxASID                  = g_HvmR0.uMaxASID;
-
-
-    if (!pVM->hwaccm.s.cMaxResumeLoops) /* allow ring-3 overrides */
-    {
-        pVM->hwaccm.s.cMaxResumeLoops       = 1024;
-#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
-        if (RTThreadPreemptIsPendingTrusty())
-            pVM->hwaccm.s.cMaxResumeLoops   = 8192;
-#endif
-    }
-
-    /*
-     * Initialize some per CPU fields.
-     */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
-
-        pVCpu->hwaccm.s.idEnteredCpu        = NIL_RTCPUID;
-
-        /* Invalidate the last cpu we were running on. */
-        pVCpu->hwaccm.s.idLastCpu           = NIL_RTCPUID;
-
-        /* We'll aways increment this the first time (host uses ASID 0) */
-        pVCpu->hwaccm.s.uCurrentASID        = 0;
-    }
-
-    /*
-     * Call the hardware specific initialization method.
-     *
-     * Note! The fInUse handling here isn't correct as we can we can be
-     *       rescheduled to a different cpu, but the fInUse case is mostly for
-     *       debugging...  Disabling preemption isn't an option when allocating
-     *       memory, so we'll let it slip for now.
-     */
-    RTCCUINTREG     fFlags = ASMIntDisableFlags();
-    PHMGLOBLCPUINFO pCpu   = HWACCMR0GetCurrentCpu();
-    ASMAtomicWriteBool(&pCpu->fInUse, true);
-    ASMSetFlags(fFlags);
-
-    int rc = g_HvmR0.pfnInitVM(pVM);
-
-    ASMAtomicWriteBool(&pCpu->fInUse, false);
-    return rc;
-}
-
-
-/**
- * Does Ring-0 per VM HM termination.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- */
-VMMR0DECL(int) HWACCMR0TermVM(PVM pVM)
-{
-    Log(("HWACCMR0TermVM: %p\n", pVM));
-    AssertReturn(pVM, VERR_INVALID_PARAMETER);
-
-    /* Make sure we don't touch hm after we've disabled hwaccm in preparation
-       of a suspend. */
-    /** @todo r=bird: This cannot be right, the termination functions are
-     *        just freeing memory and resetting pVM/pVCpu members...
-     *  ==> memory leak. */
-    AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
-
-    /*
-     * Call the hardware specific method.
-     *
-     * Note! Not correct as we can be rescheduled to a different cpu, but the
-     *       fInUse case is mostly for debugging.
-     */
-    RTCCUINTREG     fFlags = ASMIntDisableFlags();
-    PHMGLOBLCPUINFO pCpu   = HWACCMR0GetCurrentCpu();
-    ASMAtomicWriteBool(&pCpu->fInUse, true);
-    ASMSetFlags(fFlags);
-
-    int rc = g_HvmR0.pfnTermVM(pVM);
-
-    ASMAtomicWriteBool(&pCpu->fInUse, false);
-    return rc;
-}
-
-
-/**
- * Sets up a VT-x or AMD-V session.
- *
- * This is mostly about setting up the hardware VM state.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- */
-VMMR0DECL(int) HWACCMR0SetupVM(PVM pVM)
-{
-    Log(("HWACCMR0SetupVM: %p\n", pVM));
-    AssertReturn(pVM, VERR_INVALID_PARAMETER);
-
-    /* Make sure we don't touch hwaccm after we've disabled hwaccm in
-       preparation of a suspend. */
-    AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
-
-
-    /*
-     * Call the hardware specific setup VM method.  This requires the CPU to be
-     * enabled for AMD-V/VT-x and preemption to be prevented.
-     */
-    RTCCUINTREG     fFlags = ASMIntDisableFlags();
-    RTCPUID         idCpu  = RTMpCpuId();
-    PHMGLOBLCPUINFO pCpu   = &g_HvmR0.aCpuInfo[idCpu];
-    ASMAtomicWriteBool(&pCpu->fInUse, true);
-
-    /* On first entry we'll sync everything. */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        pVM->aCpus[i].hwaccm.s.fContextUseFlags = HWACCM_CHANGED_ALL;
-
-    /* Enable VT-x or AMD-V if local init is required. */
-    int rc;
-    if (!g_HvmR0.fGlobalInit)
-    {
-        rc = hmR0EnableCpu(pVM, idCpu);
-        AssertReturnStmt(RT_SUCCESS_NP(rc), ASMSetFlags(fFlags), rc);
-    }
-
-    /* Setup VT-x or AMD-V. */
-    rc = g_HvmR0.pfnSetupVM(pVM);
-
-    /* Disable VT-x or AMD-V if local init was done before. */
-    if (!g_HvmR0.fGlobalInit)
-    {
-        int rc2 = hmR0DisableCpu(idCpu);
-        AssertRC(rc2);
-    }
-
-    ASMAtomicWriteBool(&pCpu->fInUse, false);
-    ASMSetFlags(fFlags);
-
-    return rc;
-}
-
-
-/**
- * Enters the VT-x or AMD-V session.
- *
- * @returns VBox status code.
- * @param   pVM        Pointer to the VM.
- * @param   pVCpu      Pointer to the VMCPU.
- *
- * @remarks This is called with preemption disabled.
- */
-VMMR0DECL(int) HWACCMR0Enter(PVM pVM, PVMCPU pVCpu)
-{
-    RTCPUID         idCpu = RTMpCpuId();
-    PHMGLOBLCPUINFO pCpu  = &g_HvmR0.aCpuInfo[idCpu];
-
-    /* Make sure we can't enter a session after we've disabled HM in preparation of a suspend. */
-    AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
-    ASMAtomicWriteBool(&pCpu->fInUse, true);
-
-    AssertMsg(pVCpu->hwaccm.s.idEnteredCpu == NIL_RTCPUID, ("%d", (int)pVCpu->hwaccm.s.idEnteredCpu));
-    pVCpu->hwaccm.s.idEnteredCpu = idCpu;
-
-    PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-
-    /* Always load the guest's FPU/XMM state on-demand. */
-    CPUMDeactivateGuestFPUState(pVCpu);
-
-    /* Always load the guest's debug state on-demand. */
-    CPUMDeactivateGuestDebugState(pVCpu);
-
-    /* Always reload the host context and the guest's CR0 register. (!!!!) */
-    pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0 | HWACCM_CHANGED_HOST_CONTEXT;
-
-    /* Setup the register and mask according to the current execution mode. */
-    if (pCtx->msrEFER & MSR_K6_EFER_LMA)
-        pVM->hwaccm.s.u64RegisterMask = UINT64_C(0xFFFFFFFFFFFFFFFF);
-    else
-        pVM->hwaccm.s.u64RegisterMask = UINT64_C(0xFFFFFFFF);
-
-    /* Enable VT-x or AMD-V if local init is required, or enable if it's a
-       freshly onlined CPU. */
-    int rc;
-    if (   !pCpu->fConfigured
-        || !g_HvmR0.fGlobalInit)
-    {
-        rc = hmR0EnableCpu(pVM, idCpu);
-        AssertRCReturn(rc, rc);
-    }
-
-#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
-    bool fStartedSet = PGMR0DynMapStartOrMigrateAutoSet(pVCpu);
-#endif
-
-    rc  = g_HvmR0.pfnEnterSession(pVM, pVCpu, pCpu);
-    AssertRC(rc);
-    /* We must save the host context here (VT-x) as we might be rescheduled on
-       a different cpu after a long jump back to ring 3. */
-    rc |= g_HvmR0.pfnSaveHostState(pVM, pVCpu);
-    AssertRC(rc);
-    rc |= g_HvmR0.pfnLoadGuestState(pVM, pVCpu, pCtx);
-    AssertRC(rc);
-
-#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
-    if (fStartedSet)
-        PGMRZDynMapReleaseAutoSet(pVCpu);
-#endif
-
-    /* Keep track of the CPU owning the VMCS for debugging scheduling weirdness
-       and ring-3 calls. */
-    if (RT_FAILURE(rc))
-        pVCpu->hwaccm.s.idEnteredCpu = NIL_RTCPUID;
-    return rc;
-}
-
-
-/**
- * Leaves the VT-x or AMD-V session.
- *
- * @returns VBox status code.
- * @param   pVM        Pointer to the VM.
- * @param   pVCpu      Pointer to the VMCPU.
- *
- * @remarks Called with preemption disabled just like HWACCMR0Enter, our
- *          counterpart.
- */
-VMMR0DECL(int) HWACCMR0Leave(PVM pVM, PVMCPU pVCpu)
-{
-    int             rc;
-    RTCPUID         idCpu = RTMpCpuId();
-    PHMGLOBLCPUINFO pCpu  = &g_HvmR0.aCpuInfo[idCpu];
-    PCPUMCTX        pCtx  = CPUMQueryGuestCtxPtr(pVCpu);
-
-    /** @todo r=bird: This can't be entirely right? */
-    AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
-
-    /*
-     * Save the guest FPU and XMM state if necessary.
-     *
-     * Note! It's rather tricky with longjmps done by e.g. Log statements or
-     *       the page fault handler.  We must restore the host FPU here to make
-     *       absolutely sure we don't leave the guest FPU state active or trash
-     *       somebody else's FPU state.
-     */
-    if (CPUMIsGuestFPUStateActive(pVCpu))
-    {
-        Log2(("CPUMR0SaveGuestFPU\n"));
-        CPUMR0SaveGuestFPU(pVM, pVCpu, pCtx);
-
-        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0;
-        Assert(!CPUMIsGuestFPUStateActive(pVCpu));
-    }
-
-    rc = g_HvmR0.pfnLeaveSession(pVM, pVCpu, pCtx);
-
-    /* We don't pass on invlpg information to the recompiler for nested paging
-       guests, so we must make sure the recompiler flushes its TLB the next
-       time it executes code. */
-    if (    pVM->hwaccm.s.fNestedPaging
-        &&  CPUMIsGuestInPagedProtectedModeEx(pCtx))
-        CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_GLOBAL_TLB_FLUSH);
-
-    /* Keep track of the CPU owning the VMCS for debugging scheduling weirdness
-       and ring-3 calls. */
-    AssertMsgStmt(   pVCpu->hwaccm.s.idEnteredCpu == idCpu
-                  || RT_FAILURE_NP(rc),
-                  ("Owner is %u, I'm %u", pVCpu->hwaccm.s.idEnteredCpu, idCpu),
-                  rc = VERR_HM_WRONG_CPU_1);
-    pVCpu->hwaccm.s.idEnteredCpu = NIL_RTCPUID;
-
-    /*
-     * Disable VT-x or AMD-V if local init was done before.
-     */
-    if (!g_HvmR0.fGlobalInit)
-    {
-        rc = hmR0DisableCpu(idCpu);
-        AssertRC(rc);
-
-        /* Reset these to force a TLB flush for the next entry. (-> EXPENSIVE) */
-        pVCpu->hwaccm.s.idLastCpu    = NIL_RTCPUID;
-        pVCpu->hwaccm.s.uCurrentASID = 0;
-        VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
-    }
-
-    ASMAtomicWriteBool(&pCpu->fInUse, false);
-    return rc;
-}
-
-
-/**
- * Runs guest code in a hardware accelerated VM.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- *
- * @remarks Called with preemption disabled and after first having called
- *          HWACCMR0Enter.
- */
-VMMR0DECL(int) HWACCMR0RunGuestCode(PVM pVM, PVMCPU pVCpu)
-{
-#ifdef VBOX_STRICT
-    PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[RTMpCpuId()];
-    Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL));
-    Assert(pCpu->fConfigured);
-    AssertReturn(!ASMAtomicReadBool(&g_HvmR0.fSuspended), VERR_HWACCM_SUSPEND_PENDING);
-    Assert(ASMAtomicReadBool(&pCpu->fInUse) == true);
-#endif
-
-#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
-    PGMRZDynMapStartAutoSet(pVCpu);
-#endif
-
-    int rc = g_HvmR0.pfnRunGuestCode(pVM, pVCpu, CPUMQueryGuestCtxPtr(pVCpu));
-
-#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
-    PGMRZDynMapReleaseAutoSet(pVCpu);
-#endif
-    return rc;
-}
-
-#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
-
-/**
- * Save guest FPU/XMM state (64 bits guest mode & 32 bits host only)
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   pCtx        Pointer to the guest CPU context.
- */
-VMMR0DECL(int)   HWACCMR0SaveFPUState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
-    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFpu64SwitchBack);
-    if (pVM->hwaccm.s.vmx.fSupported)
-        return VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnSaveGuestFPU64, 0, NULL);
-    return SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnSaveGuestFPU64, 0, NULL);
-}
-
-
-/**
- * Save guest debug state (64 bits guest mode & 32 bits host only)
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   pCtx        Pointer to the guest CPU context.
- */
-VMMR0DECL(int)   HWACCMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
-    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatDebug64SwitchBack);
-    if (pVM->hwaccm.s.vmx.fSupported)
-        return VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnSaveGuestDebug64, 0, NULL);
-    return SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnSaveGuestDebug64, 0, NULL);
-}
-
-
-/**
- * Test the 32->64 bits switcher.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- */
-VMMR0DECL(int)   HWACCMR0TestSwitcher3264(PVM pVM)
-{
-    PVMCPU   pVCpu = &pVM->aCpus[0];
-    PCPUMCTX pCtx  = CPUMQueryGuestCtxPtr(pVCpu);
-    uint32_t aParam[5] = {0, 1, 2, 3, 4};
-    int      rc;
-
-    STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatWorldSwitch3264, z);
-    if (pVM->hwaccm.s.vmx.fSupported)
-        rc = VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnTest64, 5, &aParam[0]);
-    else
-        rc = SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnTest64, 5, &aParam[0]);
-    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatWorldSwitch3264, z);
-
-    return rc;
-}
-
-#endif /* HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL) */
-
-/**
- * Returns suspend status of the host.
- *
- * @returns Suspend pending or not.
- */
-VMMR0DECL(bool) HWACCMR0SuspendPending(void)
-{
-    return ASMAtomicReadBool(&g_HvmR0.fSuspended);
-}
-
-
-/**
- * Returns the cpu structure for the current cpu.
- * Keep in mind that there is no guarantee it will stay the same (long jumps to ring 3!!!).
- *
- * @returns The cpu structure pointer.
- */
-VMMR0DECL(PHMGLOBLCPUINFO) HWACCMR0GetCurrentCpu(void)
-{
-    RTCPUID idCpu = RTMpCpuId();
-    Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
-    return &g_HvmR0.aCpuInfo[idCpu];
-}
-
-
-/**
- * Returns the cpu structure for the current cpu.
- * Keep in mind that there is no guarantee it will stay the same (long jumps to ring 3!!!).
- *
- * @returns The cpu structure pointer.
- * @param   idCpu       id of the VCPU.
- */
-VMMR0DECL(PHMGLOBLCPUINFO) HWACCMR0GetCurrentCpuEx(RTCPUID idCpu)
-{
-    Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
-    return &g_HvmR0.aCpuInfo[idCpu];
-}
-
-
-/**
- * Save a pending IO read.
- *
- * @param   pVCpu           Pointer to the VMCPU.
- * @param   GCPtrRip        Address of IO instruction.
- * @param   GCPtrRipNext    Address of the next instruction.
- * @param   uPort           Port address.
- * @param   uAndVal         AND mask for saving the result in eax.
- * @param   cbSize          Read size.
- */
-VMMR0DECL(void) HWACCMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize)
-{
-    pVCpu->hwaccm.s.PendingIO.enmType         = HWACCMPENDINGIO_PORT_READ;
-    pVCpu->hwaccm.s.PendingIO.GCPtrRip        = GCPtrRip;
-    pVCpu->hwaccm.s.PendingIO.GCPtrRipNext    = GCPtrRipNext;
-    pVCpu->hwaccm.s.PendingIO.s.Port.uPort    = uPort;
-    pVCpu->hwaccm.s.PendingIO.s.Port.uAndVal  = uAndVal;
-    pVCpu->hwaccm.s.PendingIO.s.Port.cbSize   = cbSize;
-    return;
-}
-
-
-/**
- * Save a pending IO write.
- *
- * @param   pVCpu           Pointer to the VMCPU.
- * @param   GCPtrRIP        Address of IO instruction.
- * @param   uPort           Port address.
- * @param   uAndVal         AND mask for fetching the result from eax.
- * @param   cbSize          Read size.
- */
-VMMR0DECL(void) HWACCMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize)
-{
-    pVCpu->hwaccm.s.PendingIO.enmType         = HWACCMPENDINGIO_PORT_WRITE;
-    pVCpu->hwaccm.s.PendingIO.GCPtrRip        = GCPtrRip;
-    pVCpu->hwaccm.s.PendingIO.GCPtrRipNext    = GCPtrRipNext;
-    pVCpu->hwaccm.s.PendingIO.s.Port.uPort    = uPort;
-    pVCpu->hwaccm.s.PendingIO.s.Port.uAndVal  = uAndVal;
-    pVCpu->hwaccm.s.PendingIO.s.Port.cbSize   = cbSize;
-    return;
-}
-
-
-/**
- * Raw-mode switcher hook - disable VT-x if it's active *and* the current
- * switcher turns off paging.
- *
- * @returns VBox status code.
- * @param   pVM             Pointer to the VM.
- * @param   enmSwitcher     The switcher we're about to use.
- * @param   pfVTxDisabled   Where to store whether VT-x was disabled or not.
- */
-VMMR0DECL(int) HWACCMR0EnterSwitcher(PVM pVM, VMMSWITCHER enmSwitcher, bool *pfVTxDisabled)
-{
-    Assert(!(ASMGetFlags() & X86_EFL_IF) || !RTThreadPreemptIsEnabled(NIL_RTTHREAD));
-
-    *pfVTxDisabled = false;
-
-    /* No such issues with AMD-V */
-    if (!g_HvmR0.vmx.fSupported)
-        return VINF_SUCCESS;
-
-    /* Check if the swithcing we're up to is safe. */
-    switch (enmSwitcher)
-    {
-        case VMMSWITCHER_32_TO_32:
-        case VMMSWITCHER_PAE_TO_PAE:
-            return VINF_SUCCESS;    /* safe switchers as they don't turn off paging */
-
-        case VMMSWITCHER_32_TO_PAE:
-        case VMMSWITCHER_PAE_TO_32: /* is this one actually used?? */
-        case VMMSWITCHER_AMD64_TO_32:
-        case VMMSWITCHER_AMD64_TO_PAE:
-            break;                  /* unsafe switchers */
-
-        default:
-            AssertFailedReturn(VERR_HM_WRONG_SWITCHER);
-    }
-
-    /* When using SUPR0EnableVTx we must let the host suspend and resume VT-x,
-       regardless of whether we're currently using VT-x or not. */
-    if (g_HvmR0.vmx.fUsingSUPR0EnableVTx)
-    {
-        *pfVTxDisabled = SUPR0SuspendVTxOnCpu();
-        return VINF_SUCCESS;
-    }
-
-    /** @todo Check if this code is presumtive wrt other VT-x users on the
-     *        system... */
-
-    /* Nothing to do if we haven't enabled VT-x. */
-    if (!g_HvmR0.fEnabled)
-        return VINF_SUCCESS;
-
-    /* Local init implies the CPU is currently not in VMX root mode. */
-    if (!g_HvmR0.fGlobalInit)
-        return VINF_SUCCESS;
-
-    /* Ok, disable VT-x. */
-    PHMGLOBLCPUINFO pCpu = HWACCMR0GetCurrentCpu();
-    AssertReturn(pCpu && pCpu->hMemObj != NIL_RTR0MEMOBJ, VERR_HM_IPE_2);
-
-    *pfVTxDisabled = true;
-    void    *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
-    RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
-    return VMXR0DisableCpu(pCpu, pvCpuPage, HCPhysCpuPage);
-}
-
-
-/**
- * Raw-mode switcher hook - re-enable VT-x if was active *and* the current
- * switcher turned off paging.
- *
- * @param   pVM             Pointer to the VM.
- * @param   fVTxDisabled    Whether VT-x was disabled or not.
- */
-VMMR0DECL(void) HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled)
-{
-    Assert(!(ASMGetFlags() & X86_EFL_IF));
-
-    if (!fVTxDisabled)
-        return;         /* nothing to do */
-
-    Assert(g_HvmR0.vmx.fSupported);
-    if (g_HvmR0.vmx.fUsingSUPR0EnableVTx)
-        SUPR0ResumeVTxOnCpu(fVTxDisabled);
-    else
-    {
-        Assert(g_HvmR0.fEnabled);
-        Assert(g_HvmR0.fGlobalInit);
-
-        PHMGLOBLCPUINFO pCpu = HWACCMR0GetCurrentCpu();
-        AssertReturnVoid(pCpu && pCpu->hMemObj != NIL_RTR0MEMOBJ);
-
-        void           *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
-        RTHCPHYS        HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
-        VMXR0EnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage, false);
-    }
-}
-
-#ifdef VBOX_STRICT
-
-/**
- * Dumps a descriptor.
- *
- * @param   pDesc    Descriptor to dump.
- * @param   Sel      Selector number.
- * @param   pszMsg   Message to prepend the log entry with.
- */
-VMMR0DECL(void) HWACCMR0DumpDescriptor(PCX86DESCHC pDesc, RTSEL Sel, const char *pszMsg)
-{
-    /*
-     * Make variable description string.
-     */
-    static struct
-    {
-        unsigned    cch;
-        const char *psz;
-    } const s_aTypes[32] =
-    {
-# define STRENTRY(str) { sizeof(str) - 1, str }
-
-        /* system */
-# if HC_ARCH_BITS == 64
-        STRENTRY("Reserved0 "),                  /* 0x00 */
-        STRENTRY("Reserved1 "),                  /* 0x01 */
-        STRENTRY("LDT "),                        /* 0x02 */
-        STRENTRY("Reserved3 "),                  /* 0x03 */
-        STRENTRY("Reserved4 "),                  /* 0x04 */
-        STRENTRY("Reserved5 "),                  /* 0x05 */
-        STRENTRY("Reserved6 "),                  /* 0x06 */
-        STRENTRY("Reserved7 "),                  /* 0x07 */
-        STRENTRY("Reserved8 "),                  /* 0x08 */
-        STRENTRY("TSS64Avail "),                 /* 0x09 */
-        STRENTRY("ReservedA "),                  /* 0x0a */
-        STRENTRY("TSS64Busy "),                  /* 0x0b */
-        STRENTRY("Call64 "),                     /* 0x0c */
-        STRENTRY("ReservedD "),                  /* 0x0d */
-        STRENTRY("Int64 "),                      /* 0x0e */
-        STRENTRY("Trap64 "),                     /* 0x0f */
-# else
-        STRENTRY("Reserved0 "),                  /* 0x00 */
-        STRENTRY("TSS16Avail "),                 /* 0x01 */
-        STRENTRY("LDT "),                        /* 0x02 */
-        STRENTRY("TSS16Busy "),                  /* 0x03 */
-        STRENTRY("Call16 "),                     /* 0x04 */
-        STRENTRY("Task "),                       /* 0x05 */
-        STRENTRY("Int16 "),                      /* 0x06 */
-        STRENTRY("Trap16 "),                     /* 0x07 */
-        STRENTRY("Reserved8 "),                  /* 0x08 */
-        STRENTRY("TSS32Avail "),                 /* 0x09 */
-        STRENTRY("ReservedA "),                  /* 0x0a */
-        STRENTRY("TSS32Busy "),                  /* 0x0b */
-        STRENTRY("Call32 "),                     /* 0x0c */
-        STRENTRY("ReservedD "),                  /* 0x0d */
-        STRENTRY("Int32 "),                      /* 0x0e */
-        STRENTRY("Trap32 "),                     /* 0x0f */
-# endif
-        /* non system */
-        STRENTRY("DataRO "),                     /* 0x10 */
-        STRENTRY("DataRO Accessed "),            /* 0x11 */
-        STRENTRY("DataRW "),                     /* 0x12 */
-        STRENTRY("DataRW Accessed "),            /* 0x13 */
-        STRENTRY("DataDownRO "),                 /* 0x14 */
-        STRENTRY("DataDownRO Accessed "),        /* 0x15 */
-        STRENTRY("DataDownRW "),                 /* 0x16 */
-        STRENTRY("DataDownRW Accessed "),        /* 0x17 */
-        STRENTRY("CodeEO "),                     /* 0x18 */
-        STRENTRY("CodeEO Accessed "),            /* 0x19 */
-        STRENTRY("CodeER "),                     /* 0x1a */
-        STRENTRY("CodeER Accessed "),            /* 0x1b */
-        STRENTRY("CodeConfEO "),                 /* 0x1c */
-        STRENTRY("CodeConfEO Accessed "),        /* 0x1d */
-        STRENTRY("CodeConfER "),                 /* 0x1e */
-        STRENTRY("CodeConfER Accessed ")         /* 0x1f */
-# undef SYSENTRY
-    };
-# define ADD_STR(psz, pszAdd) do { strcpy(psz, pszAdd); psz += strlen(pszAdd); } while (0)
-    char        szMsg[128];
-    char       *psz = &szMsg[0];
-    unsigned    i = pDesc->Gen.u1DescType << 4 | pDesc->Gen.u4Type;
-    memcpy(psz, s_aTypes[i].psz, s_aTypes[i].cch);
-    psz += s_aTypes[i].cch;
-
-    if (pDesc->Gen.u1Present)
-        ADD_STR(psz, "Present ");
-    else
-        ADD_STR(psz, "Not-Present ");
-# if HC_ARCH_BITS == 64
-    if (pDesc->Gen.u1Long)
-        ADD_STR(psz, "64-bit ");
-    else
-        ADD_STR(psz, "Comp   ");
-# else
-    if (pDesc->Gen.u1Granularity)
-        ADD_STR(psz, "Page ");
-    if (pDesc->Gen.u1DefBig)
-        ADD_STR(psz, "32-bit ");
-    else
-        ADD_STR(psz, "16-bit ");
-# endif
-# undef ADD_STR
-    *psz = '\0';
-
-    /*
-     * Limit and Base and format the output.
-     */
-    uint32_t    u32Limit = X86DESC_LIMIT_G(pDesc);
-
-# if HC_ARCH_BITS == 64
-    uint64_t    u32Base  = X86DESC64_BASE(pDesc);
-
-    Log(("%s %04x - %RX64 %RX64 - base=%RX64 limit=%08x dpl=%d %s\n", pszMsg,
-         Sel, pDesc->au64[0], pDesc->au64[1], u32Base, u32Limit, pDesc->Gen.u2Dpl, szMsg));
-# else
-    uint32_t    u32Base  = X86DESC_BASE(pDesc);
-
-    Log(("%s %04x - %08x %08x - base=%08x limit=%08x dpl=%d %s\n", pszMsg,
-         Sel, pDesc->au32[0], pDesc->au32[1], u32Base, u32Limit, pDesc->Gen.u2Dpl, szMsg));
-# endif
-}
-
-
-/**
- * Formats a full register dump.
- *
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   pCtx        Pointer to the CPU context.
- */
-VMMR0DECL(void) HWACCMDumpRegs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
-    NOREF(pVM);
-
-    /*
-     * Format the flags.
-     */
-    static struct
-    {
-        const char *pszSet; const char *pszClear; uint32_t fFlag;
-    } const s_aFlags[] =
-    {
-        { "vip",NULL, X86_EFL_VIP },
-        { "vif",NULL, X86_EFL_VIF },
-        { "ac", NULL, X86_EFL_AC },
-        { "vm", NULL, X86_EFL_VM },
-        { "rf", NULL, X86_EFL_RF },
-        { "nt", NULL, X86_EFL_NT },
-        { "ov", "nv", X86_EFL_OF },
-        { "dn", "up", X86_EFL_DF },
-        { "ei", "di", X86_EFL_IF },
-        { "tf", NULL, X86_EFL_TF },
-        { "nt", "pl", X86_EFL_SF },
-        { "nz", "zr", X86_EFL_ZF },
-        { "ac", "na", X86_EFL_AF },
-        { "po", "pe", X86_EFL_PF },
-        { "cy", "nc", X86_EFL_CF },
-    };
-    char szEFlags[80];
-    char *psz = szEFlags;
-    uint32_t efl = pCtx->eflags.u32;
-    for (unsigned i = 0; i < RT_ELEMENTS(s_aFlags); i++)
-    {
-        const char *pszAdd = s_aFlags[i].fFlag & efl ? s_aFlags[i].pszSet : s_aFlags[i].pszClear;
-        if (pszAdd)
-        {
-            strcpy(psz, pszAdd);
-            psz += strlen(pszAdd);
-            *psz++ = ' ';
-        }
-    }
-    psz[-1] = '\0';
-
-
-    /*
-     * Format the registers.
-     */
-    if (CPUMIsGuestIn64BitCode(pVCpu))
-    {
-        Log(("rax=%016RX64 rbx=%016RX64 rcx=%016RX64 rdx=%016RX64\n"
-             "rsi=%016RX64 rdi=%016RX64 r8 =%016RX64 r9 =%016RX64\n"
-             "r10=%016RX64 r11=%016RX64 r12=%016RX64 r13=%016RX64\n"
-             "r14=%016RX64 r15=%016RX64\n"
-             "rip=%016RX64 rsp=%016RX64 rbp=%016RX64 iopl=%d %*s\n"
-             "cs={%04x base=%016RX64 limit=%08x flags=%08x}\n"
-             "ds={%04x base=%016RX64 limit=%08x flags=%08x}\n"
-             "es={%04x base=%016RX64 limit=%08x flags=%08x}\n"
-             "fs={%04x base=%016RX64 limit=%08x flags=%08x}\n"
-             "gs={%04x base=%016RX64 limit=%08x flags=%08x}\n"
-             "ss={%04x base=%016RX64 limit=%08x flags=%08x}\n"
-             "cr0=%016RX64 cr2=%016RX64 cr3=%016RX64 cr4=%016RX64\n"
-             "dr0=%016RX64 dr1=%016RX64 dr2=%016RX64 dr3=%016RX64\n"
-             "dr4=%016RX64 dr5=%016RX64 dr6=%016RX64 dr7=%016RX64\n"
-             "gdtr=%016RX64:%04x  idtr=%016RX64:%04x  eflags=%08x\n"
-             "ldtr={%04x base=%08RX64 limit=%08x flags=%08x}\n"
-             "tr  ={%04x base=%08RX64 limit=%08x flags=%08x}\n"
-             "SysEnter={cs=%04llx eip=%08llx esp=%08llx}\n"
-             ,
-             pCtx->rax, pCtx->rbx, pCtx->rcx, pCtx->rdx, pCtx->rsi, pCtx->rdi,
-             pCtx->r8, pCtx->r9, pCtx->r10, pCtx->r11, pCtx->r12, pCtx->r13,
-             pCtx->r14, pCtx->r15,
-             pCtx->rip, pCtx->rsp, pCtx->rbp, X86_EFL_GET_IOPL(efl), 31, szEFlags,
-             pCtx->cs.Sel, pCtx->cs.u64Base, pCtx->cs.u32Limit, pCtx->cs.Attr.u,
-             pCtx->ds.Sel, pCtx->ds.u64Base, pCtx->ds.u32Limit, pCtx->ds.Attr.u,
-             pCtx->es.Sel, pCtx->es.u64Base, pCtx->es.u32Limit, pCtx->es.Attr.u,
-             pCtx->fs.Sel, pCtx->fs.u64Base, pCtx->fs.u32Limit, pCtx->fs.Attr.u,
-             pCtx->gs.Sel, pCtx->gs.u64Base, pCtx->gs.u32Limit, pCtx->gs.Attr.u,
-             pCtx->ss.Sel, pCtx->ss.u64Base, pCtx->ss.u32Limit, pCtx->ss.Attr.u,
-             pCtx->cr0,  pCtx->cr2, pCtx->cr3,  pCtx->cr4,
-             pCtx->dr[0],  pCtx->dr[1], pCtx->dr[2],  pCtx->dr[3],
-             pCtx->dr[4],  pCtx->dr[5], pCtx->dr[6],  pCtx->dr[7],
-             pCtx->gdtr.pGdt, pCtx->gdtr.cbGdt, pCtx->idtr.pIdt, pCtx->idtr.cbIdt, efl,
-             pCtx->ldtr.Sel, pCtx->ldtr.u64Base, pCtx->ldtr.u32Limit, pCtx->ldtr.Attr.u,
-             pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u,
-             pCtx->SysEnter.cs, pCtx->SysEnter.eip, pCtx->SysEnter.esp));
-    }
-    else
-        Log(("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n"
-             "eip=%08x esp=%08x ebp=%08x iopl=%d %*s\n"
-             "cs={%04x base=%016RX64 limit=%08x flags=%08x} dr0=%08RX64 dr1=%08RX64\n"
-             "ds={%04x base=%016RX64 limit=%08x flags=%08x} dr2=%08RX64 dr3=%08RX64\n"
-             "es={%04x base=%016RX64 limit=%08x flags=%08x} dr4=%08RX64 dr5=%08RX64\n"
-             "fs={%04x base=%016RX64 limit=%08x flags=%08x} dr6=%08RX64 dr7=%08RX64\n"
-             "gs={%04x base=%016RX64 limit=%08x flags=%08x} cr0=%08RX64 cr2=%08RX64\n"
-             "ss={%04x base=%016RX64 limit=%08x flags=%08x} cr3=%08RX64 cr4=%08RX64\n"
-             "gdtr=%016RX64:%04x  idtr=%016RX64:%04x  eflags=%08x\n"
-             "ldtr={%04x base=%08RX64 limit=%08x flags=%08x}\n"
-             "tr  ={%04x base=%08RX64 limit=%08x flags=%08x}\n"
-             "SysEnter={cs=%04llx eip=%08llx esp=%08llx}\n"
-             ,
-             pCtx->eax, pCtx->ebx, pCtx->ecx, pCtx->edx, pCtx->esi, pCtx->edi,
-             pCtx->eip, pCtx->esp, pCtx->ebp, X86_EFL_GET_IOPL(efl), 31, szEFlags,
-             pCtx->cs.Sel, pCtx->cs.u64Base, pCtx->cs.u32Limit, pCtx->cs.Attr.u, pCtx->dr[0],  pCtx->dr[1],
-             pCtx->ds.Sel, pCtx->ds.u64Base, pCtx->ds.u32Limit, pCtx->ds.Attr.u, pCtx->dr[2],  pCtx->dr[3],
-             pCtx->es.Sel, pCtx->es.u64Base, pCtx->es.u32Limit, pCtx->es.Attr.u, pCtx->dr[4],  pCtx->dr[5],
-             pCtx->fs.Sel, pCtx->fs.u64Base, pCtx->fs.u32Limit, pCtx->fs.Attr.u, pCtx->dr[6],  pCtx->dr[7],
-             pCtx->gs.Sel, pCtx->gs.u64Base, pCtx->gs.u32Limit, pCtx->gs.Attr.u, pCtx->cr0,  pCtx->cr2,
-             pCtx->ss.Sel, pCtx->ss.u64Base, pCtx->ss.u32Limit, pCtx->ss.Attr.u, pCtx->cr3,  pCtx->cr4,
-             pCtx->gdtr.pGdt, pCtx->gdtr.cbGdt, pCtx->idtr.pIdt, pCtx->idtr.cbIdt, efl,
-             pCtx->ldtr.Sel, pCtx->ldtr.u64Base, pCtx->ldtr.u32Limit, pCtx->ldtr.Attr.u,
-             pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u,
-             pCtx->SysEnter.cs, pCtx->SysEnter.eip, pCtx->SysEnter.esp));
-
-    Log(("FPU:\n"
-        "FCW=%04x FSW=%04x FTW=%02x\n"
-        "FOP=%04x FPUIP=%08x CS=%04x Rsrvd1=%04x\n"
-        "FPUDP=%04x DS=%04x Rsvrd2=%04x MXCSR=%08x MXCSR_MASK=%08x\n"
-        ,
-        pCtx->fpu.FCW, pCtx->fpu.FSW, pCtx->fpu.FTW,
-        pCtx->fpu.FOP, pCtx->fpu.FPUIP, pCtx->fpu.CS, pCtx->fpu.Rsrvd1,
-        pCtx->fpu.FPUDP, pCtx->fpu.DS, pCtx->fpu.Rsrvd2,
-        pCtx->fpu.MXCSR, pCtx->fpu.MXCSR_MASK));
-
-
-    Log(("MSR:\n"
-        "EFER         =%016RX64\n"
-        "PAT          =%016RX64\n"
-        "STAR         =%016RX64\n"
-        "CSTAR        =%016RX64\n"
-        "LSTAR        =%016RX64\n"
-        "SFMASK       =%016RX64\n"
-        "KERNELGSBASE =%016RX64\n",
-        pCtx->msrEFER,
-        pCtx->msrPAT,
-        pCtx->msrSTAR,
-        pCtx->msrCSTAR,
-        pCtx->msrLSTAR,
-        pCtx->msrSFMASK,
-        pCtx->msrKERNELGSBASE));
-
-}
-
-#endif /* VBOX_STRICT */
-
Index: trunk/src/VBox/VMM/VMMR0/HWACCMR0A.asm
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWACCMR0A.asm	(revision 43379)
+++ 	(revision )
@@ -1,1506 +1,0 @@
-; $Id$
-;; @file
-; VMXM - R0 vmx helpers
-;
-
-;
-; Copyright (C) 2006-2007 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.
-;
-
-;*******************************************************************************
-;* Header Files                                                                *
-;*******************************************************************************
-%include "VBox/asmdefs.mac"
-%include "VBox/err.mac"
-%include "VBox/vmm/hwacc_vmx.mac"
-%include "VBox/vmm/cpum.mac"
-%include "iprt/x86.mac"
-%include "HWACCMInternal.mac"
-
-%ifdef RT_OS_OS2 ;; @todo fix OMF support in yasm and kick nasm out completely.
- %macro vmwrite 2,
-    int3
- %endmacro
- %define vmlaunch int3
- %define vmresume int3
- %define vmsave int3
- %define vmload int3
- %define vmrun int3
- %define clgi int3
- %define stgi int3
- %macro invlpga 2,
-    int3
- %endmacro
-%endif
-
-;*******************************************************************************
-;*  Defined Constants And Macros                                               *
-;*******************************************************************************
-%ifdef RT_ARCH_AMD64
- %define MAYBE_64_BIT
-%endif
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
- %define MAYBE_64_BIT
-%else
- %ifdef RT_OS_DARWIN
-  %ifdef RT_ARCH_AMD64
-   ;;
-   ; Load the NULL selector into DS, ES, FS and GS on 64-bit darwin so we don't
-   ; risk loading a stale LDT value or something invalid.
-   %define HWACCM_64_BIT_USE_NULL_SEL
-  %endif
- %endif
-%endif
-
-;; The offset of the XMM registers in X86FXSTATE.
-; Use define because I'm too lazy to convert the struct.
-%define XMM_OFF_IN_X86FXSTATE   160
-
-
-;; This is too risky wrt. stability, performance and correctness.
-;%define VBOX_WITH_DR6_EXPERIMENT 1
-
-;; @def MYPUSHAD
-; Macro generating an equivalent to pushad
-
-;; @def MYPOPAD
-; Macro generating an equivalent to popad
-
-;; @def MYPUSHSEGS
-; Macro saving all segment registers on the stack.
-; @param 1  full width register name
-; @param 2  16-bit register name for \a 1.
-
-;; @def MYPOPSEGS
-; Macro restoring all segment registers on the stack
-; @param 1  full width register name
-; @param 2  16-bit register name for \a 1.
-
-%ifdef MAYBE_64_BIT
-  ; Save a host and load the corresponding guest MSR (trashes rdx & rcx)
-  %macro LOADGUESTMSR 2
-    mov     rcx, %1
-    rdmsr
-    push    rdx
-    push    rax
-    mov     edx, dword [xSI + %2 + 4]
-    mov     eax, dword [xSI + %2]
-    wrmsr
-  %endmacro
-
-  ; Save a guest and load the corresponding host MSR (trashes rdx & rcx)
-  ; Only really useful for gs kernel base as that one can be changed behind our back (swapgs)
-  %macro LOADHOSTMSREX 2
-    mov     rcx, %1
-    rdmsr
-    mov     dword [xSI + %2], eax
-    mov     dword [xSI + %2 + 4], edx
-    pop     rax
-    pop     rdx
-    wrmsr
-  %endmacro
-
-  ; Load the corresponding host MSR (trashes rdx & rcx)
-  %macro LOADHOSTMSR 1
-    mov     rcx, %1
-    pop     rax
-    pop     rdx
-    wrmsr
-  %endmacro
-%endif
-
-%ifdef ASM_CALL64_GCC
- %macro MYPUSHAD64 0
-   push    r15
-   push    r14
-   push    r13
-   push    r12
-   push    rbx
- %endmacro
- %macro MYPOPAD64 0
-   pop     rbx
-   pop     r12
-   pop     r13
-   pop     r14
-   pop     r15
- %endmacro
-
-%else ; ASM_CALL64_MSC
- %macro MYPUSHAD64 0
-   push    r15
-   push    r14
-   push    r13
-   push    r12
-   push    rbx
-   push    rsi
-   push    rdi
- %endmacro
- %macro MYPOPAD64 0
-   pop     rdi
-   pop     rsi
-   pop     rbx
-   pop     r12
-   pop     r13
-   pop     r14
-   pop     r15
- %endmacro
-%endif
-
-; trashes, rax, rdx & rcx
-%macro MYPUSHSEGS64 2
- %ifndef HWACCM_64_BIT_USE_NULL_SEL
-   mov     %2, es
-   push    %1
-   mov     %2, ds
-   push    %1
- %endif
-
-   ; Special case for FS; Windows and Linux either don't use it or restore it when leaving kernel mode, Solaris OTOH doesn't and we must save it.
-   mov     ecx, MSR_K8_FS_BASE
-   rdmsr
-   push    rdx
-   push    rax
- %ifndef HWACCM_64_BIT_USE_NULL_SEL
-   push    fs
- %endif
-
-   ; Special case for GS; OSes typically use swapgs to reset the hidden base register for GS on entry into the kernel. The same happens on exit
-   mov     ecx, MSR_K8_GS_BASE
-   rdmsr
-   push    rdx
-   push    rax
- %ifndef HWACCM_64_BIT_USE_NULL_SEL
-   push    gs
- %endif
-%endmacro
-
-; trashes, rax, rdx & rcx
-%macro MYPOPSEGS64 2
-   ; Note: do not step through this code with a debugger!
- %ifndef HWACCM_64_BIT_USE_NULL_SEL
-   xor     eax, eax
-   mov     ds, ax
-   mov     es, ax
-   mov     fs, ax
-   mov     gs, ax
- %endif
-
- %ifndef HWACCM_64_BIT_USE_NULL_SEL
-   pop     gs
- %endif
-   pop     rax
-   pop     rdx
-   mov     ecx, MSR_K8_GS_BASE
-   wrmsr
-
- %ifndef HWACCM_64_BIT_USE_NULL_SEL
-   pop     fs
- %endif
-   pop     rax
-   pop     rdx
-   mov     ecx, MSR_K8_FS_BASE
-   wrmsr
-   ; Now it's safe to step again
-
- %ifndef HWACCM_64_BIT_USE_NULL_SEL
-   pop     %1
-   mov     ds, %2
-   pop     %1
-   mov     es, %2
- %endif
-%endmacro
-
-%macro MYPUSHAD32 0
-  pushad
-%endmacro
-%macro MYPOPAD32 0
-  popad
-%endmacro
-
-%macro MYPUSHSEGS32 2
-  push    ds
-  push    es
-  push    fs
-  push    gs
-%endmacro
-%macro MYPOPSEGS32 2
-  pop     gs
-  pop     fs
-  pop     es
-  pop     ds
-%endmacro
-
-
-;*******************************************************************************
-;* External Symbols                                                            *
-;*******************************************************************************
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-extern NAME(SUPR0AbsIs64bit)
-extern NAME(SUPR0Abs64bitKernelCS)
-extern NAME(SUPR0Abs64bitKernelSS)
-extern NAME(SUPR0Abs64bitKernelDS)
-extern NAME(SUPR0AbsKernelCS)
-%endif
-%ifdef VBOX_WITH_KERNEL_USING_XMM
-extern NAME(CPUMIsGuestFPUStateActive)
-%endif
-
-
-;*******************************************************************************
-;*  Global Variables                                                           *
-;*******************************************************************************
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-BEGINDATA
-;;
-; Store the SUPR0AbsIs64bit absolute value here so we can cmp/test without
-; needing to clobber a register. (This trick doesn't quite work for PE btw.
-; but that's not relevant atm.)
-GLOBALNAME g_fVMXIs64bitHost
-    dd  NAME(SUPR0AbsIs64bit)
-%endif
-
-
-BEGINCODE
-
-
-;/**
-; * Executes VMWRITE, 64-bit value.
-; *
-; * @returns VBox status code
-; * @param   idxField   x86: [ebp + 08h]  msc: rcx  gcc: rdi   VMCS index
-; * @param   u64Data    x86: [ebp + 0ch]  msc: rdx  gcc: rsi   VM field value
-; */
-ALIGNCODE(16)
-BEGINPROC VMXWriteVMCS64
-%ifdef RT_ARCH_AMD64
- %ifdef ASM_CALL64_GCC
-    and         edi, 0ffffffffh
-    xor         rax, rax
-    vmwrite     rdi, rsi
- %else
-    and         ecx, 0ffffffffh
-    xor         rax, rax
-    vmwrite     rcx, rdx
- %endif
-%else  ; RT_ARCH_X86
-    mov         ecx, [esp + 4]          ; idxField
-    lea         edx, [esp + 8]          ; &u64Data
- %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    cmp         byte [NAME(g_fVMXIs64bitHost)], 0
-    jz          .legacy_mode
-    db          0xea                    ; jmp far .sixtyfourbit_mode
-    dd          .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
- %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-    vmwrite     ecx, [edx]              ; low dword
-    jz          .done
-    jc          .done
-    inc         ecx
-    xor         eax, eax
-    vmwrite     ecx, [edx + 4]          ; high dword
-.done:
-%endif ; RT_ARCH_X86
-    jnc         .valid_vmcs
-    mov         eax, VERR_VMX_INVALID_VMCS_PTR
-    ret
-.valid_vmcs:
-    jnz         .the_end
-    mov         eax, VERR_VMX_INVALID_VMCS_FIELD
-.the_end:
-    ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    and     edx, 0ffffffffh
-    and     ecx, 0ffffffffh
-    xor     eax, eax
-    vmwrite rcx, [rdx]
-    mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
-    cmovz   eax, r8d
-    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
-    cmovc   eax, r9d
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-ENDPROC VMXWriteVMCS64
-
-
-;/**
-; * Executes VMREAD, 64-bit value
-; *
-; * @returns VBox status code
-; * @param   idxField        VMCS index
-; * @param   pData           Ptr to store VM field value
-; */
-;DECLASM(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData);
-ALIGNCODE(16)
-BEGINPROC VMXReadVMCS64
-%ifdef RT_ARCH_AMD64
- %ifdef ASM_CALL64_GCC
-    and         edi, 0ffffffffh
-    xor         rax, rax
-    vmread      [rsi], rdi
- %else
-    and         ecx, 0ffffffffh
-    xor         rax, rax
-    vmread      [rdx], rcx
- %endif
-%else  ; RT_ARCH_X86
-    mov         ecx, [esp + 4]          ; idxField
-    mov         edx, [esp + 8]          ; pData
- %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    cmp         byte [NAME(g_fVMXIs64bitHost)], 0
-    jz          .legacy_mode
-    db          0xea                    ; jmp far .sixtyfourbit_mode
-    dd          .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
- %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-    vmread      [edx], ecx              ; low dword
-    jz          .done
-    jc          .done
-    inc         ecx
-    xor         eax, eax
-    vmread      [edx + 4], ecx          ; high dword
-.done:
-%endif ; RT_ARCH_X86
-    jnc         .valid_vmcs
-    mov         eax, VERR_VMX_INVALID_VMCS_PTR
-    ret
-.valid_vmcs:
-    jnz         .the_end
-    mov         eax, VERR_VMX_INVALID_VMCS_FIELD
-.the_end:
-    ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    and     edx, 0ffffffffh
-    and     ecx, 0ffffffffh
-    xor     eax, eax
-    vmread  [rdx], rcx
-    mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
-    cmovz   eax, r8d
-    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
-    cmovc   eax, r9d
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-ENDPROC VMXReadVMCS64
-
-
-;/**
-; * Executes VMREAD, 32-bit value.
-; *
-; * @returns VBox status code
-; * @param   idxField        VMCS index
-; * @param   pu32Data        Ptr to store VM field value
-; */
-;DECLASM(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pu32Data);
-ALIGNCODE(16)
-BEGINPROC VMXReadVMCS32
-%ifdef RT_ARCH_AMD64
- %ifdef ASM_CALL64_GCC
-    and     edi, 0ffffffffh
-    xor     rax, rax
-    vmread  r10, rdi
-    mov     [rsi], r10d
- %else
-    and     ecx, 0ffffffffh
-    xor     rax, rax
-    vmread  r10, rcx
-    mov     [rdx], r10d
- %endif
-%else  ; RT_ARCH_X86
-    mov     ecx, [esp + 4]              ; idxField
-    mov     edx, [esp + 8]              ; pu32Data
- %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    jz      .legacy_mode
-    db      0xea                        ; jmp far .sixtyfourbit_mode
-    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
- %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-    xor     eax, eax
-    vmread  [edx], ecx
-%endif ; RT_ARCH_X86
-    jnc     .valid_vmcs
-    mov     eax, VERR_VMX_INVALID_VMCS_PTR
-    ret
-.valid_vmcs:
-    jnz     .the_end
-    mov     eax, VERR_VMX_INVALID_VMCS_FIELD
-.the_end:
-    ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    and     edx, 0ffffffffh
-    and     ecx, 0ffffffffh
-    xor     eax, eax
-    vmread  r10, rcx
-    mov     [rdx], r10d
-    mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
-    cmovz   eax, r8d
-    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
-    cmovc   eax, r9d
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-ENDPROC VMXReadVMCS32
-
-
-;/**
-; * Executes VMWRITE, 32-bit value.
-; *
-; * @returns VBox status code
-; * @param   idxField        VMCS index
-; * @param   u32Data         Ptr to store VM field value
-; */
-;DECLASM(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Data);
-ALIGNCODE(16)
-BEGINPROC VMXWriteVMCS32
-%ifdef RT_ARCH_AMD64
- %ifdef ASM_CALL64_GCC
-    and     edi, 0ffffffffh
-    and     esi, 0ffffffffh
-    xor     rax, rax
-    vmwrite rdi, rsi
- %else
-    and     ecx, 0ffffffffh
-    and     edx, 0ffffffffh
-    xor     rax, rax
-    vmwrite rcx, rdx
- %endif
-%else  ; RT_ARCH_X86
-    mov     ecx, [esp + 4]              ; idxField
-    mov     edx, [esp + 8]              ; u32Data
- %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    jz      .legacy_mode
-    db      0xea                        ; jmp far .sixtyfourbit_mode
-    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
- %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-    xor     eax, eax
-    vmwrite ecx, edx
-%endif ; RT_ARCH_X86
-    jnc     .valid_vmcs
-    mov     eax, VERR_VMX_INVALID_VMCS_PTR
-    ret
-.valid_vmcs:
-    jnz     .the_end
-    mov     eax, VERR_VMX_INVALID_VMCS_FIELD
-.the_end:
-    ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    and     edx, 0ffffffffh
-    and     ecx, 0ffffffffh
-    xor     eax, eax
-    vmwrite rcx, rdx
-    mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
-    cmovz   eax, r8d
-    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
-    cmovc   eax, r9d
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-ENDPROC VMXWriteVMCS32
-
-
-;/**
-; * Executes VMXON
-; *
-; * @returns VBox status code
-; * @param   HCPhysVMXOn      Physical address of VMXON structure
-; */
-;DECLASM(int) VMXEnable(RTHCPHYS HCPhysVMXOn);
-BEGINPROC VMXEnable
-%ifdef RT_ARCH_AMD64
-    xor     rax, rax
- %ifdef ASM_CALL64_GCC
-    push    rdi
- %else
-    push    rcx
- %endif
-    vmxon   [rsp]
-%else  ; RT_ARCH_X86
- %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    jz      .legacy_mode
-    db      0xea                        ; jmp far .sixtyfourbit_mode
-    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
- %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-    xor     eax, eax
-    vmxon   [esp + 4]
-%endif ; RT_ARCH_X86
-    jnc     .good
-    mov     eax, VERR_VMX_INVALID_VMXON_PTR
-    jmp     .the_end
-
-.good:
-    jnz     .the_end
-    mov     eax, VERR_VMX_GENERIC
-
-.the_end:
-%ifdef RT_ARCH_AMD64
-    add     rsp, 8
-%endif
-    ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    lea     rdx, [rsp + 4]              ; &HCPhysVMXOn.
-    and     edx, 0ffffffffh
-    xor     eax, eax
-    vmxon   [rdx]
-    mov     r8d, VERR_INVALID_PARAMETER
-    cmovz   eax, r8d
-    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
-    cmovc   eax, r9d
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-ENDPROC VMXEnable
-
-
-;/**
-; * Executes VMXOFF
-; */
-;DECLASM(void) VMXDisable(void);
-BEGINPROC VMXDisable
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    jz      .legacy_mode
-    db      0xea                        ; jmp far .sixtyfourbit_mode
-    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-    vmxoff
-.the_end:
-    ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    vmxoff
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-ENDPROC VMXDisable
-
-
-;/**
-; * Executes VMCLEAR
-; *
-; * @returns VBox status code
-; * @param   HCPhysVMCS     Physical address of VM control structure
-; */
-;DECLASM(int) VMXClearVMCS(RTHCPHYS HCPhysVMCS);
-ALIGNCODE(16)
-BEGINPROC VMXClearVMCS
-%ifdef RT_ARCH_AMD64
-    xor     rax, rax
- %ifdef ASM_CALL64_GCC
-    push    rdi
- %else
-    push    rcx
- %endif
-    vmclear [rsp]
-%else  ; RT_ARCH_X86
- %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    jz      .legacy_mode
-    db      0xea                        ; jmp far .sixtyfourbit_mode
-    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
- %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-    xor     eax, eax
-    vmclear [esp + 4]
-%endif ; RT_ARCH_X86
-    jnc     .the_end
-    mov     eax, VERR_VMX_INVALID_VMCS_PTR
-.the_end:
-%ifdef RT_ARCH_AMD64
-    add     rsp, 8
-%endif
-    ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    lea     rdx, [rsp + 4]              ; &HCPhysVMCS
-    and     edx, 0ffffffffh
-    xor     eax, eax
-    vmclear [rdx]
-    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
-    cmovc   eax, r9d
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif
-ENDPROC VMXClearVMCS
-
-
-;/**
-; * Executes VMPTRLD
-; *
-; * @returns VBox status code
-; * @param   HCPhysVMCS     Physical address of VMCS structure
-; */
-;DECLASM(int) VMXActivateVMCS(RTHCPHYS HCPhysVMCS);
-ALIGNCODE(16)
-BEGINPROC VMXActivateVMCS
-%ifdef RT_ARCH_AMD64
-    xor     rax, rax
- %ifdef ASM_CALL64_GCC
-    push    rdi
- %else
-    push    rcx
- %endif
-    vmptrld [rsp]
-%else
- %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    jz      .legacy_mode
-    db      0xea                        ; jmp far .sixtyfourbit_mode
-    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
- %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-    xor     eax, eax
-    vmptrld [esp + 4]
-%endif
-    jnc     .the_end
-    mov     eax, VERR_VMX_INVALID_VMCS_PTR
-.the_end:
-%ifdef RT_ARCH_AMD64
-    add     rsp, 8
-%endif
-    ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    lea     rdx, [rsp + 4]              ; &HCPhysVMCS
-    and     edx, 0ffffffffh
-    xor     eax, eax
-    vmptrld [rdx]
-    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
-    cmovc   eax, r9d
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-ENDPROC VMXActivateVMCS
-
-
-;/**
-; * Executes VMPTRST
-; *
-; * @returns VBox status code
-; * @param    [esp + 04h]  gcc:rdi  msc:rcx   Param 1 - First parameter - Address that will receive the current pointer
-; */
-;DECLASM(int) VMXGetActivateVMCS(RTHCPHYS *pVMCS);
-BEGINPROC VMXGetActivateVMCS
-%ifdef RT_OS_OS2
-    mov     eax, VERR_NOT_SUPPORTED
-    ret
-%else
- %ifdef RT_ARCH_AMD64
-  %ifdef ASM_CALL64_GCC
-    vmptrst qword [rdi]
-  %else
-    vmptrst qword [rcx]
-  %endif
- %else
-  %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    jz      .legacy_mode
-    db      0xea                        ; jmp far .sixtyfourbit_mode
-    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
-  %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-    vmptrst qword [esp+04h]
- %endif
-    xor     eax, eax
-.the_end:
-    ret
-
- %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    lea     rdx, [rsp + 4]              ; &HCPhysVMCS
-    and     edx, 0ffffffffh
-    vmptrst qword [rdx]
-    xor     eax, eax
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
- %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-%endif
-ENDPROC VMXGetActivateVMCS
-
-;/**
-; * Invalidate a page using invept
-; @param   enmFlush     msc:ecx  gcc:edi  x86:[esp+04]  Type of flush
-; @param   pDescriptor  msc:edx  gcc:esi  x86:[esp+08]  Descriptor pointer
-; */
-;DECLASM(int) VMXR0InvEPT(VMX_FLUSH enmFlush, uint64_t *pDescriptor);
-BEGINPROC VMXR0InvEPT
-%ifdef RT_ARCH_AMD64
- %ifdef ASM_CALL64_GCC
-    and         edi, 0ffffffffh
-    xor         rax, rax
-;    invept      rdi, qword [rsi]
-    DB          0x66, 0x0F, 0x38, 0x80, 0x3E
- %else
-    and         ecx, 0ffffffffh
-    xor         rax, rax
-;    invept      rcx, qword [rdx]
-    DB          0x66, 0x0F, 0x38, 0x80, 0xA
- %endif
-%else
- %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    cmp         byte [NAME(g_fVMXIs64bitHost)], 0
-    jz          .legacy_mode
-    db          0xea                        ; jmp far .sixtyfourbit_mode
-    dd          .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
- %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-    mov         ecx, [esp + 4]
-    mov         edx, [esp + 8]
-    xor         eax, eax
-;    invept      ecx, qword [edx]
-    DB          0x66, 0x0F, 0x38, 0x80, 0xA
-%endif
-    jnc         .valid_vmcs
-    mov         eax, VERR_VMX_INVALID_VMCS_PTR
-    ret
-.valid_vmcs:
-    jnz         .the_end
-    mov         eax, VERR_INVALID_PARAMETER
-.the_end:
-    ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    and     esp, 0ffffffffh
-    mov     ecx, [rsp + 4]              ; enmFlush
-    mov     edx, [rsp + 8]              ; pDescriptor
-    xor     eax, eax
-;    invept  rcx, qword [rdx]
-    DB      0x66, 0x0F, 0x38, 0x80, 0xA
-    mov     r8d, VERR_INVALID_PARAMETER
-    cmovz   eax, r8d
-    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
-    cmovc   eax, r9d
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-ENDPROC VMXR0InvEPT
-
-
-;/**
-; * Invalidate a page using invvpid
-; @param   enmFlush     msc:ecx  gcc:edi  x86:[esp+04]  Type of flush
-; @param   pDescriptor  msc:edx  gcc:esi  x86:[esp+08]  Descriptor pointer
-; */
-;DECLASM(int) VMXR0InvVPID(VMX_FLUSH enmFlush, uint64_t *pDescriptor);
-BEGINPROC VMXR0InvVPID
-%ifdef RT_ARCH_AMD64
- %ifdef ASM_CALL64_GCC
-    and         edi, 0ffffffffh
-    xor         rax, rax
-;    invvpid     rdi, qword [rsi]
-    DB          0x66, 0x0F, 0x38, 0x81, 0x3E
- %else
-    and         ecx, 0ffffffffh
-    xor         rax, rax
-;    invvpid     rcx, qword [rdx]
-    DB          0x66, 0x0F, 0x38, 0x81, 0xA
- %endif
-%else
- %ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    jz      .legacy_mode
-    db      0xea                        ; jmp far .sixtyfourbit_mode
-    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.legacy_mode:
- %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-    mov         ecx, [esp + 4]
-    mov         edx, [esp + 8]
-    xor         eax, eax
-;    invvpid     ecx, qword [edx]
-    DB          0x66, 0x0F, 0x38, 0x81, 0xA
-%endif
-    jnc         .valid_vmcs
-    mov         eax, VERR_VMX_INVALID_VMCS_PTR
-    ret
-.valid_vmcs:
-    jnz         .the_end
-    mov         eax, VERR_INVALID_PARAMETER
-.the_end:
-    ret
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    and     esp, 0ffffffffh
-    mov     ecx, [rsp + 4]              ; enmFlush
-    mov     edx, [rsp + 8]              ; pDescriptor
-    xor     eax, eax
-;    invvpid rcx, qword [rdx]
-    DB      0x66, 0x0F, 0x38, 0x81, 0xA
-    mov     r8d, VERR_INVALID_PARAMETER
-    cmovz   eax, r8d
-    mov     r9d, VERR_VMX_INVALID_VMCS_PTR
-    cmovc   eax, r9d
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-ENDPROC VMXR0InvVPID
-
-
-%if GC_ARCH_BITS == 64
-;;
-; Executes INVLPGA
-;
-; @param   pPageGC  msc:rcx  gcc:rdi  x86:[esp+04]  Virtual page to invalidate
-; @param   uASID    msc:rdx  gcc:rsi  x86:[esp+0C]  Tagged TLB id
-;
-;DECLASM(void) SVMR0InvlpgA(RTGCPTR pPageGC, uint32_t uASID);
-BEGINPROC SVMR0InvlpgA
-%ifdef RT_ARCH_AMD64
- %ifdef ASM_CALL64_GCC
-    mov     rax, rdi
-    mov     rcx, rsi
- %else
-    mov     rax, rcx
-    mov     rcx, rdx
- %endif
-%else
-    mov     eax, [esp + 4]
-    mov     ecx, [esp + 0Ch]
-%endif
-    invlpga [xAX], ecx
-    ret
-ENDPROC SVMR0InvlpgA
-
-%else ; GC_ARCH_BITS != 64
-;;
-; Executes INVLPGA
-;
-; @param   pPageGC  msc:ecx  gcc:edi  x86:[esp+04]  Virtual page to invalidate
-; @param   uASID    msc:edx  gcc:esi  x86:[esp+08]  Tagged TLB id
-;
-;DECLASM(void) SVMR0InvlpgA(RTGCPTR pPageGC, uint32_t uASID);
-BEGINPROC SVMR0InvlpgA
-%ifdef RT_ARCH_AMD64
- %ifdef ASM_CALL64_GCC
-    movzx   rax, edi
-    mov     ecx, esi
- %else
-    ; from http://www.cs.cmu.edu/~fp/courses/15213-s06/misc/asm64-handout.pdf:
-    ; ``Perhaps unexpectedly, instructions that move or generate 32-bit register
-    ;   values also set the upper 32 bits of the register to zero. Consequently
-    ;   there is no need for an instruction movzlq.''
-    mov     eax, ecx
-    mov     ecx, edx
- %endif
-%else
-    mov     eax, [esp + 4]
-    mov     ecx, [esp + 8]
-%endif
-    invlpga [xAX], ecx
-    ret
-ENDPROC SVMR0InvlpgA
-
-%endif ; GC_ARCH_BITS != 64
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-
-;/**
-; * Gets 64-bit GDTR and IDTR on darwin.
-; * @param  pGdtr        Where to store the 64-bit GDTR.
-; * @param  pIdtr        Where to store the 64-bit IDTR.
-; */
-;DECLASM(void) hwaccmR0Get64bitGDTRandIDTR(PX86XDTR64 pGdtr, PX86XDTR64 pIdtr);
-ALIGNCODE(16)
-BEGINPROC hwaccmR0Get64bitGDTRandIDTR
-    db      0xea                        ; jmp far .sixtyfourbit_mode
-    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.the_end:
-    ret
-
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    and     esp, 0ffffffffh
-    mov     ecx, [rsp + 4]              ; pGdtr
-    mov     edx, [rsp + 8]              ; pIdtr
-    sgdt    [rcx]
-    sidt    [rdx]
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-ENDPROC   hwaccmR0Get64bitGDTRandIDTR
-
-
-;/**
-; * Gets 64-bit CR3 on darwin.
-; * @returns CR3
-; */
-;DECLASM(uint64_t) hwaccmR0Get64bitCR3(void);
-ALIGNCODE(16)
-BEGINPROC hwaccmR0Get64bitCR3
-    db      0xea                        ; jmp far .sixtyfourbit_mode
-    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
-.the_end:
-    ret
-
-ALIGNCODE(16)
-BITS 64
-.sixtyfourbit_mode:
-    mov     rax, cr3
-    mov     rdx, rax
-    shr     rdx, 32
-    jmp far [.fpret wrt rip]
-.fpret:                                 ; 16:32 Pointer to .the_end.
-    dd      .the_end, NAME(SUPR0AbsKernelCS)
-BITS 32
-ENDPROC   hwaccmR0Get64bitCR3
-
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
-
-%ifdef VBOX_WITH_KERNEL_USING_XMM
-
-;;
-; Wrapper around vmx.pfnStartVM that preserves host XMM registers and
-; load the guest ones when necessary.
-;
-; @cproto       DECLASM(int) hwaccmR0VMXStartVMWrapXMM(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu, PFNHWACCMVMXSTARTVM pfnStartVM);
-;
-; @returns      eax
-;
-; @param        fResumeVM       msc:rcx
-; @param        pCtx            msc:rdx
-; @param        pVMCSCache      msc:r8
-; @param        pVM             msc:r9
-; @param        pVCpu           msc:[rbp+30h]
-; @param        pfnStartVM      msc:[rbp+38h]
-;
-; @remarks      This is essentially the same code as hwaccmR0SVMRunWrapXMM, only the parameters differ a little bit.
-;
-; ASSUMING 64-bit and windows for now.
-ALIGNCODE(16)
-BEGINPROC hwaccmR0VMXStartVMWrapXMM
-        push    xBP
-        mov     xBP, xSP
-        sub     xSP, 0a0h + 040h        ; Don't bother optimizing the frame size.
-
-        ; spill input parameters.
-        mov     [xBP + 010h], rcx       ; fResumeVM
-        mov     [xBP + 018h], rdx       ; pCtx
-        mov     [xBP + 020h], r8        ; pVMCSCache
-        mov     [xBP + 028h], r9        ; pVM
-
-        ; Ask CPUM whether we've started using the FPU yet.
-        mov     rcx, [xBP + 30h]        ; pVCpu
-        call    NAME(CPUMIsGuestFPUStateActive)
-        test    al, al
-        jnz     .guest_fpu_state_active
-
-        ; No need to mess with XMM registers just call the start routine and return.
-        mov     r11, [xBP + 38h]        ; pfnStartVM
-        mov     r10, [xBP + 30h]        ; pVCpu
-        mov     [xSP + 020h], r10
-        mov     rcx, [xBP + 010h]       ; fResumeVM
-        mov     rdx, [xBP + 018h]       ; pCtx
-        mov     r8,  [xBP + 020h]       ; pVMCSCache
-        mov     r9,  [xBP + 028h]       ; pVM
-        call    r11
-
-        leave
-        ret
-
-ALIGNCODE(8)
-.guest_fpu_state_active:
-        ; Save the host XMM registers.
-        movdqa  [rsp + 040h + 000h], xmm6
-        movdqa  [rsp + 040h + 010h], xmm7
-        movdqa  [rsp + 040h + 020h], xmm8
-        movdqa  [rsp + 040h + 030h], xmm9
-        movdqa  [rsp + 040h + 040h], xmm10
-        movdqa  [rsp + 040h + 050h], xmm11
-        movdqa  [rsp + 040h + 060h], xmm12
-        movdqa  [rsp + 040h + 070h], xmm13
-        movdqa  [rsp + 040h + 080h], xmm14
-        movdqa  [rsp + 040h + 090h], xmm15
-
-        ; Load the full guest XMM register state.
-        mov     r10, [xBP + 018h]       ; pCtx
-        lea     r10, [r10 + XMM_OFF_IN_X86FXSTATE]
-        movdqa  xmm0,  [r10 + 000h]
-        movdqa  xmm1,  [r10 + 010h]
-        movdqa  xmm2,  [r10 + 020h]
-        movdqa  xmm3,  [r10 + 030h]
-        movdqa  xmm4,  [r10 + 040h]
-        movdqa  xmm5,  [r10 + 050h]
-        movdqa  xmm6,  [r10 + 060h]
-        movdqa  xmm7,  [r10 + 070h]
-        movdqa  xmm8,  [r10 + 080h]
-        movdqa  xmm9,  [r10 + 090h]
-        movdqa  xmm10, [r10 + 0a0h]
-        movdqa  xmm11, [r10 + 0b0h]
-        movdqa  xmm12, [r10 + 0c0h]
-        movdqa  xmm13, [r10 + 0d0h]
-        movdqa  xmm14, [r10 + 0e0h]
-        movdqa  xmm15, [r10 + 0f0h]
-
-        ; Make the call (same as in the other case ).
-        mov     r11, [xBP + 38h]        ; pfnStartVM
-        mov     r10, [xBP + 30h]        ; pVCpu
-        mov     [xSP + 020h], r10
-        mov     rcx, [xBP + 010h]       ; fResumeVM
-        mov     rdx, [xBP + 018h]       ; pCtx
-        mov     r8,  [xBP + 020h]       ; pVMCSCache
-        mov     r9,  [xBP + 028h]       ; pVM
-        call    r11
-
-        ; Save the guest XMM registers.
-        mov     r10, [xBP + 018h]       ; pCtx
-        lea     r10, [r10 + XMM_OFF_IN_X86FXSTATE]
-        movdqa  [r10 + 000h], xmm0
-        movdqa  [r10 + 010h], xmm1
-        movdqa  [r10 + 020h], xmm2
-        movdqa  [r10 + 030h], xmm3
-        movdqa  [r10 + 040h], xmm4
-        movdqa  [r10 + 050h], xmm5
-        movdqa  [r10 + 060h], xmm6
-        movdqa  [r10 + 070h], xmm7
-        movdqa  [r10 + 080h], xmm8
-        movdqa  [r10 + 090h], xmm9
-        movdqa  [r10 + 0a0h], xmm10
-        movdqa  [r10 + 0b0h], xmm11
-        movdqa  [r10 + 0c0h], xmm12
-        movdqa  [r10 + 0d0h], xmm13
-        movdqa  [r10 + 0e0h], xmm14
-        movdqa  [r10 + 0f0h], xmm15
-
-        ; Load the host XMM registers.
-        movdqa  xmm6,  [rsp + 040h + 000h]
-        movdqa  xmm7,  [rsp + 040h + 010h]
-        movdqa  xmm8,  [rsp + 040h + 020h]
-        movdqa  xmm9,  [rsp + 040h + 030h]
-        movdqa  xmm10, [rsp + 040h + 040h]
-        movdqa  xmm11, [rsp + 040h + 050h]
-        movdqa  xmm12, [rsp + 040h + 060h]
-        movdqa  xmm13, [rsp + 040h + 070h]
-        movdqa  xmm14, [rsp + 040h + 080h]
-        movdqa  xmm15, [rsp + 040h + 090h]
-        leave
-        ret
-ENDPROC   hwaccmR0VMXStartVMWrapXMM
-
-;;
-; Wrapper around svm.pfnVMRun that preserves host XMM registers and
-; load the guest ones when necessary.
-;
-; @cproto       DECLASM(int) hwaccmR0SVMRunWrapXMM(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu, PFNHWACCMSVMVMRUN pfnVMRun);
-;
-; @returns      eax
-;
-; @param        pVMCBHostPhys   msc:rcx
-; @param        pVMCBPhys       msc:rdx
-; @param        pCtx            msc:r8
-; @param        pVM             msc:r9
-; @param        pVCpu           msc:[rbp+30h]
-; @param        pfnVMRun        msc:[rbp+38h]
-;
-; @remarks      This is essentially the same code as hwaccmR0VMXStartVMWrapXMM, only the parameters differ a little bit.
-;
-; ASSUMING 64-bit and windows for now.
-ALIGNCODE(16)
-BEGINPROC hwaccmR0SVMRunWrapXMM
-        push    xBP
-        mov     xBP, xSP
-        sub     xSP, 0a0h + 040h        ; Don't bother optimizing the frame size.
-
-        ; spill input parameters.
-        mov     [xBP + 010h], rcx       ; pVMCBHostPhys
-        mov     [xBP + 018h], rdx       ; pVMCBPhys
-        mov     [xBP + 020h], r8        ; pCtx
-        mov     [xBP + 028h], r9        ; pVM
-
-        ; Ask CPUM whether we've started using the FPU yet.
-        mov     rcx, [xBP + 30h]        ; pVCpu
-        call    NAME(CPUMIsGuestFPUStateActive)
-        test    al, al
-        jnz     .guest_fpu_state_active
-
-        ; No need to mess with XMM registers just call the start routine and return.
-        mov     r11, [xBP + 38h]        ; pfnVMRun
-        mov     r10, [xBP + 30h]        ; pVCpu
-        mov     [xSP + 020h], r10
-        mov     rcx, [xBP + 010h]       ; pVMCBHostPhys
-        mov     rdx, [xBP + 018h]       ; pVMCBPhys
-        mov     r8,  [xBP + 020h]       ; pCtx
-        mov     r9,  [xBP + 028h]       ; pVM
-        call    r11
-
-        leave
-        ret
-
-ALIGNCODE(8)
-.guest_fpu_state_active:
-        ; Save the host XMM registers.
-        movdqa  [rsp + 040h + 000h], xmm6
-        movdqa  [rsp + 040h + 010h], xmm7
-        movdqa  [rsp + 040h + 020h], xmm8
-        movdqa  [rsp + 040h + 030h], xmm9
-        movdqa  [rsp + 040h + 040h], xmm10
-        movdqa  [rsp + 040h + 050h], xmm11
-        movdqa  [rsp + 040h + 060h], xmm12
-        movdqa  [rsp + 040h + 070h], xmm13
-        movdqa  [rsp + 040h + 080h], xmm14
-        movdqa  [rsp + 040h + 090h], xmm15
-
-        ; Load the full guest XMM register state.
-        mov     r10, [xBP + 020h]       ; pCtx
-        lea     r10, [r10 + XMM_OFF_IN_X86FXSTATE]
-        movdqa  xmm0,  [r10 + 000h]
-        movdqa  xmm1,  [r10 + 010h]
-        movdqa  xmm2,  [r10 + 020h]
-        movdqa  xmm3,  [r10 + 030h]
-        movdqa  xmm4,  [r10 + 040h]
-        movdqa  xmm5,  [r10 + 050h]
-        movdqa  xmm6,  [r10 + 060h]
-        movdqa  xmm7,  [r10 + 070h]
-        movdqa  xmm8,  [r10 + 080h]
-        movdqa  xmm9,  [r10 + 090h]
-        movdqa  xmm10, [r10 + 0a0h]
-        movdqa  xmm11, [r10 + 0b0h]
-        movdqa  xmm12, [r10 + 0c0h]
-        movdqa  xmm13, [r10 + 0d0h]
-        movdqa  xmm14, [r10 + 0e0h]
-        movdqa  xmm15, [r10 + 0f0h]
-
-        ; Make the call (same as in the other case ).
-        mov     r11, [xBP + 38h]        ; pfnVMRun
-        mov     r10, [xBP + 30h]        ; pVCpu
-        mov     [xSP + 020h], r10
-        mov     rcx, [xBP + 010h]       ; pVMCBHostPhys
-        mov     rdx, [xBP + 018h]       ; pVMCBPhys
-        mov     r8,  [xBP + 020h]       ; pCtx
-        mov     r9,  [xBP + 028h]       ; pVM
-        call    r11
-
-        ; Save the guest XMM registers.
-        mov     r10, [xBP + 020h]       ; pCtx
-        lea     r10, [r10 + XMM_OFF_IN_X86FXSTATE]
-        movdqa  [r10 + 000h], xmm0
-        movdqa  [r10 + 010h], xmm1
-        movdqa  [r10 + 020h], xmm2
-        movdqa  [r10 + 030h], xmm3
-        movdqa  [r10 + 040h], xmm4
-        movdqa  [r10 + 050h], xmm5
-        movdqa  [r10 + 060h], xmm6
-        movdqa  [r10 + 070h], xmm7
-        movdqa  [r10 + 080h], xmm8
-        movdqa  [r10 + 090h], xmm9
-        movdqa  [r10 + 0a0h], xmm10
-        movdqa  [r10 + 0b0h], xmm11
-        movdqa  [r10 + 0c0h], xmm12
-        movdqa  [r10 + 0d0h], xmm13
-        movdqa  [r10 + 0e0h], xmm14
-        movdqa  [r10 + 0f0h], xmm15
-
-        ; Load the host XMM registers.
-        movdqa  xmm6,  [rsp + 040h + 000h]
-        movdqa  xmm7,  [rsp + 040h + 010h]
-        movdqa  xmm8,  [rsp + 040h + 020h]
-        movdqa  xmm9,  [rsp + 040h + 030h]
-        movdqa  xmm10, [rsp + 040h + 040h]
-        movdqa  xmm11, [rsp + 040h + 050h]
-        movdqa  xmm12, [rsp + 040h + 060h]
-        movdqa  xmm13, [rsp + 040h + 070h]
-        movdqa  xmm14, [rsp + 040h + 080h]
-        movdqa  xmm15, [rsp + 040h + 090h]
-        leave
-        ret
-ENDPROC   hwaccmR0SVMRunWrapXMM
-
-%endif ; VBOX_WITH_KERNEL_USING_XMM
-
-;
-; The default setup of the StartVM routines.
-;
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
- %define MY_NAME(name)   name %+ _32
-%else
- %define MY_NAME(name)   name
-%endif
-%ifdef RT_ARCH_AMD64
- %define MYPUSHAD       MYPUSHAD64
- %define MYPOPAD        MYPOPAD64
- %define MYPUSHSEGS     MYPUSHSEGS64
- %define MYPOPSEGS      MYPOPSEGS64
-%else
- %define MYPUSHAD       MYPUSHAD32
- %define MYPOPAD        MYPOPAD32
- %define MYPUSHSEGS     MYPUSHSEGS32
- %define MYPOPSEGS      MYPOPSEGS32
-%endif
-
-%include "HWACCMR0Mixed.mac"
-
-
-%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
- ;
- ; Write the wrapper procedures.
- ;
- ; These routines are probably being too paranoid about selector
- ; restoring, but better safe than sorry...
- ;
-
-; DECLASM(int) VMXR0StartVM32(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache /*, PVM pVM, PVMCPU pVCpu*/);
-ALIGNCODE(16)
-BEGINPROC VMXR0StartVM32
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    je near NAME(VMXR0StartVM32_32)
-
-    ; stack frame
-    push    esi
-    push    edi
-    push    fs
-    push    gs
-
-    ; jmp far .thunk64
-    db      0xea
-    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
-
-ALIGNCODE(16)
-BITS 64
-.thunk64:
-    sub     esp, 20h
-    mov     edi, [rsp + 20h + 14h]      ; fResume
-    mov     esi, [rsp + 20h + 18h]      ; pCtx
-    mov     edx, [rsp + 20h + 1Ch]      ; pCache
-    call    NAME(VMXR0StartVM32_64)
-    add     esp, 20h
-    jmp far [.fpthunk32 wrt rip]
-.fpthunk32:                             ; 16:32 Pointer to .thunk32.
-    dd      .thunk32, NAME(SUPR0AbsKernelCS)
-
-BITS 32
-ALIGNCODE(16)
-.thunk32:
-    pop     gs
-    pop     fs
-    pop     edi
-    pop     esi
-    ret
-ENDPROC   VMXR0StartVM32
-
-
-; DECLASM(int) VMXR0StartVM64(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache /*, PVM pVM, PVMCPU pVCpu*/);
-ALIGNCODE(16)
-BEGINPROC VMXR0StartVM64
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    je      .not_in_long_mode
-
-    ; stack frame
-    push    esi
-    push    edi
-    push    fs
-    push    gs
-
-    ; jmp far .thunk64
-    db      0xea
-    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
-
-ALIGNCODE(16)
-BITS 64
-.thunk64:
-    sub     esp, 20h
-    mov     edi, [rsp + 20h + 14h]      ; fResume
-    mov     esi, [rsp + 20h + 18h]      ; pCtx
-    mov     edx, [rsp + 20h + 1Ch]      ; pCache
-    call    NAME(VMXR0StartVM64_64)
-    add     esp, 20h
-    jmp far [.fpthunk32 wrt rip]
-.fpthunk32:                             ; 16:32 Pointer to .thunk32.
-    dd      .thunk32, NAME(SUPR0AbsKernelCS)
-
-BITS 32
-ALIGNCODE(16)
-.thunk32:
-    pop     gs
-    pop     fs
-    pop     edi
-    pop     esi
-    ret
-
-.not_in_long_mode:
-    mov     eax, VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE
-    ret
-ENDPROC   VMXR0StartVM64
-
-;DECLASM(int) SVMR0VMRun(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx /*, PVM pVM, PVMCPU pVCpu*/);
-ALIGNCODE(16)
-BEGINPROC SVMR0VMRun
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    je near NAME(SVMR0VMRun_32)
-
-    ; stack frame
-    push    esi
-    push    edi
-    push    fs
-    push    gs
-
-    ; jmp far .thunk64
-    db      0xea
-    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
-
-ALIGNCODE(16)
-BITS 64
-.thunk64:
-    sub     esp, 20h
-    mov     rdi, [rsp + 20h + 14h]      ; pVMCBHostPhys
-    mov     rsi, [rsp + 20h + 1Ch]      ; pVMCBPhys
-    mov     edx, [rsp + 20h + 24h]      ; pCtx
-    call    NAME(SVMR0VMRun_64)
-    add     esp, 20h
-    jmp far [.fpthunk32 wrt rip]
-.fpthunk32:                             ; 16:32 Pointer to .thunk32.
-    dd      .thunk32, NAME(SUPR0AbsKernelCS)
-
-BITS 32
-ALIGNCODE(16)
-.thunk32:
-    pop     gs
-    pop     fs
-    pop     edi
-    pop     esi
-    ret
-ENDPROC   SVMR0VMRun
-
-
-; DECLASM(int) SVMR0VMRun64(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx /*, PVM pVM, PVMCPU pVCpu*/);
-ALIGNCODE(16)
-BEGINPROC SVMR0VMRun64
-    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
-    je      .not_in_long_mode
-
-    ; stack frame
-    push    esi
-    push    edi
-    push    fs
-    push    gs
-
-    ; jmp far .thunk64
-    db      0xea
-    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
-
-ALIGNCODE(16)
-BITS 64
-.thunk64:
-    sub     esp, 20h
-    mov     rdi, [rbp + 20h + 14h]      ; pVMCBHostPhys
-    mov     rsi, [rbp + 20h + 1Ch]      ; pVMCBPhys
-    mov     edx, [rbp + 20h + 24h]      ; pCtx
-    call    NAME(SVMR0VMRun64_64)
-    add     esp, 20h
-    jmp far [.fpthunk32 wrt rip]
-.fpthunk32:                             ; 16:32 Pointer to .thunk32.
-    dd      .thunk32, NAME(SUPR0AbsKernelCS)
-
-BITS 32
-ALIGNCODE(16)
-.thunk32:
-    pop     gs
-    pop     fs
-    pop     edi
-    pop     esi
-    ret
-
-.not_in_long_mode:
-    mov     eax, VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE
-    ret
-ENDPROC   SVMR0VMRun64
-
- ;
- ; Do it a second time pretending we're a 64-bit host.
- ;
- ; This *HAS* to be done at the very end of the file to avoid restoring
- ; macros. So, add new code *BEFORE* this mess.
- ;
- BITS 64
- %undef  RT_ARCH_X86
- %define RT_ARCH_AMD64
- %undef  ASM_CALL64_MSC
- %define ASM_CALL64_GCC
- %define xS             8
- %define xSP            rsp
- %define xBP            rbp
- %define xAX            rax
- %define xBX            rbx
- %define xCX            rcx
- %define xDX            rdx
- %define xDI            rdi
- %define xSI            rsi
- %define MY_NAME(name)   name %+ _64
- %define MYPUSHAD       MYPUSHAD64
- %define MYPOPAD        MYPOPAD64
- %define MYPUSHSEGS     MYPUSHSEGS64
- %define MYPOPSEGS      MYPOPSEGS64
-
- %include "HWACCMR0Mixed.mac"
-%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
Index: trunk/src/VBox/VMM/VMMR0/HWACCMR0Mixed.mac
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWACCMR0Mixed.mac	(revision 43379)
+++ 	(revision )
@@ -1,901 +1,0 @@
-; $Id$
-;; @file
-; HWACCMR0Mixed.mac - Stuff that darwin needs to build two versions of.
-;
-; Included by HWACCMR0A.asm with RT_ARCH_AMD64 defined or or undefined.
-;
-
-;
-; 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;
-; 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.
-;
-
-
-;/**
-; * Prepares for and executes VMLAUNCH/VMRESUME (32 bits guest mode)
-; *
-; * @returns VBox status code
-; * @param   fResume    x86:[ebp+8], msc:rcx,gcc:rdi     vmlauch/vmresume
-; * @param   pCtx       x86:[ebp+c], msc:rdx,gcc:rsi     Guest context
-; * @param   pCache     x86:[esp+10],msc:r8, gcc:rdx     VMCS cache
-; */
-ALIGNCODE(16)
-BEGINPROC MY_NAME(VMXR0StartVM32)
-    push    xBP
-    mov     xBP, xSP
-
-    pushf
-    cli
-
-    ;/* Save all general purpose host registers. */
-    MYPUSHAD
-
-    ;/* First we have to save some final CPU context registers. */
-    mov     eax, VMX_VMCS_HOST_RIP
-%ifdef RT_ARCH_AMD64
-    lea     r10, [.vmlaunch_done wrt rip]
-    vmwrite rax, r10
-%else
-    mov     ecx, .vmlaunch_done
-    vmwrite eax, ecx
-%endif
-    ;/* Note: assumes success... */
-
-    ;/* Manual save and restore:
-    ; * - General purpose registers except RIP, RSP
-    ; *
-    ; * Trashed:
-    ; * - CR2 (we don't care)
-    ; * - LDTR (reset to 0)
-    ; * - DRx (presumably not changed at all)
-    ; * - DR7 (reset to 0x400)
-    ; * - EFLAGS (reset to RT_BIT(1); not relevant)
-    ; *
-    ; */
-
-    ;/* Save the Guest CPU context pointer. */
-%ifdef RT_ARCH_AMD64
- %ifdef ASM_CALL64_GCC
-    ; fResume already in rdi
-    ; pCtx    already in rsi
-    mov     rbx, rdx        ; pCache
- %else
-    mov     rdi, rcx        ; fResume
-    mov     rsi, rdx        ; pCtx
-    mov     rbx, r8         ; pCache
- %endif
-%else
-    mov     edi, [ebp + 8]  ; fResume
-    mov     esi, [ebp + 12] ; pCtx
-    mov     ebx, [ebp + 16] ; pCache
-%endif
-
-    ;/* Save segment registers */
-    ; Note: MYPUSHSEGS trashes rdx & rcx, so we moved it here (msvc amd64 case)
-    MYPUSHSEGS xAX, ax
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    mov     ecx, [xBX + VMCSCACHE.Write.cValidEntries]
-    cmp     ecx, 0
-    je      .no_cached_writes
-    mov     edx, ecx
-    mov     ecx, 0
-    jmp     .cached_write
-
-ALIGN(16)
-.cached_write:
-    mov     eax, [xBX + VMCSCACHE.Write.aField + xCX*4]
-    vmwrite xAX, [xBX + VMCSCACHE.Write.aFieldVal + xCX*8]
-    inc     xCX
-    cmp     xCX, xDX
-    jl     .cached_write
-
-    mov     dword [xBX + VMCSCACHE.Write.cValidEntries], 0
-.no_cached_writes:
-
-    ; Save the pCache pointer
-    push    xBX
-%endif
-
-    ; Save the pCtx pointer
-    push    xSI
-
-    ; Save LDTR
-    xor     eax, eax
-    sldt    ax
-    push    xAX
-
-    ; The TR limit is reset to 0x67; restore it manually
-    str     eax
-    push    xAX
-
-    ; VMX only saves the base of the GDTR & IDTR and resets the limit to 0xffff; we must restore the limit correctly!
-    sub     xSP, xS*2
-    sgdt    [xSP]
-
-    sub     xSP, xS*2
-    sidt    [xSP]
-
-%ifdef VBOX_WITH_DR6_EXPERIMENT
-    ; Restore DR6 - experiment, not safe!
-    mov     xBX, [xSI + CPUMCTX.dr6]
-    mov     dr6, xBX
-%endif
-
-    ; Restore CR2
-    mov     ebx, [xSI + CPUMCTX.cr2]
-    mov     cr2, xBX
-
-    mov     eax, VMX_VMCS_HOST_RSP
-    vmwrite xAX, xSP
-    ;/* Note: assumes success... */
-    ;/* Don't mess with ESP anymore!! */
-
-    ;/* Restore Guest's general purpose registers. */
-    mov     eax, [xSI + CPUMCTX.eax]
-    mov     ebx, [xSI + CPUMCTX.ebx]
-    mov     ecx, [xSI + CPUMCTX.ecx]
-    mov     edx, [xSI + CPUMCTX.edx]
-    mov     ebp, [xSI + CPUMCTX.ebp]
-
-    ; resume or start?
-    cmp     xDI, 0                  ; fResume
-    je      .vmlauch_lauch
-
-    ;/* Restore edi & esi. */
-    mov     edi, [xSI + CPUMCTX.edi]
-    mov     esi, [xSI + CPUMCTX.esi]
-
-    vmresume
-    jmp     .vmlaunch_done;      ;/* here if vmresume detected a failure. */
-
-.vmlauch_lauch:
-    ;/* Restore edi & esi. */
-    mov     edi, [xSI + CPUMCTX.edi]
-    mov     esi, [xSI + CPUMCTX.esi]
-
-    vmlaunch
-    jmp     .vmlaunch_done;      ;/* here if vmlaunch detected a failure. */
-
-ALIGNCODE(16) ;; @todo YASM BUG - this alignment is wrong on darwin, it's 1 byte off.
-.vmlaunch_done:
-    jc      near .vmxstart_invalid_vmxon_ptr
-    jz      near .vmxstart_start_failed
-
-    ; Restore base and limit of the IDTR & GDTR
-    lidt    [xSP]
-    add     xSP, xS*2
-    lgdt    [xSP]
-    add     xSP, xS*2
-
-    push    xDI
-    mov     xDI, [xSP + xS * 3]         ; pCtx (*3 to skip the saved LDTR + TR)
-
-    mov     [ss:xDI + CPUMCTX.eax], eax
-    mov     [ss:xDI + CPUMCTX.ebx], ebx
-    mov     [ss:xDI + CPUMCTX.ecx], ecx
-    mov     [ss:xDI + CPUMCTX.edx], edx
-    mov     [ss:xDI + CPUMCTX.esi], esi
-    mov     [ss:xDI + CPUMCTX.ebp], ebp
-%ifdef RT_ARCH_AMD64
-    pop     xAX                                 ; the guest edi we pushed above
-    mov     dword [ss:xDI + CPUMCTX.edi], eax
-%else
-    pop     dword [ss:xDI + CPUMCTX.edi]        ; the guest edi we pushed above
-%endif
-
-%ifdef VBOX_WITH_DR6_EXPERIMENT
-    ; Save DR6 - experiment, not safe!
-    mov     xAX, dr6
-    mov     [ss:xDI + CPUMCTX.dr6], xAX
-%endif
-
-    ; Restore TSS selector; must mark it as not busy before using ltr (!)
-    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
-    ; @todo get rid of sgdt
-    pop     xBX         ; saved TR
-    sub     xSP, xS*2
-    sgdt    [xSP]
-    mov     xAX, xBX
-    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
-    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
-    and     dword [ss:xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
-    ltr     bx
-    add     xSP, xS*2
-
-    pop     xAX         ; saved LDTR
-    lldt    ax
-
-    add     xSP, xS      ; pCtx
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    pop     xDX         ; saved pCache
-
-    mov     ecx, [ss:xDX + VMCSCACHE.Read.cValidEntries]
-    cmp     ecx, 0  ; can't happen
-    je      .no_cached_reads
-    jmp     .cached_read
-
-ALIGN(16)
-.cached_read:
-    dec     xCX
-    mov     eax, [ss:xDX + VMCSCACHE.Read.aField + xCX*4]
-    vmread  [ss:xDX + VMCSCACHE.Read.aFieldVal + xCX*8], xAX
-    cmp     xCX, 0
-    jnz     .cached_read
-.no_cached_reads:
-
-    ; Save CR2 for EPT
-    mov     xAX, cr2
-    mov     [ss:xDX + VMCSCACHE.cr2], xAX
-%endif
-
-    ; Restore segment registers
-    MYPOPSEGS xAX, ax
-
-    ; Restore general purpose registers
-    MYPOPAD
-
-    mov     eax, VINF_SUCCESS
-
-.vmstart_end:
-    popf
-    pop     xBP
-    ret
-
-
-.vmxstart_invalid_vmxon_ptr:
-    ; Restore base and limit of the IDTR & GDTR
-    lidt    [xSP]
-    add     xSP, xS*2
-    lgdt    [xSP]
-    add     xSP, xS*2
-
-    ; Restore TSS selector; must mark it as not busy before using ltr (!)
-    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
-    ; @todo get rid of sgdt
-    pop     xBX         ; saved TR
-    sub     xSP, xS*2
-    sgdt    [xSP]
-    mov     xAX, xBX
-    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
-    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
-    and     dword [ss:xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
-    ltr     bx
-    add     xSP, xS*2
-
-    pop     xAX         ; saved LDTR
-    lldt    ax
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    add     xSP, xS*2   ; pCtx + pCache
-%else
-    add     xSP, xS     ; pCtx
-%endif
-
-    ; Restore segment registers
-    MYPOPSEGS xAX, ax
-
-    ; Restore all general purpose host registers.
-    MYPOPAD
-    mov     eax, VERR_VMX_INVALID_VMXON_PTR
-    jmp     .vmstart_end
-
-.vmxstart_start_failed:
-    ; Restore base and limit of the IDTR & GDTR
-    lidt    [xSP]
-    add     xSP, xS*2
-    lgdt    [xSP]
-    add     xSP, xS*2
-
-    ; Restore TSS selector; must mark it as not busy before using ltr (!)
-    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
-    ; @todo get rid of sgdt
-    pop     xBX         ; saved TR
-    sub     xSP, xS*2
-    sgdt    [xSP]
-    mov     xAX, xBX
-    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
-    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
-    and     dword [ss:xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
-    ltr     bx
-    add     xSP, xS*2
-
-    pop     xAX         ; saved LDTR
-    lldt    ax
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    add     xSP, xS*2   ; pCtx + pCache
-%else
-    add     xSP, xS     ; pCtx
-%endif
-
-    ; Restore segment registers
-    MYPOPSEGS xAX, ax
-
-    ; Restore all general purpose host registers.
-    MYPOPAD
-    mov     eax, VERR_VMX_UNABLE_TO_START_VM
-    jmp     .vmstart_end
-
-ENDPROC MY_NAME(VMXR0StartVM32)
-
-%ifdef RT_ARCH_AMD64
-;/**
-; * Prepares for and executes VMLAUNCH/VMRESUME (64 bits guest mode)
-; *
-; * @returns VBox status code
-; * @param   fResume    msc:rcx, gcc:rdi     vmlauch/vmresume
-; * @param   pCtx       msc:rdx, gcc:rsi     Guest context
-; * @param   pCache     msc:r8,  gcc:rdx     VMCS cache
-; */
-ALIGNCODE(16)
-BEGINPROC MY_NAME(VMXR0StartVM64)
-    push    xBP
-    mov     xBP, xSP
-
-    pushf
-    cli
-
-    ;/* Save all general purpose host registers. */
-    MYPUSHAD
-
-    ;/* First we have to save some final CPU context registers. */
-    lea     r10, [.vmlaunch64_done wrt rip]
-    mov     rax, VMX_VMCS_HOST_RIP  ;/* return address (too difficult to continue after VMLAUNCH?) */
-    vmwrite rax, r10
-    ;/* Note: assumes success... */
-
-    ;/* Manual save and restore:
-    ; * - General purpose registers except RIP, RSP
-    ; *
-    ; * Trashed:
-    ; * - CR2 (we don't care)
-    ; * - LDTR (reset to 0)
-    ; * - DRx (presumably not changed at all)
-    ; * - DR7 (reset to 0x400)
-    ; * - EFLAGS (reset to RT_BIT(1); not relevant)
-    ; *
-    ; */
-
-    ;/* Save the Guest CPU context pointer. */
-%ifdef ASM_CALL64_GCC
-    ; fResume already in rdi
-    ; pCtx    already in rsi
-    mov     rbx, rdx        ; pCache
-%else
-    mov     rdi, rcx        ; fResume
-    mov     rsi, rdx        ; pCtx
-    mov     rbx, r8         ; pCache
-%endif
-
-    ;/* Save segment registers */
-    ; Note: MYPUSHSEGS trashes rdx & rcx, so we moved it here (msvc amd64 case)
-    MYPUSHSEGS xAX, ax
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    mov     ecx, [xBX + VMCSCACHE.Write.cValidEntries]
-    cmp     ecx, 0
-    je      .no_cached_writes
-    mov     edx, ecx
-    mov     ecx, 0
-    jmp     .cached_write
-
-ALIGN(16)
-.cached_write:
-    mov     eax, [xBX + VMCSCACHE.Write.aField + xCX*4]
-    vmwrite xAX, [xBX + VMCSCACHE.Write.aFieldVal + xCX*8]
-    inc     xCX
-    cmp     xCX, xDX
-    jl     .cached_write
-
-    mov     dword [xBX + VMCSCACHE.Write.cValidEntries], 0
-.no_cached_writes:
-
-    ; Save the pCache pointer
-    push    xBX
-%endif
-
-%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
-    ; Save the host MSRs and load the guest MSRs
-    LOADGUESTMSR MSR_K8_LSTAR, CPUMCTX.msrLSTAR
-    LOADGUESTMSR MSR_K6_STAR, CPUMCTX.msrSTAR
-    LOADGUESTMSR MSR_K8_SF_MASK, CPUMCTX.msrSFMASK
-%endif
-    ; Kernel GS Base is special, we need to manually load/store it, see @bugref{6208}
-    LOADGUESTMSR MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
-
-    ; Save the pCtx pointer
-    push    xSI
-
-    ; Save LDTR
-    xor     eax, eax
-    sldt    ax
-    push    xAX
-
-    ; The TR limit is reset to 0x67; restore it manually
-    str     eax
-    push    xAX
-
-    ; VMX only saves the base of the GDTR & IDTR and resets the limit to 0xffff; we must restore the limit correctly!
-    sub     xSP, xS*2
-    sgdt    [xSP]
-
-    sub     xSP, xS*2
-    sidt    [xSP]
-
-%ifdef VBOX_WITH_DR6_EXPERIMENT
-    ; Restore DR6 - experiment, not safe!
-    mov     xBX, [xSI + CPUMCTX.dr6]
-    mov     dr6, xBX
-%endif
-
-    ; Restore CR2
-    mov     rbx, qword [xSI + CPUMCTX.cr2]
-    mov     cr2, rbx
-
-    mov     eax, VMX_VMCS_HOST_RSP
-    vmwrite xAX, xSP
-    ;/* Note: assumes success... */
-    ;/* Don't mess with ESP anymore!! */
-
-    ;/* Restore Guest's general purpose registers. */
-    mov     rax, qword [xSI + CPUMCTX.eax]
-    mov     rbx, qword [xSI + CPUMCTX.ebx]
-    mov     rcx, qword [xSI + CPUMCTX.ecx]
-    mov     rdx, qword [xSI + CPUMCTX.edx]
-    mov     rbp, qword [xSI + CPUMCTX.ebp]
-    mov     r8,  qword [xSI + CPUMCTX.r8]
-    mov     r9,  qword [xSI + CPUMCTX.r9]
-    mov     r10, qword [xSI + CPUMCTX.r10]
-    mov     r11, qword [xSI + CPUMCTX.r11]
-    mov     r12, qword [xSI + CPUMCTX.r12]
-    mov     r13, qword [xSI + CPUMCTX.r13]
-    mov     r14, qword [xSI + CPUMCTX.r14]
-    mov     r15, qword [xSI + CPUMCTX.r15]
-
-    ; resume or start?
-    cmp     xDI, 0                  ; fResume
-    je      .vmlauch64_lauch
-
-    ;/* Restore edi & esi. */
-    mov     rdi, qword [xSI + CPUMCTX.edi]
-    mov     rsi, qword [xSI + CPUMCTX.esi]
-
-    vmresume
-    jmp     .vmlaunch64_done;      ;/* here if vmresume detected a failure. */
-
-.vmlauch64_lauch:
-    ;/* Restore rdi & rsi. */
-    mov     rdi, qword [xSI + CPUMCTX.edi]
-    mov     rsi, qword [xSI + CPUMCTX.esi]
-
-    vmlaunch
-    jmp     .vmlaunch64_done;      ;/* here if vmlaunch detected a failure. */
-
-ALIGNCODE(16)
-.vmlaunch64_done:
-    jc      near .vmxstart64_invalid_vmxon_ptr
-    jz      near .vmxstart64_start_failed
-
-    ; Restore base and limit of the IDTR & GDTR
-    lidt    [xSP]
-    add     xSP, xS*2
-    lgdt    [xSP]
-    add     xSP, xS*2
-
-    push    xDI
-    mov     xDI, [xSP + xS * 3]         ; pCtx (*3 to skip the saved LDTR + TR)
-
-    mov     qword [xDI + CPUMCTX.eax], rax
-    mov     qword [xDI + CPUMCTX.ebx], rbx
-    mov     qword [xDI + CPUMCTX.ecx], rcx
-    mov     qword [xDI + CPUMCTX.edx], rdx
-    mov     qword [xDI + CPUMCTX.esi], rsi
-    mov     qword [xDI + CPUMCTX.ebp], rbp
-    mov     qword [xDI + CPUMCTX.r8],  r8
-    mov     qword [xDI + CPUMCTX.r9],  r9
-    mov     qword [xDI + CPUMCTX.r10], r10
-    mov     qword [xDI + CPUMCTX.r11], r11
-    mov     qword [xDI + CPUMCTX.r12], r12
-    mov     qword [xDI + CPUMCTX.r13], r13
-    mov     qword [xDI + CPUMCTX.r14], r14
-    mov     qword [xDI + CPUMCTX.r15], r15
-
-    pop     xAX                                 ; the guest edi we pushed above
-    mov     qword [xDI + CPUMCTX.edi], rax
-
-%ifdef VBOX_WITH_DR6_EXPERIMENT
-    ; Save DR6 - experiment, not safe!
-    mov     xAX, dr6
-    mov     [xDI + CPUMCTX.dr6], xAX
-%endif
-
-    ; Restore TSS selector; must mark it as not busy before using ltr (!)
-    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
-    ; @todo get rid of sgdt
-    pop     xBX         ; saved TR
-    sub     xSP, xS*2
-    sgdt    [xSP]
-    mov     xAX, xBX
-    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
-    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
-    and     dword [xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
-    ltr     bx
-    add     xSP, xS*2
-
-    pop     xAX         ; saved LDTR
-    lldt    ax
-
-    pop     xSI         ; pCtx (needed in rsi by the macros below)
-
-    ; Kernel GS Base is special, we need to manually load/store it, see @bugref{6208}.
-    LOADHOSTMSREX MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
-%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
-    ; Save the guest MSRs and load the host MSRs
-    LOADHOSTMSREX MSR_K8_SF_MASK, CPUMCTX.msrSFMASK
-    LOADHOSTMSREX MSR_K6_STAR, CPUMCTX.msrSTAR
-    LOADHOSTMSREX MSR_K8_LSTAR, CPUMCTX.msrLSTAR
-%endif
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    pop     xDX         ; saved pCache
-
-    mov     ecx, [xDX + VMCSCACHE.Read.cValidEntries]
-    cmp     ecx, 0  ; can't happen
-    je      .no_cached_reads
-    jmp     .cached_read
-
-ALIGN(16)
-.cached_read:
-    dec     xCX
-    mov     eax, [xDX + VMCSCACHE.Read.aField + xCX*4]
-    vmread  [xDX + VMCSCACHE.Read.aFieldVal + xCX*8], xAX
-    cmp      xCX, 0
-    jnz     .cached_read
-.no_cached_reads:
-
-    ; Save CR2 for EPT
-    mov     xAX, cr2
-    mov     [xDX + VMCSCACHE.cr2], xAX
-%endif
-
-    ; Restore segment registers
-    MYPOPSEGS xAX, ax
-
-    ; Restore general purpose registers
-    MYPOPAD
-
-    mov     eax, VINF_SUCCESS
-
-.vmstart64_end:
-    popf
-    pop     xBP
-    ret
-
-
-.vmxstart64_invalid_vmxon_ptr:
-    ; Restore base and limit of the IDTR & GDTR
-    lidt    [xSP]
-    add     xSP, xS*2
-    lgdt    [xSP]
-    add     xSP, xS*2
-
-    ; Restore TSS selector; must mark it as not busy before using ltr (!)
-    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
-    ; @todo get rid of sgdt
-    pop     xBX         ; saved TR
-    sub     xSP, xS*2
-    sgdt    [xSP]
-    mov     xAX, xBX
-    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
-    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
-    and     dword [xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
-    ltr     bx
-    add     xSP, xS*2
-
-    pop     xAX         ; saved LDTR
-    lldt    ax
-
-    pop     xSI         ; pCtx (needed in rsi by the macros below)
-
-    ; Kernel GS base is special, we need to manually load/store it See @bugref{6208}.
-    LOADHOSTMSREX MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
-%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
-    ; Load the host MSRs
-    LOADHOSTMSR MSR_K8_SF_MASK
-    LOADHOSTMSR MSR_K6_STAR
-    LOADHOSTMSR MSR_K8_LSTAR
-%endif
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    add     xSP, xS     ; pCache
-%endif
-
-    ; Restore segment registers
-    MYPOPSEGS xAX, ax
-
-    ; Restore all general purpose host registers.
-    MYPOPAD
-    mov     eax, VERR_VMX_INVALID_VMXON_PTR
-    jmp     .vmstart64_end
-
-.vmxstart64_start_failed:
-    ; Restore base and limit of the IDTR & GDTR
-    lidt    [xSP]
-    add     xSP, xS*2
-    lgdt    [xSP]
-    add     xSP, xS*2
-
-    ; Restore TSS selector; must mark it as not busy before using ltr (!)
-    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
-    ; @todo get rid of sgdt
-    pop     xBX         ; saved TR
-    sub     xSP, xS*2
-    sgdt    [xSP]
-    mov     xAX, xBX
-    and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
-    add     xAX, [xSP + 2]                          ; eax <- GDTR.address + descriptor offset.
-    and     dword [xAX + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
-    ltr     bx
-    add     xSP, xS*2
-
-    pop     xAX         ; saved LDTR
-    lldt    ax
-
-    pop     xSI         ; pCtx (needed in rsi by the macros below)
-
-    ; Kernel GS base is special, load it manually. See @bugref{6208}.
-    LOADHOSTMSREX MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
-%ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
-    ; Load the host MSRs
-    LOADHOSTMSR MSR_K8_SF_MASK
-    LOADHOSTMSR MSR_K6_STAR
-    LOADHOSTMSR MSR_K8_LSTAR
-%endif
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    add     xSP, xS     ; pCache
-%endif
-
-    ; Restore segment registers
-    MYPOPSEGS xAX, ax
-
-    ; Restore all general purpose host registers.
-    MYPOPAD
-    mov     eax, VERR_VMX_UNABLE_TO_START_VM
-    jmp     .vmstart64_end
-ENDPROC MY_NAME(VMXR0StartVM64)
-%endif ; RT_ARCH_AMD64
-
-
-;/**
-; * Prepares for and executes VMRUN (32 bits guests)
-; *
-; * @returns VBox status code
-; * @param   HCPhysVMCB     Physical address of host VMCB
-; * @param   HCPhysVMCB     Physical address of guest VMCB
-; * @param   pCtx           Guest context
-; */
-ALIGNCODE(16)
-BEGINPROC MY_NAME(SVMR0VMRun)
-%ifdef RT_ARCH_AMD64 ; fake a cdecl stack frame
- %ifdef ASM_CALL64_GCC
-    push    rdx
-    push    rsi
-    push    rdi
- %else
-    push    r8
-    push    rdx
-    push    rcx
- %endif
-    push    0
-%endif
-    push    xBP
-    mov     xBP, xSP
-    pushf
-
-    ;/* Manual save and restore:
-    ; * - General purpose registers except RIP, RSP, RAX
-    ; *
-    ; * Trashed:
-    ; * - CR2 (we don't care)
-    ; * - LDTR (reset to 0)
-    ; * - DRx (presumably not changed at all)
-    ; * - DR7 (reset to 0x400)
-    ; */
-
-    ;/* Save all general purpose host registers. */
-    MYPUSHAD
-
-    ;/* Save the Guest CPU context pointer. */
-    mov     xSI, [xBP + xS*2 + RTHCPHYS_CB*2]   ; pCtx
-    push    xSI                     ; push for saving the state at the end
-
-    ; save host fs, gs, sysenter msr etc
-    mov     xAX, [xBP + xS*2]       ; pVMCBHostPhys (64 bits physical address; x86: take low dword only)
-    push    xAX                     ; save for the vmload after vmrun
-    vmsave
-
-    ; setup eax for VMLOAD
-    mov     xAX, [xBP + xS*2 + RTHCPHYS_CB]     ; pVMCBPhys (64 bits physical address; take low dword only)
-
-    ;/* Restore Guest's general purpose registers. */
-    ;/* EAX is loaded from the VMCB by VMRUN */
-    mov     ebx, [xSI + CPUMCTX.ebx]
-    mov     ecx, [xSI + CPUMCTX.ecx]
-    mov     edx, [xSI + CPUMCTX.edx]
-    mov     edi, [xSI + CPUMCTX.edi]
-    mov     ebp, [xSI + CPUMCTX.ebp]
-    mov     esi, [xSI + CPUMCTX.esi]
-
-    ; Clear the global interrupt flag & execute sti to make sure external interrupts cause a world switch
-    clgi
-    sti
-
-    ; load guest fs, gs, sysenter msr etc
-    vmload
-    ; run the VM
-    vmrun
-
-    ;/* EAX is in the VMCB already; we can use it here. */
-
-    ; save guest fs, gs, sysenter msr etc
-    vmsave
-
-    ; load host fs, gs, sysenter msr etc
-    pop     xAX                     ; pushed above
-    vmload
-
-    ; Set the global interrupt flag again, but execute cli to make sure IF=0.
-    cli
-    stgi
-
-    pop     xAX                     ; pCtx
-
-    mov     [ss:xAX + CPUMCTX.ebx], ebx
-    mov     [ss:xAX + CPUMCTX.ecx], ecx
-    mov     [ss:xAX + CPUMCTX.edx], edx
-    mov     [ss:xAX + CPUMCTX.esi], esi
-    mov     [ss:xAX + CPUMCTX.edi], edi
-    mov     [ss:xAX + CPUMCTX.ebp], ebp
-
-    ; Restore general purpose registers
-    MYPOPAD
-
-    mov     eax, VINF_SUCCESS
-
-    popf
-    pop     xBP
-%ifdef RT_ARCH_AMD64
-    add     xSP, 4*xS
-%endif
-    ret
-ENDPROC MY_NAME(SVMR0VMRun)
-
-%ifdef RT_ARCH_AMD64
-;/**
-; * Prepares for and executes VMRUN (64 bits guests)
-; *
-; * @returns VBox status code
-; * @param   HCPhysVMCB     Physical address of host VMCB
-; * @param   HCPhysVMCB     Physical address of guest VMCB
-; * @param   pCtx           Guest context
-; */
-ALIGNCODE(16)
-BEGINPROC MY_NAME(SVMR0VMRun64)
-    ; fake a cdecl stack frame
- %ifdef ASM_CALL64_GCC
-    push    rdx
-    push    rsi
-    push    rdi
- %else
-    push    r8
-    push    rdx
-    push    rcx
- %endif
-    push    0
-    push    rbp
-    mov     rbp, rsp
-    pushf
-
-    ;/* Manual save and restore:
-    ; * - General purpose registers except RIP, RSP, RAX
-    ; *
-    ; * Trashed:
-    ; * - CR2 (we don't care)
-    ; * - LDTR (reset to 0)
-    ; * - DRx (presumably not changed at all)
-    ; * - DR7 (reset to 0x400)
-    ; */
-
-    ;/* Save all general purpose host registers. */
-    MYPUSHAD
-
-    ;/* Save the Guest CPU context pointer. */
-    mov     rsi, [rbp + xS*2 + RTHCPHYS_CB*2]   ; pCtx
-    push    rsi                     ; push for saving the state at the end
-
-    ; save host fs, gs, sysenter msr etc
-    mov     rax, [rbp + xS*2]       ; pVMCBHostPhys (64 bits physical address; x86: take low dword only)
-    push    rax                     ; save for the vmload after vmrun
-    vmsave
-
-    ; setup eax for VMLOAD
-    mov     rax, [rbp + xS*2 + RTHCPHYS_CB]     ; pVMCBPhys (64 bits physical address; take low dword only)
-
-    ;/* Restore Guest's general purpose registers. */
-    ;/* RAX is loaded from the VMCB by VMRUN */
-    mov     rbx, qword [xSI + CPUMCTX.ebx]
-    mov     rcx, qword [xSI + CPUMCTX.ecx]
-    mov     rdx, qword [xSI + CPUMCTX.edx]
-    mov     rdi, qword [xSI + CPUMCTX.edi]
-    mov     rbp, qword [xSI + CPUMCTX.ebp]
-    mov     r8,  qword [xSI + CPUMCTX.r8]
-    mov     r9,  qword [xSI + CPUMCTX.r9]
-    mov     r10, qword [xSI + CPUMCTX.r10]
-    mov     r11, qword [xSI + CPUMCTX.r11]
-    mov     r12, qword [xSI + CPUMCTX.r12]
-    mov     r13, qword [xSI + CPUMCTX.r13]
-    mov     r14, qword [xSI + CPUMCTX.r14]
-    mov     r15, qword [xSI + CPUMCTX.r15]
-    mov     rsi, qword [xSI + CPUMCTX.esi]
-
-    ; Clear the global interrupt flag & execute sti to make sure external interrupts cause a world switch
-    clgi
-    sti
-
-    ; load guest fs, gs, sysenter msr etc
-    vmload
-    ; run the VM
-    vmrun
-
-    ;/* RAX is in the VMCB already; we can use it here. */
-
-    ; save guest fs, gs, sysenter msr etc
-    vmsave
-
-    ; load host fs, gs, sysenter msr etc
-    pop     rax                     ; pushed above
-    vmload
-
-    ; Set the global interrupt flag again, but execute cli to make sure IF=0.
-    cli
-    stgi
-
-    pop     rax                     ; pCtx
-
-    mov     qword [rax + CPUMCTX.ebx], rbx
-    mov     qword [rax + CPUMCTX.ecx], rcx
-    mov     qword [rax + CPUMCTX.edx], rdx
-    mov     qword [rax + CPUMCTX.esi], rsi
-    mov     qword [rax + CPUMCTX.edi], rdi
-    mov     qword [rax + CPUMCTX.ebp], rbp
-    mov     qword [rax + CPUMCTX.r8],  r8
-    mov     qword [rax + CPUMCTX.r9],  r9
-    mov     qword [rax + CPUMCTX.r10], r10
-    mov     qword [rax + CPUMCTX.r11], r11
-    mov     qword [rax + CPUMCTX.r12], r12
-    mov     qword [rax + CPUMCTX.r13], r13
-    mov     qword [rax + CPUMCTX.r14], r14
-    mov     qword [rax + CPUMCTX.r15], r15
-
-    ; Restore general purpose registers
-    MYPOPAD
-
-    mov     eax, VINF_SUCCESS
-
-    popf
-    pop     rbp
-    add     rsp, 4*xS
-    ret
-ENDPROC MY_NAME(SVMR0VMRun64)
-%endif ; RT_ARCH_AMD64
-
Index: trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 43387)
@@ -19,6 +19,6 @@
 *   Header Files                                                               *
 *******************************************************************************/
-#define LOG_GROUP LOG_GROUP_HWACCM
-#include <VBox/vmm/hwaccm.h>
+#define LOG_GROUP LOG_GROUP_HM
+#include <VBox/vmm/hm.h>
 #include <VBox/vmm/pgm.h>
 #include <VBox/vmm/selm.h>
@@ -28,7 +28,7 @@
 #include <VBox/vmm/tm.h>
 #include <VBox/vmm/pdmapi.h>
-#include "HWACCMInternal.h"
+#include "HMInternal.h"
 #include <VBox/vmm/vm.h>
-#include <VBox/vmm/hwacc_svm.h>
+#include <VBox/vmm/hm_svm.h>
 #include <VBox/err.h>
 #include <VBox/log.h>
@@ -92,5 +92,5 @@
          */
         if (    pVM
-            &&  pVM->hwaccm.s.svm.fIgnoreInUseError)
+            &&  pVM->hm.s.svm.fIgnoreInUseError)
         {
             pCpu->fIgnoreAMDVInUseError = true;
@@ -159,15 +159,15 @@
     int rc;
 
-    pVM->hwaccm.s.svm.pMemObjIOBitmap = NIL_RTR0MEMOBJ;
+    pVM->hm.s.svm.pMemObjIOBitmap = NIL_RTR0MEMOBJ;
 
     /* Allocate 12 KB for the IO bitmap (doesn't seem to be a way to convince SVM not to use it) */
-    rc = RTR0MemObjAllocCont(&pVM->hwaccm.s.svm.pMemObjIOBitmap, 3 << PAGE_SHIFT, false /* executable R0 mapping */);
+    rc = RTR0MemObjAllocCont(&pVM->hm.s.svm.pMemObjIOBitmap, 3 << PAGE_SHIFT, false /* executable R0 mapping */);
     if (RT_FAILURE(rc))
         return rc;
 
-    pVM->hwaccm.s.svm.pIOBitmap     = RTR0MemObjAddress(pVM->hwaccm.s.svm.pMemObjIOBitmap);
-    pVM->hwaccm.s.svm.pIOBitmapPhys = RTR0MemObjGetPagePhysAddr(pVM->hwaccm.s.svm.pMemObjIOBitmap, 0);
+    pVM->hm.s.svm.pIOBitmap     = RTR0MemObjAddress(pVM->hm.s.svm.pMemObjIOBitmap);
+    pVM->hm.s.svm.pIOBitmapPhys = RTR0MemObjGetPagePhysAddr(pVM->hm.s.svm.pMemObjIOBitmap, 0);
     /* Set all bits to intercept all IO accesses. */
-    ASMMemFill32(pVM->hwaccm.s.svm.pIOBitmap, 3 << PAGE_SHIFT, 0xffffffff);
+    ASMMemFill32(pVM->hm.s.svm.pIOBitmap, 3 << PAGE_SHIFT, 0xffffffff);
 
     /*
@@ -199,5 +199,5 @@
     {
         Log(("SVMR0InitVM: AMD cpu with erratum 170 family %x model %x stepping %x\n", u32Family, u32Model, u32Stepping));
-        pVM->hwaccm.s.svm.fAlwaysFlushTLB = true;
+        pVM->hm.s.svm.fAlwaysFlushTLB = true;
     }
 
@@ -207,37 +207,37 @@
         PVMCPU pVCpu = &pVM->aCpus[i];
 
-        pVCpu->hwaccm.s.svm.pMemObjVMCBHost  = NIL_RTR0MEMOBJ;
-        pVCpu->hwaccm.s.svm.pMemObjVMCB      = NIL_RTR0MEMOBJ;
-        pVCpu->hwaccm.s.svm.pMemObjMSRBitmap = NIL_RTR0MEMOBJ;
+        pVCpu->hm.s.svm.pMemObjVMCBHost  = NIL_RTR0MEMOBJ;
+        pVCpu->hm.s.svm.pMemObjVMCB      = NIL_RTR0MEMOBJ;
+        pVCpu->hm.s.svm.pMemObjMSRBitmap = NIL_RTR0MEMOBJ;
 
         /* Allocate one page for the host context */
-        rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.svm.pMemObjVMCBHost, 1 << PAGE_SHIFT, false /* executable R0 mapping */);
+        rc = RTR0MemObjAllocCont(&pVCpu->hm.s.svm.pMemObjVMCBHost, 1 << PAGE_SHIFT, false /* executable R0 mapping */);
         if (RT_FAILURE(rc))
             return rc;
 
-        pVCpu->hwaccm.s.svm.pVMCBHost     = RTR0MemObjAddress(pVCpu->hwaccm.s.svm.pMemObjVMCBHost);
-        pVCpu->hwaccm.s.svm.pVMCBHostPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.svm.pMemObjVMCBHost, 0);
-        Assert(pVCpu->hwaccm.s.svm.pVMCBHostPhys < _4G);
-        ASMMemZeroPage(pVCpu->hwaccm.s.svm.pVMCBHost);
+        pVCpu->hm.s.svm.pVMCBHost     = RTR0MemObjAddress(pVCpu->hm.s.svm.pMemObjVMCBHost);
+        pVCpu->hm.s.svm.pVMCBHostPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hm.s.svm.pMemObjVMCBHost, 0);
+        Assert(pVCpu->hm.s.svm.pVMCBHostPhys < _4G);
+        ASMMemZeroPage(pVCpu->hm.s.svm.pVMCBHost);
 
         /* Allocate one page for the VM control block (VMCB). */
-        rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.svm.pMemObjVMCB, 1 << PAGE_SHIFT, false /* executable R0 mapping */);
+        rc = RTR0MemObjAllocCont(&pVCpu->hm.s.svm.pMemObjVMCB, 1 << PAGE_SHIFT, false /* executable R0 mapping */);
         if (RT_FAILURE(rc))
             return rc;
 
-        pVCpu->hwaccm.s.svm.pVMCB     = RTR0MemObjAddress(pVCpu->hwaccm.s.svm.pMemObjVMCB);
-        pVCpu->hwaccm.s.svm.pVMCBPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.svm.pMemObjVMCB, 0);
-        Assert(pVCpu->hwaccm.s.svm.pVMCBPhys < _4G);
-        ASMMemZeroPage(pVCpu->hwaccm.s.svm.pVMCB);
+        pVCpu->hm.s.svm.pVMCB     = RTR0MemObjAddress(pVCpu->hm.s.svm.pMemObjVMCB);
+        pVCpu->hm.s.svm.pVMCBPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hm.s.svm.pMemObjVMCB, 0);
+        Assert(pVCpu->hm.s.svm.pVMCBPhys < _4G);
+        ASMMemZeroPage(pVCpu->hm.s.svm.pVMCB);
 
         /* Allocate 8 KB for the MSR bitmap (doesn't seem to be a way to convince SVM not to use it) */
-        rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.svm.pMemObjMSRBitmap, 2 << PAGE_SHIFT, false /* executable R0 mapping */);
+        rc = RTR0MemObjAllocCont(&pVCpu->hm.s.svm.pMemObjMSRBitmap, 2 << PAGE_SHIFT, false /* executable R0 mapping */);
         if (RT_FAILURE(rc))
             return rc;
 
-        pVCpu->hwaccm.s.svm.pMSRBitmap     = RTR0MemObjAddress(pVCpu->hwaccm.s.svm.pMemObjMSRBitmap);
-        pVCpu->hwaccm.s.svm.pMSRBitmapPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.svm.pMemObjMSRBitmap, 0);
+        pVCpu->hm.s.svm.pMSRBitmap     = RTR0MemObjAddress(pVCpu->hm.s.svm.pMemObjMSRBitmap);
+        pVCpu->hm.s.svm.pMSRBitmapPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hm.s.svm.pMemObjMSRBitmap, 0);
         /* Set all bits to intercept all MSR accesses. */
-        ASMMemFill32(pVCpu->hwaccm.s.svm.pMSRBitmap, 2 << PAGE_SHIFT, 0xffffffff);
+        ASMMemFill32(pVCpu->hm.s.svm.pMSRBitmap, 2 << PAGE_SHIFT, 0xffffffff);
     }
 
@@ -258,33 +258,33 @@
         PVMCPU pVCpu = &pVM->aCpus[i];
 
-        if (pVCpu->hwaccm.s.svm.pMemObjVMCBHost != NIL_RTR0MEMOBJ)
-        {
-            RTR0MemObjFree(pVCpu->hwaccm.s.svm.pMemObjVMCBHost, false);
-            pVCpu->hwaccm.s.svm.pVMCBHost       = 0;
-            pVCpu->hwaccm.s.svm.pVMCBHostPhys   = 0;
-            pVCpu->hwaccm.s.svm.pMemObjVMCBHost = NIL_RTR0MEMOBJ;
-        }
-
-        if (pVCpu->hwaccm.s.svm.pMemObjVMCB != NIL_RTR0MEMOBJ)
-        {
-            RTR0MemObjFree(pVCpu->hwaccm.s.svm.pMemObjVMCB, false);
-            pVCpu->hwaccm.s.svm.pVMCB       = 0;
-            pVCpu->hwaccm.s.svm.pVMCBPhys   = 0;
-            pVCpu->hwaccm.s.svm.pMemObjVMCB = NIL_RTR0MEMOBJ;
-        }
-        if (pVCpu->hwaccm.s.svm.pMemObjMSRBitmap != NIL_RTR0MEMOBJ)
-        {
-            RTR0MemObjFree(pVCpu->hwaccm.s.svm.pMemObjMSRBitmap, false);
-            pVCpu->hwaccm.s.svm.pMSRBitmap       = 0;
-            pVCpu->hwaccm.s.svm.pMSRBitmapPhys   = 0;
-            pVCpu->hwaccm.s.svm.pMemObjMSRBitmap = NIL_RTR0MEMOBJ;
-        }
-    }
-    if (pVM->hwaccm.s.svm.pMemObjIOBitmap != NIL_RTR0MEMOBJ)
-    {
-        RTR0MemObjFree(pVM->hwaccm.s.svm.pMemObjIOBitmap, false);
-        pVM->hwaccm.s.svm.pIOBitmap       = 0;
-        pVM->hwaccm.s.svm.pIOBitmapPhys   = 0;
-        pVM->hwaccm.s.svm.pMemObjIOBitmap = NIL_RTR0MEMOBJ;
+        if (pVCpu->hm.s.svm.pMemObjVMCBHost != NIL_RTR0MEMOBJ)
+        {
+            RTR0MemObjFree(pVCpu->hm.s.svm.pMemObjVMCBHost, false);
+            pVCpu->hm.s.svm.pVMCBHost       = 0;
+            pVCpu->hm.s.svm.pVMCBHostPhys   = 0;
+            pVCpu->hm.s.svm.pMemObjVMCBHost = NIL_RTR0MEMOBJ;
+        }
+
+        if (pVCpu->hm.s.svm.pMemObjVMCB != NIL_RTR0MEMOBJ)
+        {
+            RTR0MemObjFree(pVCpu->hm.s.svm.pMemObjVMCB, false);
+            pVCpu->hm.s.svm.pVMCB       = 0;
+            pVCpu->hm.s.svm.pVMCBPhys   = 0;
+            pVCpu->hm.s.svm.pMemObjVMCB = NIL_RTR0MEMOBJ;
+        }
+        if (pVCpu->hm.s.svm.pMemObjMSRBitmap != NIL_RTR0MEMOBJ)
+        {
+            RTR0MemObjFree(pVCpu->hm.s.svm.pMemObjMSRBitmap, false);
+            pVCpu->hm.s.svm.pMSRBitmap       = 0;
+            pVCpu->hm.s.svm.pMSRBitmapPhys   = 0;
+            pVCpu->hm.s.svm.pMemObjMSRBitmap = NIL_RTR0MEMOBJ;
+        }
+    }
+    if (pVM->hm.s.svm.pMemObjIOBitmap != NIL_RTR0MEMOBJ)
+    {
+        RTR0MemObjFree(pVM->hm.s.svm.pMemObjIOBitmap, false);
+        pVM->hm.s.svm.pIOBitmap       = 0;
+        pVM->hm.s.svm.pIOBitmapPhys   = 0;
+        pVM->hm.s.svm.pMemObjIOBitmap = NIL_RTR0MEMOBJ;
     }
     return VINF_SUCCESS;
@@ -303,10 +303,10 @@
 
     AssertReturn(pVM, VERR_INVALID_PARAMETER);
-    Assert(pVM->hwaccm.s.svm.fSupported);
+    Assert(pVM->hm.s.svm.fSupported);
 
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
         PVMCPU    pVCpu = &pVM->aCpus[i];
-        SVM_VMCB *pVMCB = (SVM_VMCB *)pVM->aCpus[i].hwaccm.s.svm.pVMCB;
+        SVM_VMCB *pVMCB = (SVM_VMCB *)pVM->aCpus[i].hm.s.svm.pVMCB;
 
         AssertMsgReturn(pVMCB, ("Invalid pVMCB\n"), VERR_HMSVM_INVALID_PVMCB);
@@ -382,6 +382,6 @@
 
         /* Set IO and MSR bitmap addresses. */
-        pVMCB->ctrl.u64IOPMPhysAddr  = pVM->hwaccm.s.svm.pIOBitmapPhys;
-        pVMCB->ctrl.u64MSRPMPhysAddr = pVCpu->hwaccm.s.svm.pMSRBitmapPhys;
+        pVMCB->ctrl.u64IOPMPhysAddr  = pVM->hm.s.svm.pIOBitmapPhys;
+        pVMCB->ctrl.u64MSRPMPhysAddr = pVCpu->hm.s.svm.pMSRBitmapPhys;
 
         /* No LBR virtualization. */
@@ -399,5 +399,5 @@
 
         /* If nested paging is not in use, additional intercepts have to be set up. */
-        if (!pVM->hwaccm.s.fNestedPaging)
+        if (!pVM->hm.s.fNestedPaging)
         {
             /* CR3 reads/writes must be intercepted; our shadow values are different from guest's. */
@@ -448,5 +448,5 @@
 {
     unsigned ulBit;
-    uint8_t *pMSRBitmap = (uint8_t *)pVCpu->hwaccm.s.svm.pMSRBitmap;
+    uint8_t *pMSRBitmap = (uint8_t *)pVCpu->hm.s.svm.pMSRBitmap;
 
     if (ulMSR <= 0x00001FFF)
@@ -498,5 +498,5 @@
 {
 #ifdef VBOX_WITH_STATISTICS
-    STAM_COUNTER_INC(&pVCpu->hwaccm.s.paStatInjectedIrqsR0[pEvent->n.u8Vector & MASK_INJECT_IRQ_STAT]);
+    STAM_COUNTER_INC(&pVCpu->hm.s.paStatInjectedIrqsR0[pEvent->n.u8Vector & MASK_INJECT_IRQ_STAT]);
 #endif
 
@@ -539,15 +539,15 @@
      * Dispatch any pending interrupts (injected before, but a VM-exit occurred prematurely).
      */
-    if (pVCpu->hwaccm.s.Event.fPending)
+    if (pVCpu->hm.s.Event.fPending)
     {
         SVM_EVENT Event;
 
-        Log(("Reinjecting event %08x %08x at %RGv\n", pVCpu->hwaccm.s.Event.intInfo, pVCpu->hwaccm.s.Event.errCode,
+        Log(("Reinjecting event %08x %08x at %RGv\n", pVCpu->hm.s.Event.intInfo, pVCpu->hm.s.Event.errCode,
              (RTGCPTR)pCtx->rip));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatIntReinject);
-        Event.au64[0] = pVCpu->hwaccm.s.Event.intInfo;
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatIntReinject);
+        Event.au64[0] = pVCpu->hm.s.Event.intInfo;
         hmR0SvmInjectEvent(pVCpu, pVMCB, pCtx, &Event);
 
-        pVCpu->hwaccm.s.Event.fPending = false;
+        pVCpu->hm.s.Event.fPending = false;
         return VINF_SUCCESS;
     }
@@ -614,5 +614,5 @@
                     /* Can only happen in rare cases where a pending interrupt is cleared behind our back */
                     Assert(!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)));
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchGuestIrq);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchGuestIrq);
                     /* Just continue */
                 }
@@ -681,5 +681,5 @@
             Event.n.u3Type = SVM_EVENT_EXTERNAL_IRQ;
 
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatIntInject);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject);
         hmR0SvmInjectEvent(pVCpu, pVMCB, pCtx, &Event);
     } /* if (interrupts can be dispatched) */
@@ -724,11 +724,11 @@
 
     /* Setup AMD SVM. */
-    Assert(pVM->hwaccm.s.svm.fSupported);
-
-    pVMCB = (SVM_VMCB *)pVCpu->hwaccm.s.svm.pVMCB;
+    Assert(pVM->hm.s.svm.fSupported);
+
+    pVMCB = (SVM_VMCB *)pVCpu->hm.s.svm.pVMCB;
     AssertMsgReturn(pVMCB, ("Invalid pVMCB\n"), VERR_HMSVM_INVALID_PVMCB);
 
     /* Guest CPU context: ES, CS, SS, DS, FS, GS. */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_SEGMENT_REGS)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_SEGMENT_REGS)
     {
         SVM_WRITE_SELREG(CS, cs);
@@ -741,5 +741,5 @@
 
     /* Guest CPU context: LDTR. */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_LDTR)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_LDTR)
     {
         SVM_WRITE_SELREG(LDTR, ldtr);
@@ -747,5 +747,5 @@
 
     /* Guest CPU context: TR. */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_TR)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_TR)
     {
         SVM_WRITE_SELREG(TR, tr);
@@ -753,5 +753,5 @@
 
     /* Guest CPU context: GDTR. */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_GDTR)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_GDTR)
     {
         pVMCB->guest.GDTR.u32Limit = pCtx->gdtr.cbGdt;
@@ -760,5 +760,5 @@
 
     /* Guest CPU context: IDTR. */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_IDTR)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_IDTR)
     {
         pVMCB->guest.IDTR.u32Limit = pCtx->idtr.cbIdt;
@@ -774,5 +774,5 @@
 
     /* Control registers */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_CR0)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_CR0)
     {
         val = pCtx->cr0;
@@ -790,8 +790,8 @@
 
                 /* Also catch floating point exceptions as we need to report them to the guest in a different way. */
-                if (!pVCpu->hwaccm.s.fFPUOldStyleOverride)
+                if (!pVCpu->hm.s.fFPUOldStyleOverride)
                 {
                     pVMCB->ctrl.u32InterceptException |= RT_BIT(X86_XCPT_MF);
-                    pVCpu->hwaccm.s.fFPUOldStyleOverride = true;
+                    pVCpu->hm.s.fFPUOldStyleOverride = true;
                 }
             }
@@ -806,5 +806,5 @@
          * translation will remain active.
          */
-        if (!pVM->hwaccm.s.fNestedPaging)
+        if (!pVM->hm.s.fNestedPaging)
         {
             val |= X86_CR0_PG;  /* Paging is always enabled; even when the guest is running in real mode or PE without paging. */
@@ -816,8 +816,8 @@
     pVMCB->guest.u64CR2 = pCtx->cr2;
 
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_CR3)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_CR3)
     {
         /* Save our shadow CR3 register. */
-        if (pVM->hwaccm.s.fNestedPaging)
+        if (pVM->hm.s.fNestedPaging)
         {
             PGMMODE enmShwPagingMode;
@@ -841,10 +841,10 @@
     }
 
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_CR4)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_CR4)
     {
         val = pCtx->cr4;
-        if (!pVM->hwaccm.s.fNestedPaging)
-        {
-            switch (pVCpu->hwaccm.s.enmShadowMode)
+        if (!pVM->hm.s.fNestedPaging)
+        {
+            switch (pVCpu->hm.s.enmShadowMode)
             {
                 case PGMMODE_REAL:
@@ -881,5 +881,5 @@
 
     /* Debug registers. */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_DEBUG)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_DEBUG)
     {
         pCtx->dr[6] |= X86_DR6_INIT_VAL;                                          /* set all reserved bits to 1. */
@@ -916,5 +916,5 @@
             && !DBGFIsStepping(pVCpu))
         {
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatDRxArmed);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatDRxArmed);
 
             /* Disable drx move intercepts. */
@@ -948,13 +948,13 @@
         return VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE;
 #elif HC_ARCH_BITS == 32 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
-        pVCpu->hwaccm.s.svm.pfnVMRun = SVMR0VMSwitcherRun64;
+        pVCpu->hm.s.svm.pfnVMRun = SVMR0VMSwitcherRun64;
 #else
 # ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-        if (!pVM->hwaccm.s.fAllow64BitGuests)
+        if (!pVM->hm.s.fAllow64BitGuests)
             return VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE;
 # endif
-        pVCpu->hwaccm.s.svm.pfnVMRun = SVMR0VMRun64;
-#endif
-        /* Unconditionally update these as wrmsr might have changed them. (HWACCM_CHANGED_GUEST_SEGMENT_REGS will not be set) */
+        pVCpu->hm.s.svm.pfnVMRun = SVMR0VMRun64;
+#endif
+        /* Unconditionally update these as wrmsr might have changed them. (HM_CHANGED_GUEST_SEGMENT_REGS will not be set) */
         pVMCB->guest.FS.u64Base    = pCtx->fs.u64Base;
         pVMCB->guest.GS.u64Base    = pCtx->gs.u64Base;
@@ -965,5 +965,5 @@
         pVMCB->guest.u64EFER &= ~MSR_K6_EFER_LME;
 
-        pVCpu->hwaccm.s.svm.pfnVMRun = SVMR0VMRun;
+        pVCpu->hm.s.svm.pfnVMRun = SVMR0VMRun;
     }
 
@@ -976,5 +976,5 @@
             pVMCB->ctrl.u32InterceptCtrl1 &= ~SVM_CTRL1_INTERCEPT_RDTSC;
             pVMCB->ctrl.u32InterceptCtrl2 &= ~SVM_CTRL2_INTERCEPT_RDTSCP;
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCOffset);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatTSCOffset);
         }
         else
@@ -986,5 +986,5 @@
             pVMCB->ctrl.u32InterceptCtrl1 |= SVM_CTRL1_INTERCEPT_RDTSC;
             pVMCB->ctrl.u32InterceptCtrl2 |= SVM_CTRL2_INTERCEPT_RDTSCP;
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCInterceptOverFlow);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatTSCInterceptOverFlow);
         }
     }
@@ -993,5 +993,5 @@
         pVMCB->ctrl.u32InterceptCtrl1 |= SVM_CTRL1_INTERCEPT_RDTSC;
         pVMCB->ctrl.u32InterceptCtrl2 |= SVM_CTRL2_INTERCEPT_RDTSCP;
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCIntercept);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatTSCIntercept);
     }
 
@@ -1013,5 +1013,5 @@
 
     /* Done. */
-    pVCpu->hwaccm.s.fContextUseFlags &= ~HWACCM_CHANGED_ALL_GUEST;
+    pVCpu->hm.s.fContextUseFlags &= ~HM_CHANGED_ALL_GUEST;
 
     return VINF_SUCCESS;
@@ -1032,6 +1032,6 @@
     AssertPtr(pVCpu);
 
-    SVM_VMCB *pVMCB = (SVM_VMCB *)pVCpu->hwaccm.s.svm.pVMCB;
-    pCpu = HWACCMR0GetCurrentCpu();
+    SVM_VMCB *pVMCB = (SVM_VMCB *)pVCpu->hm.s.svm.pVMCB;
+    pCpu = HMR0GetCurrentCpu();
 
     /*
@@ -1042,8 +1042,8 @@
      */
     bool fNewASID = false;
-    if (    pVCpu->hwaccm.s.idLastCpu   != pCpu->idCpu
-        ||  pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
-    {
-        pVCpu->hwaccm.s.fForceTLBFlush = true;
+    if (    pVCpu->hm.s.idLastCpu   != pCpu->idCpu
+        ||  pVCpu->hm.s.cTLBFlushes != pCpu->cTLBFlushes)
+    {
+        pVCpu->hm.s.fForceTLBFlush = true;
         fNewASID = true;
     }
@@ -1052,5 +1052,5 @@
      * Set TLB flush state as checked until we return from the world switch.
      */
-    ASMAtomicWriteBool(&pVCpu->hwaccm.s.fCheckedTLBFlush, true);
+    ASMAtomicWriteBool(&pVCpu->hm.s.fCheckedTLBFlush, true);
 
     /*
@@ -1058,10 +1058,10 @@
      */
     if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH))
-        pVCpu->hwaccm.s.fForceTLBFlush = true;
-
-    pVCpu->hwaccm.s.idLastCpu = pCpu->idCpu;
+        pVCpu->hm.s.fForceTLBFlush = true;
+
+    pVCpu->hm.s.idLastCpu = pCpu->idCpu;
     pVMCB->ctrl.TLBCtrl.n.u8TLBFlush = SVM_TLB_FLUSH_NOTHING;
 
-    if (RT_UNLIKELY(pVM->hwaccm.s.svm.fAlwaysFlushTLB))
+    if (RT_UNLIKELY(pVM->hm.s.svm.fAlwaysFlushTLB))
     {
         /*
@@ -1069,9 +1069,9 @@
          */
         pCpu->uCurrentASID               = 1;
-        pVCpu->hwaccm.s.uCurrentASID     = 1;
-        pVCpu->hwaccm.s.cTLBFlushes      = pCpu->cTLBFlushes;
+        pVCpu->hm.s.uCurrentASID     = 1;
+        pVCpu->hm.s.cTLBFlushes      = pCpu->cTLBFlushes;
         pVMCB->ctrl.TLBCtrl.n.u8TLBFlush = SVM_TLB_FLUSH_ENTIRE;
     }
-    else if (pVCpu->hwaccm.s.fForceTLBFlush)
+    else if (pVCpu->hm.s.fForceTLBFlush)
     {
         if (fNewASID)
@@ -1079,5 +1079,5 @@
             ++pCpu->uCurrentASID;
             bool fHitASIDLimit = false;
-            if (pCpu->uCurrentASID >= pVM->hwaccm.s.uMaxASID)
+            if (pCpu->uCurrentASID >= pVM->hm.s.uMaxASID)
             {
                 pCpu->uCurrentASID        = 1;  /* start at 1; host uses 0 */
@@ -1085,5 +1085,5 @@
                 fHitASIDLimit             = true;
 
-                if (pVM->hwaccm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID)
+                if (pVM->hm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID)
                 {
                     pVMCB->ctrl.TLBCtrl.n.u8TLBFlush = SVM_TLB_FLUSH_SINGLE_CONTEXT;
@@ -1100,5 +1100,5 @@
                 && pCpu->fFlushASIDBeforeUse)
             {
-                if (pVM->hwaccm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID)
+                if (pVM->hm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID)
                     pVMCB->ctrl.TLBCtrl.n.u8TLBFlush = SVM_TLB_FLUSH_SINGLE_CONTEXT;
                 else
@@ -1109,10 +1109,10 @@
             }
 
-            pVCpu->hwaccm.s.uCurrentASID = pCpu->uCurrentASID;
-            pVCpu->hwaccm.s.cTLBFlushes  = pCpu->cTLBFlushes;
+            pVCpu->hm.s.uCurrentASID = pCpu->uCurrentASID;
+            pVCpu->hm.s.cTLBFlushes  = pCpu->cTLBFlushes;
         }
         else
         {
-            if (pVM->hwaccm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID)
+            if (pVM->hm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID)
                 pVMCB->ctrl.TLBCtrl.n.u8TLBFlush = SVM_TLB_FLUSH_SINGLE_CONTEXT;
             else
@@ -1120,43 +1120,43 @@
         }
 
-        pVCpu->hwaccm.s.fForceTLBFlush = false;
+        pVCpu->hm.s.fForceTLBFlush = false;
     }
     else
     {
         /** @todo We never set VMCPU_FF_TLB_SHOOTDOWN anywhere so this path should
-         *        not be executed. See hwaccmQueueInvlPage() where it is commented
+         *        not be executed. See hmQueueInvlPage() where it is commented
          *        out. Support individual entry flushing someday. */
         if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TLB_SHOOTDOWN))
         {
             /* Deal with pending TLB shootdown actions which were queued when we were not executing code. */
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdown);
-            for (unsigned i = 0; i < pVCpu->hwaccm.s.TlbShootdown.cPages; i++)
-                SVMR0InvlpgA(pVCpu->hwaccm.s.TlbShootdown.aPages[i], pVMCB->ctrl.TLBCtrl.n.u32ASID);
-        }
-    }
-
-    pVCpu->hwaccm.s.TlbShootdown.cPages = 0;
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatTlbShootdown);
+            for (unsigned i = 0; i < pVCpu->hm.s.TlbShootdown.cPages; i++)
+                SVMR0InvlpgA(pVCpu->hm.s.TlbShootdown.aPages[i], pVMCB->ctrl.TLBCtrl.n.u32ASID);
+        }
+    }
+
+    pVCpu->hm.s.TlbShootdown.cPages = 0;
     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TLB_SHOOTDOWN);
 
     /* Update VMCB with the ASID. */
-    pVMCB->ctrl.TLBCtrl.n.u32ASID = pVCpu->hwaccm.s.uCurrentASID;
-
-    AssertMsg(pVCpu->hwaccm.s.cTLBFlushes == pCpu->cTLBFlushes,
-              ("Flush count mismatch for cpu %d (%x vs %x)\n", pCpu->idCpu, pVCpu->hwaccm.s.cTLBFlushes, pCpu->cTLBFlushes));
-    AssertMsg(pCpu->uCurrentASID >= 1 && pCpu->uCurrentASID < pVM->hwaccm.s.uMaxASID,
+    pVMCB->ctrl.TLBCtrl.n.u32ASID = pVCpu->hm.s.uCurrentASID;
+
+    AssertMsg(pVCpu->hm.s.cTLBFlushes == pCpu->cTLBFlushes,
+              ("Flush count mismatch for cpu %d (%x vs %x)\n", pCpu->idCpu, pVCpu->hm.s.cTLBFlushes, pCpu->cTLBFlushes));
+    AssertMsg(pCpu->uCurrentASID >= 1 && pCpu->uCurrentASID < pVM->hm.s.uMaxASID,
               ("cpu%d uCurrentASID = %x\n", pCpu->idCpu, pCpu->uCurrentASID));
-    AssertMsg(pVCpu->hwaccm.s.uCurrentASID >= 1 && pVCpu->hwaccm.s.uCurrentASID < pVM->hwaccm.s.uMaxASID,
-              ("cpu%d VM uCurrentASID = %x\n", pCpu->idCpu, pVCpu->hwaccm.s.uCurrentASID));
+    AssertMsg(pVCpu->hm.s.uCurrentASID >= 1 && pVCpu->hm.s.uCurrentASID < pVM->hm.s.uMaxASID,
+              ("cpu%d VM uCurrentASID = %x\n", pCpu->idCpu, pVCpu->hm.s.uCurrentASID));
 
 #ifdef VBOX_WITH_STATISTICS
     if (pVMCB->ctrl.TLBCtrl.n.u8TLBFlush == SVM_TLB_FLUSH_NOTHING)
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatNoFlushTLBWorldSwitch);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatNoFlushTLBWorldSwitch);
     else if (   pVMCB->ctrl.TLBCtrl.n.u8TLBFlush == SVM_TLB_FLUSH_SINGLE_CONTEXT
              || pVMCB->ctrl.TLBCtrl.n.u8TLBFlush == SVM_TLB_FLUSH_SINGLE_CONTEXT_RETAIN_GLOBALS)
     {
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushASID);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushASID);
     }
     else
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushTLBWorldSwitch);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTLBWorldSwitch);
 #endif
 }
@@ -1173,7 +1173,7 @@
 VMMR0DECL(int) SVMR0RunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 {
-    STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatEntry, x);
-    STAM_PROFILE_ADV_SET_STOPPED(&pVCpu->hwaccm.s.StatExit1);
-    STAM_PROFILE_ADV_SET_STOPPED(&pVCpu->hwaccm.s.StatExit2);
+    STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatEntry, x);
+    STAM_PROFILE_ADV_SET_STOPPED(&pVCpu->hm.s.StatExit1);
+    STAM_PROFILE_ADV_SET_STOPPED(&pVCpu->hm.s.StatExit2);
 
     VBOXSTRICTRC    rc = VINF_SUCCESS;
@@ -1194,5 +1194,5 @@
 #endif
 
-    pVMCB = (SVM_VMCB *)pVCpu->hwaccm.s.svm.pVMCB;
+    pVMCB = (SVM_VMCB *)pVCpu->hm.s.svm.pVMCB;
     AssertMsgReturn(pVMCB, ("Invalid pVMCB\n"), VERR_HMSVM_INVALID_PVMCB);
 
@@ -1201,14 +1201,14 @@
      */
 ResumeExecution:
-    if (!STAM_PROFILE_ADV_IS_RUNNING(&pVCpu->hwaccm.s.StatEntry))
-        STAM_PROFILE_ADV_STOP_START(&pVCpu->hwaccm.s.StatExit2, &pVCpu->hwaccm.s.StatEntry, x);
-    Assert(!HWACCMR0SuspendPending());
+    if (!STAM_PROFILE_ADV_IS_RUNNING(&pVCpu->hm.s.StatEntry))
+        STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatExit2, &pVCpu->hm.s.StatEntry, x);
+    Assert(!HMR0SuspendPending());
 
     /*
      * Safety precaution; looping for too long here can have a very bad effect on the host.
      */
-    if (RT_UNLIKELY(++cResume > pVM->hwaccm.s.cMaxResumeLoops))
-    {
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitMaxResume);
+    if (RT_UNLIKELY(++cResume > pVM->hm.s.cMaxResumeLoops))
+    {
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitMaxResume);
         rc = VINF_EM_RAW_INTERRUPT;
         goto end;
@@ -1256,7 +1256,7 @@
      * Check for pending actions that force us to go back to ring-3.
      */
-    if (    VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK | VM_FF_REQUEST | VM_FF_PGM_POOL_FLUSH_PENDING | VM_FF_PDM_DMA)
+    if (    VM_FF_ISPENDING(pVM, VM_FF_HM_TO_R3_MASK | VM_FF_REQUEST | VM_FF_PGM_POOL_FLUSH_PENDING | VM_FF_PDM_DMA)
         ||  VMCPU_FF_ISPENDING(pVCpu,
-                                 VMCPU_FF_HWACCM_TO_R3_MASK
+                                 VMCPU_FF_HM_TO_R3_MASK
                                | VMCPU_FF_PGM_SYNC_CR3
                                | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL
@@ -1280,8 +1280,8 @@
 #endif
         {
-            if (    VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK)
-                ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HWACCM_TO_R3_MASK))
+            if (    VM_FF_ISPENDING(pVM, VM_FF_HM_TO_R3_MASK)
+                ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK))
             {
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchToR3);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchToR3);
                 rc = RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3;
                 goto end;
@@ -1326,5 +1326,5 @@
     if (RTThreadPreemptIsPending(NIL_RTTHREAD))
     {
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitPreemptPending);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitPreemptPending);
         rc = VINF_EM_RAW_INTERRUPT;
         goto end;
@@ -1348,5 +1348,5 @@
     /** @todo query and update the TPR only when it could have been changed (mmio access)
      */
-    if (pVM->hwaccm.s.fHasIoApic)
+    if (pVM->hm.s.fHasIoApic)
     {
         /* TPR caching in CR8 */
@@ -1355,5 +1355,5 @@
         AssertRC(rc2);
 
-        if (pVM->hwaccm.s.fTPRPatchingActive)
+        if (pVM->hm.s.fTPRPatchingActive)
         {
             /* Our patch code uses LSTAR for TPR caching. */
@@ -1399,12 +1399,12 @@
 
     /* Enable nested paging if necessary (disabled each time after #VMEXIT). */
-    pVMCB->ctrl.NestedPaging.n.u1NestedPaging = pVM->hwaccm.s.fNestedPaging;
+    pVMCB->ctrl.NestedPaging.n.u1NestedPaging = pVM->hm.s.fNestedPaging;
 
 #ifdef LOG_ENABLED
-    pCpu = HWACCMR0GetCurrentCpu();
-    if (pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu)
-        LogFlow(("Force TLB flush due to rescheduling to a different cpu (%d vs %d)\n", pVCpu->hwaccm.s.idLastCpu, pCpu->idCpu));
-    else if (pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
-        LogFlow(("Force TLB flush due to changed TLB flush count (%x vs %x)\n", pVCpu->hwaccm.s.cTLBFlushes, pCpu->cTLBFlushes));
+    pCpu = HMR0GetCurrentCpu();
+    if (pVCpu->hm.s.idLastCpu != pCpu->idCpu)
+        LogFlow(("Force TLB flush due to rescheduling to a different cpu (%d vs %d)\n", pVCpu->hm.s.idLastCpu, pCpu->idCpu));
+    else if (pVCpu->hm.s.cTLBFlushes != pCpu->cTLBFlushes)
+        LogFlow(("Force TLB flush due to changed TLB flush count (%x vs %x)\n", pVCpu->hm.s.cTLBFlushes, pCpu->cTLBFlushes));
     else if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH))
         LogFlow(("Manual TLB flush\n"));
@@ -1438,5 +1438,5 @@
     VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC);
 #endif
-    STAM_PROFILE_ADV_STOP_START(&pVCpu->hwaccm.s.StatEntry, &pVCpu->hwaccm.s.StatInGC, x);
+    STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatEntry, &pVCpu->hm.s.StatInGC, x);
 
     /* Setup TLB control and ASID in the VMCB. */
@@ -1444,11 +1444,11 @@
 
     /* In case we execute a goto ResumeExecution later on. */
-    pVCpu->hwaccm.s.fResumeVM      = true;
-    pVCpu->hwaccm.s.fForceTLBFlush = pVM->hwaccm.s.svm.fAlwaysFlushTLB;
-
-    Assert(sizeof(pVCpu->hwaccm.s.svm.pVMCBPhys) == 8);
+    pVCpu->hm.s.fResumeVM      = true;
+    pVCpu->hm.s.fForceTLBFlush = pVM->hm.s.svm.fAlwaysFlushTLB;
+
+    Assert(sizeof(pVCpu->hm.s.svm.pVMCBPhys) == 8);
     Assert(pVMCB->ctrl.IntCtrl.n.u1VIrqMasking);
-    Assert(pVMCB->ctrl.u64IOPMPhysAddr  == pVM->hwaccm.s.svm.pIOBitmapPhys);
-    Assert(pVMCB->ctrl.u64MSRPMPhysAddr == pVCpu->hwaccm.s.svm.pMSRBitmapPhys);
+    Assert(pVMCB->ctrl.u64IOPMPhysAddr  == pVM->hm.s.svm.pIOBitmapPhys);
+    Assert(pVMCB->ctrl.u64MSRPMPhysAddr == pVCpu->hm.s.svm.pMSRBitmapPhys);
     Assert(pVMCB->ctrl.u64LBRVirt == 0);
 
@@ -1462,9 +1462,9 @@
      * RDTSCPs (that don't cause exits) reads the guest MSR. See @bugref{3324}.
      */
-    u32HostExtFeatures = pVM->hwaccm.s.cpuid.u32AMDFeatureEDX;
+    u32HostExtFeatures = pVM->hm.s.cpuid.u32AMDFeatureEDX;
     if (    (u32HostExtFeatures & X86_CPUID_EXT_FEATURE_EDX_RDTSCP)
         && !(pVMCB->ctrl.u32InterceptCtrl2 & SVM_CTRL2_INTERCEPT_RDTSCP))
     {
-        pVCpu->hwaccm.s.u64HostTSCAux = ASMRdMsr(MSR_K8_TSC_AUX);
+        pVCpu->hm.s.u64HostTSCAux = ASMRdMsr(MSR_K8_TSC_AUX);
         uint64_t u64GuestTSCAux = 0;
         rc2 = CPUMQueryGuestMsr(pVCpu, MSR_K8_TSC_AUX, &u64GuestTSCAux);
@@ -1474,11 +1474,11 @@
 
 #ifdef VBOX_WITH_KERNEL_USING_XMM
-    hwaccmR0SVMRunWrapXMM(pVCpu->hwaccm.s.svm.pVMCBHostPhys, pVCpu->hwaccm.s.svm.pVMCBPhys, pCtx, pVM, pVCpu,
-                          pVCpu->hwaccm.s.svm.pfnVMRun);
+    hmR0SVMRunWrapXMM(pVCpu->hm.s.svm.pVMCBHostPhys, pVCpu->hm.s.svm.pVMCBPhys, pCtx, pVM, pVCpu,
+                          pVCpu->hm.s.svm.pfnVMRun);
 #else
-    pVCpu->hwaccm.s.svm.pfnVMRun(pVCpu->hwaccm.s.svm.pVMCBHostPhys, pVCpu->hwaccm.s.svm.pVMCBPhys, pCtx, pVM, pVCpu);
-#endif
-    ASMAtomicWriteBool(&pVCpu->hwaccm.s.fCheckedTLBFlush, false);
-    ASMAtomicIncU32(&pVCpu->hwaccm.s.cWorldSwitchExits);
+    pVCpu->hm.s.svm.pfnVMRun(pVCpu->hm.s.svm.pVMCBHostPhys, pVCpu->hm.s.svm.pVMCBPhys, pCtx, pVM, pVCpu);
+#endif
+    ASMAtomicWriteBool(&pVCpu->hm.s.fCheckedTLBFlush, false);
+    ASMAtomicIncU32(&pVCpu->hm.s.cWorldSwitchExits);
     /* Possibly the last TSC value seen by the guest (too high) (only when we're in TSC offset mode). */
     if (!(pVMCB->ctrl.u32InterceptCtrl1 & SVM_CTRL1_INTERCEPT_RDTSC))
@@ -1486,5 +1486,5 @@
         /* Restore host's TSC_AUX. */
         if (u32HostExtFeatures & X86_CPUID_EXT_FEATURE_EDX_RDTSCP)
-            ASMWrMsr(MSR_K8_TSC_AUX, pVCpu->hwaccm.s.u64HostTSCAux);
+            ASMWrMsr(MSR_K8_TSC_AUX, pVCpu->hm.s.u64HostTSCAux);
 
         TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() +
@@ -1493,5 +1493,5 @@
     TMNotifyEndOfExecution(pVCpu);
     VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED);
-    STAM_PROFILE_ADV_STOP_START(&pVCpu->hwaccm.s.StatInGC, &pVCpu->hwaccm.s.StatExit1, x);
+    STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatInGC, &pVCpu->hm.s.StatExit1, x);
     ASMSetFlags(uOldEFlags);
 #ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
@@ -1510,5 +1510,5 @@
     if (RT_UNLIKELY(exitCode == (uint64_t)SVM_EXIT_INVALID))      /* Invalid guest state. */
     {
-        HWACCMDumpRegs(pVM, pVCpu, pCtx);
+        HMDumpRegs(pVM, pVCpu, pCtx);
 #ifdef DEBUG
         Log(("ctrl.u16InterceptRdCRx            %x\n",      pVMCB->ctrl.u16InterceptRdCRx));
@@ -1713,5 +1713,5 @@
      * unless in the nested paging case where CR3 can be changed by the guest.
      */
-    if (   pVM->hwaccm.s.fNestedPaging
+    if (   pVM->hm.s.fNestedPaging
         && pCtx->cr3 != pVMCB->guest.u64CR3)
     {
@@ -1740,14 +1740,14 @@
 
     /* Check if an injected event was interrupted prematurely. */
-    pVCpu->hwaccm.s.Event.intInfo = pVMCB->ctrl.ExitIntInfo.au64[0];
+    pVCpu->hm.s.Event.intInfo = pVMCB->ctrl.ExitIntInfo.au64[0];
     if (    pVMCB->ctrl.ExitIntInfo.n.u1Valid
             /* we don't care about 'int xx' as the instruction will be restarted. */
         &&  pVMCB->ctrl.ExitIntInfo.n.u3Type != SVM_EVENT_SOFTWARE_INT)
     {
-        Log(("Pending inject %RX64 at %RGv exit=%08x\n", pVCpu->hwaccm.s.Event.intInfo, (RTGCPTR)pCtx->rip, exitCode));
+        Log(("Pending inject %RX64 at %RGv exit=%08x\n", pVCpu->hm.s.Event.intInfo, (RTGCPTR)pCtx->rip, exitCode));
 
 #ifdef LOG_ENABLED
         SVM_EVENT Event;
-        Event.au64[0] = pVCpu->hwaccm.s.Event.intInfo;
+        Event.au64[0] = pVCpu->hm.s.Event.intInfo;
 
         if (    exitCode == SVM_EXIT_EXCEPTION_E
@@ -1758,16 +1758,16 @@
 #endif
 
-        pVCpu->hwaccm.s.Event.fPending = true;
+        pVCpu->hm.s.Event.fPending = true;
         /* Error code present? (redundant) */
         if (pVMCB->ctrl.ExitIntInfo.n.u1ErrorCodeValid)
-            pVCpu->hwaccm.s.Event.errCode  = pVMCB->ctrl.ExitIntInfo.n.u32ErrorCode;
+            pVCpu->hm.s.Event.errCode  = pVMCB->ctrl.ExitIntInfo.n.u32ErrorCode;
         else
-            pVCpu->hwaccm.s.Event.errCode  = 0;
+            pVCpu->hm.s.Event.errCode  = 0;
     }
 #ifdef VBOX_WITH_STATISTICS
     if (exitCode == SVM_EXIT_NPF)
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitReasonNPF);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitReasonNPF);
     else
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.paStatExitReasonR0[exitCode & MASK_EXITREASON_STAT]);
+        STAM_COUNTER_INC(&pVCpu->hm.s.paStatExitReasonR0[exitCode & MASK_EXITREASON_STAT]);
 #endif
 
@@ -1775,5 +1775,5 @@
     if (fSyncTPR)
     {
-        if (pVM->hwaccm.s.fTPRPatchingActive)
+        if (pVM->hm.s.fTPRPatchingActive)
         {
             if ((pCtx->msrLSTAR & 0xff) != u8LastTPR)
@@ -1804,5 +1804,5 @@
                             pVMCB->ctrl.ExitIntInfo.au64[0], UINT64_MAX);
 #endif
-    STAM_PROFILE_ADV_STOP_START(&pVCpu->hwaccm.s.StatExit1, &pVCpu->hwaccm.s.StatExit2, x);
+    STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatExit1, &pVCpu->hm.s.StatExit2, x);
 
     /* Deal with the reason of the VM-exit. */
@@ -1827,5 +1827,5 @@
         case X86_XCPT_DB:
         {
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestDB);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDB);
 
             /* Note that we don't support guest and host-initiated debugging at the same time. */
@@ -1861,8 +1861,8 @@
             {
                 Assert(CPUMIsGuestFPUStateActive(pVCpu));
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitShadowNM);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitShadowNM);
 
                 /* Continue execution. */
-                pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0;
+                pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR0;
 
                 goto ResumeExecution;
@@ -1870,5 +1870,5 @@
 
             Log(("Forward #NM fault to the guest\n"));
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestNM);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNM);
 
             Event.au64[0]    = 0;
@@ -1887,5 +1887,5 @@
 
 #ifdef VBOX_ALWAYS_TRAP_PF
-            if (pVM->hwaccm.s.fNestedPaging)
+            if (pVM->hm.s.fNestedPaging)
             {
                 /*
@@ -1894,5 +1894,5 @@
                 Log(("Guest page fault at %04X:%RGv cr2=%RGv error code %x rsp=%RGv\n", pCtx->cs, (RTGCPTR)pCtx->rip,
                      uFaultAddress, errCode, (RTGCPTR)pCtx->rsp));
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestPF);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF);
 
                 /* Now we must update CR2. */
@@ -1910,14 +1910,14 @@
             }
 #endif
-            Assert(!pVM->hwaccm.s.fNestedPaging);
-
-#ifdef VBOX_HWACCM_WITH_GUEST_PATCHING
+            Assert(!pVM->hm.s.fNestedPaging);
+
+#ifdef VBOX_HM_WITH_GUEST_PATCHING
             /* Shortcut for APIC TPR reads and writes; 32 bits guests only */
-            if (    pVM->hwaccm.s.fTRPPatchingAllowed
+            if (    pVM->hm.s.fTRPPatchingAllowed
                 &&  (uFaultAddress & 0xfff) == 0x080
                 &&  !(errCode & X86_TRAP_PF_P)  /* not present */
                 &&  CPUMGetGuestCPL(pVCpu) == 0
                 &&  !CPUMIsGuestInLongModeEx(pCtx)
-                &&  pVM->hwaccm.s.cPatches < RT_ELEMENTS(pVM->hwaccm.s.aPatches))
+                &&  pVM->hm.s.cPatches < RT_ELEMENTS(pVM->hm.s.aPatches))
             {
                 RTGCPHYS GCPhysApicBase, GCPhys;
@@ -1930,8 +1930,8 @@
                 {
                     /* Only attempt to patch the instruction once. */
-                    PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
+                    PHMTPRPATCH pPatch = (PHMTPRPATCH)RTAvloU32Get(&pVM->hm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
                     if (!pPatch)
                     {
-                        rc = VINF_EM_HWACCM_PATCH_TPR_INSTR;
+                        rc = VINF_EM_HM_PATCH_TPR_INSTR;
                         break;
                     }
@@ -1953,5 +1953,5 @@
                 /* We've successfully synced our shadow pages, so let's just continue execution. */
                 Log2(("Shadow page fault at %RGv cr2=%RGv error code %x\n", (RTGCPTR)pCtx->rip, uFaultAddress, errCode));
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitShadowPF);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitShadowPF);
 
                 TRPMResetTrap(pVCpu);
@@ -1964,5 +1964,5 @@
                  */
                 Log2(("Forward page fault to the guest\n"));
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestPF);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF);
                 /* The error code might have been changed. */
                 errCode = TRPMGetErrorCode(pVCpu);
@@ -1994,5 +1994,5 @@
         case X86_XCPT_MF: /* Floating point exception. */
         {
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestMF);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestMF);
             if (!(pCtx->cr0 & X86_CR0_NE))
             {
@@ -2029,5 +2029,5 @@
             {
                 case X86_XCPT_GP:
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestGP);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestGP);
                     Event.n.u1ErrorCodeValid    = 1;
                     Event.n.u32ErrorCode        = pVMCB->ctrl.u64ExitInfo1; /* EXITINFO1 = error code */
@@ -2037,16 +2037,16 @@
                     break;
                 case X86_XCPT_DE:
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestDE);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDE);
                     break;
                 case X86_XCPT_UD:
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestUD);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestUD);
                     break;
                 case X86_XCPT_SS:
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestSS);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestSS);
                     Event.n.u1ErrorCodeValid    = 1;
                     Event.n.u32ErrorCode        = pVMCB->ctrl.u64ExitInfo1; /* EXITINFO1 = error code */
                     break;
                 case X86_XCPT_NP:
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestNP);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNP);
                     Event.n.u1ErrorCodeValid    = 1;
                     Event.n.u32ErrorCode        = pVMCB->ctrl.u64ExitInfo1; /* EXITINFO1 = error code */
@@ -2074,10 +2074,10 @@
         PGMMODE     enmShwPagingMode;
 
-        Assert(pVM->hwaccm.s.fNestedPaging);
+        Assert(pVM->hm.s.fNestedPaging);
         LogFlow(("Nested page fault at %RGv cr2=%RGp error code %x\n", (RTGCPTR)pCtx->rip, GCPhysFault, errCode));
 
-#ifdef VBOX_HWACCM_WITH_GUEST_PATCHING
+#ifdef VBOX_HM_WITH_GUEST_PATCHING
         /* Shortcut for APIC TPR reads and writes; 32 bits guests only */
-        if (    pVM->hwaccm.s.fTRPPatchingAllowed
+        if (    pVM->hm.s.fTRPPatchingAllowed
             &&  (GCPhysFault & PAGE_OFFSET_MASK) == 0x080
             &&  (   !(errCode & X86_TRAP_PF_P)  /* not present */
@@ -2085,5 +2085,5 @@
             &&  CPUMGetGuestCPL(pVCpu) == 0
             &&  !CPUMIsGuestInLongModeEx(pCtx)
-            &&  pVM->hwaccm.s.cPatches < RT_ELEMENTS(pVM->hwaccm.s.aPatches))
+            &&  pVM->hm.s.cPatches < RT_ELEMENTS(pVM->hm.s.aPatches))
         {
             RTGCPHYS GCPhysApicBase;
@@ -2094,8 +2094,8 @@
             {
                 /* Only attempt to patch the instruction once. */
-                PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
+                PHMTPRPATCH pPatch = (PHMTPRPATCH)RTAvloU32Get(&pVM->hm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
                 if (!pPatch)
                 {
-                    rc = VINF_EM_HWACCM_PATCH_TPR_INSTR;
+                    rc = VINF_EM_HM_PATCH_TPR_INSTR;
                     break;
                 }
@@ -2153,5 +2153,5 @@
             /* We've successfully synced our shadow pages, so let's just continue execution. */
             Log2(("Shadow page fault at %RGv cr2=%RGp error code %x\n", (RTGCPTR)pCtx->rip, GCPhysFault, errCode));
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitShadowPF);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitShadowPF);
 
             TRPMResetTrap(pVCpu);
@@ -2186,5 +2186,5 @@
     case SVM_EXIT_WBINVD:
     case SVM_EXIT_INVD:                 /* Guest software attempted to execute INVD. */
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInvd);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInvd);
         /* Skip instruction and continue directly. */
         pCtx->rip += 2;     /* Note! hardcoded opcode size! */
@@ -2195,5 +2195,5 @@
     {
         Log2(("SVM: Cpuid at %RGv for %x\n", (RTGCPTR)pCtx->rip, pCtx->eax));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCpuid);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCpuid);
         rc = EMInterpretCpuId(pVM, pVCpu, CPUMCTX2CORE(pCtx));
         if (rc == VINF_SUCCESS)
@@ -2211,5 +2211,5 @@
     {
         Log2(("SVM: Rdtsc\n"));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitRdtsc);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitRdtsc);
         rc = EMInterpretRdtsc(pVM, pVCpu, CPUMCTX2CORE(pCtx));
         if (rc == VINF_SUCCESS)
@@ -2226,5 +2226,5 @@
     {
         Log2(("SVM: Rdpmc %x\n", pCtx->ecx));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitRdpmc);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitRdpmc);
         rc = EMInterpretRdpmc(pVM, pVCpu, CPUMCTX2CORE(pCtx));
         if (rc == VINF_SUCCESS)
@@ -2241,5 +2241,5 @@
     {
         Log2(("SVM: Rdtscp\n"));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitRdtscp);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitRdtscp);
         rc = EMInterpretRdtscp(pVM, pVCpu, pCtx);
         if (rc == VINF_SUCCESS)
@@ -2257,7 +2257,7 @@
     {
         Log2(("SVM: invlpg\n"));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInvlpg);
-
-        Assert(!pVM->hwaccm.s.fNestedPaging);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInvlpg);
+
+        Assert(!pVM->hm.s.fNestedPaging);
 
         /* Truly a pita. Why can't SVM give the same information as VT-x? */
@@ -2265,5 +2265,5 @@
         if (rc == VINF_SUCCESS)
         {
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushPageInvlpg);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushPageInvlpg);
             goto ResumeExecution;   /* eip already updated */
         }
@@ -2277,5 +2277,5 @@
     {
         Log2(("SVM: %RGv mov cr%d, \n", (RTGCPTR)pCtx->rip, exitCode - SVM_EXIT_WRITE_CR0));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCRxWrite[exitCode - SVM_EXIT_WRITE_CR0]);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCRxWrite[exitCode - SVM_EXIT_WRITE_CR0]);
         rc = EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0);
 
@@ -2283,14 +2283,14 @@
         {
             case 0:
-                pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0;
+                pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR0;
                 break;
             case 2:
                 break;
             case 3:
-                Assert(!pVM->hwaccm.s.fNestedPaging);
-                pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR3;
+                Assert(!pVM->hm.s.fNestedPaging);
+                pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR3;
                 break;
             case 4:
-                pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR4;
+                pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR4;
                 break;
             case 8:
@@ -2315,5 +2315,5 @@
     {
         Log2(("SVM: %RGv mov x, cr%d\n", (RTGCPTR)pCtx->rip, exitCode - SVM_EXIT_READ_CR0));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCRxRead[exitCode - SVM_EXIT_READ_CR0]);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCRxRead[exitCode - SVM_EXIT_READ_CR0]);
         rc = EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0);
         if (rc == VINF_SUCCESS)
@@ -2333,10 +2333,10 @@
     {
         Log2(("SVM: %RGv mov dr%d, x\n", (RTGCPTR)pCtx->rip, exitCode - SVM_EXIT_WRITE_DR0));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitDRxWrite);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitDRxWrite);
 
         if (   !DBGFIsStepping(pVCpu)
             && !CPUMIsHyperDebugStateActive(pVCpu))
         {
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatDRxContextSwitch);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatDRxContextSwitch);
 
             /* Disable drx move intercepts. */
@@ -2354,5 +2354,5 @@
         {
             /* EIP has been updated already. */
-            pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_DEBUG;
+            pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_DEBUG;
 
             /* Only resume if successful. */
@@ -2369,9 +2369,9 @@
     {
         Log2(("SVM: %RGv mov x, dr%d\n", (RTGCPTR)pCtx->rip, exitCode - SVM_EXIT_READ_DR0));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitDRxRead);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitDRxRead);
 
         if (!DBGFIsStepping(pVCpu))
         {
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatDRxContextSwitch);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatDRxContextSwitch);
 
             /* Disable DRx move intercepts. */
@@ -2415,5 +2415,5 @@
         {
             /* ins/outs */
-            PDISCPUSTATE pDis = &pVCpu->hwaccm.s.DisState;
+            PDISCPUSTATE pDis = &pVCpu->hm.s.DisState;
 
             /* Disassemble manually to deal with segment prefixes. */
@@ -2424,5 +2424,5 @@
                 {
                     Log2(("IOMInterpretOUTSEx %RGv %x size=%d\n", (RTGCPTR)pCtx->rip, IoExitInfo.n.u16Port, uIOSize));
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOStringWrite);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIOStringWrite);
                     rc = IOMInterpretOUTSEx(pVM, CPUMCTX2CORE(pCtx), IoExitInfo.n.u16Port, pDis->fPrefix,
                                             (DISCPUMODE)pDis->uAddrMode, uIOSize);
@@ -2431,5 +2431,5 @@
                 {
                     Log2(("IOMInterpretINSEx  %RGv %x size=%d\n", (RTGCPTR)pCtx->rip, IoExitInfo.n.u16Port, uIOSize));
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOStringRead);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIOStringRead);
                     rc = IOMInterpretINSEx(pVM, CPUMCTX2CORE(pCtx), IoExitInfo.n.u16Port, pDis->fPrefix,
                                            (DISCPUMODE)pDis->uAddrMode, uIOSize);
@@ -2448,9 +2448,9 @@
                 Log2(("IOMIOPortWrite %RGv %x %x size=%d\n", (RTGCPTR)pCtx->rip, IoExitInfo.n.u16Port, pCtx->eax & uAndVal,
                       uIOSize));
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOWrite);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIOWrite);
                 rc = IOMIOPortWrite(pVM, IoExitInfo.n.u16Port, pCtx->eax & uAndVal, uIOSize);
                 if (rc == VINF_IOM_R3_IOPORT_WRITE)
                 {
-                    HWACCMR0SavePendingIOPortWrite(pVCpu, pCtx->rip, pVMCB->ctrl.u64ExitInfo2, IoExitInfo.n.u16Port,
+                    HMR0SavePendingIOPortWrite(pVCpu, pCtx->rip, pVMCB->ctrl.u64ExitInfo2, IoExitInfo.n.u16Port,
                                                    uAndVal, uIOSize);
                 }
@@ -2460,5 +2460,5 @@
                 uint32_t u32Val = 0;
 
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIORead);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIORead);
                 rc = IOMIOPortRead(pVM, IoExitInfo.n.u16Port, &u32Val, uIOSize);
                 if (IOM_SUCCESS(rc))
@@ -2471,5 +2471,5 @@
                 else if (rc == VINF_IOM_R3_IOPORT_READ)
                 {
-                    HWACCMR0SavePendingIOPortRead(pVCpu, pCtx->rip, pVMCB->ctrl.u64ExitInfo2, IoExitInfo.n.u16Port,
+                    HMR0SavePendingIOPortRead(pVCpu, pCtx->rip, pVMCB->ctrl.u64ExitInfo2, IoExitInfo.n.u16Port,
                                                   uAndVal, uIOSize);
                 }
@@ -2493,5 +2493,5 @@
                     static uint32_t const aIOSize[4] = { 1, 2, 0, 4 };
 
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatDRxIOCheck);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatDRxIOCheck);
                     for (unsigned i = 0; i < 4; i++)
                     {
@@ -2566,5 +2566,5 @@
     case SVM_EXIT_HLT:
         /* Check if external interrupts are pending; if so, don't switch back. */
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitHlt);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHlt);
         pCtx->rip++;    /* skip hlt */
         if (EMShouldContinueAfterHalt(pVCpu, pCtx))
@@ -2576,5 +2576,5 @@
     case SVM_EXIT_MWAIT_UNCOND:
         Log2(("SVM: mwait\n"));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitMwait);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitMwait);
         rc = EMInterpretMWait(pVM, pVCpu, CPUMCTX2CORE(pCtx));
         if (    rc == VINF_EM_HALT
@@ -2598,5 +2598,5 @@
         Log2(("SVM: monitor\n"));
 
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitMonitor);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitMonitor);
         rc = EMInterpretMonitor(pVM, pVCpu, CPUMCTX2CORE(pCtx));
         if (rc == VINF_SUCCESS)
@@ -2644,5 +2644,5 @@
     {
         /* When an interrupt is pending, we'll let MSR_K8_LSTAR writes fault in our TPR patch code. */
-        if (    pVM->hwaccm.s.fTPRPatchingActive
+        if (    pVM->hm.s.fTPRPatchingActive
             &&  pCtx->ecx == MSR_K8_LSTAR
             &&  pVMCB->ctrl.u64ExitInfo1 == 1 /* wrmsr */)
@@ -2668,5 +2668,5 @@
          * so we play safe by completely disassembling the instruction.
          */
-        STAM_COUNTER_INC((pVMCB->ctrl.u64ExitInfo1 == 0) ? &pVCpu->hwaccm.s.StatExitRdmsr : &pVCpu->hwaccm.s.StatExitWrmsr);
+        STAM_COUNTER_INC((pVMCB->ctrl.u64ExitInfo1 == 0) ? &pVCpu->hm.s.StatExitRdmsr : &pVCpu->hm.s.StatExitWrmsr);
         Log(("SVM: %s\n", (pVMCB->ctrl.u64ExitInfo1 == 0) ? "rdmsr" : "wrmsr"));
         rc = EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0);
@@ -2685,11 +2685,11 @@
         Log(("SVM_EXIT_TASK_SWITCH: exit2=%RX64\n", pVMCB->ctrl.u64ExitInfo2));
         if (    !(pVMCB->ctrl.u64ExitInfo2 & (SVM_EXIT2_TASK_SWITCH_IRET | SVM_EXIT2_TASK_SWITCH_JMP))
-            &&  pVCpu->hwaccm.s.Event.fPending)
+            &&  pVCpu->hm.s.Event.fPending)
         {
             SVM_EVENT Event;
-            Event.au64[0] = pVCpu->hwaccm.s.Event.intInfo;
+            Event.au64[0] = pVCpu->hm.s.Event.intInfo;
 
             /* Caused by an injected interrupt. */
-            pVCpu->hwaccm.s.Event.fPending = false;
+            pVCpu->hm.s.Event.fPending = false;
             switch (Event.n.u3Type)
             {
@@ -2758,7 +2758,7 @@
     if (exitCode == SVM_EXIT_INTR)
     {
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatPendingHostIrq);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatPendingHostIrq);
         /* On the next entry we'll only sync the host context. */
-        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_HOST_CONTEXT;
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT;
     }
     else
@@ -2767,5 +2767,5 @@
         /** @todo we can do better than this */
         /* Not in the VINF_PGM_CHANGE_MODE though! */
-        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_ALL;
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_ALL;
     }
 
@@ -2783,7 +2783,7 @@
 #endif
 
-    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2, x);
-    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, x);
-    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatEntry, x);
+    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2, x);
+    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit1, x);
+    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatEntry, x);
     return VBOXSTRICTRC_TODO(rc);
 }
@@ -2809,5 +2809,5 @@
         uint8_t u8Tpr;
 
-        PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
+        PHMTPRPATCH pPatch = (PHMTPRPATCH)RTAvloU32Get(&pVM->hm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
         if (!pPatch)
             break;
@@ -2815,5 +2815,5 @@
         switch (pPatch->enmType)
         {
-            case HWACCMTPRINSTR_READ:
+            case HMTPRINSTR_READ:
                 /* TPR caching in CR8 */
                 rc = PDMApicGetTPR(pVCpu, &u8Tpr, &fPending);
@@ -2827,8 +2827,8 @@
                 break;
 
-            case HWACCMTPRINSTR_WRITE_REG:
-            case HWACCMTPRINSTR_WRITE_IMM:
+            case HMTPRINSTR_WRITE_REG:
+            case HMTPRINSTR_WRITE_IMM:
                 /* Fetch the new TPR value */
-                if (pPatch->enmType == HWACCMTPRINSTR_WRITE_REG)
+                if (pPatch->enmType == HMTPRINSTR_WRITE_REG)
                 {
                     uint32_t val;
@@ -2865,11 +2865,11 @@
 VMMR0DECL(int) SVMR0Enter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu)
 {
-    Assert(pVM->hwaccm.s.svm.fSupported);
-
-    LogFlow(("SVMR0Enter cpu%d last=%d asid=%d\n", pCpu->idCpu, pVCpu->hwaccm.s.idLastCpu, pVCpu->hwaccm.s.uCurrentASID));
-    pVCpu->hwaccm.s.fResumeVM = false;
+    Assert(pVM->hm.s.svm.fSupported);
+
+    LogFlow(("SVMR0Enter cpu%d last=%d asid=%d\n", pCpu->idCpu, pVCpu->hm.s.idLastCpu, pVCpu->hm.s.uCurrentASID));
+    pVCpu->hm.s.fResumeVM = false;
 
     /* Force to reload LDTR, so we'll execute VMLoad to load additional guest state. */
-    pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_LDTR;
+    pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_LDTR;
 
     return VINF_SUCCESS;
@@ -2887,7 +2887,7 @@
 VMMR0DECL(int) SVMR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 {
-    SVM_VMCB *pVMCB = (SVM_VMCB *)pVCpu->hwaccm.s.svm.pVMCB;
-
-    Assert(pVM->hwaccm.s.svm.fSupported);
+    SVM_VMCB *pVMCB = (SVM_VMCB *)pVCpu->hm.s.svm.pVMCB;
+
+    Assert(pVM->hm.s.svm.fSupported);
 
 #ifdef DEBUG
@@ -2908,5 +2908,5 @@
 
         /* Resync the debug registers the next time. */
-        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_DEBUG;
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_DEBUG;
     }
     else
@@ -2979,5 +2979,5 @@
     if (CPUMGetGuestCodeBits(pVCpu) != 16)
     {
-        PDISSTATE pDis = &pVCpu->hwaccm.s.DisState;
+        PDISSTATE pDis = &pVCpu->hm.s.DisState;
         int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
         if (RT_SUCCESS(rc) && pDis->pCurInstr->uOpcode == OP_INVLPG)
@@ -3003,5 +3003,5 @@
 VMMR0DECL(int) SVMR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt)
 {
-    bool fFlushPending = pVM->hwaccm.s.svm.fAlwaysFlushTLB | VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH);
+    bool fFlushPending = pVM->hm.s.svm.fAlwaysFlushTLB | VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH);
 
     /* Skip it if a TLB flush is already pending. */
@@ -3012,7 +3012,7 @@
         Log2(("SVMR0InvalidatePage %RGv\n", GCVirt));
         AssertReturn(pVM, VERR_INVALID_PARAMETER);
-        Assert(pVM->hwaccm.s.svm.fSupported);
-
-        pVMCB = (SVM_VMCB *)pVCpu->hwaccm.s.svm.pVMCB;
+        Assert(pVM->hm.s.svm.fSupported);
+
+        pVMCB = (SVM_VMCB *)pVCpu->hm.s.svm.pVMCB;
         AssertMsgReturn(pVMCB, ("Invalid pVMCB\n"), VERR_HMSVM_INVALID_PVMCB);
 
@@ -3040,8 +3040,8 @@
 VMMR0DECL(int) SVMR0InvalidatePhysPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys)
 {
-    Assert(pVM->hwaccm.s.fNestedPaging);
+    Assert(pVM->hm.s.fNestedPaging);
     /* invlpga only invalidates TLB entries for guest virtual addresses; we have no choice but to force a TLB flush here. */
     VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
-    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushTLBInvlpga);
+    STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTLBInvlpga);
     return VINF_SUCCESS;
 }
@@ -3069,5 +3069,5 @@
     aParam[3] = (uint32_t)(pVMCBPhys >> 32);                /* Param 2: pVMCBPhys - Hi. */
 
-    return SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnSVMGCVMRun64, 4, &aParam[0]);
+    return SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hm.s.pfnSVMGCVMRun64, 4, &aParam[0]);
 }
 
@@ -3105,8 +3105,8 @@
         CPUMPushHyper(pVCpu, paParam[i]);
 
-    STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatWorldSwitch3264, z);
+    STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatWorldSwitch3264, z);
     /* Call switcher. */
-    rc = pVM->hwaccm.s.pfnHost32ToGuest64R0(pVM, RT_OFFSETOF(VM, aCpus[pVCpu->idCpu].cpum) - RT_OFFSETOF(VM, cpum));
-    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatWorldSwitch3264, z);
+    rc = pVM->hm.s.pfnHost32ToGuest64R0(pVM, RT_OFFSETOF(VM, aCpus[pVCpu->idCpu].cpum) - RT_OFFSETOF(VM, cpum));
+    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatWorldSwitch3264, z);
 
     ASMSetFlags(uOldEFlags);
Index: trunk/src/VBox/VMM/VMMR0/HWSVMR0.h
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWSVMR0.h	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR0/HWSVMR0.h	(revision 43387)
@@ -24,7 +24,7 @@
 #include <VBox/vmm/stam.h>
 #include <VBox/dis.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <VBox/vmm/pgm.h>
-#include <VBox/vmm/hwacc_svm.h>
+#include <VBox/vmm/hm_svm.h>
 
 RT_C_DECLS_BEGIN
Index: trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 43387)
@@ -20,7 +20,7 @@
 *   Header Files                                                               *
 *******************************************************************************/
-#define LOG_GROUP LOG_GROUP_HWACCM
+#define LOG_GROUP LOG_GROUP_HM
 #include <iprt/asm-amd64-x86.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <VBox/vmm/pgm.h>
 #include <VBox/vmm/dbgf.h>
@@ -32,5 +32,5 @@
 #endif
 #include <VBox/vmm/tm.h>
-#include "HWACCMInternal.h"
+#include "HMInternal.h"
 #include <VBox/vmm/vm.h>
 #include <VBox/vmm/pdmapi.h>
@@ -70,5 +70,5 @@
 
 #ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-/** See HWACCMR0A.asm. */
+/** See HMR0A.asm. */
 extern "C" uint32_t g_fVMXIs64bitHost;
 #endif
@@ -90,5 +90,5 @@
 
 /**
- * Updates error from VMCS to HWACCMCPU's lasterror record.
+ * Updates error from VMCS to HMCPU's lasterror record.
  *
  * @param    pVM            Pointer to the VM.
@@ -103,7 +103,7 @@
 
         VMXReadVMCS(VMX_VMCS32_RO_VM_INSTR_ERROR, &instrError);
-        pVCpu->hwaccm.s.vmx.lasterror.ulInstrError = instrError;
-    }
-    pVM->hwaccm.s.lLastError = rc;
+        pVCpu->hm.s.vmx.lasterror.ulInstrError = instrError;
+    }
+    pVM->hm.s.lLastError = rc;
 }
 
@@ -130,5 +130,5 @@
         {
             /* Set revision dword at the beginning of the VMXON structure. */
-            *(uint32_t *)pvCpuPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);
+            *(uint32_t *)pvCpuPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hm.s.vmx.msr.vmx_basic_info);
         }
 
@@ -165,6 +165,6 @@
      */
     if (   pVM
-        && pVM->hwaccm.s.vmx.fVPID
-        && (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS))
+        && pVM->hm.s.vmx.fVPID
+        && (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS))
     {
         hmR0VmxFlushVPID(pVM, NULL /* pvCpu */, VMX_FLUSH_VPID_ALL_CONTEXTS, 0 /* GCPtr */);
@@ -224,38 +224,38 @@
 #endif
 
-    pVM->hwaccm.s.vmx.pMemObjAPIC = NIL_RTR0MEMOBJ;
-
-    if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
+    pVM->hm.s.vmx.pMemObjAPIC = NIL_RTR0MEMOBJ;
+
+    if (pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
     {
         /* Allocate one page for the APIC physical page (serves for filtering accesses). */
-        rc = RTR0MemObjAllocCont(&pVM->hwaccm.s.vmx.pMemObjAPIC, PAGE_SIZE, false /* executable R0 mapping */);
+        rc = RTR0MemObjAllocCont(&pVM->hm.s.vmx.pMemObjAPIC, PAGE_SIZE, false /* executable R0 mapping */);
         AssertRC(rc);
         if (RT_FAILURE(rc))
             return rc;
 
-        pVM->hwaccm.s.vmx.pAPIC     = (uint8_t *)RTR0MemObjAddress(pVM->hwaccm.s.vmx.pMemObjAPIC);
-        pVM->hwaccm.s.vmx.pAPICPhys = RTR0MemObjGetPagePhysAddr(pVM->hwaccm.s.vmx.pMemObjAPIC, 0);
-        ASMMemZero32(pVM->hwaccm.s.vmx.pAPIC, PAGE_SIZE);
+        pVM->hm.s.vmx.pAPIC     = (uint8_t *)RTR0MemObjAddress(pVM->hm.s.vmx.pMemObjAPIC);
+        pVM->hm.s.vmx.pAPICPhys = RTR0MemObjGetPagePhysAddr(pVM->hm.s.vmx.pMemObjAPIC, 0);
+        ASMMemZero32(pVM->hm.s.vmx.pAPIC, PAGE_SIZE);
     }
     else
     {
-        pVM->hwaccm.s.vmx.pMemObjAPIC = 0;
-        pVM->hwaccm.s.vmx.pAPIC       = 0;
-        pVM->hwaccm.s.vmx.pAPICPhys   = 0;
+        pVM->hm.s.vmx.pMemObjAPIC = 0;
+        pVM->hm.s.vmx.pAPIC       = 0;
+        pVM->hm.s.vmx.pAPICPhys   = 0;
     }
 
 #ifdef VBOX_WITH_CRASHDUMP_MAGIC
     {
-        rc = RTR0MemObjAllocCont(&pVM->hwaccm.s.vmx.pMemObjScratch, PAGE_SIZE, false /* executable R0 mapping */);
+        rc = RTR0MemObjAllocCont(&pVM->hm.s.vmx.pMemObjScratch, PAGE_SIZE, false /* executable R0 mapping */);
         AssertRC(rc);
         if (RT_FAILURE(rc))
             return rc;
 
-        pVM->hwaccm.s.vmx.pScratch     = (uint8_t *)RTR0MemObjAddress(pVM->hwaccm.s.vmx.pMemObjScratch);
-        pVM->hwaccm.s.vmx.pScratchPhys = RTR0MemObjGetPagePhysAddr(pVM->hwaccm.s.vmx.pMemObjScratch, 0);
-
-        ASMMemZero32(pVM->hwaccm.s.vmx.pScratch, PAGE_SIZE);
-        strcpy((char *)pVM->hwaccm.s.vmx.pScratch, "SCRATCH Magic");
-        *(uint64_t *)(pVM->hwaccm.s.vmx.pScratch + 16) = UINT64_C(0xDEADBEEFDEADBEEF);
+        pVM->hm.s.vmx.pScratch     = (uint8_t *)RTR0MemObjAddress(pVM->hm.s.vmx.pMemObjScratch);
+        pVM->hm.s.vmx.pScratchPhys = RTR0MemObjGetPagePhysAddr(pVM->hm.s.vmx.pMemObjScratch, 0);
+
+        ASMMemZero32(pVM->hm.s.vmx.pScratch, PAGE_SIZE);
+        strcpy((char *)pVM->hm.s.vmx.pScratch, "SCRATCH Magic");
+        *(uint64_t *)(pVM->hm.s.vmx.pScratch + 16) = UINT64_C(0xDEADBEEFDEADBEEF);
     }
 #endif
@@ -266,71 +266,71 @@
         PVMCPU pVCpu = &pVM->aCpus[i];
 
-        pVCpu->hwaccm.s.vmx.hMemObjVMCS = NIL_RTR0MEMOBJ;
+        pVCpu->hm.s.vmx.hMemObjVMCS = NIL_RTR0MEMOBJ;
 
         /* Allocate one page for the VM control structure (VMCS). */
-        rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.hMemObjVMCS, PAGE_SIZE, false /* executable R0 mapping */);
+        rc = RTR0MemObjAllocCont(&pVCpu->hm.s.vmx.hMemObjVMCS, PAGE_SIZE, false /* executable R0 mapping */);
         AssertRC(rc);
         if (RT_FAILURE(rc))
             return rc;
 
-        pVCpu->hwaccm.s.vmx.pvVMCS     = RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.hMemObjVMCS);
-        pVCpu->hwaccm.s.vmx.HCPhysVMCS = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.hMemObjVMCS, 0);
-        ASMMemZeroPage(pVCpu->hwaccm.s.vmx.pvVMCS);
-
-        pVCpu->hwaccm.s.vmx.cr0_mask = 0;
-        pVCpu->hwaccm.s.vmx.cr4_mask = 0;
+        pVCpu->hm.s.vmx.pvVMCS     = RTR0MemObjAddress(pVCpu->hm.s.vmx.hMemObjVMCS);
+        pVCpu->hm.s.vmx.HCPhysVMCS = RTR0MemObjGetPagePhysAddr(pVCpu->hm.s.vmx.hMemObjVMCS, 0);
+        ASMMemZeroPage(pVCpu->hm.s.vmx.pvVMCS);
+
+        pVCpu->hm.s.vmx.cr0_mask = 0;
+        pVCpu->hm.s.vmx.cr4_mask = 0;
 
         /* Allocate one page for the virtual APIC page for TPR caching. */
-        rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.hMemObjVAPIC, PAGE_SIZE, false /* executable R0 mapping */);
+        rc = RTR0MemObjAllocCont(&pVCpu->hm.s.vmx.hMemObjVAPIC, PAGE_SIZE, false /* executable R0 mapping */);
         AssertRC(rc);
         if (RT_FAILURE(rc))
             return rc;
 
-        pVCpu->hwaccm.s.vmx.pbVAPIC     = (uint8_t *)RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.hMemObjVAPIC);
-        pVCpu->hwaccm.s.vmx.HCPhysVAPIC = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.hMemObjVAPIC, 0);
-        ASMMemZeroPage(pVCpu->hwaccm.s.vmx.pbVAPIC);
+        pVCpu->hm.s.vmx.pbVAPIC     = (uint8_t *)RTR0MemObjAddress(pVCpu->hm.s.vmx.hMemObjVAPIC);
+        pVCpu->hm.s.vmx.HCPhysVAPIC = RTR0MemObjGetPagePhysAddr(pVCpu->hm.s.vmx.hMemObjVAPIC, 0);
+        ASMMemZeroPage(pVCpu->hm.s.vmx.pbVAPIC);
 
         /* Allocate the MSR bitmap if this feature is supported. */
-        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
-        {
-            rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap, PAGE_SIZE, false /* executable R0 mapping */);
+        if (pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
+        {
+            rc = RTR0MemObjAllocCont(&pVCpu->hm.s.vmx.pMemObjMSRBitmap, PAGE_SIZE, false /* executable R0 mapping */);
             AssertRC(rc);
             if (RT_FAILURE(rc))
                 return rc;
 
-            pVCpu->hwaccm.s.vmx.pMSRBitmap     = (uint8_t *)RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap);
-            pVCpu->hwaccm.s.vmx.pMSRBitmapPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap, 0);
-            memset(pVCpu->hwaccm.s.vmx.pMSRBitmap, 0xff, PAGE_SIZE);
+            pVCpu->hm.s.vmx.pMSRBitmap     = (uint8_t *)RTR0MemObjAddress(pVCpu->hm.s.vmx.pMemObjMSRBitmap);
+            pVCpu->hm.s.vmx.pMSRBitmapPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hm.s.vmx.pMemObjMSRBitmap, 0);
+            memset(pVCpu->hm.s.vmx.pMSRBitmap, 0xff, PAGE_SIZE);
         }
 
 #ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
         /* Allocate one page for the guest MSR load area (for preloading guest MSRs during the world switch). */
-        rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjGuestMSR, PAGE_SIZE, false /* executable R0 mapping */);
+        rc = RTR0MemObjAllocCont(&pVCpu->hm.s.vmx.pMemObjGuestMSR, PAGE_SIZE, false /* executable R0 mapping */);
         AssertRC(rc);
         if (RT_FAILURE(rc))
             return rc;
 
-        pVCpu->hwaccm.s.vmx.pGuestMSR     = (uint8_t *)RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.pMemObjGuestMSR);
-        pVCpu->hwaccm.s.vmx.pGuestMSRPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.pMemObjGuestMSR, 0);
-        Assert(!(pVCpu->hwaccm.s.vmx.pGuestMSRPhys & 0xf));
-        memset(pVCpu->hwaccm.s.vmx.pGuestMSR, 0, PAGE_SIZE);
+        pVCpu->hm.s.vmx.pGuestMSR     = (uint8_t *)RTR0MemObjAddress(pVCpu->hm.s.vmx.pMemObjGuestMSR);
+        pVCpu->hm.s.vmx.pGuestMSRPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hm.s.vmx.pMemObjGuestMSR, 0);
+        Assert(!(pVCpu->hm.s.vmx.pGuestMSRPhys & 0xf));
+        memset(pVCpu->hm.s.vmx.pGuestMSR, 0, PAGE_SIZE);
 
         /* Allocate one page for the host MSR load area (for restoring host MSRs after the world switch back). */
-        rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjHostMSR, PAGE_SIZE, false /* executable R0 mapping */);
+        rc = RTR0MemObjAllocCont(&pVCpu->hm.s.vmx.pMemObjHostMSR, PAGE_SIZE, false /* executable R0 mapping */);
         AssertRC(rc);
         if (RT_FAILURE(rc))
             return rc;
 
-        pVCpu->hwaccm.s.vmx.pHostMSR     = (uint8_t *)RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.pMemObjHostMSR);
-        pVCpu->hwaccm.s.vmx.pHostMSRPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.pMemObjHostMSR, 0);
-        Assert(!(pVCpu->hwaccm.s.vmx.pHostMSRPhys & 0xf));
-        memset(pVCpu->hwaccm.s.vmx.pHostMSR, 0, PAGE_SIZE);
+        pVCpu->hm.s.vmx.pHostMSR     = (uint8_t *)RTR0MemObjAddress(pVCpu->hm.s.vmx.pMemObjHostMSR);
+        pVCpu->hm.s.vmx.pHostMSRPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hm.s.vmx.pMemObjHostMSR, 0);
+        Assert(!(pVCpu->hm.s.vmx.pHostMSRPhys & 0xf));
+        memset(pVCpu->hm.s.vmx.pHostMSR, 0, PAGE_SIZE);
 #endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
 
         /* Current guest paging mode. */
-        pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode = PGMMODE_REAL;
+        pVCpu->hm.s.vmx.enmLastSeenGuestMode = PGMMODE_REAL;
 
 #ifdef LOG_ENABLED
-        SUPR0Printf("VMXR0InitVM %x VMCS=%x (%x)\n", pVM, pVCpu->hwaccm.s.vmx.pvVMCS, (uint32_t)pVCpu->hwaccm.s.vmx.HCPhysVMCS);
+        SUPR0Printf("VMXR0InitVM %x VMCS=%x (%x)\n", pVM, pVCpu->hm.s.vmx.pvVMCS, (uint32_t)pVCpu->hm.s.vmx.HCPhysVMCS);
 #endif
     }
@@ -352,57 +352,57 @@
         PVMCPU pVCpu = &pVM->aCpus[i];
 
-        if (pVCpu->hwaccm.s.vmx.hMemObjVMCS != NIL_RTR0MEMOBJ)
-        {
-            RTR0MemObjFree(pVCpu->hwaccm.s.vmx.hMemObjVMCS, false);
-            pVCpu->hwaccm.s.vmx.hMemObjVMCS = NIL_RTR0MEMOBJ;
-            pVCpu->hwaccm.s.vmx.pvVMCS      = 0;
-            pVCpu->hwaccm.s.vmx.HCPhysVMCS  = 0;
-        }
-        if (pVCpu->hwaccm.s.vmx.hMemObjVAPIC != NIL_RTR0MEMOBJ)
-        {
-            RTR0MemObjFree(pVCpu->hwaccm.s.vmx.hMemObjVAPIC, false);
-            pVCpu->hwaccm.s.vmx.hMemObjVAPIC = NIL_RTR0MEMOBJ;
-            pVCpu->hwaccm.s.vmx.pbVAPIC      = 0;
-            pVCpu->hwaccm.s.vmx.HCPhysVAPIC  = 0;
-        }
-        if (pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap != NIL_RTR0MEMOBJ)
-        {
-            RTR0MemObjFree(pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap, false);
-            pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap = NIL_RTR0MEMOBJ;
-            pVCpu->hwaccm.s.vmx.pMSRBitmap       = 0;
-            pVCpu->hwaccm.s.vmx.pMSRBitmapPhys   = 0;
+        if (pVCpu->hm.s.vmx.hMemObjVMCS != NIL_RTR0MEMOBJ)
+        {
+            RTR0MemObjFree(pVCpu->hm.s.vmx.hMemObjVMCS, false);
+            pVCpu->hm.s.vmx.hMemObjVMCS = NIL_RTR0MEMOBJ;
+            pVCpu->hm.s.vmx.pvVMCS      = 0;
+            pVCpu->hm.s.vmx.HCPhysVMCS  = 0;
+        }
+        if (pVCpu->hm.s.vmx.hMemObjVAPIC != NIL_RTR0MEMOBJ)
+        {
+            RTR0MemObjFree(pVCpu->hm.s.vmx.hMemObjVAPIC, false);
+            pVCpu->hm.s.vmx.hMemObjVAPIC = NIL_RTR0MEMOBJ;
+            pVCpu->hm.s.vmx.pbVAPIC      = 0;
+            pVCpu->hm.s.vmx.HCPhysVAPIC  = 0;
+        }
+        if (pVCpu->hm.s.vmx.pMemObjMSRBitmap != NIL_RTR0MEMOBJ)
+        {
+            RTR0MemObjFree(pVCpu->hm.s.vmx.pMemObjMSRBitmap, false);
+            pVCpu->hm.s.vmx.pMemObjMSRBitmap = NIL_RTR0MEMOBJ;
+            pVCpu->hm.s.vmx.pMSRBitmap       = 0;
+            pVCpu->hm.s.vmx.pMSRBitmapPhys   = 0;
         }
 #ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
-        if (pVCpu->hwaccm.s.vmx.pMemObjHostMSR != NIL_RTR0MEMOBJ)
-        {
-            RTR0MemObjFree(pVCpu->hwaccm.s.vmx.pMemObjHostMSR, false);
-            pVCpu->hwaccm.s.vmx.pMemObjHostMSR = NIL_RTR0MEMOBJ;
-            pVCpu->hwaccm.s.vmx.pHostMSR       = 0;
-            pVCpu->hwaccm.s.vmx.pHostMSRPhys   = 0;
-        }
-        if (pVCpu->hwaccm.s.vmx.pMemObjGuestMSR != NIL_RTR0MEMOBJ)
-        {
-            RTR0MemObjFree(pVCpu->hwaccm.s.vmx.pMemObjGuestMSR, false);
-            pVCpu->hwaccm.s.vmx.pMemObjGuestMSR = NIL_RTR0MEMOBJ;
-            pVCpu->hwaccm.s.vmx.pGuestMSR       = 0;
-            pVCpu->hwaccm.s.vmx.pGuestMSRPhys   = 0;
+        if (pVCpu->hm.s.vmx.pMemObjHostMSR != NIL_RTR0MEMOBJ)
+        {
+            RTR0MemObjFree(pVCpu->hm.s.vmx.pMemObjHostMSR, false);
+            pVCpu->hm.s.vmx.pMemObjHostMSR = NIL_RTR0MEMOBJ;
+            pVCpu->hm.s.vmx.pHostMSR       = 0;
+            pVCpu->hm.s.vmx.pHostMSRPhys   = 0;
+        }
+        if (pVCpu->hm.s.vmx.pMemObjGuestMSR != NIL_RTR0MEMOBJ)
+        {
+            RTR0MemObjFree(pVCpu->hm.s.vmx.pMemObjGuestMSR, false);
+            pVCpu->hm.s.vmx.pMemObjGuestMSR = NIL_RTR0MEMOBJ;
+            pVCpu->hm.s.vmx.pGuestMSR       = 0;
+            pVCpu->hm.s.vmx.pGuestMSRPhys   = 0;
         }
 #endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
     }
-    if (pVM->hwaccm.s.vmx.pMemObjAPIC != NIL_RTR0MEMOBJ)
-    {
-        RTR0MemObjFree(pVM->hwaccm.s.vmx.pMemObjAPIC, false);
-        pVM->hwaccm.s.vmx.pMemObjAPIC = NIL_RTR0MEMOBJ;
-        pVM->hwaccm.s.vmx.pAPIC       = 0;
-        pVM->hwaccm.s.vmx.pAPICPhys   = 0;
+    if (pVM->hm.s.vmx.pMemObjAPIC != NIL_RTR0MEMOBJ)
+    {
+        RTR0MemObjFree(pVM->hm.s.vmx.pMemObjAPIC, false);
+        pVM->hm.s.vmx.pMemObjAPIC = NIL_RTR0MEMOBJ;
+        pVM->hm.s.vmx.pAPIC       = 0;
+        pVM->hm.s.vmx.pAPICPhys   = 0;
     }
 #ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    if (pVM->hwaccm.s.vmx.pMemObjScratch != NIL_RTR0MEMOBJ)
-    {
-        ASMMemZero32(pVM->hwaccm.s.vmx.pScratch, PAGE_SIZE);
-        RTR0MemObjFree(pVM->hwaccm.s.vmx.pMemObjScratch, false);
-        pVM->hwaccm.s.vmx.pMemObjScratch = NIL_RTR0MEMOBJ;
-        pVM->hwaccm.s.vmx.pScratch       = 0;
-        pVM->hwaccm.s.vmx.pScratchPhys   = 0;
+    if (pVM->hm.s.vmx.pMemObjScratch != NIL_RTR0MEMOBJ)
+    {
+        ASMMemZero32(pVM->hm.s.vmx.pScratch, PAGE_SIZE);
+        RTR0MemObjFree(pVM->hm.s.vmx.pMemObjScratch, false);
+        pVM->hm.s.vmx.pMemObjScratch = NIL_RTR0MEMOBJ;
+        pVM->hm.s.vmx.pScratch       = 0;
+        pVM->hm.s.vmx.pScratchPhys   = 0;
     }
 #endif
@@ -424,17 +424,17 @@
     AssertReturn(pVM, VERR_INVALID_PARAMETER);
 
-    /* Initialize these always, see hwaccmR3InitFinalizeR0().*/
-    pVM->hwaccm.s.vmx.enmFlushEPT  = VMX_FLUSH_EPT_NONE;
-    pVM->hwaccm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_NONE;
+    /* Initialize these always, see hmR3InitFinalizeR0().*/
+    pVM->hm.s.vmx.enmFlushEPT  = VMX_FLUSH_EPT_NONE;
+    pVM->hm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_NONE;
 
     /* Determine optimal flush type for EPT. */
-    if (pVM->hwaccm.s.fNestedPaging)
-    {
-        if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT)
-        {
-            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_SINGLE_CONTEXT)
-                pVM->hwaccm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_SINGLE_CONTEXT;
-            else if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL_CONTEXTS)
-                pVM->hwaccm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_ALL_CONTEXTS;
+    if (pVM->hm.s.fNestedPaging)
+    {
+        if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT)
+        {
+            if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_SINGLE_CONTEXT)
+                pVM->hm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_SINGLE_CONTEXT;
+            else if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL_CONTEXTS)
+                pVM->hm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_ALL_CONTEXTS;
             else
             {
@@ -443,5 +443,5 @@
                  * We cannot ignore EPT at this point as we've already setup Unrestricted Guest execution.
                  */
-                pVM->hwaccm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_NOT_SUPPORTED;
+                pVM->hm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_NOT_SUPPORTED;
                 return VERR_VMX_GENERIC;
             }
@@ -452,5 +452,5 @@
              * Should never really happen. EPT is supported but INVEPT instruction is not supported.
              */
-            pVM->hwaccm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_NOT_SUPPORTED;
+            pVM->hm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_NOT_SUPPORTED;
             return VERR_VMX_GENERIC;
         }
@@ -458,12 +458,12 @@
 
     /* Determine optimal flush type for VPID. */
-    if (pVM->hwaccm.s.vmx.fVPID)
-    {
-        if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID)
-        {
-            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT)
-                pVM->hwaccm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_SINGLE_CONTEXT;
-            else if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS)
-                pVM->hwaccm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_ALL_CONTEXTS;
+    if (pVM->hm.s.vmx.fVPID)
+    {
+        if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID)
+        {
+            if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT)
+                pVM->hm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_SINGLE_CONTEXT;
+            else if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS)
+                pVM->hm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_ALL_CONTEXTS;
             else
             {
@@ -472,10 +472,10 @@
                  * We do not handle other flush type combinations, ignore VPID capabilities.
                  */
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
                     Log(("VMXR0SetupVM: Only VMX_FLUSH_VPID_INDIV_ADDR supported. Ignoring VPID.\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT_RETAIN_GLOBALS)
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT_RETAIN_GLOBALS)
                     Log(("VMXR0SetupVM: Only VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS supported. Ignoring VPID.\n"));
-                pVM->hwaccm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_NOT_SUPPORTED;
-                pVM->hwaccm.s.vmx.fVPID = false;
+                pVM->hm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_NOT_SUPPORTED;
+                pVM->hm.s.vmx.fVPID = false;
             }
         }
@@ -487,6 +487,6 @@
              */
             Log(("VMXR0SetupVM: VPID supported without INVEPT support. Ignoring VPID.\n"));
-            pVM->hwaccm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_NOT_SUPPORTED;
-            pVM->hwaccm.s.vmx.fVPID = false;
+            pVM->hm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_NOT_SUPPORTED;
+            pVM->hm.s.vmx.fVPID = false;
         }
     }
@@ -496,18 +496,18 @@
         PVMCPU pVCpu = &pVM->aCpus[i];
 
-        AssertPtr(pVCpu->hwaccm.s.vmx.pvVMCS);
+        AssertPtr(pVCpu->hm.s.vmx.pvVMCS);
 
         /* Set revision dword at the beginning of the VMCS structure. */
-        *(uint32_t *)pVCpu->hwaccm.s.vmx.pvVMCS = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);
+        *(uint32_t *)pVCpu->hm.s.vmx.pvVMCS = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hm.s.vmx.msr.vmx_basic_info);
 
         /*
          * Clear and activate the VMCS.
          */
-        Log(("HCPhysVMCS  = %RHp\n", pVCpu->hwaccm.s.vmx.HCPhysVMCS));
-        rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
+        Log(("HCPhysVMCS  = %RHp\n", pVCpu->hm.s.vmx.HCPhysVMCS));
+        rc = VMXClearVMCS(pVCpu->hm.s.vmx.HCPhysVMCS);
         if (RT_FAILURE(rc))
             goto vmx_end;
 
-        rc = VMXActivateVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
+        rc = VMXActivateVMCS(pVCpu->hm.s.vmx.HCPhysVMCS);
         if (RT_FAILURE(rc))
             goto vmx_end;
@@ -517,5 +517,5 @@
          * Set required bits to one and zero according to the MSR capabilities.
          */
-        val = pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.disallowed0;
+        val = pVM->hm.s.vmx.msr.vmx_pin_ctls.n.disallowed0;
         val |=    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT      /* External interrupts */
                 | VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT;         /* Non-maskable interrupts */
@@ -524,7 +524,7 @@
          * Enable the VMX preemption timer.
          */
-        if (pVM->hwaccm.s.vmx.fUsePreemptTimer)
+        if (pVM->hm.s.vmx.fUsePreemptTimer)
             val |= VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER;
-        val &= pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.allowed1;
+        val &= pVM->hm.s.vmx.msr.vmx_pin_ctls.n.allowed1;
 
         rc = VMXWriteVMCS(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, val);
@@ -535,5 +535,5 @@
          * Set required bits to one and zero according to the MSR capabilities.
          */
-        val = pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.disallowed0;
+        val = pVM->hm.s.vmx.msr.vmx_proc_ctls.n.disallowed0;
         /* Program which event cause VM-exits and which features we want to use. */
         val |=   VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT
@@ -547,5 +547,5 @@
 
         /* Without nested paging we should intercept invlpg and cr3 mov instructions. */
-        if (!pVM->hwaccm.s.fNestedPaging)
+        if (!pVM->hm.s.fNestedPaging)
         {
             val |=   VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT
@@ -558,9 +558,9 @@
          * failure with an invalid control fields error. (combined with some other exit reasons)
          */
-        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
+        if (pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
         {
             /* CR8 reads from the APIC shadow page; writes cause an exit is they lower the TPR below the threshold */
             val |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW;
-            Assert(pVM->hwaccm.s.vmx.pAPIC);
+            Assert(pVM->hm.s.vmx.pAPIC);
         }
         else
@@ -568,7 +568,7 @@
             val |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT;
 
-        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
-        {
-            Assert(pVCpu->hwaccm.s.vmx.pMSRBitmapPhys);
+        if (pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
+        {
+            Assert(pVCpu->hm.s.vmx.pMSRBitmapPhys);
             val |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS;
         }
@@ -579,11 +579,11 @@
         /* Mask away the bits that the CPU doesn't support */
         /** @todo make sure they don't conflict with the above requirements. */
-        val &= pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1;
-        pVCpu->hwaccm.s.vmx.proc_ctls = val;
+        val &= pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1;
+        pVCpu->hm.s.vmx.proc_ctls = val;
 
         rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, val);
         AssertRC(rc);
 
-        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
+        if (pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
         {
             /*
@@ -591,26 +591,26 @@
              * Set required bits to one and zero according to the MSR capabilities.
              */
-            val  = pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.disallowed0;
+            val  = pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.disallowed0;
             val |= VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT;
 
-            if (pVM->hwaccm.s.fNestedPaging)
+            if (pVM->hm.s.fNestedPaging)
                 val |= VMX_VMCS_CTRL_PROC_EXEC2_EPT;
 
-            if (pVM->hwaccm.s.vmx.fVPID)
+            if (pVM->hm.s.vmx.fVPID)
                 val |= VMX_VMCS_CTRL_PROC_EXEC2_VPID;
 
-            if (pVM->hwaccm.s.fHasIoApic)
+            if (pVM->hm.s.fHasIoApic)
                 val |= VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC;
 
-            if (pVM->hwaccm.s.vmx.fUnrestrictedGuest)
+            if (pVM->hm.s.vmx.fUnrestrictedGuest)
                 val |= VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE;
 
-            if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
+            if (pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
                 val |= VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP;
 
             /* Mask away the bits that the CPU doesn't support */
             /** @todo make sure they don't conflict with the above requirements. */
-            val &= pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1;
-            pVCpu->hwaccm.s.vmx.proc_ctls2 = val;
+            val &= pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1;
+            pVCpu->hm.s.vmx.proc_ctls2 = val;
             rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2, val);
             AssertRC(rc);
@@ -656,9 +656,9 @@
          * Set the MSR bitmap address.
          */
-        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
-        {
-            Assert(pVCpu->hwaccm.s.vmx.pMSRBitmapPhys);
-
-            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_MSR_BITMAP_FULL, pVCpu->hwaccm.s.vmx.pMSRBitmapPhys);
+        if (pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
+        {
+            Assert(pVCpu->hm.s.vmx.pMSRBitmapPhys);
+
+            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_MSR_BITMAP_FULL, pVCpu->hm.s.vmx.pMSRBitmapPhys);
             AssertRC(rc);
 
@@ -676,5 +676,5 @@
             hmR0VmxSetMSRPermission(pVCpu, MSR_K8_GS_BASE, true, true);
             hmR0VmxSetMSRPermission(pVCpu, MSR_K8_FS_BASE, true, true);
-            if (pVCpu->hwaccm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
+            if (pVCpu->hm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
                 hmR0VmxSetMSRPermission(pVCpu, MSR_K8_TSC_AUX, true, true);
         }
@@ -684,11 +684,11 @@
          * Set the guest & host MSR load/store physical addresses.
          */
-        Assert(pVCpu->hwaccm.s.vmx.pGuestMSRPhys);
-        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL, pVCpu->hwaccm.s.vmx.pGuestMSRPhys);
+        Assert(pVCpu->hm.s.vmx.pGuestMSRPhys);
+        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL, pVCpu->hm.s.vmx.pGuestMSRPhys);
         AssertRC(rc);
-        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL, pVCpu->hwaccm.s.vmx.pGuestMSRPhys);
+        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL, pVCpu->hm.s.vmx.pGuestMSRPhys);
         AssertRC(rc);
-        Assert(pVCpu->hwaccm.s.vmx.pHostMSRPhys);
-        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL,  pVCpu->hwaccm.s.vmx.pHostMSRPhys);
+        Assert(pVCpu->hm.s.vmx.pHostMSRPhys);
+        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL,  pVCpu->hm.s.vmx.pHostMSRPhys);
         AssertRC(rc);
 #endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
@@ -701,13 +701,13 @@
         AssertRC(rc);
 
-        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
-        {
-            Assert(pVM->hwaccm.s.vmx.pMemObjAPIC);
+        if (pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
+        {
+            Assert(pVM->hm.s.vmx.pMemObjAPIC);
             /* Optional */
             rc  = VMXWriteVMCS(VMX_VMCS_CTRL_TPR_THRESHOLD, 0);
-            rc |= VMXWriteVMCS64(VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL, pVCpu->hwaccm.s.vmx.HCPhysVAPIC);
-
-            if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
-                rc |= VMXWriteVMCS64(VMX_VMCS_CTRL_APIC_ACCESSADDR_FULL, pVM->hwaccm.s.vmx.pAPICPhys);
+            rc |= VMXWriteVMCS64(VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL, pVCpu->hm.s.vmx.HCPhysVAPIC);
+
+            if (pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
+                rc |= VMXWriteVMCS64(VMX_VMCS_CTRL_APIC_ACCESSADDR_FULL, pVM->hm.s.vmx.pAPICPhys);
 
             AssertRC(rc);
@@ -722,5 +722,5 @@
          * VMCS data back to memory.
          */
-        rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
+        rc = VMXClearVMCS(pVCpu->hm.s.vmx.HCPhysVMCS);
         AssertRC(rc);
 
@@ -728,5 +728,5 @@
          * Configure the VMCS read cache.
          */
-        PVMCSCACHE pCache = &pVCpu->hwaccm.s.vmx.VMCSCache;
+        PVMCSCACHE pCache = &pVCpu->hm.s.vmx.VMCSCache;
 
         VMXSetupCachedReadVMCS(pCache, VMX_VMCS64_GUEST_RIP);
@@ -769,5 +769,5 @@
         VMXSetupCachedReadVMCS(pCache, VMX_VMCS32_RO_IDT_ERRCODE);
 
-        if (pVM->hwaccm.s.fNestedPaging)
+        if (pVM->hm.s.fNestedPaging)
         {
             VMXSetupCachedReadVMCS(pCache, VMX_VMCS64_GUEST_CR3);
@@ -782,12 +782,12 @@
      * Setup the right TLB function based on CPU capabilities.
      */
-    if (pVM->hwaccm.s.fNestedPaging && pVM->hwaccm.s.vmx.fVPID)
-        pVM->hwaccm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBBoth;
-    else if (pVM->hwaccm.s.fNestedPaging)
-        pVM->hwaccm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBEPT;
-    else if (pVM->hwaccm.s.vmx.fVPID)
-        pVM->hwaccm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBVPID;
+    if (pVM->hm.s.fNestedPaging && pVM->hm.s.vmx.fVPID)
+        pVM->hm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBBoth;
+    else if (pVM->hm.s.fNestedPaging)
+        pVM->hm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBEPT;
+    else if (pVM->hm.s.vmx.fVPID)
+        pVM->hm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBVPID;
     else
-        pVM->hwaccm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBDummy;
+        pVM->hm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBDummy;
 
 vmx_end:
@@ -808,5 +808,5 @@
 {
     unsigned ulBit;
-    uint8_t *pMSRBitmap = (uint8_t *)pVCpu->hwaccm.s.vmx.pMSRBitmap;
+    uint8_t *pMSRBitmap = (uint8_t *)pVCpu->hm.s.vmx.pMSRBitmap;
 
     /*
@@ -867,5 +867,5 @@
 
 #ifdef VBOX_WITH_STATISTICS
-    STAM_COUNTER_INC(&pVCpu->hwaccm.s.paStatInjectedIrqsR0[iGate & MASK_INJECT_IRQ_STAT]);
+    STAM_COUNTER_INC(&pVCpu->hm.s.paStatInjectedIrqsR0[iGate & MASK_INJECT_IRQ_STAT]);
 #endif
 
@@ -892,5 +892,5 @@
 
     if (    CPUMIsGuestInRealModeEx(pCtx)
-        &&  pVM->hwaccm.s.vmx.pRealModeTSS)
+        &&  pVM->hm.s.vmx.pRealModeTSS)
     {
         RTGCPHYS GCPhysHandler;
@@ -967,5 +967,5 @@
         pCtx->eflags.u     &= ~(X86_EFL_IF | X86_EFL_TF | X86_EFL_RF | X86_EFL_AC);
 
-        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_SEGMENT_REGS;
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_SEGMENT_REGS;
         return VINF_SUCCESS;
     }
@@ -998,13 +998,13 @@
      * Dispatch any pending interrupts (injected before, but a VM exit occurred prematurely).
      */
-    if (pVCpu->hwaccm.s.Event.fPending)
-    {
-        Log(("CPU%d: Reinjecting event %RX64 %08x at %RGv cr2=%RX64\n", pVCpu->idCpu, pVCpu->hwaccm.s.Event.intInfo,
-             pVCpu->hwaccm.s.Event.errCode, (RTGCPTR)pCtx->rip, pCtx->cr2));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatIntReinject);
-        rc = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, pVCpu->hwaccm.s.Event.intInfo, 0, pVCpu->hwaccm.s.Event.errCode);
+    if (pVCpu->hm.s.Event.fPending)
+    {
+        Log(("CPU%d: Reinjecting event %RX64 %08x at %RGv cr2=%RX64\n", pVCpu->idCpu, pVCpu->hm.s.Event.intInfo,
+             pVCpu->hm.s.Event.errCode, (RTGCPTR)pCtx->rip, pCtx->cr2));
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatIntReinject);
+        rc = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, pVCpu->hm.s.Event.intInfo, 0, pVCpu->hm.s.Event.errCode);
         AssertRC(rc);
 
-        pVCpu->hwaccm.s.Event.fPending = false;
+        pVCpu->hm.s.Event.fPending = false;
         return VINF_SUCCESS;
     }
@@ -1040,9 +1040,9 @@
             if (!(pCtx->eflags.u32 & X86_EFL_IF))
             {
-                if (!(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT))
+                if (!(pVCpu->hm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT))
                 {
                     LogFlow(("Enable irq window exit!\n"));
-                    pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT;
-                    rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
+                    pVCpu->hm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT;
+                    rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hm.s.vmx.proc_ctls);
                     AssertRC(rc);
                 }
@@ -1065,5 +1065,5 @@
                     /* Can only happen in rare cases where a pending interrupt is cleared behind our back */
                     Assert(!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)));
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchGuestIrq);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchGuestIrq);
                     /* Just continue */
                 }
@@ -1142,5 +1142,5 @@
             intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
 
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatIntInject);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject);
         rc = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, intInfo, 0, errCode);
         AssertRC(rc);
@@ -1166,5 +1166,5 @@
      * Host CPU Context.
      */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_HOST_CONTEXT)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_HOST_CONTEXT)
     {
         RTIDTR      idtr;
@@ -1185,5 +1185,5 @@
         if (VMX_IS_64BIT_HOST_MODE())
         {
-            cr3 = hwaccmR0Get64bitCR3();
+            cr3 = hmR0Get64bitCR3();
             rc |= VMXWriteVMCS64(VMX_VMCS_HOST_CR3,     cr3);
         }
@@ -1250,5 +1250,5 @@
         {
             X86XDTR64 gdtr64, idtr64;
-            hwaccmR0Get64bitGDTRandIDTR(&gdtr64, &idtr64);
+            hmR0Get64bitGDTRandIDTR(&gdtr64, &idtr64);
             rc  = VMXWriteVMCS64(VMX_VMCS_HOST_GDTR_BASE, gdtr64.uAddr);
             rc |= VMXWriteVMCS64(VMX_VMCS_HOST_IDTR_BASE, gdtr64.uAddr);
@@ -1356,5 +1356,5 @@
          * the world switch back to the host.
          */
-        PVMXMSR pMsr = (PVMXMSR)pVCpu->hwaccm.s.vmx.pHostMSR;
+        PVMXMSR pMsr = (PVMXMSR)pVCpu->hm.s.vmx.pHostMSR;
         unsigned idxMsr = 0;
 
@@ -1404,5 +1404,5 @@
 # endif
 
-        if (pVCpu->hwaccm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
+        if (pVCpu->hm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
         {
             pMsr->u32IndexMSR = MSR_K8_TSC_AUX;
@@ -1418,5 +1418,5 @@
 #endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
 
-        pVCpu->hwaccm.s.fContextUseFlags &= ~HWACCM_CHANGED_HOST_CONTEXT;
+        pVCpu->hm.s.fContextUseFlags &= ~HM_CHANGED_HOST_CONTEXT;
     }
     return rc;
@@ -1515,5 +1515,5 @@
      */
     /** @todo NP state won't change so maybe we should build the initial trap mask up front? */
-    if (!pVM->hwaccm.s.fNestedPaging)
+    if (!pVM->hm.s.fNestedPaging)
         u32TrapMask |= RT_BIT(X86_XCPT_PF);
 
@@ -1531,5 +1531,5 @@
     /** @todo Despite the claim to intercept everything, with NP we do not intercept #PF. Should we? */
     if (    CPUMIsGuestInRealModeEx(pCtx)
-        &&  pVM->hwaccm.s.vmx.pRealModeTSS)
+        &&  pVM->hm.s.vmx.pRealModeTSS)
     {
         u32TrapMask |=   RT_BIT(X86_XCPT_DE)
@@ -1572,5 +1572,5 @@
     X86EFLAGS   eflags;
 
-    Assert(!(pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_ALL_GUEST));
+    Assert(!(pVCpu->hm.s.fContextUseFlags & HM_CHANGED_ALL_GUEST));
 
     /*
@@ -1592,7 +1592,7 @@
      */
     if (    CPUMIsGuestInRealModeEx(pCtx)
-        &&  pVM->hwaccm.s.vmx.pRealModeTSS)
-    {
-        pVCpu->hwaccm.s.vmx.RealMode.eflags = eflags;
+        &&  pVM->hm.s.vmx.pRealModeTSS)
+    {
+        pVCpu->hm.s.vmx.RealMode.eflags = eflags;
 
         eflags.Bits.u1VM   = 1;
@@ -1623,5 +1623,5 @@
      * Set required bits to one and zero according to the MSR capabilities.
      */
-    val  = pVM->hwaccm.s.vmx.msr.vmx_entry.n.disallowed0;
+    val  = pVM->hm.s.vmx.msr.vmx_entry.n.disallowed0;
 
     /*
@@ -1638,5 +1638,5 @@
      * Mask away the bits that the CPU doesn't support.
      */
-    val &= pVM->hwaccm.s.vmx.msr.vmx_entry.n.allowed1;
+    val &= pVM->hm.s.vmx.msr.vmx_entry.n.allowed1;
     rc = VMXWriteVMCS(VMX_VMCS_CTRL_ENTRY_CONTROLS, val);
     AssertRC(rc);
@@ -1646,5 +1646,5 @@
      * Set required bits to one and zero according to the MSR capabilities.
      */
-    val  = pVM->hwaccm.s.vmx.msr.vmx_exit.n.disallowed0;
+    val  = pVM->hm.s.vmx.msr.vmx_exit.n.disallowed0;
 
     /*
@@ -1664,5 +1664,5 @@
         Assert(!(val & VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64));
 #endif
-    val &= pVM->hwaccm.s.vmx.msr.vmx_exit.n.allowed1;
+    val &= pVM->hm.s.vmx.msr.vmx_exit.n.allowed1;
 
     /*
@@ -1675,15 +1675,15 @@
      * Guest CPU context: ES, CS, SS, DS, FS, GS.
      */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_SEGMENT_REGS)
-    {
-        if (pVM->hwaccm.s.vmx.pRealModeTSS)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_SEGMENT_REGS)
+    {
+        if (pVM->hm.s.vmx.pRealModeTSS)
         {
             PGMMODE enmGuestMode = PGMGetGuestMode(pVCpu);
-            if (pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode != enmGuestMode)
+            if (pVCpu->hm.s.vmx.enmLastSeenGuestMode != enmGuestMode)
             {
                 /*
                  * Correct weird requirements for switching to protected mode.
                  */
-                if (    pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode == PGMMODE_REAL
+                if (    pVCpu->hm.s.vmx.enmLastSeenGuestMode == PGMMODE_REAL
                     &&  enmGuestMode >= PGMMODE_PROTECTED)
                 {
@@ -1708,5 +1708,5 @@
                     pCtx->ss.Attr.n.u2Dpl  = 0;
                 }
-                pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode = enmGuestMode;
+                pVCpu->hm.s.vmx.enmLastSeenGuestMode = enmGuestMode;
             }
             else if (   CPUMIsGuestInRealModeEx(pCtx)
@@ -1741,5 +1741,5 @@
      * Guest CPU context: LDTR.
      */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_LDTR)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_LDTR)
     {
         if (pCtx->ldtr.Sel == 0)
@@ -1764,5 +1764,5 @@
      * Guest CPU context: TR.
      */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_TR)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_TR)
     {
         /*
@@ -1771,14 +1771,14 @@
          */
         if (    CPUMIsGuestInRealModeEx(pCtx)
-            &&  pVM->hwaccm.s.vmx.pRealModeTSS)
+            &&  pVM->hm.s.vmx.pRealModeTSS)
         {
             RTGCPHYS GCPhys;
 
             /* We convert it here every time as PCI regions could be reconfigured. */
-            rc = PDMVMMDevHeapR3ToGCPhys(pVM, pVM->hwaccm.s.vmx.pRealModeTSS, &GCPhys);
+            rc = PDMVMMDevHeapR3ToGCPhys(pVM, pVM->hm.s.vmx.pRealModeTSS, &GCPhys);
             AssertRC(rc);
 
             rc =  VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_TR,         0);
-            rc |= VMXWriteVMCS(VMX_VMCS32_GUEST_TR_LIMIT,         HWACCM_VTX_TSS_SIZE);
+            rc |= VMXWriteVMCS(VMX_VMCS32_GUEST_TR_LIMIT,         HM_VTX_TSS_SIZE);
             rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_TR_BASE,          GCPhys /* phys = virt in this mode */);
 
@@ -1817,5 +1817,5 @@
      * Guest CPU context: GDTR.
      */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_GDTR)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_GDTR)
     {
         rc  = VMXWriteVMCS(VMX_VMCS32_GUEST_GDTR_LIMIT,       pCtx->gdtr.cbGdt);
@@ -1827,5 +1827,5 @@
      * Guest CPU context: IDTR.
      */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_IDTR)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_IDTR)
     {
         rc  = VMXWriteVMCS(VMX_VMCS32_GUEST_IDTR_LIMIT,       pCtx->idtr.cbIdt);
@@ -1837,5 +1837,5 @@
      * Sysenter MSRs.
      */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_MSR)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_MSR)
     {
         rc  = VMXWriteVMCS(VMX_VMCS32_GUEST_SYSENTER_CS,    pCtx->SysEnter.cs);
@@ -1848,5 +1848,5 @@
      * Guest CPU context: Control registers.
      */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_CR0)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_CR0)
     {
         val = pCtx->cr0;
@@ -1867,13 +1867,13 @@
         }
         /* Protected mode & paging are always enabled; we use them for emulating real and protected mode without paging too. */
-        if (!pVM->hwaccm.s.vmx.fUnrestrictedGuest)
+        if (!pVM->hm.s.vmx.fUnrestrictedGuest)
             val |= X86_CR0_PE | X86_CR0_PG;
 
-        if (pVM->hwaccm.s.fNestedPaging)
+        if (pVM->hm.s.fNestedPaging)
         {
             if (CPUMIsGuestInPagedProtectedModeEx(pCtx))
             {
                 /* Disable CR3 read/write monitoring as we don't need it for EPT. */
-                pVCpu->hwaccm.s.vmx.proc_ctls &=  ~(  VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT
+                pVCpu->hm.s.vmx.proc_ctls &=  ~(  VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT
                                                     | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT);
             }
@@ -1881,8 +1881,8 @@
             {
                 /* Reenable CR3 read/write monitoring as our identity mapped page table is active. */
-                pVCpu->hwaccm.s.vmx.proc_ctls |=   VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT
+                pVCpu->hm.s.vmx.proc_ctls |=   VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT
                                                  | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT;
             }
-            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
+            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hm.s.vmx.proc_ctls);
             AssertRC(rc);
         }
@@ -1915,5 +1915,5 @@
             val |= X86_CR0_TS | X86_CR0_ET | X86_CR0_MP;
 
-        pVCpu->hwaccm.s.vmx.cr0_mask = val;
+        pVCpu->hm.s.vmx.cr0_mask = val;
 
         rc |= VMXWriteVMCS(VMX_VMCS_CTRL_CR0_MASK, val);
@@ -1922,14 +1922,14 @@
     }
 
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_CR4)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_CR4)
     {
         rc  = VMXWriteVMCS(VMX_VMCS_CTRL_CR4_READ_SHADOW,   pCtx->cr4);
         Log2(("Guest CR4-shadow %08x\n", pCtx->cr4));
         /* Set the required bits in cr4 too (currently X86_CR4_VMXE). */
-        val = pCtx->cr4 | (uint32_t)pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed0;
-
-        if (!pVM->hwaccm.s.fNestedPaging)
-        {
-            switch (pVCpu->hwaccm.s.enmShadowMode)
+        val = pCtx->cr4 | (uint32_t)pVM->hm.s.vmx.msr.vmx_cr4_fixed0;
+
+        if (!pVM->hm.s.fNestedPaging)
+        {
+            switch (pVCpu->hm.s.enmShadowMode)
             {
                 case PGMMODE_REAL:          /* Real mode                 -> emulated using v86 mode */
@@ -1959,5 +1959,5 @@
         }
         else if (   !CPUMIsGuestInPagedProtectedModeEx(pCtx)
-                 && !pVM->hwaccm.s.vmx.fUnrestrictedGuest)
+                 && !pVM->hm.s.vmx.fUnrestrictedGuest)
         {
             /* We use 4 MB pages in our identity mapping page table for real and protected mode without paging. */
@@ -1971,5 +1971,5 @@
          */
         if (    CPUMIsGuestInRealModeEx(pCtx)
-            &&  pVM->hwaccm.s.vmx.pRealModeTSS)
+            &&  pVM->hm.s.vmx.pRealModeTSS)
         {
             val &= ~X86_CR4_VME;
@@ -1988,5 +1988,5 @@
               | X86_CR4_PSE
               | X86_CR4_VMXE;
-        pVCpu->hwaccm.s.vmx.cr4_mask = val;
+        pVCpu->hm.s.vmx.cr4_mask = val;
 
         rc |= VMXWriteVMCS(VMX_VMCS_CTRL_CR4_MASK, val);
@@ -1997,36 +1997,36 @@
 #if 0
     /* Enable single stepping if requested and CPU supports it. */
-    if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG)
+    if (pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG)
         if (DBGFIsStepping(pVCpu))
         {
-            pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG;
-            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
+            pVCpu->hm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG;
+            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hm.s.vmx.proc_ctls);
             AssertRC(rc);
         }
 #endif
 
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_CR3)
-    {
-        if (pVM->hwaccm.s.fNestedPaging)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_CR3)
+    {
+        if (pVM->hm.s.fNestedPaging)
         {
             Assert(PGMGetHyperCR3(pVCpu));
-            pVCpu->hwaccm.s.vmx.GCPhysEPTP = PGMGetHyperCR3(pVCpu);
-
-            Assert(!(pVCpu->hwaccm.s.vmx.GCPhysEPTP & 0xfff));
+            pVCpu->hm.s.vmx.GCPhysEPTP = PGMGetHyperCR3(pVCpu);
+
+            Assert(!(pVCpu->hm.s.vmx.GCPhysEPTP & 0xfff));
             /** @todo Check the IA32_VMX_EPT_VPID_CAP MSR for other supported memory types. */
-            pVCpu->hwaccm.s.vmx.GCPhysEPTP |=   VMX_EPT_MEMTYPE_WB
+            pVCpu->hm.s.vmx.GCPhysEPTP |=   VMX_EPT_MEMTYPE_WB
                                              | (VMX_EPT_PAGE_WALK_LENGTH_DEFAULT << VMX_EPT_PAGE_WALK_LENGTH_SHIFT);
 
-            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_EPTP_FULL, pVCpu->hwaccm.s.vmx.GCPhysEPTP);
+            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_EPTP_FULL, pVCpu->hm.s.vmx.GCPhysEPTP);
             AssertRC(rc);
 
             if (    !CPUMIsGuestInPagedProtectedModeEx(pCtx)
-                &&  !pVM->hwaccm.s.vmx.fUnrestrictedGuest)
+                &&  !pVM->hm.s.vmx.fUnrestrictedGuest)
             {
                 RTGCPHYS GCPhys;
 
                 /* We convert it here every time as PCI regions could be reconfigured. */
-                rc = PDMVMMDevHeapR3ToGCPhys(pVM, pVM->hwaccm.s.vmx.pNonPagingModeEPTPageTable, &GCPhys);
-                AssertMsgRC(rc, ("pNonPagingModeEPTPageTable = %RGv\n", pVM->hwaccm.s.vmx.pNonPagingModeEPTPageTable));
+                rc = PDMVMMDevHeapR3ToGCPhys(pVM, pVM->hm.s.vmx.pNonPagingModeEPTPageTable, &GCPhys);
+                AssertMsgRC(rc, ("pNonPagingModeEPTPageTable = %RGv\n", pVM->hm.s.vmx.pNonPagingModeEPTPageTable));
 
                 /*
@@ -2058,5 +2058,5 @@
      * Guest CPU context: Debug registers.
      */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_DEBUG)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_DEBUG)
     {
         pCtx->dr[6] |= X86_DR6_INIT_VAL;                                          /* set all reserved bits to 1. */
@@ -2094,9 +2094,9 @@
             &&  !DBGFIsStepping(pVCpu))
         {
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatDRxArmed);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatDRxArmed);
 
             /* Disable DRx move intercepts. */
-            pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT;
-            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
+            pVCpu->hm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT;
+            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hm.s.vmx.proc_ctls);
             AssertRC(rc);
 
@@ -2123,13 +2123,13 @@
         return VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE;
 #elif HC_ARCH_BITS == 32 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
-        pVCpu->hwaccm.s.vmx.pfnStartVM  = VMXR0SwitcherStartVM64;
+        pVCpu->hm.s.vmx.pfnStartVM  = VMXR0SwitcherStartVM64;
 #else
 # ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-        if (!pVM->hwaccm.s.fAllow64BitGuests)
+        if (!pVM->hm.s.fAllow64BitGuests)
             return VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE;
 # endif
-        pVCpu->hwaccm.s.vmx.pfnStartVM  = VMXR0StartVM64;
-#endif
-        if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_MSR)
+        pVCpu->hm.s.vmx.pfnStartVM  = VMXR0StartVM64;
+#endif
+        if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_MSR)
         {
             /* Update these as wrmsr might have changed them. */
@@ -2142,5 +2142,5 @@
     else
     {
-        pVCpu->hwaccm.s.vmx.pfnStartVM  = VMXR0StartVM32;
+        pVCpu->hm.s.vmx.pfnStartVM  = VMXR0StartVM32;
     }
 
@@ -2152,5 +2152,5 @@
      * during VM-entry and restored into the VM-exit store area during VM-exit.
      */
-    PVMXMSR pMsr = (PVMXMSR)pVCpu->hwaccm.s.vmx.pGuestMSR;
+    PVMXMSR pMsr = (PVMXMSR)pVCpu->hm.s.vmx.pGuestMSR;
     unsigned idxMsr = 0;
 
@@ -2196,5 +2196,5 @@
     }
 
-    if (   pVCpu->hwaccm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP
+    if (   pVCpu->hm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP
         && (u32GstExtFeatures & X86_CPUID_EXT_FEATURE_EDX_RDTSCP))
     {
@@ -2206,5 +2206,5 @@
     }
 
-    pVCpu->hwaccm.s.vmx.cCachedMSRs = idxMsr;
+    pVCpu->hm.s.vmx.cCachedMSRs = idxMsr;
 
     rc = VMXWriteVMCS(VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT, idxMsr);
@@ -2216,7 +2216,7 @@
 
     bool fOffsettedTsc;
-    if (pVM->hwaccm.s.vmx.fUsePreemptTimer)
-    {
-        uint64_t cTicksToDeadline = TMCpuTickGetDeadlineAndTscOffset(pVCpu, &fOffsettedTsc, &pVCpu->hwaccm.s.vmx.u64TSCOffset);
+    if (pVM->hm.s.vmx.fUsePreemptTimer)
+    {
+        uint64_t cTicksToDeadline = TMCpuTickGetDeadlineAndTscOffset(pVCpu, &fOffsettedTsc, &pVCpu->hm.s.vmx.u64TSCOffset);
 
         /* Make sure the returned values have sane upper and lower boundaries. */
@@ -2226,5 +2226,5 @@
         cTicksToDeadline = RT_MAX(cTicksToDeadline, u64CpuHz / 2048); /* 1/2048th of a second */
 
-        cTicksToDeadline >>= pVM->hwaccm.s.vmx.cPreemptTimerShift;
+        cTicksToDeadline >>= pVM->hm.s.vmx.cPreemptTimerShift;
         uint32_t cPreemptionTickCount = (uint32_t)RT_MIN(cTicksToDeadline, UINT32_MAX - 16);
         rc = VMXWriteVMCS(VMX_VMCS32_GUEST_PREEMPTION_TIMER_VALUE, cPreemptionTickCount);
@@ -2232,19 +2232,19 @@
     }
     else
-        fOffsettedTsc = TMCpuTickCanUseRealTSC(pVCpu, &pVCpu->hwaccm.s.vmx.u64TSCOffset);
+        fOffsettedTsc = TMCpuTickCanUseRealTSC(pVCpu, &pVCpu->hm.s.vmx.u64TSCOffset);
 
     if (fOffsettedTsc)
     {
         uint64_t u64CurTSC = ASMReadTSC();
-        if (u64CurTSC + pVCpu->hwaccm.s.vmx.u64TSCOffset >= TMCpuTickGetLastSeen(pVCpu))
+        if (u64CurTSC + pVCpu->hm.s.vmx.u64TSCOffset >= TMCpuTickGetLastSeen(pVCpu))
         {
             /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT takes precedence over TSC_OFFSET, applies to RDTSCP too. */
-            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_TSC_OFFSET_FULL, pVCpu->hwaccm.s.vmx.u64TSCOffset);
+            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_TSC_OFFSET_FULL, pVCpu->hm.s.vmx.u64TSCOffset);
             AssertRC(rc);
 
-            pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
-            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
+            pVCpu->hm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
+            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hm.s.vmx.proc_ctls);
             AssertRC(rc);
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCOffset);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatTSCOffset);
         }
         else
@@ -2252,23 +2252,23 @@
             /* Fall back to rdtsc, rdtscp emulation as we would otherwise pass decreasing tsc values to the guest. */
             LogFlow(("TSC %RX64 offset %RX64 time=%RX64 last=%RX64 (diff=%RX64, virt_tsc=%RX64)\n", u64CurTSC,
-                     pVCpu->hwaccm.s.vmx.u64TSCOffset, u64CurTSC + pVCpu->hwaccm.s.vmx.u64TSCOffset,
-                     TMCpuTickGetLastSeen(pVCpu), TMCpuTickGetLastSeen(pVCpu) - u64CurTSC - pVCpu->hwaccm.s.vmx.u64TSCOffset,
+                     pVCpu->hm.s.vmx.u64TSCOffset, u64CurTSC + pVCpu->hm.s.vmx.u64TSCOffset,
+                     TMCpuTickGetLastSeen(pVCpu), TMCpuTickGetLastSeen(pVCpu) - u64CurTSC - pVCpu->hm.s.vmx.u64TSCOffset,
                      TMCpuTickGet(pVCpu)));
-            pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
-            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
+            pVCpu->hm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
+            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hm.s.vmx.proc_ctls);
             AssertRC(rc);
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCInterceptOverFlow);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatTSCInterceptOverFlow);
         }
     }
     else
     {
-        pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
-        rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
+        pVCpu->hm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
+        rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hm.s.vmx.proc_ctls);
         AssertRC(rc);
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCIntercept);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatTSCIntercept);
     }
 
     /* Done with the major changes */
-    pVCpu->hwaccm.s.fContextUseFlags &= ~HWACCM_CHANGED_ALL_GUEST;
+    pVCpu->hm.s.fContextUseFlags &= ~HM_CHANGED_ALL_GUEST;
 
     /* Minimal guest state update (ESP, EIP, EFLAGS mostly) */
@@ -2318,10 +2318,10 @@
     VMXReadCachedVMCS(VMX_VMCS_CTRL_CR0_READ_SHADOW,     &valShadow);
     VMXReadCachedVMCS(VMX_VMCS64_GUEST_CR0,              &val);
-    val = (valShadow & pVCpu->hwaccm.s.vmx.cr0_mask) | (val & ~pVCpu->hwaccm.s.vmx.cr0_mask);
+    val = (valShadow & pVCpu->hm.s.vmx.cr0_mask) | (val & ~pVCpu->hm.s.vmx.cr0_mask);
     CPUMSetGuestCR0(pVCpu, val);
 
     VMXReadCachedVMCS(VMX_VMCS_CTRL_CR4_READ_SHADOW,     &valShadow);
     VMXReadCachedVMCS(VMX_VMCS64_GUEST_CR4,              &val);
-    val = (valShadow & pVCpu->hwaccm.s.vmx.cr4_mask) | (val & ~pVCpu->hwaccm.s.vmx.cr4_mask);
+    val = (valShadow & pVCpu->hm.s.vmx.cr4_mask) | (val & ~pVCpu->hm.s.vmx.cr4_mask);
     CPUMSetGuestCR4(pVCpu, val);
 
@@ -2330,8 +2330,8 @@
      * the nested paging case where CR3 & CR4 can be changed by the guest.
      */
-    if (   pVM->hwaccm.s.fNestedPaging
+    if (   pVM->hm.s.fNestedPaging
         && CPUMIsGuestInPagedProtectedModeEx(pCtx)) /** @todo check if we will always catch mode switches and such... */
     {
-        PVMCSCACHE pCache = &pVCpu->hwaccm.s.vmx.VMCSCache;
+        PVMCSCACHE pCache = &pVCpu->hm.s.vmx.VMCSCache;
 
         /* Can be updated behind our back in the nested paging case. */
@@ -2384,5 +2384,5 @@
     /* Real mode emulation using v86 mode. */
     if (    CPUMIsGuestInRealModeEx(pCtx)
-        &&  pVM->hwaccm.s.vmx.pRealModeTSS)
+        &&  pVM->hm.s.vmx.pRealModeTSS)
     {
         /* Hide our emulation flags */
@@ -2390,8 +2390,8 @@
 
         /* Restore original IOPL setting as we always use 0. */
-        pCtx->eflags.Bits.u2IOPL = pVCpu->hwaccm.s.vmx.RealMode.eflags.Bits.u2IOPL;
+        pCtx->eflags.Bits.u2IOPL = pVCpu->hm.s.vmx.RealMode.eflags.Bits.u2IOPL;
 
         /* Force a TR resync every time in case we switch modes. */
-        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_TR;
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_TR;
     }
     else
@@ -2405,7 +2405,7 @@
      * Save the possibly changed MSRs that we automatically restore and save during a world switch.
      */
-    for (unsigned i = 0; i < pVCpu->hwaccm.s.vmx.cCachedMSRs; i++)
-    {
-        PVMXMSR pMsr = (PVMXMSR)pVCpu->hwaccm.s.vmx.pGuestMSR;
+    for (unsigned i = 0; i < pVCpu->hm.s.vmx.cCachedMSRs; i++)
+    {
+        PVMXMSR pMsr = (PVMXMSR)pVCpu->hm.s.vmx.pGuestMSR;
         pMsr += i;
 
@@ -2458,5 +2458,5 @@
     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TLB_FLUSH);
     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TLB_SHOOTDOWN);
-    pVCpu->hwaccm.s.TlbShootdown.cPages = 0;
+    pVCpu->hm.s.TlbShootdown.cPages = 0;
     return;
 }
@@ -2473,7 +2473,7 @@
     PHMGLOBLCPUINFO pCpu;
 
-    Assert(pVM->hwaccm.s.fNestedPaging && pVM->hwaccm.s.vmx.fVPID);
-
-    pCpu = HWACCMR0GetCurrentCpu();
+    Assert(pVM->hm.s.fNestedPaging && pVM->hm.s.vmx.fVPID);
+
+    pCpu = HMR0GetCurrentCpu();
 
     /*
@@ -2484,8 +2484,8 @@
      */
     bool fNewASID = false;
-    if (   pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu
-        || pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
-    {
-        pVCpu->hwaccm.s.fForceTLBFlush = true;
+    if (   pVCpu->hm.s.idLastCpu != pCpu->idCpu
+        || pVCpu->hm.s.cTLBFlushes != pCpu->cTLBFlushes)
+    {
+        pVCpu->hm.s.fForceTLBFlush = true;
         fNewASID = true;
     }
@@ -2495,14 +2495,14 @@
      */
     if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH))
-        pVCpu->hwaccm.s.fForceTLBFlush = true;
-
-    pVCpu->hwaccm.s.idLastCpu = pCpu->idCpu;
-
-    if (pVCpu->hwaccm.s.fForceTLBFlush)
+        pVCpu->hm.s.fForceTLBFlush = true;
+
+    pVCpu->hm.s.idLastCpu = pCpu->idCpu;
+
+    if (pVCpu->hm.s.fForceTLBFlush)
     {
         if (fNewASID)
         {
             ++pCpu->uCurrentASID;
-            if (pCpu->uCurrentASID >= pVM->hwaccm.s.uMaxASID)
+            if (pCpu->uCurrentASID >= pVM->hm.s.uMaxASID)
             {
                 pCpu->uCurrentASID = 1;       /* start at 1; host uses 0 */
@@ -2511,10 +2511,10 @@
             }
 
-            pVCpu->hwaccm.s.uCurrentASID = pCpu->uCurrentASID;
+            pVCpu->hm.s.uCurrentASID = pCpu->uCurrentASID;
             if (pCpu->fFlushASIDBeforeUse)
             {
-                hmR0VmxFlushVPID(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushVPID, 0 /* GCPtr */);
+                hmR0VmxFlushVPID(pVM, pVCpu, pVM->hm.s.vmx.enmFlushVPID, 0 /* GCPtr */);
 #ifdef VBOX_WITH_STATISTICS
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushASID);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushASID);
 #endif
             }
@@ -2522,8 +2522,8 @@
         else
         {
-            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT)
+            if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT)
                 hmR0VmxFlushVPID(pVM, pVCpu, VMX_FLUSH_VPID_SINGLE_CONTEXT, 0 /* GCPtr */);
             else
-                hmR0VmxFlushEPT(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushEPT);
+                hmR0VmxFlushEPT(pVM, pVCpu, pVM->hm.s.vmx.enmFlushEPT);
 
 #ifdef VBOX_WITH_STATISTICS
@@ -2532,24 +2532,24 @@
              * as ASID flushes too, better than including them under StatFlushTLBWorldSwitch.
              */
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushASID);
-#endif
-        }
-
-        pVCpu->hwaccm.s.cTLBFlushes    = pCpu->cTLBFlushes;
-        pVCpu->hwaccm.s.fForceTLBFlush = false;
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushASID);
+#endif
+        }
+
+        pVCpu->hm.s.cTLBFlushes    = pCpu->cTLBFlushes;
+        pVCpu->hm.s.fForceTLBFlush = false;
     }
     else
     {
-        AssertMsg(pVCpu->hwaccm.s.uCurrentASID && pCpu->uCurrentASID,
-                  ("hwaccm->uCurrentASID=%lu hwaccm->cTLBFlushes=%lu cpu->uCurrentASID=%lu cpu->cTLBFlushes=%lu\n",
-                   pVCpu->hwaccm.s.uCurrentASID, pVCpu->hwaccm.s.cTLBFlushes,
+        AssertMsg(pVCpu->hm.s.uCurrentASID && pCpu->uCurrentASID,
+                  ("hm->uCurrentASID=%lu hm->cTLBFlushes=%lu cpu->uCurrentASID=%lu cpu->cTLBFlushes=%lu\n",
+                   pVCpu->hm.s.uCurrentASID, pVCpu->hm.s.cTLBFlushes,
                    pCpu->uCurrentASID, pCpu->cTLBFlushes));
 
         /** @todo We never set VMCPU_FF_TLB_SHOOTDOWN anywhere so this path should
-         *        not be executed. See hwaccmQueueInvlPage() where it is commented
+         *        not be executed. See hmQueueInvlPage() where it is commented
          *        out. Support individual entry flushing someday. */
         if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TLB_SHOOTDOWN))
         {
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdown);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatTlbShootdown);
 
             /*
@@ -2557,31 +2557,31 @@
              * as supported by the CPU.
              */
-            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
+            if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
             {
-                for (unsigned i = 0; i < pVCpu->hwaccm.s.TlbShootdown.cPages; i++)
-                    hmR0VmxFlushVPID(pVM, pVCpu, VMX_FLUSH_VPID_INDIV_ADDR, pVCpu->hwaccm.s.TlbShootdown.aPages[i]);
+                for (unsigned i = 0; i < pVCpu->hm.s.TlbShootdown.cPages; i++)
+                    hmR0VmxFlushVPID(pVM, pVCpu, VMX_FLUSH_VPID_INDIV_ADDR, pVCpu->hm.s.TlbShootdown.aPages[i]);
             }
             else
-                hmR0VmxFlushEPT(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushEPT);
+                hmR0VmxFlushEPT(pVM, pVCpu, pVM->hm.s.vmx.enmFlushEPT);
         }
         else
         {
 #ifdef VBOX_WITH_STATISTICS
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatNoFlushTLBWorldSwitch);
-#endif
-        }
-    }
-    pVCpu->hwaccm.s.TlbShootdown.cPages = 0;
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatNoFlushTLBWorldSwitch);
+#endif
+        }
+    }
+    pVCpu->hm.s.TlbShootdown.cPages = 0;
     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TLB_SHOOTDOWN);
 
-    AssertMsg(pVCpu->hwaccm.s.cTLBFlushes == pCpu->cTLBFlushes,
-              ("Flush count mismatch for cpu %d (%x vs %x)\n", pCpu->idCpu, pVCpu->hwaccm.s.cTLBFlushes, pCpu->cTLBFlushes));
-    AssertMsg(pCpu->uCurrentASID >= 1 && pCpu->uCurrentASID < pVM->hwaccm.s.uMaxASID,
+    AssertMsg(pVCpu->hm.s.cTLBFlushes == pCpu->cTLBFlushes,
+              ("Flush count mismatch for cpu %d (%x vs %x)\n", pCpu->idCpu, pVCpu->hm.s.cTLBFlushes, pCpu->cTLBFlushes));
+    AssertMsg(pCpu->uCurrentASID >= 1 && pCpu->uCurrentASID < pVM->hm.s.uMaxASID,
               ("cpu%d uCurrentASID = %x\n", pCpu->idCpu, pCpu->uCurrentASID));
-    AssertMsg(pVCpu->hwaccm.s.uCurrentASID >= 1 && pVCpu->hwaccm.s.uCurrentASID < pVM->hwaccm.s.uMaxASID,
-              ("cpu%d VM uCurrentASID = %x\n", pCpu->idCpu, pVCpu->hwaccm.s.uCurrentASID));
+    AssertMsg(pVCpu->hm.s.uCurrentASID >= 1 && pVCpu->hm.s.uCurrentASID < pVM->hm.s.uMaxASID,
+              ("cpu%d VM uCurrentASID = %x\n", pCpu->idCpu, pVCpu->hm.s.uCurrentASID));
 
     /* Update VMCS with the VPID. */
-    int rc  = VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_VPID, pVCpu->hwaccm.s.uCurrentASID);
+    int rc  = VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_VPID, pVCpu->hm.s.uCurrentASID);
     AssertRC(rc);
 }
@@ -2599,8 +2599,8 @@
     PHMGLOBLCPUINFO pCpu;
 
-    Assert(pVM->hwaccm.s.fNestedPaging);
-    Assert(!pVM->hwaccm.s.vmx.fVPID);
-
-    pCpu = HWACCMR0GetCurrentCpu();
+    Assert(pVM->hm.s.fNestedPaging);
+    Assert(!pVM->hm.s.vmx.fVPID);
+
+    pCpu = HMR0GetCurrentCpu();
 
     /*
@@ -2609,8 +2609,8 @@
      * A change in the TLB flush count implies the host Cpu is online after a suspend/resume.
      */
-    if (   pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu
-        || pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
-    {
-        pVCpu->hwaccm.s.fForceTLBFlush = true;
+    if (   pVCpu->hm.s.idLastCpu != pCpu->idCpu
+        || pVCpu->hm.s.cTLBFlushes != pCpu->cTLBFlushes)
+    {
+        pVCpu->hm.s.fForceTLBFlush = true;
     }
 
@@ -2619,15 +2619,15 @@
      */
     if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH))
-        pVCpu->hwaccm.s.fForceTLBFlush = true;
-
-    pVCpu->hwaccm.s.idLastCpu   = pCpu->idCpu;
-    pVCpu->hwaccm.s.cTLBFlushes = pCpu->cTLBFlushes;
-
-    if (pVCpu->hwaccm.s.fForceTLBFlush)
-        hmR0VmxFlushEPT(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushEPT);
+        pVCpu->hm.s.fForceTLBFlush = true;
+
+    pVCpu->hm.s.idLastCpu   = pCpu->idCpu;
+    pVCpu->hm.s.cTLBFlushes = pCpu->cTLBFlushes;
+
+    if (pVCpu->hm.s.fForceTLBFlush)
+        hmR0VmxFlushEPT(pVM, pVCpu, pVM->hm.s.vmx.enmFlushEPT);
     else
     {
         /** @todo We never set VMCPU_FF_TLB_SHOOTDOWN anywhere so this path should
-         *        not be executed. See hwaccmQueueInvlPage() where it is commented
+         *        not be executed. See hmQueueInvlPage() where it is commented
          *        out. Support individual entry flushing someday. */
         if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TLB_SHOOTDOWN))
@@ -2636,16 +2636,16 @@
              * We cannot flush individual entries without VPID support. Flush using EPT.
              */
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdown);
-            hmR0VmxFlushEPT(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushEPT);
-        }
-    }
-    pVCpu->hwaccm.s.TlbShootdown.cPages= 0;
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatTlbShootdown);
+            hmR0VmxFlushEPT(pVM, pVCpu, pVM->hm.s.vmx.enmFlushEPT);
+        }
+    }
+    pVCpu->hm.s.TlbShootdown.cPages= 0;
     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TLB_SHOOTDOWN);
 
 #ifdef VBOX_WITH_STATISTICS
-    if (pVCpu->hwaccm.s.fForceTLBFlush)
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushTLBWorldSwitch);
+    if (pVCpu->hm.s.fForceTLBFlush)
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTLBWorldSwitch);
     else
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatNoFlushTLBWorldSwitch);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatNoFlushTLBWorldSwitch);
 #endif
 }
@@ -2663,8 +2663,8 @@
     PHMGLOBLCPUINFO pCpu;
 
-    Assert(pVM->hwaccm.s.vmx.fVPID);
-    Assert(!pVM->hwaccm.s.fNestedPaging);
-
-    pCpu = HWACCMR0GetCurrentCpu();
+    Assert(pVM->hm.s.vmx.fVPID);
+    Assert(!pVM->hm.s.fNestedPaging);
+
+    pCpu = HMR0GetCurrentCpu();
 
     /*
@@ -2674,9 +2674,9 @@
      * or the host Cpu is online after a suspend/resume, so we cannot reuse the current ASID anymore.
      */
-    if (   pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu
-        || pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
+    if (   pVCpu->hm.s.idLastCpu != pCpu->idCpu
+        || pVCpu->hm.s.cTLBFlushes != pCpu->cTLBFlushes)
     {
         /* Force a TLB flush on VM entry. */
-        pVCpu->hwaccm.s.fForceTLBFlush = true;
+        pVCpu->hm.s.fForceTLBFlush = true;
     }
 
@@ -2685,12 +2685,12 @@
      */
     if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH))
-        pVCpu->hwaccm.s.fForceTLBFlush = true;
-
-    pVCpu->hwaccm.s.idLastCpu = pCpu->idCpu;
-
-    if (pVCpu->hwaccm.s.fForceTLBFlush)
+        pVCpu->hm.s.fForceTLBFlush = true;
+
+    pVCpu->hm.s.idLastCpu = pCpu->idCpu;
+
+    if (pVCpu->hm.s.fForceTLBFlush)
     {
         ++pCpu->uCurrentASID;
-        if (pCpu->uCurrentASID >= pVM->hwaccm.s.uMaxASID)
+        if (pCpu->uCurrentASID >= pVM->hm.s.uMaxASID)
         {
             pCpu->uCurrentASID               = 1;       /* start at 1; host uses 0 */
@@ -2699,21 +2699,21 @@
         }
         else
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushASID);
-
-        pVCpu->hwaccm.s.fForceTLBFlush = false;
-        pVCpu->hwaccm.s.cTLBFlushes    = pCpu->cTLBFlushes;
-        pVCpu->hwaccm.s.uCurrentASID   = pCpu->uCurrentASID;
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushASID);
+
+        pVCpu->hm.s.fForceTLBFlush = false;
+        pVCpu->hm.s.cTLBFlushes    = pCpu->cTLBFlushes;
+        pVCpu->hm.s.uCurrentASID   = pCpu->uCurrentASID;
         if (pCpu->fFlushASIDBeforeUse)
-            hmR0VmxFlushVPID(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushVPID, 0 /* GCPtr */);
+            hmR0VmxFlushVPID(pVM, pVCpu, pVM->hm.s.vmx.enmFlushVPID, 0 /* GCPtr */);
     }
     else
     {
-        AssertMsg(pVCpu->hwaccm.s.uCurrentASID && pCpu->uCurrentASID,
-                  ("hwaccm->uCurrentASID=%lu hwaccm->cTLBFlushes=%lu cpu->uCurrentASID=%lu cpu->cTLBFlushes=%lu\n",
-                   pVCpu->hwaccm.s.uCurrentASID, pVCpu->hwaccm.s.cTLBFlushes,
+        AssertMsg(pVCpu->hm.s.uCurrentASID && pCpu->uCurrentASID,
+                  ("hm->uCurrentASID=%lu hm->cTLBFlushes=%lu cpu->uCurrentASID=%lu cpu->cTLBFlushes=%lu\n",
+                   pVCpu->hm.s.uCurrentASID, pVCpu->hm.s.cTLBFlushes,
                    pCpu->uCurrentASID, pCpu->cTLBFlushes));
 
         /** @todo We never set VMCPU_FF_TLB_SHOOTDOWN anywhere so this path should
-         *        not be executed. See hwaccmQueueInvlPage() where it is commented
+         *        not be executed. See hmQueueInvlPage() where it is commented
          *        out. Support individual entry flushing someday. */
         if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TLB_SHOOTDOWN))
@@ -2723,31 +2723,31 @@
              * as supported by the CPU.
              */
-            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
+            if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
             {
-                for (unsigned i = 0; i < pVCpu->hwaccm.s.TlbShootdown.cPages; i++)
-                    hmR0VmxFlushVPID(pVM, pVCpu, VMX_FLUSH_VPID_INDIV_ADDR, pVCpu->hwaccm.s.TlbShootdown.aPages[i]);
+                for (unsigned i = 0; i < pVCpu->hm.s.TlbShootdown.cPages; i++)
+                    hmR0VmxFlushVPID(pVM, pVCpu, VMX_FLUSH_VPID_INDIV_ADDR, pVCpu->hm.s.TlbShootdown.aPages[i]);
             }
             else
-                hmR0VmxFlushVPID(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushVPID, 0 /* GCPtr */);
-        }
-    }
-    pVCpu->hwaccm.s.TlbShootdown.cPages = 0;
+                hmR0VmxFlushVPID(pVM, pVCpu, pVM->hm.s.vmx.enmFlushVPID, 0 /* GCPtr */);
+        }
+    }
+    pVCpu->hm.s.TlbShootdown.cPages = 0;
     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TLB_SHOOTDOWN);
 
-    AssertMsg(pVCpu->hwaccm.s.cTLBFlushes == pCpu->cTLBFlushes,
-              ("Flush count mismatch for cpu %d (%x vs %x)\n", pCpu->idCpu, pVCpu->hwaccm.s.cTLBFlushes, pCpu->cTLBFlushes));
-    AssertMsg(pCpu->uCurrentASID >= 1 && pCpu->uCurrentASID < pVM->hwaccm.s.uMaxASID,
+    AssertMsg(pVCpu->hm.s.cTLBFlushes == pCpu->cTLBFlushes,
+              ("Flush count mismatch for cpu %d (%x vs %x)\n", pCpu->idCpu, pVCpu->hm.s.cTLBFlushes, pCpu->cTLBFlushes));
+    AssertMsg(pCpu->uCurrentASID >= 1 && pCpu->uCurrentASID < pVM->hm.s.uMaxASID,
               ("cpu%d uCurrentASID = %x\n", pCpu->idCpu, pCpu->uCurrentASID));
-    AssertMsg(pVCpu->hwaccm.s.uCurrentASID >= 1 && pVCpu->hwaccm.s.uCurrentASID < pVM->hwaccm.s.uMaxASID,
-              ("cpu%d VM uCurrentASID = %x\n", pCpu->idCpu, pVCpu->hwaccm.s.uCurrentASID));
-
-    int rc  = VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_VPID, pVCpu->hwaccm.s.uCurrentASID);
+    AssertMsg(pVCpu->hm.s.uCurrentASID >= 1 && pVCpu->hm.s.uCurrentASID < pVM->hm.s.uMaxASID,
+              ("cpu%d VM uCurrentASID = %x\n", pCpu->idCpu, pVCpu->hm.s.uCurrentASID));
+
+    int rc  = VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_VPID, pVCpu->hm.s.uCurrentASID);
     AssertRC(rc);
 
 # ifdef VBOX_WITH_STATISTICS
-    if (pVCpu->hwaccm.s.fForceTLBFlush)
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushTLBWorldSwitch);
+    if (pVCpu->hm.s.fForceTLBFlush)
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatFlushTLBWorldSwitch);
     else
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatNoFlushTLBWorldSwitch);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatNoFlushTLBWorldSwitch);
 # endif
 }
@@ -2764,7 +2764,7 @@
 VMMR0DECL(int) VMXR0RunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 {
-    STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatEntry, x);
-    STAM_PROFILE_ADV_SET_STOPPED(&pVCpu->hwaccm.s.StatExit1);
-    STAM_PROFILE_ADV_SET_STOPPED(&pVCpu->hwaccm.s.StatExit2);
+    STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatEntry, x);
+    STAM_PROFILE_ADV_SET_STOPPED(&pVCpu->hm.s.StatExit1);
+    STAM_PROFILE_ADV_SET_STOPPED(&pVCpu->hm.s.StatExit2);
 
     VBOXSTRICTRC rc = VINF_SUCCESS;
@@ -2789,6 +2789,6 @@
 #endif
 
-    Assert(!(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
-           || (pVCpu->hwaccm.s.vmx.pbVAPIC && pVM->hwaccm.s.vmx.pAPIC));
+    Assert(!(pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
+           || (pVCpu->hm.s.vmx.pbVAPIC && pVM->hm.s.vmx.pAPIC));
 
     /*
@@ -2796,7 +2796,7 @@
      */
     if (    CPUMIsGuestInLongModeEx(pCtx)
-        || (   ((   pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
-                 || pVM->hwaccm.s.fTRPPatchingAllowed)
-            &&  pVM->hwaccm.s.fHasIoApic)
+        || (   ((   pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
+                 || pVM->hm.s.fTRPPatchingAllowed)
+            &&  pVM->hm.s.fHasIoApic)
        )
     {
@@ -2807,5 +2807,5 @@
 
     /* This is not ideal, but if we don't clear the event injection in the VMCS right here,
-     * we may end up injecting some stale event into a VM, including injecting an event that 
+     * we may end up injecting some stale event into a VM, including injecting an event that
      * originated before a VM reset *after* the VM has been reset. See @bugref{6220}.
      */
@@ -2821,9 +2821,9 @@
 
         /* allowed zero */
-        if ((val2 & pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.disallowed0) != pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.disallowed0)
+        if ((val2 & pVM->hm.s.vmx.msr.vmx_pin_ctls.n.disallowed0) != pVM->hm.s.vmx.msr.vmx_pin_ctls.n.disallowed0)
             Log(("Invalid VMX_VMCS_CTRL_PIN_EXEC_CONTROLS: zero\n"));
 
         /* allowed one */
-        if ((val2 & ~pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.allowed1) != 0)
+        if ((val2 & ~pVM->hm.s.vmx.msr.vmx_pin_ctls.n.allowed1) != 0)
             Log(("Invalid VMX_VMCS_CTRL_PIN_EXEC_CONTROLS: one\n"));
 
@@ -2835,5 +2835,5 @@
          * Must be set according to the MSR, but can be cleared if nested paging is used.
          */
-        if (pVM->hwaccm.s.fNestedPaging)
+        if (pVM->hm.s.fNestedPaging)
         {
             val2 |=   VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT
@@ -2843,9 +2843,9 @@
 
         /* allowed zero */
-        if ((val2 & pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.disallowed0) != pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.disallowed0)
+        if ((val2 & pVM->hm.s.vmx.msr.vmx_proc_ctls.n.disallowed0) != pVM->hm.s.vmx.msr.vmx_proc_ctls.n.disallowed0)
             Log(("Invalid VMX_VMCS_CTRL_PROC_EXEC_CONTROLS: zero\n"));
 
         /* allowed one */
-        if ((val2 & ~pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1) != 0)
+        if ((val2 & ~pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1) != 0)
             Log(("Invalid VMX_VMCS_CTRL_PROC_EXEC_CONTROLS: one\n"));
 
@@ -2855,9 +2855,9 @@
 
         /* allowed zero */
-        if ((val2 & pVM->hwaccm.s.vmx.msr.vmx_entry.n.disallowed0) != pVM->hwaccm.s.vmx.msr.vmx_entry.n.disallowed0)
+        if ((val2 & pVM->hm.s.vmx.msr.vmx_entry.n.disallowed0) != pVM->hm.s.vmx.msr.vmx_entry.n.disallowed0)
             Log(("Invalid VMX_VMCS_CTRL_ENTRY_CONTROLS: zero\n"));
 
         /* allowed one */
-        if ((val2 & ~pVM->hwaccm.s.vmx.msr.vmx_entry.n.allowed1) != 0)
+        if ((val2 & ~pVM->hm.s.vmx.msr.vmx_entry.n.allowed1) != 0)
             Log(("Invalid VMX_VMCS_CTRL_ENTRY_CONTROLS: one\n"));
 
@@ -2867,9 +2867,9 @@
 
         /* allowed zero */
-        if ((val2 & pVM->hwaccm.s.vmx.msr.vmx_exit.n.disallowed0) != pVM->hwaccm.s.vmx.msr.vmx_exit.n.disallowed0)
+        if ((val2 & pVM->hm.s.vmx.msr.vmx_exit.n.disallowed0) != pVM->hm.s.vmx.msr.vmx_exit.n.disallowed0)
             Log(("Invalid VMX_VMCS_CTRL_EXIT_CONTROLS: zero\n"));
 
         /* allowed one */
-        if ((val2 & ~pVM->hwaccm.s.vmx.msr.vmx_exit.n.allowed1) != 0)
+        if ((val2 & ~pVM->hm.s.vmx.msr.vmx_exit.n.allowed1) != 0)
             Log(("Invalid VMX_VMCS_CTRL_EXIT_CONTROLS: one\n"));
     }
@@ -2878,5 +2878,5 @@
 
 #ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    pVCpu->hwaccm.s.vmx.VMCSCache.u64TimeEntry = RTTimeNanoTS();
+    pVCpu->hm.s.vmx.VMCSCache.u64TimeEntry = RTTimeNanoTS();
 #endif
 
@@ -2885,10 +2885,10 @@
      */
 ResumeExecution:
-    if (!STAM_REL_PROFILE_ADV_IS_RUNNING(&pVCpu->hwaccm.s.StatEntry))
-        STAM_REL_PROFILE_ADV_STOP_START(&pVCpu->hwaccm.s.StatExit2, &pVCpu->hwaccm.s.StatEntry, x);
-    AssertMsg(pVCpu->hwaccm.s.idEnteredCpu == RTMpCpuId(),
+    if (!STAM_REL_PROFILE_ADV_IS_RUNNING(&pVCpu->hm.s.StatEntry))
+        STAM_REL_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatExit2, &pVCpu->hm.s.StatEntry, x);
+    AssertMsg(pVCpu->hm.s.idEnteredCpu == RTMpCpuId(),
               ("Expected %d, I'm %d; cResume=%d exitReason=%RGv exitQualification=%RGv\n",
-               (int)pVCpu->hwaccm.s.idEnteredCpu, (int)RTMpCpuId(), cResume, exitReason, exitQualification));
-    Assert(!HWACCMR0SuspendPending());
+               (int)pVCpu->hm.s.idEnteredCpu, (int)RTMpCpuId(), cResume, exitReason, exitQualification));
+    Assert(!HMR0SuspendPending());
     /* Not allowed to switch modes without reloading the host state (32->64 switcher)!! */
     Assert(fWasInLongMode == CPUMIsGuestInLongModeEx(pCtx));
@@ -2897,7 +2897,7 @@
      * Safety precaution; looping for too long here can have a very bad effect on the host.
      */
-    if (RT_UNLIKELY(++cResume > pVM->hwaccm.s.cMaxResumeLoops))
-    {
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitMaxResume);
+    if (RT_UNLIKELY(++cResume > pVM->hm.s.cMaxResumeLoops))
+    {
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitMaxResume);
         rc = VINF_EM_RAW_INTERRUPT;
         goto end;
@@ -2947,6 +2947,6 @@
      * Check for pending actions that force us to go back to ring-3.
      */
-    if (    VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK | VM_FF_REQUEST | VM_FF_PGM_POOL_FLUSH_PENDING | VM_FF_PDM_DMA)
-        ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HWACCM_TO_R3_MASK | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_REQUEST))
+    if (    VM_FF_ISPENDING(pVM, VM_FF_HM_TO_R3_MASK | VM_FF_REQUEST | VM_FF_PGM_POOL_FLUSH_PENDING | VM_FF_PDM_DMA)
+        ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_REQUEST))
     {
         /* Check if a sync operation is pending. */
@@ -2967,8 +2967,8 @@
 #endif
         {
-            if (    VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK)
-                ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HWACCM_TO_R3_MASK))
+            if (    VM_FF_ISPENDING(pVM, VM_FF_HM_TO_R3_MASK)
+                ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK))
             {
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchToR3);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchToR3);
                 rc = RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3;
                 goto end;
@@ -3013,5 +3013,5 @@
     if (RTThreadPreemptIsPending(NIL_RTTHREAD))
     {
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitPreemptPending);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitPreemptPending);
         rc = VINF_EM_RAW_INTERRUPT;
         goto end;
@@ -3045,5 +3045,5 @@
         AssertRC(rc2);
         /* The TPR can be found at offset 0x80 in the APIC mmio page. */
-        pVCpu->hwaccm.s.vmx.pbVAPIC[0x80] = u8LastTPR;
+        pVCpu->hm.s.vmx.pbVAPIC[0x80] = u8LastTPR;
 
         /*
@@ -3059,5 +3059,5 @@
         AssertRC(VBOXSTRICTRC_VAL(rc));
 
-        if (pVM->hwaccm.s.fTPRPatchingActive)
+        if (pVM->hm.s.fTPRPatchingActive)
         {
             Assert(!CPUMIsGuestInLongModeEx(pCtx));
@@ -3083,16 +3083,16 @@
 
 #ifdef LOG_ENABLED
-    if (    pVM->hwaccm.s.fNestedPaging
-        ||  pVM->hwaccm.s.vmx.fVPID)
-    {
-        PHMGLOBLCPUINFO pCpu = HWACCMR0GetCurrentCpu();
-        if (pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu)
-        {
-            LogFlow(("Force TLB flush due to rescheduling to a different cpu (%d vs %d)\n", pVCpu->hwaccm.s.idLastCpu,
+    if (    pVM->hm.s.fNestedPaging
+        ||  pVM->hm.s.vmx.fVPID)
+    {
+        PHMGLOBLCPUINFO pCpu = HMR0GetCurrentCpu();
+        if (pVCpu->hm.s.idLastCpu != pCpu->idCpu)
+        {
+            LogFlow(("Force TLB flush due to rescheduling to a different cpu (%d vs %d)\n", pVCpu->hm.s.idLastCpu,
                      pCpu->idCpu));
         }
-        else if (pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
-        {
-            LogFlow(("Force TLB flush due to changed TLB flush count (%x vs %x)\n", pVCpu->hwaccm.s.cTLBFlushes,
+        else if (pVCpu->hm.s.cTLBFlushes != pCpu->cTLBFlushes)
+        {
+            LogFlow(("Force TLB flush due to changed TLB flush count (%x vs %x)\n", pVCpu->hm.s.cTLBFlushes,
                      pCpu->cTLBFlushes));
         }
@@ -3119,5 +3119,5 @@
      * Save the host state first.
      */
-    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_HOST_CONTEXT)
+    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_HOST_CONTEXT)
     {
         rc  = VMXR0SaveHostState(pVM, pVCpu);
@@ -3132,8 +3132,8 @@
      * Load the guest state.
      */
-    if (!pVCpu->hwaccm.s.fContextUseFlags)
+    if (!pVCpu->hm.s.fContextUseFlags)
     {
         VMXR0LoadMinimalGuestState(pVM, pVCpu, pCtx);
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatLoadMinimal);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatLoadMinimal);
     }
     else
@@ -3145,5 +3145,5 @@
             goto end;
         }
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatLoadFull);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatLoadFull);
     }
 
@@ -3163,7 +3163,7 @@
 
     /* Set TLB flush state as checked until we return from the world switch. */
-    ASMAtomicWriteBool(&pVCpu->hwaccm.s.fCheckedTLBFlush, true);
+    ASMAtomicWriteBool(&pVCpu->hm.s.fCheckedTLBFlush, true);
     /* Deal with tagged TLB setup and invalidation. */
-    pVM->hwaccm.s.vmx.pfnSetupTaggedTLB(pVM, pVCpu);
+    pVM->hm.s.vmx.pfnSetupTaggedTLB(pVM, pVCpu);
 
     /*
@@ -3180,10 +3180,10 @@
 
     /* All done! Let's start VM execution. */
-    STAM_PROFILE_ADV_STOP_START(&pVCpu->hwaccm.s.StatEntry, &pVCpu->hwaccm.s.StatInGC, x);
+    STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatEntry, &pVCpu->hm.s.StatInGC, x);
     Assert(idCpuCheck == RTMpCpuId());
 
 #ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    pVCpu->hwaccm.s.vmx.VMCSCache.cResume = cResume;
-    pVCpu->hwaccm.s.vmx.VMCSCache.u64TimeSwitch = RTTimeNanoTS();
+    pVCpu->hm.s.vmx.VMCSCache.cResume = cResume;
+    pVCpu->hm.s.vmx.VMCSCache.u64TimeSwitch = RTTimeNanoTS();
 #endif
 
@@ -3191,7 +3191,7 @@
      * Save the current TPR value in the LSTAR MSR so our patches can access it.
      */
-    if (pVM->hwaccm.s.fTPRPatchingActive)
-    {
-        Assert(pVM->hwaccm.s.fTPRPatchingActive);
+    if (pVM->hm.s.fTPRPatchingActive)
+    {
+        Assert(pVM->hm.s.fTPRPatchingActive);
         u64OldLSTAR = ASMRdMsr(MSR_K8_LSTAR);
         ASMWrMsr(MSR_K8_LSTAR, u8LastTPR);
@@ -3205,8 +3205,8 @@
      * RDTSCPs (that don't cause exits) reads the guest MSR. See @bugref{3324}.
      */
-    if (    (pVCpu->hwaccm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
-        && !(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT))
-    {
-        pVCpu->hwaccm.s.u64HostTSCAux = ASMRdMsr(MSR_K8_TSC_AUX);
+    if (    (pVCpu->hm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
+        && !(pVCpu->hm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT))
+    {
+        pVCpu->hm.s.u64HostTSCAux = ASMRdMsr(MSR_K8_TSC_AUX);
         uint64_t u64GuestTSCAux = 0;
         rc2 = CPUMQueryGuestMsr(pVCpu, MSR_K8_TSC_AUX, &u64GuestTSCAux);
@@ -3217,22 +3217,22 @@
 
 #ifdef VBOX_WITH_KERNEL_USING_XMM
-    rc = hwaccmR0VMXStartVMWrapXMM(pVCpu->hwaccm.s.fResumeVM, pCtx, &pVCpu->hwaccm.s.vmx.VMCSCache, pVM, pVCpu, pVCpu->hwaccm.s.vmx.pfnStartVM);
+    rc = hmR0VMXStartVMWrapXMM(pVCpu->hm.s.fResumeVM, pCtx, &pVCpu->hm.s.vmx.VMCSCache, pVM, pVCpu, pVCpu->hm.s.vmx.pfnStartVM);
 #else
-    rc = pVCpu->hwaccm.s.vmx.pfnStartVM(pVCpu->hwaccm.s.fResumeVM, pCtx, &pVCpu->hwaccm.s.vmx.VMCSCache, pVM, pVCpu);
-#endif
-    ASMAtomicWriteBool(&pVCpu->hwaccm.s.fCheckedTLBFlush, false);
-    ASMAtomicIncU32(&pVCpu->hwaccm.s.cWorldSwitchExits);
+    rc = pVCpu->hm.s.vmx.pfnStartVM(pVCpu->hm.s.fResumeVM, pCtx, &pVCpu->hm.s.vmx.VMCSCache, pVM, pVCpu);
+#endif
+    ASMAtomicWriteBool(&pVCpu->hm.s.fCheckedTLBFlush, false);
+    ASMAtomicIncU32(&pVCpu->hm.s.cWorldSwitchExits);
 
     /* Possibly the last TSC value seen by the guest (too high) (only when we're in TSC offset mode). */
-    if (!(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT))
+    if (!(pVCpu->hm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT))
     {
 #ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
         /* Restore host's TSC_AUX. */
-        if (pVCpu->hwaccm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
-            ASMWrMsr(MSR_K8_TSC_AUX, pVCpu->hwaccm.s.u64HostTSCAux);
+        if (pVCpu->hm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
+            ASMWrMsr(MSR_K8_TSC_AUX, pVCpu->hm.s.u64HostTSCAux);
 #endif
 
         TMCpuTickSetLastSeen(pVCpu,
-                             ASMReadTSC() + pVCpu->hwaccm.s.vmx.u64TSCOffset - 0x400 /* guestimate of world switch overhead in clock ticks */);
+                             ASMReadTSC() + pVCpu->hm.s.vmx.u64TSCOffset - 0x400 /* guestimate of world switch overhead in clock ticks */);
     }
 
@@ -3244,12 +3244,12 @@
      * Restore the host LSTAR MSR if the guest could have changed it.
      */
-    if (pVM->hwaccm.s.fTPRPatchingActive)
-    {
-        Assert(pVM->hwaccm.s.fTPRPatchingActive);
-        pVCpu->hwaccm.s.vmx.pbVAPIC[0x80] = pCtx->msrLSTAR = ASMRdMsr(MSR_K8_LSTAR);
+    if (pVM->hm.s.fTPRPatchingActive)
+    {
+        Assert(pVM->hm.s.fTPRPatchingActive);
+        pVCpu->hm.s.vmx.pbVAPIC[0x80] = pCtx->msrLSTAR = ASMRdMsr(MSR_K8_LSTAR);
         ASMWrMsr(MSR_K8_LSTAR, u64OldLSTAR);
     }
 
-    STAM_PROFILE_ADV_STOP_START(&pVCpu->hwaccm.s.StatInGC, &pVCpu->hwaccm.s.StatExit1, x);
+    STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatInGC, &pVCpu->hm.s.StatExit1, x);
     ASMSetFlags(uOldEFlags);
 #ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
@@ -3257,10 +3257,10 @@
 #endif
 
-    AssertMsg(!pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries, ("pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries=%d\n",
-                                                                   pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries));
+    AssertMsg(!pVCpu->hm.s.vmx.VMCSCache.Write.cValidEntries, ("pVCpu->hm.s.vmx.VMCSCache.Write.cValidEntries=%d\n",
+                                                                   pVCpu->hm.s.vmx.VMCSCache.Write.cValidEntries));
 
     /* In case we execute a goto ResumeExecution later on. */
-    pVCpu->hwaccm.s.fResumeVM  = true;
-    pVCpu->hwaccm.s.fForceTLBFlush = false;
+    pVCpu->hm.s.fResumeVM  = true;
+    pVCpu->hm.s.fForceTLBFlush = false;
 
     /*
@@ -3281,5 +3281,5 @@
     /* Investigate why there was a VM-exit. */
     rc2  = VMXReadCachedVMCS(VMX_VMCS32_RO_EXIT_REASON, &exitReason);
-    STAM_COUNTER_INC(&pVCpu->hwaccm.s.paStatExitReasonR0[exitReason & MASK_EXITREASON_STAT]);
+    STAM_COUNTER_INC(&pVCpu->hm.s.paStatExitReasonR0[exitReason & MASK_EXITREASON_STAT]);
 
     exitReason &= 0xffff;   /* bit 0-15 contain the exit code. */
@@ -3311,40 +3311,40 @@
     rc2 = VMXReadCachedVMCS(VMX_VMCS32_RO_IDT_INFO,            &val);
     AssertRC(rc2);
-    pVCpu->hwaccm.s.Event.intInfo = VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(val);
-    if (    VMX_EXIT_INTERRUPTION_INFO_VALID(pVCpu->hwaccm.s.Event.intInfo)
+    pVCpu->hm.s.Event.intInfo = VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(val);
+    if (    VMX_EXIT_INTERRUPTION_INFO_VALID(pVCpu->hm.s.Event.intInfo)
         /* Ignore 'int xx' as they'll be restarted anyway. */
-        &&  VMX_EXIT_INTERRUPTION_INFO_TYPE(pVCpu->hwaccm.s.Event.intInfo) != VMX_EXIT_INTERRUPTION_INFO_TYPE_SW
+        &&  VMX_EXIT_INTERRUPTION_INFO_TYPE(pVCpu->hm.s.Event.intInfo) != VMX_EXIT_INTERRUPTION_INFO_TYPE_SW
         /* Ignore software exceptions (such as int3) as they'll reoccur when we restart the instruction anyway. */
-        &&  VMX_EXIT_INTERRUPTION_INFO_TYPE(pVCpu->hwaccm.s.Event.intInfo) != VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT)
-    {
-        Assert(!pVCpu->hwaccm.s.Event.fPending);
-        pVCpu->hwaccm.s.Event.fPending = true;
+        &&  VMX_EXIT_INTERRUPTION_INFO_TYPE(pVCpu->hm.s.Event.intInfo) != VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT)
+    {
+        Assert(!pVCpu->hm.s.Event.fPending);
+        pVCpu->hm.s.Event.fPending = true;
         /* Error code present? */
-        if (VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(pVCpu->hwaccm.s.Event.intInfo))
+        if (VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(pVCpu->hm.s.Event.intInfo))
         {
             rc2 = VMXReadCachedVMCS(VMX_VMCS32_RO_IDT_ERRCODE, &val);
             AssertRC(rc2);
-            pVCpu->hwaccm.s.Event.errCode  = val;
+            pVCpu->hm.s.Event.errCode  = val;
             Log(("Pending inject %RX64 at %RGv exit=%08x intInfo=%08x exitQualification=%RGv pending error=%RX64\n",
-                 pVCpu->hwaccm.s.Event.intInfo, (RTGCPTR)pCtx->rip, exitReason, intInfo, exitQualification, val));
+                 pVCpu->hm.s.Event.intInfo, (RTGCPTR)pCtx->rip, exitReason, intInfo, exitQualification, val));
         }
         else
         {
-            Log(("Pending inject %RX64 at %RGv exit=%08x intInfo=%08x exitQualification=%RGv\n", pVCpu->hwaccm.s.Event.intInfo,
+            Log(("Pending inject %RX64 at %RGv exit=%08x intInfo=%08x exitQualification=%RGv\n", pVCpu->hm.s.Event.intInfo,
                  (RTGCPTR)pCtx->rip, exitReason, intInfo, exitQualification));
-            pVCpu->hwaccm.s.Event.errCode  = 0;
+            pVCpu->hm.s.Event.errCode  = 0;
         }
     }
 #ifdef VBOX_STRICT
-    else if (   VMX_EXIT_INTERRUPTION_INFO_VALID(pVCpu->hwaccm.s.Event.intInfo)
+    else if (   VMX_EXIT_INTERRUPTION_INFO_VALID(pVCpu->hm.s.Event.intInfo)
                 /* Ignore software exceptions (such as int3) as they're reoccur when we restart the instruction anyway. */
-             && VMX_EXIT_INTERRUPTION_INFO_TYPE(pVCpu->hwaccm.s.Event.intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT)
+             && VMX_EXIT_INTERRUPTION_INFO_TYPE(pVCpu->hm.s.Event.intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT)
     {
         Log(("Ignore pending inject %RX64 at %RGv exit=%08x intInfo=%08x exitQualification=%RGv\n",
-             pVCpu->hwaccm.s.Event.intInfo, (RTGCPTR)pCtx->rip, exitReason, intInfo, exitQualification));
+             pVCpu->hm.s.Event.intInfo, (RTGCPTR)pCtx->rip, exitReason, intInfo, exitQualification));
     }
 
     if (exitReason == VMX_EXIT_ERR_INVALID_GUEST_STATE)
-        HWACCMDumpRegs(pVM, pVCpu, pCtx);
+        HMDumpRegs(pVM, pVCpu, pCtx);
 #endif
 
@@ -3359,7 +3359,7 @@
      */
     if (    fSetupTPRCaching
-        &&  u8LastTPR != pVCpu->hwaccm.s.vmx.pbVAPIC[0x80])
-    {
-        rc2 = PDMApicSetTPR(pVCpu, pVCpu->hwaccm.s.vmx.pbVAPIC[0x80]);
+        &&  u8LastTPR != pVCpu->hm.s.vmx.pbVAPIC[0x80])
+    {
+        rc2 = PDMApicSetTPR(pVCpu, pVCpu->hm.s.vmx.pbVAPIC[0x80]);
         AssertRC(rc2);
     }
@@ -3369,5 +3369,5 @@
                       exitReason, (uint64_t)exitQualification, pCtx->cs.Sel, pCtx->rip, (uint64_t)intInfo);
 #endif
-    STAM_PROFILE_ADV_STOP_START(&pVCpu->hwaccm.s.StatExit1, &pVCpu->hwaccm.s.StatExit2, x);
+    STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatExit1, &pVCpu->hm.s.StatExit2, x);
 
     /* Some cases don't need a complete resync of the guest CPU state; handle them here. */
@@ -3392,5 +3392,5 @@
             break;
         }
-        STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+        STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatExit2Sub3, y3);
         switch (VMX_EXIT_INTERRUPTION_INFO_TYPE(intInfo))
         {
@@ -3423,19 +3423,19 @@
                     Assert(CPUMIsGuestFPUStateActive(pVCpu));
 
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitShadowNM);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitShadowNM);
 
                     /* Continue execution. */
-                    pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0;
-
-                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                    pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR0;
+
+                    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                     goto ResumeExecution;
                 }
 
                 Log(("Forward #NM fault to the guest\n"));
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestNM);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNM);
                 rc2 = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo),
                                          cbInstr, 0);
                 AssertRC(rc2);
-                STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                 goto ResumeExecution;
             }
@@ -3444,5 +3444,5 @@
             {
 #ifdef VBOX_ALWAYS_TRAP_PF
-                if (pVM->hwaccm.s.fNestedPaging)
+                if (pVM->hm.s.fNestedPaging)
                 {
                     /*
@@ -3454,5 +3454,5 @@
                     Assert(CPUMIsGuestInPagedProtectedModeEx(pCtx));
 
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestPF);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF);
 
                     /* Now we must update CR2. */
@@ -3462,20 +3462,20 @@
                     AssertRC(rc2);
 
-                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                     goto ResumeExecution;
                 }
 #else
-                Assert(!pVM->hwaccm.s.fNestedPaging);
-#endif
-
-#ifdef VBOX_HWACCM_WITH_GUEST_PATCHING
+                Assert(!pVM->hm.s.fNestedPaging);
+#endif
+
+#ifdef VBOX_HM_WITH_GUEST_PATCHING
                 /* Shortcut for APIC TPR reads and writes; 32 bits guests only */
-                if (    pVM->hwaccm.s.fTRPPatchingAllowed
-                    &&  pVM->hwaccm.s.pGuestPatchMem
+                if (    pVM->hm.s.fTRPPatchingAllowed
+                    &&  pVM->hm.s.pGuestPatchMem
                     &&  (exitQualification & 0xfff) == 0x080
                     &&  !(errCode & X86_TRAP_PF_P)  /* not present */
                     &&  CPUMGetGuestCPL(pVCpu) == 0
                     &&  !CPUMIsGuestInLongModeEx(pCtx)
-                    &&  pVM->hwaccm.s.cPatches < RT_ELEMENTS(pVM->hwaccm.s.aPatches))
+                    &&  pVM->hm.s.cPatches < RT_ELEMENTS(pVM->hm.s.aPatches))
                 {
                     RTGCPHYS GCPhysApicBase, GCPhys;
@@ -3488,8 +3488,8 @@
                     {
                         /* Only attempt to patch the instruction once. */
-                        PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
+                        PHMTPRPATCH pPatch = (PHMTPRPATCH)RTAvloU32Get(&pVM->hm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
                         if (!pPatch)
                         {
-                            rc = VINF_EM_HWACCM_PATCH_TPR_INSTR;
+                            rc = VINF_EM_HM_PATCH_TPR_INSTR;
                             break;
                         }
@@ -3508,5 +3508,5 @@
                     &&  !(errCode & X86_TRAP_PF_P)  /* not present */
                     &&  fSetupTPRCaching
-                    &&  (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC))
+                    &&  (pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC))
                 {
                     RTGCPHYS GCPhysApicBase, GCPhys;
@@ -3519,5 +3519,5 @@
                     {
                         Log(("Enable VT-x virtual APIC access filtering\n"));
-                        rc2 = IOMMMIOMapMMIOHCPage(pVM, GCPhysApicBase, pVM->hwaccm.s.vmx.pAPICPhys, X86_PTE_RW | X86_PTE_P);
+                        rc2 = IOMMMIOMapMMIOHCPage(pVM, GCPhysApicBase, pVM->hm.s.vmx.pAPICPhys, X86_PTE_RW | X86_PTE_P);
                         AssertRC(rc2);
                     }
@@ -3531,8 +3531,8 @@
                 {   /* We've successfully synced our shadow pages, so let's just continue execution. */
                     Log2(("Shadow page fault at %RGv cr2=%RGv error code %x\n", (RTGCPTR)pCtx->rip, exitQualification ,errCode));
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitShadowPF);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitShadowPF);
 
                     TRPMResetTrap(pVCpu);
-                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                     goto ResumeExecution;
                 }
@@ -3544,5 +3544,5 @@
                     Log2(("Forward page fault to the guest\n"));
 
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestPF);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF);
                     /* The error code might have been changed. */
                     errCode = TRPMGetErrorCode(pVCpu);
@@ -3556,5 +3556,5 @@
                     AssertRC(rc2);
 
-                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                     goto ResumeExecution;
                 }
@@ -3564,5 +3564,5 @@
 #endif
                 /* Need to go back to the recompiler to emulate the instruction. */
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitShadowPFEM);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitShadowPFEM);
                 TRPMResetTrap(pVCpu);
                 break;
@@ -3571,5 +3571,5 @@
             case X86_XCPT_MF: /* Floating point exception. */
             {
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestMF);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestMF);
                 if (!(pCtx->cr0 & X86_CR0_NE))
                 {
@@ -3584,5 +3584,5 @@
                 AssertRC(rc2);
 
-                STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                 goto ResumeExecution;
             }
@@ -3602,5 +3602,5 @@
                  * 63:15    Reserved (0)
                  */
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestDB);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDB);
 
                 /* Note that we don't support guest and host-initiated debugging at the same time. */
@@ -3636,5 +3636,5 @@
                     AssertRC(rc2);
 
-                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                     goto ResumeExecution;
                 }
@@ -3646,5 +3646,5 @@
             case X86_XCPT_BP:   /* Breakpoint. */
             {
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestBP);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestBP);
                 rc = DBGFRZTrap03Handler(pVM, pVCpu, CPUMCTX2CORE(pCtx));
                 if (rc == VINF_EM_RAW_GUEST_TRAP)
@@ -3654,10 +3654,10 @@
                                              cbInstr, errCode);
                     AssertRC(rc2);
-                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                     goto ResumeExecution;
                 }
                 if (rc == VINF_SUCCESS)
                 {
-                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                     goto ResumeExecution;
                 }
@@ -3669,10 +3669,10 @@
             {
                 uint32_t     cbOp;
-                PDISCPUSTATE pDis = &pVCpu->hwaccm.s.DisState;
-
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestGP);
+                PDISCPUSTATE pDis = &pVCpu->hm.s.DisState;
+
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestGP);
 #ifdef VBOX_STRICT
                 if (    !CPUMIsGuestInRealModeEx(pCtx)
-                    ||  !pVM->hwaccm.s.vmx.pRealModeTSS)
+                    ||  !pVM->hm.s.vmx.pRealModeTSS)
                 {
                     Log(("Trap %x at %04X:%RGv errorCode=%RGv\n", vector, pCtx->cs.Sel, (RTGCPTR)pCtx->rip, errCode));
@@ -3680,5 +3680,5 @@
                                              cbInstr, errCode);
                     AssertRC(rc2);
-                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                     goto ResumeExecution;
                 }
@@ -3699,5 +3699,5 @@
                         case OP_CLI:
                             pCtx->eflags.Bits.u1IF = 0;
-                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCli);
+                            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCli);
                             break;
 
@@ -3709,5 +3709,5 @@
                                                VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI);
                             AssertRC(rc2);
-                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitSti);
+                            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitSti);
                             break;
 
@@ -3716,5 +3716,5 @@
                             rc = VINF_EM_HALT;
                             pCtx->rip += pDis->cbInstr;
-                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitHlt);
+                            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHlt);
                             break;
 
@@ -3758,5 +3758,5 @@
                             pCtx->esp &= uMask;
 
-                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitPopf);
+                            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitPopf);
                             break;
                         }
@@ -3801,5 +3801,5 @@
                             pCtx->esp -= cbParm;
                             pCtx->esp &= uMask;
-                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitPushf);
+                            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitPushf);
                             break;
                         }
@@ -3839,5 +3839,5 @@
                             LogFlow(("iret to %04x:%x\n", pCtx->cs.Sel, pCtx->ip));
                             fUpdateRIP = false;
-                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIret);
+                            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIret);
                             break;
                         }
@@ -3855,5 +3855,5 @@
                             AssertRC(VBOXSTRICTRC_VAL(rc));
                             fUpdateRIP = false;
-                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInt);
+                            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInt);
                             break;
                         }
@@ -3873,5 +3873,5 @@
                                 AssertRC(VBOXSTRICTRC_VAL(rc));
                                 fUpdateRIP = false;
-                                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInt);
+                                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInt);
                             }
                             break;
@@ -3890,5 +3890,5 @@
                             AssertRC(VBOXSTRICTRC_VAL(rc));
                             fUpdateRIP = false;
-                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInt);
+                            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInt);
                             break;
                         }
@@ -3909,8 +3909,8 @@
                          * whole context to be done with it.
                          */
-                        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_ALL;
+                        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_ALL;
 
                         /* Only resume if successful. */
-                        STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                        STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                         goto ResumeExecution;
                     }
@@ -3933,9 +3933,9 @@
                 switch (vector)
                 {
-                    case X86_XCPT_DE: STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestDE); break;
-                    case X86_XCPT_UD: STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestUD); break;
-                    case X86_XCPT_SS: STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestSS); break;
-                    case X86_XCPT_NP: STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestNP); break;
-                    case X86_XCPT_XF: STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestXF); break;
+                    case X86_XCPT_DE: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDE); break;
+                    case X86_XCPT_UD: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestUD); break;
+                    case X86_XCPT_SS: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestSS); break;
+                    case X86_XCPT_NP: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNP); break;
+                    case X86_XCPT_XF: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestXF); break;
                 }
 
@@ -3945,12 +3945,12 @@
                 AssertRC(rc2);
 
-                STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                 goto ResumeExecution;
             }
 #endif
             default:
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestXcpUnk);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestXcpUnk);
                 if (    CPUMIsGuestInRealModeEx(pCtx)
-                    &&  pVM->hwaccm.s.vmx.pRealModeTSS)
+                    &&  pVM->hm.s.vmx.pRealModeTSS)
                 {
                     Log(("Real Mode Trap %x at %04x:%04X error code %x\n", vector, pCtx->cs.Sel, pCtx->eip, errCode));
@@ -3966,5 +3966,5 @@
                     }
 
-                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+                    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
                     goto ResumeExecution;
                 }
@@ -3982,5 +3982,5 @@
         }
 
-        STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
+        STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub3, y3);
         break;
     }
@@ -3994,5 +3994,5 @@
         RTGCPHYS GCPhys;
 
-        Assert(pVM->hwaccm.s.fNestedPaging);
+        Assert(pVM->hm.s.fNestedPaging);
 
         rc2 = VMXReadVMCS64(VMX_VMCS_EXIT_PHYS_ADDR_FULL, &GCPhys);
@@ -4017,5 +4017,5 @@
                 &&  GCPhys > 0x1000000          /* to skip VGA frame buffer accesses */
                 &&  fSetupTPRCaching
-                &&  (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC))
+                &&  (pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC))
             {
                 RTGCPHYS GCPhysApicBase;
@@ -4025,5 +4025,5 @@
                 {
                     Log(("Enable VT-x virtual APIC access filtering\n"));
-                    rc2 = IOMMMIOMapMMIOHCPage(pVM, GCPhysApicBase, pVM->hwaccm.s.vmx.pAPICPhys, X86_PTE_RW | X86_PTE_P);
+                    rc2 = IOMMMIOMapMMIOHCPage(pVM, GCPhysApicBase, pVM->hm.s.vmx.pAPICPhys, X86_PTE_RW | X86_PTE_P);
                     AssertRC(rc2);
                 }
@@ -4049,5 +4049,5 @@
             /* We've successfully synced our shadow pages, so let's just continue execution. */
             Log2(("Shadow page fault at %RGv cr2=%RGp error code %x\n", (RTGCPTR)pCtx->rip, exitQualification , errCode));
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitReasonNPF);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitReasonNPF);
 
             TRPMResetTrap(pVCpu);
@@ -4068,5 +4068,5 @@
         RTGCPHYS GCPhys;
 
-        Assert(pVM->hwaccm.s.fNestedPaging);
+        Assert(pVM->hm.s.fNestedPaging);
 
         rc2 = VMXReadVMCS64(VMX_VMCS_EXIT_PHYS_ADDR_FULL, &GCPhys);
@@ -4078,5 +4078,5 @@
             &&  GCPhys > 0x1000000              /* to skip VGA frame buffer accesses */
             &&  fSetupTPRCaching
-            &&  (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC))
+            &&  (pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC))
         {
             RTGCPHYS GCPhysApicBase;
@@ -4086,5 +4086,5 @@
             {
                 Log(("Enable VT-x virtual APIC access filtering\n"));
-                rc2 = IOMMMIOMapMMIOHCPage(pVM, GCPhysApicBase, pVM->hwaccm.s.vmx.pAPICPhys, X86_PTE_RW | X86_PTE_P);
+                rc2 = IOMMMIOMapMMIOHCPage(pVM, GCPhysApicBase, pVM->hm.s.vmx.pAPICPhys, X86_PTE_RW | X86_PTE_P);
                 AssertRC(rc2);
             }
@@ -4116,13 +4116,13 @@
         LogFlow(("VMX_EXIT_IRQ_WINDOW %RGv pending=%d IF=%d\n", (RTGCPTR)pCtx->rip,
                  VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)), pCtx->eflags.Bits.u1IF));
-        pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT;
-        rc2 = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
+        pVCpu->hm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT;
+        rc2 = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hm.s.vmx.proc_ctls);
         AssertRC(rc2);
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIrqWindow);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIrqWindow);
         goto ResumeExecution;   /* we check for pending guest interrupts there */
 
     case VMX_EXIT_WBINVD:               /* 54 Guest software attempted to execute WBINVD. (conditional) */
     case VMX_EXIT_INVD:                 /* 13 Guest software attempted to execute INVD. (unconditional) */
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInvd);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInvd);
         /* Skip instruction and continue directly. */
         pCtx->rip += cbInstr;
@@ -4133,5 +4133,5 @@
     {
         Log2(("VMX: Cpuid %x\n", pCtx->eax));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCpuid);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCpuid);
         rc = EMInterpretCpuId(pVM, pVCpu, CPUMCTX2CORE(pCtx));
         if (rc == VINF_SUCCESS)
@@ -4150,5 +4150,5 @@
     {
         Log2(("VMX: Rdpmc %x\n", pCtx->ecx));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitRdpmc);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitRdpmc);
         rc = EMInterpretRdpmc(pVM, pVCpu, CPUMCTX2CORE(pCtx));
         if (rc == VINF_SUCCESS)
@@ -4166,5 +4166,5 @@
     {
         Log2(("VMX: Rdtsc\n"));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitRdtsc);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitRdtsc);
         rc = EMInterpretRdtsc(pVM, pVCpu, CPUMCTX2CORE(pCtx));
         if (rc == VINF_SUCCESS)
@@ -4182,5 +4182,5 @@
     {
         Log2(("VMX: Rdtscp\n"));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitRdtscp);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitRdtscp);
         rc = EMInterpretRdtscp(pVM, pVCpu, pCtx);
         if (rc == VINF_SUCCESS)
@@ -4198,7 +4198,7 @@
     {
         Log2(("VMX: invlpg\n"));
-        Assert(!pVM->hwaccm.s.fNestedPaging);
-
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInvlpg);
+        Assert(!pVM->hm.s.fNestedPaging);
+
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInvlpg);
         rc = EMInterpretInvlpg(pVM, pVCpu, CPUMCTX2CORE(pCtx), exitQualification);
         if (rc == VINF_SUCCESS)
@@ -4216,5 +4216,5 @@
         Log2(("VMX: monitor\n"));
 
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitMonitor);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitMonitor);
         rc = EMInterpretMonitor(pVM, pVCpu, CPUMCTX2CORE(pCtx));
         if (rc == VINF_SUCCESS)
@@ -4230,5 +4230,5 @@
     case VMX_EXIT_WRMSR:                /* 32 WRMSR. Guest software attempted to execute WRMSR. */
         /* When an interrupt is pending, we'll let MSR_K8_LSTAR writes fault in our TPR patch code. */
-        if (    pVM->hwaccm.s.fTPRPatchingActive
+        if (    pVM->hm.s.fTPRPatchingActive
             &&  pCtx->ecx == MSR_K8_LSTAR)
         {
@@ -4249,9 +4249,9 @@
             goto ResumeExecution;
         }
-        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_MSR;
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_MSR;
         /* no break */
     case VMX_EXIT_RDMSR:                /* 31 RDMSR. Guest software attempted to execute RDMSR. */
     {
-        STAM_COUNTER_INC((exitReason == VMX_EXIT_RDMSR) ? &pVCpu->hwaccm.s.StatExitRdmsr : &pVCpu->hwaccm.s.StatExitWrmsr);
+        STAM_COUNTER_INC((exitReason == VMX_EXIT_RDMSR) ? &pVCpu->hm.s.StatExitRdmsr : &pVCpu->hm.s.StatExitWrmsr);
 
         /*
@@ -4274,5 +4274,5 @@
     case VMX_EXIT_CRX_MOVE:             /* 28 Control-register accesses. */
     {
-        STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatExit2Sub2, y2);
+        STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatExit2Sub2, y2);
 
         switch (VMX_EXIT_QUALIFICATION_CRX_ACCESS(exitQualification))
@@ -4281,5 +4281,5 @@
             {
                 Log2(("VMX: %RGv mov cr%d, x\n", (RTGCPTR)pCtx->rip, VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification)));
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCRxWrite[VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification)]);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCRxWrite[VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification)]);
                 rc = EMInterpretCRxWrite(pVM, pVCpu, CPUMCTX2CORE(pCtx),
                                          VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification),
@@ -4288,18 +4288,18 @@
                 {
                     case 0:
-                        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0 | HWACCM_CHANGED_GUEST_CR3;
+                        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR0 | HM_CHANGED_GUEST_CR3;
                         break;
                     case 2:
                         break;
                     case 3:
-                        Assert(!pVM->hwaccm.s.fNestedPaging || !CPUMIsGuestInPagedProtectedModeEx(pCtx));
-                        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR3;
+                        Assert(!pVM->hm.s.fNestedPaging || !CPUMIsGuestInPagedProtectedModeEx(pCtx));
+                        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR3;
                         break;
                     case 4:
-                        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR4;
+                        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR4;
                         break;
                     case 8:
                         /* CR8 contains the APIC TPR */
-                        Assert(!(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1
+                        Assert(!(pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1
                                  & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW));
                         break;
@@ -4315,7 +4315,7 @@
             {
                 Log2(("VMX: mov x, crx\n"));
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCRxRead[VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification)]);
-
-                Assert(   !pVM->hwaccm.s.fNestedPaging
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCRxRead[VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification)]);
+
+                Assert(   !pVM->hm.s.fNestedPaging
                        || !CPUMIsGuestInPagedProtectedModeEx(pCtx)
                        || VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification) != DISCREG_CR3);
@@ -4323,5 +4323,5 @@
                 /* CR8 reads only cause an exit when the TPR shadow feature isn't present. */
                 Assert(   VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification) != 8
-                       || !(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW));
+                       || !(pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW));
 
                 rc = EMInterpretCRxRead(pVM, pVCpu, CPUMCTX2CORE(pCtx),
@@ -4334,7 +4334,7 @@
             {
                 Log2(("VMX: clts\n"));
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCLTS);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCLTS);
                 rc = EMInterpretCLTS(pVM, pVCpu);
-                pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0;
+                pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR0;
                 break;
             }
@@ -4343,7 +4343,7 @@
             {
                 Log2(("VMX: lmsw %x\n", VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(exitQualification)));
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitLMSW);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitLMSW);
                 rc = EMInterpretLMSW(pVM, pVCpu, CPUMCTX2CORE(pCtx), VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(exitQualification));
-                pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0;
+                pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_CR0;
                 break;
             }
@@ -4357,9 +4357,9 @@
         {
             /* Only resume if successful. */
-            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub2, y2);
+            STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub2, y2);
             goto ResumeExecution;
         }
         Assert(rc == VERR_EM_INTERPRETER || rc == VINF_PGM_CHANGE_MODE || rc == VINF_PGM_SYNC_CR3);
-        STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub2, y2);
+        STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub2, y2);
         break;
     }
@@ -4371,6 +4371,6 @@
         {
             /* Disable DRx move intercepts. */
-            pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT;
-            rc2 = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
+            pVCpu->hm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT;
+            rc2 = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hm.s.vmx.proc_ctls);
             AssertRC(rc2);
 
@@ -4390,9 +4390,9 @@
 
 #ifdef VBOX_WITH_STATISTICS
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatDRxContextSwitch);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatDRxContextSwitch);
             if (VMX_EXIT_QUALIFICATION_DRX_DIRECTION(exitQualification) == VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE)
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitDRxWrite);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitDRxWrite);
             else
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitDRxRead);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitDRxRead);
 #endif
 
@@ -4406,9 +4406,9 @@
             Log2(("VMX: mov DRx%d, genreg%d\n", VMX_EXIT_QUALIFICATION_DRX_REGISTER(exitQualification),
                   VMX_EXIT_QUALIFICATION_DRX_GENREG(exitQualification)));
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitDRxWrite);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitDRxWrite);
             rc = EMInterpretDRxWrite(pVM, pVCpu, CPUMCTX2CORE(pCtx),
                                      VMX_EXIT_QUALIFICATION_DRX_REGISTER(exitQualification),
                                      VMX_EXIT_QUALIFICATION_DRX_GENREG(exitQualification));
-            pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_DEBUG;
+            pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_DEBUG;
             Log2(("DR7=%08x\n", pCtx->dr[7]));
         }
@@ -4416,5 +4416,5 @@
         {
             Log2(("VMX: mov x, DRx\n"));
-            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitDRxRead);
+            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitDRxRead);
             rc = EMInterpretDRxRead(pVM, pVCpu, CPUMCTX2CORE(pCtx),
                                     VMX_EXIT_QUALIFICATION_DRX_GENREG(exitQualification),
@@ -4437,5 +4437,5 @@
     case VMX_EXIT_PORT_IO:              /* 30 I/O instruction. */
     {
-        STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatExit2Sub1, y1);
+        STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatExit2Sub1, y1);
         uint32_t uPort;
         uint32_t uIOWidth = VMX_EXIT_QUALIFICATION_IO_WIDTH(exitQualification);
@@ -4451,5 +4451,5 @@
         {
             rc = fIOWrite ? VINF_IOM_R3_IOPORT_WRITE : VINF_IOM_R3_IOPORT_READ;
-            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub1, y1);
+            STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub1, y1);
             break;
         }
@@ -4459,5 +4459,5 @@
         {
             /* ins/outs */
-            PDISCPUSTATE pDis = &pVCpu->hwaccm.s.DisState;
+            PDISCPUSTATE pDis = &pVCpu->hm.s.DisState;
 
             /* Disassemble manually to deal with segment prefixes. */
@@ -4470,5 +4470,5 @@
                 {
                     Log2(("IOMInterpretOUTSEx %RGv %x size=%d\n", (RTGCPTR)pCtx->rip, uPort, cbSize));
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOStringWrite);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIOStringWrite);
                     rc = IOMInterpretOUTSEx(pVM, CPUMCTX2CORE(pCtx), uPort, pDis->fPrefix, (DISCPUMODE)pDis->uAddrMode, cbSize);
                 }
@@ -4476,5 +4476,5 @@
                 {
                     Log2(("IOMInterpretINSEx  %RGv %x size=%d\n", (RTGCPTR)pCtx->rip, uPort, cbSize));
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOStringRead);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIOStringRead);
                     rc = IOMInterpretINSEx(pVM, CPUMCTX2CORE(pCtx), uPort, pDis->fPrefix, (DISCPUMODE)pDis->uAddrMode, cbSize);
                 }
@@ -4492,8 +4492,8 @@
             if (fIOWrite)
             {
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOWrite);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIOWrite);
                 rc = IOMIOPortWrite(pVM, uPort, pCtx->eax & uAndVal, cbSize);
                 if (rc == VINF_IOM_R3_IOPORT_WRITE)
-                    HWACCMR0SavePendingIOPortWrite(pVCpu, pCtx->rip, pCtx->rip + cbInstr, uPort, uAndVal, cbSize);
+                    HMR0SavePendingIOPortWrite(pVCpu, pCtx->rip, pCtx->rip + cbInstr, uPort, uAndVal, cbSize);
             }
             else
@@ -4501,5 +4501,5 @@
                 uint32_t u32Val = 0;
 
-                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIORead);
+                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIORead);
                 rc = IOMIOPortRead(pVM, uPort, &u32Val, cbSize);
                 if (IOM_SUCCESS(rc))
@@ -4510,5 +4510,5 @@
                 else
                 if (rc == VINF_IOM_R3_IOPORT_READ)
-                    HWACCMR0SavePendingIOPortRead(pVCpu, pCtx->rip, pCtx->rip + cbInstr, uPort, uAndVal, cbSize);
+                    HMR0SavePendingIOPortRead(pVCpu, pCtx->rip, pCtx->rip + cbInstr, uPort, uAndVal, cbSize);
             }
         }
@@ -4527,5 +4527,5 @@
                 if (pCtx->dr[7] & X86_DR7_ENABLED_MASK)
                 {
-                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatDRxIOCheck);
+                    STAM_COUNTER_INC(&pVCpu->hm.s.StatDRxIOCheck);
                     for (unsigned i = 0; i < 4; i++)
                     {
@@ -4575,13 +4575,13 @@
                             AssertRC(rc2);
 
-                            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub1, y1);
+                            STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub1, y1);
                             goto ResumeExecution;
                         }
                     }
                 }
-                STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub1, y1);
+                STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub1, y1);
                 goto ResumeExecution;
             }
-            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub1, y1);
+            STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub1, y1);
             break;
         }
@@ -4600,5 +4600,5 @@
         }
 #endif
-        STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub1, y1);
+        STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2Sub1, y1);
         break;
     }
@@ -4686,12 +4686,12 @@
         Log(("VMX_EXIT_TASK_SWITCH: exit=%RX64\n", exitQualification));
         if (    (VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE(exitQualification) == VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IDT)
-            &&  pVCpu->hwaccm.s.Event.fPending)
+            &&  pVCpu->hm.s.Event.fPending)
         {
             /* Caused by an injected interrupt. */
-            pVCpu->hwaccm.s.Event.fPending = false;
-
-            Log(("VMX_EXIT_TASK_SWITCH: reassert trap %d\n", VMX_EXIT_INTERRUPTION_INFO_VECTOR(pVCpu->hwaccm.s.Event.intInfo)));
-            Assert(!VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(pVCpu->hwaccm.s.Event.intInfo));
-            rc2 = TRPMAssertTrap(pVCpu, VMX_EXIT_INTERRUPTION_INFO_VECTOR(pVCpu->hwaccm.s.Event.intInfo), TRPM_HARDWARE_INT);
+            pVCpu->hm.s.Event.fPending = false;
+
+            Log(("VMX_EXIT_TASK_SWITCH: reassert trap %d\n", VMX_EXIT_INTERRUPTION_INFO_VECTOR(pVCpu->hm.s.Event.intInfo)));
+            Assert(!VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(pVCpu->hm.s.Event.intInfo));
+            rc2 = TRPMAssertTrap(pVCpu, VMX_EXIT_INTERRUPTION_INFO_VECTOR(pVCpu->hm.s.Event.intInfo), TRPM_HARDWARE_INT);
             AssertRC(rc2);
         }
@@ -4702,5 +4702,5 @@
     case VMX_EXIT_HLT:                  /* 12 Guest software attempted to execute HLT. */
         /* Check if external interrupts are pending; if so, don't switch back. */
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitHlt);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHlt);
         pCtx->rip++;    /* skip hlt */
         if (EMShouldContinueAfterHalt(pVCpu, pCtx))
@@ -4712,5 +4712,5 @@
     case VMX_EXIT_MWAIT:                /* 36 Guest software executed MWAIT. */
         Log2(("VMX: mwait\n"));
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitMwait);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitMwait);
         rc = EMInterpretMWait(pVM, pVCpu, CPUMCTX2CORE(pCtx));
         if (    rc == VINF_EM_HALT
@@ -4737,8 +4737,8 @@
     case VMX_EXIT_MTF:                  /* 37 Exit due to Monitor Trap Flag. */
         LogFlow(("VMX_EXIT_MTF at %RGv\n", (RTGCPTR)pCtx->rip));
-        pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG;
-        rc2 = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
+        pVCpu->hm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG;
+        rc2 = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hm.s.vmx.proc_ctls);
         AssertRC(rc2);
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitMTF);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitMTF);
 #if 0
         DBGFDoneStepping(pVCpu);
@@ -4872,7 +4872,7 @@
         &&  !VMX_EXIT_INTERRUPTION_INFO_VALID(intInfo))
     {
-        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatPendingHostIrq);
+        STAM_COUNTER_INC(&pVCpu->hm.s.StatPendingHostIrq);
         /* On the next entry we'll only sync the host context. */
-        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_HOST_CONTEXT;
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT;
     }
     else
@@ -4881,5 +4881,5 @@
         /** @todo we can do better than this */
         /* Not in the VINF_PGM_CHANGE_MODE though! */
-        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_ALL;
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_ALL;
     }
 
@@ -4890,8 +4890,8 @@
     {
         /* Try to extract more information about what might have gone wrong here. */
-        VMXGetActivateVMCS(&pVCpu->hwaccm.s.vmx.lasterror.u64VMCSPhys);
-        pVCpu->hwaccm.s.vmx.lasterror.ulVMCSRevision = *(uint32_t *)pVCpu->hwaccm.s.vmx.pvVMCS;
-        pVCpu->hwaccm.s.vmx.lasterror.idEnteredCpu   = pVCpu->hwaccm.s.idEnteredCpu;
-        pVCpu->hwaccm.s.vmx.lasterror.idCurrentCpu   = RTMpCpuId();
+        VMXGetActivateVMCS(&pVCpu->hm.s.vmx.lasterror.u64VMCSPhys);
+        pVCpu->hm.s.vmx.lasterror.ulVMCSRevision = *(uint32_t *)pVCpu->hm.s.vmx.pvVMCS;
+        pVCpu->hm.s.vmx.lasterror.idEnteredCpu   = pVCpu->hm.s.idEnteredCpu;
+        pVCpu->hm.s.vmx.lasterror.idCurrentCpu   = RTMpCpuId();
     }
 
@@ -4905,7 +4905,7 @@
 #endif
 
-    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2, x);
-    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, x);
-    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatEntry, x);
+    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit2, x);
+    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExit1, x);
+    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatEntry, x);
     Log2(("X"));
     return VBOXSTRICTRC_TODO(rc);
@@ -4923,5 +4923,5 @@
 VMMR0DECL(int) VMXR0Enter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu)
 {
-    Assert(pVM->hwaccm.s.vmx.fSupported);
+    Assert(pVM->hm.s.vmx.fSupported);
     NOREF(pCpu);
 
@@ -4934,9 +4934,9 @@
 
     /* Activate the VMCS. */
-    int rc = VMXActivateVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
+    int rc = VMXActivateVMCS(pVCpu->hm.s.vmx.HCPhysVMCS);
     if (RT_FAILURE(rc))
         return rc;
 
-    pVCpu->hwaccm.s.fResumeVM = false;
+    pVCpu->hm.s.fResumeVM = false;
     return VINF_SUCCESS;
 }
@@ -4953,5 +4953,5 @@
 VMMR0DECL(int) VMXR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 {
-    Assert(pVM->hwaccm.s.vmx.fSupported);
+    Assert(pVM->hm.s.vmx.fSupported);
 
 #ifdef DEBUG
@@ -4959,5 +4959,5 @@
     {
         CPUMR0LoadHostDebugState(pVM, pVCpu);
-        Assert(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT);
+        Assert(pVCpu->hm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT);
     }
     else
@@ -4972,13 +4972,13 @@
 
         /* Enable DRx move intercepts again. */
-        pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT;
-        int rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
+        pVCpu->hm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT;
+        int rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hm.s.vmx.proc_ctls);
         AssertRC(rc);
 
         /* Resync the debug registers the next time. */
-        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_DEBUG;
+        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_DEBUG;
     }
     else
-        Assert(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT);
+        Assert(pVCpu->hm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT);
 
     /*
@@ -4986,5 +4986,5 @@
      * VMCS data back to memory.
      */
-    int rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
+    int rc = VMXClearVMCS(pVCpu->hm.s.vmx.HCPhysVMCS);
     AssertRC(rc);
 
@@ -5006,9 +5006,9 @@
 
     LogFlow(("hmR0VmxFlushEPT %d\n", enmFlush));
-    Assert(pVM->hwaccm.s.fNestedPaging);
-    descriptor[0] = pVCpu->hwaccm.s.vmx.GCPhysEPTP;
+    Assert(pVM->hm.s.fNestedPaging);
+    descriptor[0] = pVCpu->hm.s.vmx.GCPhysEPTP;
     descriptor[1] = 0; /* MBZ. Intel spec. 33.3 VMX Instructions */
     int rc = VMXR0InvEPT(enmFlush, &descriptor[0]);
-    AssertMsg(rc == VINF_SUCCESS, ("VMXR0InvEPT %x %RGv failed with %d\n", enmFlush, pVCpu->hwaccm.s.vmx.GCPhysEPTP, rc));
+    AssertMsg(rc == VINF_SUCCESS, ("VMXR0InvEPT %x %RGv failed with %d\n", enmFlush, pVCpu->hm.s.vmx.GCPhysEPTP, rc));
 }
 
@@ -5029,5 +5029,5 @@
     uint64_t descriptor[2];
 
-    Assert(pVM->hwaccm.s.vmx.fVPID);
+    Assert(pVM->hm.s.vmx.fVPID);
     if (enmFlush == VMX_FLUSH_VPID_ALL_CONTEXTS)
     {
@@ -5038,12 +5038,12 @@
     {
         AssertPtr(pVCpu);
-        AssertMsg(pVCpu->hwaccm.s.uCurrentASID != 0, ("VMXR0InvVPID invalid ASID %lu\n", pVCpu->hwaccm.s.uCurrentASID));
-        AssertMsg(pVCpu->hwaccm.s.uCurrentASID <= UINT16_MAX, ("VMXR0InvVPID invalid ASID %lu\n", pVCpu->hwaccm.s.uCurrentASID));
-        descriptor[0] = pVCpu->hwaccm.s.uCurrentASID;
+        AssertMsg(pVCpu->hm.s.uCurrentASID != 0, ("VMXR0InvVPID invalid ASID %lu\n", pVCpu->hm.s.uCurrentASID));
+        AssertMsg(pVCpu->hm.s.uCurrentASID <= UINT16_MAX, ("VMXR0InvVPID invalid ASID %lu\n", pVCpu->hm.s.uCurrentASID));
+        descriptor[0] = pVCpu->hm.s.uCurrentASID;
         descriptor[1] = GCPtr;
     }
     int rc = VMXR0InvVPID(enmFlush, &descriptor[0]); NOREF(rc);
     AssertMsg(rc == VINF_SUCCESS,
-              ("VMXR0InvVPID %x %x %RGv failed with %d\n", enmFlush, pVCpu ? pVCpu->hwaccm.s.uCurrentASID : 0, GCPtr, rc));
+              ("VMXR0InvVPID %x %x %RGv failed with %d\n", enmFlush, pVCpu ? pVCpu->hm.s.uCurrentASID : 0, GCPtr, rc));
 }
 
@@ -5073,13 +5073,13 @@
          * function maybe called in a loop with individual addresses.
          */
-        if (pVM->hwaccm.s.vmx.fVPID)
+        if (pVM->hm.s.vmx.fVPID)
         {
             /* If we can flush just this page do it, otherwise flush as little as possible. */
-            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
+            if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
                 hmR0VmxFlushVPID(pVM, pVCpu, VMX_FLUSH_VPID_INDIV_ADDR, GCVirt);
             else
                 VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
         }
-        else if (pVM->hwaccm.s.fNestedPaging)
+        else if (pVM->hm.s.fNestedPaging)
             VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
     }
@@ -5147,6 +5147,6 @@
                 Log(("Current stack %08x\n", &rc2));
 
-                pVCpu->hwaccm.s.vmx.lasterror.ulInstrError = instrError;
-                pVCpu->hwaccm.s.vmx.lasterror.ulExitReason = exitReason;
+                pVCpu->hm.s.vmx.lasterror.ulInstrError = instrError;
+                pVCpu->hm.s.vmx.lasterror.ulExitReason = exitReason;
 
 #ifdef VBOX_STRICT
@@ -5183,5 +5183,5 @@
                 {
                     pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
-                    HWACCMR0DumpDescriptor(pDesc, val, "CS: ");
+                    HMR0DumpDescriptor(pDesc, val, "CS: ");
                 }
 
@@ -5191,5 +5191,5 @@
                 {
                     pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
-                    HWACCMR0DumpDescriptor(pDesc, val, "DS: ");
+                    HMR0DumpDescriptor(pDesc, val, "DS: ");
                 }
 
@@ -5199,5 +5199,5 @@
                 {
                     pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
-                    HWACCMR0DumpDescriptor(pDesc, val, "ES: ");
+                    HMR0DumpDescriptor(pDesc, val, "ES: ");
                 }
 
@@ -5207,5 +5207,5 @@
                 {
                     pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
-                    HWACCMR0DumpDescriptor(pDesc, val, "FS: ");
+                    HMR0DumpDescriptor(pDesc, val, "FS: ");
                 }
 
@@ -5215,5 +5215,5 @@
                 {
                     pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
-                    HWACCMR0DumpDescriptor(pDesc, val, "GS: ");
+                    HMR0DumpDescriptor(pDesc, val, "GS: ");
                 }
 
@@ -5223,5 +5223,5 @@
                 {
                     pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
-                    HWACCMR0DumpDescriptor(pDesc, val, "SS: ");
+                    HMR0DumpDescriptor(pDesc, val, "SS: ");
                 }
 
@@ -5231,5 +5231,5 @@
                 {
                     pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
-                    HWACCMR0DumpDescriptor(pDesc, val, "TR: ");
+                    HMR0DumpDescriptor(pDesc, val, "TR: ");
                 }
 
@@ -5292,5 +5292,5 @@
     int             rc;
 
-    pCpu = HWACCMR0GetCurrentCpu();
+    pCpu = HMR0GetCurrentCpu();
     HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
 
@@ -5298,5 +5298,5 @@
     pCache->uPos = 1;
     pCache->interPD = PGMGetInterPaeCR3(pVM);
-    pCache->pSwitcher = (uint64_t)pVM->hwaccm.s.pfnHost32ToGuest64R0;
+    pCache->pSwitcher = (uint64_t)pVM->hm.s.pfnHost32ToGuest64R0;
 #endif
 
@@ -5313,31 +5313,31 @@
     aParam[0] = (uint32_t)(HCPhysCpuPage);                                  /* Param 1: VMXON physical address - Lo. */
     aParam[1] = (uint32_t)(HCPhysCpuPage >> 32);                            /* Param 1: VMXON physical address - Hi. */
-    aParam[2] = (uint32_t)(pVCpu->hwaccm.s.vmx.HCPhysVMCS);                 /* Param 2: VMCS physical address - Lo. */
-    aParam[3] = (uint32_t)(pVCpu->hwaccm.s.vmx.HCPhysVMCS >> 32);           /* Param 2: VMCS physical address - Hi. */
-    aParam[4] = VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hwaccm.s.vmx.VMCSCache);
+    aParam[2] = (uint32_t)(pVCpu->hm.s.vmx.HCPhysVMCS);                 /* Param 2: VMCS physical address - Lo. */
+    aParam[3] = (uint32_t)(pVCpu->hm.s.vmx.HCPhysVMCS >> 32);           /* Param 2: VMCS physical address - Hi. */
+    aParam[4] = VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hm.s.vmx.VMCSCache);
     aParam[5] = 0;
 
 #ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    pCtx->dr[4] = pVM->hwaccm.s.vmx.pScratchPhys + 16 + 8;
-    *(uint32_t *)(pVM->hwaccm.s.vmx.pScratch + 16 + 8) = 1;
-#endif
-    rc = VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnVMXGCStartVM64, 6, &aParam[0]);
+    pCtx->dr[4] = pVM->hm.s.vmx.pScratchPhys + 16 + 8;
+    *(uint32_t *)(pVM->hm.s.vmx.pScratch + 16 + 8) = 1;
+#endif
+    rc = VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hm.s.pfnVMXGCStartVM64, 6, &aParam[0]);
 
 #ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    Assert(*(uint32_t *)(pVM->hwaccm.s.vmx.pScratch + 16 + 8) == 5);
+    Assert(*(uint32_t *)(pVM->hm.s.vmx.pScratch + 16 + 8) == 5);
     Assert(pCtx->dr[4] == 10);
-    *(uint32_t *)(pVM->hwaccm.s.vmx.pScratch + 16 + 8) = 0xff;
+    *(uint32_t *)(pVM->hm.s.vmx.pScratch + 16 + 8) = 0xff;
 #endif
 
 #ifdef DEBUG
     AssertMsg(pCache->TestIn.HCPhysCpuPage== HCPhysCpuPage, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysCpuPage, HCPhysCpuPage));
-    AssertMsg(pCache->TestIn.HCPhysVMCS   == pVCpu->hwaccm.s.vmx.HCPhysVMCS, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysVMCS,
-                                                                              pVCpu->hwaccm.s.vmx.HCPhysVMCS));
+    AssertMsg(pCache->TestIn.HCPhysVMCS   == pVCpu->hm.s.vmx.HCPhysVMCS, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysVMCS,
+                                                                              pVCpu->hm.s.vmx.HCPhysVMCS));
     AssertMsg(pCache->TestIn.HCPhysVMCS   == pCache->TestOut.HCPhysVMCS, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysVMCS,
                                                                           pCache->TestOut.HCPhysVMCS));
     AssertMsg(pCache->TestIn.pCache       == pCache->TestOut.pCache, ("%RGv vs %RGv\n", pCache->TestIn.pCache,
                                                                       pCache->TestOut.pCache));
-    AssertMsg(pCache->TestIn.pCache       == VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hwaccm.s.vmx.VMCSCache),
-              ("%RGv vs %RGv\n", pCache->TestIn.pCache, VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hwaccm.s.vmx.VMCSCache)));
+    AssertMsg(pCache->TestIn.pCache       == VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hm.s.vmx.VMCSCache),
+              ("%RGv vs %RGv\n", pCache->TestIn.pCache, VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hm.s.vmx.VMCSCache)));
     AssertMsg(pCache->TestIn.pCtx         == pCache->TestOut.pCtx, ("%RGv vs %RGv\n", pCache->TestIn.pCtx,
                                                                     pCache->TestOut.pCtx));
@@ -5466,15 +5466,15 @@
     RTHCUINTREG     uOldEFlags;
 
-    AssertReturn(pVM->hwaccm.s.pfnHost32ToGuest64R0, VERR_HM_NO_32_TO_64_SWITCHER);
+    AssertReturn(pVM->hm.s.pfnHost32ToGuest64R0, VERR_HM_NO_32_TO_64_SWITCHER);
     Assert(pfnHandler);
-    Assert(pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries <= RT_ELEMENTS(pVCpu->hwaccm.s.vmx.VMCSCache.Write.aField));
-    Assert(pVCpu->hwaccm.s.vmx.VMCSCache.Read.cValidEntries <= RT_ELEMENTS(pVCpu->hwaccm.s.vmx.VMCSCache.Read.aField));
+    Assert(pVCpu->hm.s.vmx.VMCSCache.Write.cValidEntries <= RT_ELEMENTS(pVCpu->hm.s.vmx.VMCSCache.Write.aField));
+    Assert(pVCpu->hm.s.vmx.VMCSCache.Read.cValidEntries <= RT_ELEMENTS(pVCpu->hm.s.vmx.VMCSCache.Read.aField));
 
 #ifdef VBOX_STRICT
-    for (unsigned i=0;i<pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries;i++)
-        Assert(hmR0VmxIsValidWriteField(pVCpu->hwaccm.s.vmx.VMCSCache.Write.aField[i]));
-
-    for (unsigned i=0;i<pVCpu->hwaccm.s.vmx.VMCSCache.Read.cValidEntries;i++)
-        Assert(hmR0VmxIsValidReadField(pVCpu->hwaccm.s.vmx.VMCSCache.Read.aField[i]));
+    for (unsigned i=0;i<pVCpu->hm.s.vmx.VMCSCache.Write.cValidEntries;i++)
+        Assert(hmR0VmxIsValidWriteField(pVCpu->hm.s.vmx.VMCSCache.Write.aField[i]));
+
+    for (unsigned i=0;i<pVCpu->hm.s.vmx.VMCSCache.Read.cValidEntries;i++)
+        Assert(hmR0VmxIsValidReadField(pVCpu->hm.s.vmx.VMCSCache.Read.aField[i]));
 #endif
 
@@ -5487,9 +5487,9 @@
 #endif
 
-    pCpu = HWACCMR0GetCurrentCpu();
+    pCpu = HMR0GetCurrentCpu();
     HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
 
     /* Clear VMCS. Marking it inactive, clearing implementation-specific data and writing VMCS data back to memory. */
-    VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
+    VMXClearVMCS(pVCpu->hm.s.vmx.HCPhysVMCS);
 
     /* Leave VMX Root Mode. */
@@ -5503,9 +5503,9 @@
         CPUMPushHyper(pVCpu, paParam[i]);
 
-    STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatWorldSwitch3264, z);
+    STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatWorldSwitch3264, z);
 
     /* Call switcher. */
-    rc = pVM->hwaccm.s.pfnHost32ToGuest64R0(pVM, RT_OFFSETOF(VM, aCpus[pVCpu->idCpu].cpum) - RT_OFFSETOF(VM, cpum));
-    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatWorldSwitch3264, z);
+    rc = pVM->hm.s.pfnHost32ToGuest64R0(pVM, RT_OFFSETOF(VM, aCpus[pVCpu->idCpu].cpum) - RT_OFFSETOF(VM, cpum));
+    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatWorldSwitch3264, z);
 
     /* Make sure the VMX instructions don't cause #UD faults. */
@@ -5521,5 +5521,5 @@
     }
 
-    rc2 = VMXActivateVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
+    rc2 = VMXActivateVMCS(pVCpu->hm.s.vmx.HCPhysVMCS);
     AssertRC(rc2);
     Assert(!(ASMGetFlags() & X86_EFL_IF));
@@ -5609,5 +5609,5 @@
 VMMR0DECL(int) VMXWriteCachedVMCSEx(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val)
 {
-    PVMCSCACHE pCache = &pVCpu->hwaccm.s.vmx.VMCSCache;
+    PVMCSCACHE pCache = &pVCpu->hm.s.vmx.VMCSCache;
 
     AssertMsgReturn(pCache->Write.cValidEntries < VMCSCACHE_MAX_ENTRY - 1,
Index: trunk/src/VBox/VMM/VMMR0/HWVMXR0.h
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWVMXR0.h	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR0/HWVMXR0.h	(revision 43387)
@@ -24,7 +24,7 @@
 #include <VBox/vmm/stam.h>
 #include <VBox/dis.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <VBox/vmm/pgm.h>
-#include <VBox/vmm/hwacc_vmx.h>
+#include <VBox/vmm/hm_vmx.h>
 
 RT_C_DECLS_BEGIN
@@ -220,5 +220,5 @@
         else                                                                                    \
         if (    CPUMIsGuestInRealModeEx(pCtx)                                                   \
-            &&  !pVM->hwaccm.s.vmx.fUnrestrictedGuest)                                          \
+            &&  !pVM->hm.s.vmx.fUnrestrictedGuest)                                          \
         {                                                                                       \
             /* Must override this or else VT-x will fail with invalid guest state errors. */    \
@@ -291,5 +291,5 @@
 {
     Assert(idxCache <= VMX_VMCS_MAX_NESTED_PAGING_CACHE_IDX);
-    *pVal = pVCpu->hwaccm.s.vmx.VMCSCache.Read.aFieldVal[idxCache];
+    *pVal = pVCpu->hm.s.vmx.VMCSCache.Read.aFieldVal[idxCache];
     return VINF_SUCCESS;
 }
Index: trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 43387)
@@ -28,5 +28,5 @@
 #include <VBox/vmm/vmm.h>
 #include <VBox/vmm/patm.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 
 #include <VBox/log.h>
@@ -374,5 +374,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return HWACCMCanEmulateIoBlock(VMMGetCpu(pDevIns->Internal.s.pVMR0));
+    return HMCanEmulateIoBlock(VMMGetCpu(pDevIns->Internal.s.pVMR0));
 }
 
Index: trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 43387)
@@ -37,5 +37,5 @@
 #include <VBox/vmm/gmm.h>
 #include <VBox/intnet.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <VBox/param.h>
 #include <VBox/err.h>
@@ -117,5 +117,5 @@
 
     /*
-     * Initialize the VMM, GVMM, GMM, HWACCM, PGM (Darwin) and INTNET.
+     * Initialize the VMM, GVMM, GMM, HM, PGM (Darwin) and INTNET.
      */
     int rc = vmmInitFormatTypes();
@@ -128,5 +128,5 @@
             if (RT_SUCCESS(rc))
             {
-                rc = HWACCMR0Init();
+                rc = HMR0Init();
                 if (RT_SUCCESS(rc))
                 {
@@ -188,8 +188,8 @@
                     else
                         LogRel(("ModuleInit: PGMRegisterStringFormatTypes -> %Rrc\n", rc));
-                    HWACCMR0Term();
+                    HMR0Term();
                 }
                 else
-                    LogRel(("ModuleInit: HWACCMR0Init -> %Rrc\n", rc));
+                    LogRel(("ModuleInit: HMR0Init -> %Rrc\n", rc));
                 GMMR0Term();
             }
@@ -231,5 +231,5 @@
 
     /*
-     * PGM (Darwin), HWACCM and PciRaw global cleanup.
+     * PGM (Darwin), HM and PciRaw global cleanup.
      */
 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
@@ -240,5 +240,5 @@
 #endif
     PGMDeregisterStringFormatTypes();
-    HWACCMR0Term();
+    HMR0Term();
 #ifdef VBOX_WITH_TRIPLE_FAULT_HACK
     vmmR0TripleFaultHackTerm();
@@ -342,7 +342,7 @@
     {
         /*
-         * Init HWACCM, CPUM and PGM (Darwin only).
-         */
-        rc = HWACCMR0InitVM(pVM);
+         * Init HM, CPUM and PGM (Darwin only).
+         */
+        rc = HMR0InitVM(pVM);
         if (RT_SUCCESS(rc))
         {
@@ -370,5 +370,5 @@
             PciRawR0TermVM(pVM);
 #endif
-            HWACCMR0TermVM(pVM);
+            HMR0TermVM(pVM);
         }
     }
@@ -410,5 +410,5 @@
         PGMR0DynMapTermVM(pVM);
 #endif
-        HWACCMR0TermVM(pVM);
+        HMR0TermVM(pVM);
     }
 
@@ -603,5 +603,5 @@
             STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPendingRequest);
             break;
-        case VINF_EM_HWACCM_PATCH_TPR_INSTR:
+        case VINF_EM_HM_PATCH_TPR_INSTR:
             STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPatchTPR);
             break;
@@ -662,5 +662,5 @@
             /* Some safety precautions first. */
 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
-            if (RT_LIKELY(   !pVM->vmm.s.fSwitcherDisabled /* hwaccm */
+            if (RT_LIKELY(   !pVM->vmm.s.fSwitcherDisabled /* hm */
                           && pVM->cCpus == 1               /* !smp */
                           && PGMGetHyperCR3(pVCpu)))
@@ -683,5 +683,5 @@
                 /* We might need to disable VT-x if the active switcher turns off paging. */
                 bool fVTxDisabled;
-                int rc = HWACCMR0EnterSwitcher(pVM, pVM->vmm.s.enmSwitcher, &fVTxDisabled);
+                int rc = HMR0EnterSwitcher(pVM, pVM->vmm.s.enmSwitcher, &fVTxDisabled);
                 if (RT_SUCCESS(rc))
                 {
@@ -705,5 +705,5 @@
 
                     /* Re-enable VT-x if previously turned off. */
-                    HWACCMR0LeaveSwitcher(pVM, fVTxDisabled);
+                    HMR0LeaveSwitcher(pVM, fVTxDisabled);
 
                     if (    rc == VINF_EM_RAW_INTERRUPT
@@ -770,11 +770,11 @@
 #endif
             int rc;
-            if (!HWACCMR0SuspendPending())
+            if (!HMR0SuspendPending())
             {
-                rc = HWACCMR0Enter(pVM, pVCpu);
+                rc = HMR0Enter(pVM, pVCpu);
                 if (RT_SUCCESS(rc))
                 {
-                    rc = vmmR0CallRing3SetJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, HWACCMR0RunGuestCode, pVM, pVCpu); /* this may resume code. */
-                    int rc2 = HWACCMR0Leave(pVM, pVCpu);
+                    rc = vmmR0CallRing3SetJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, HMR0RunGuestCode, pVM, pVCpu); /* this may resume code. */
+                    int rc2 = HMR0Leave(pVM, pVCpu);
                     AssertRC(rc2);
                 }
@@ -962,8 +962,8 @@
 
         /*
-         * Attempt to enable hwacc mode and check the current setting.
+         * Attempt to enable hm mode and check the current setting.
          */
         case VMMR0_DO_HWACC_ENABLE:
-            return HWACCMR0EnableAllCpus(pVM);
+            return HMR0EnableAllCpus(pVM);
 
         /*
@@ -971,5 +971,5 @@
          */
         case VMMR0_DO_HWACC_SETUP_VM:
-            return HWACCMR0SetupVM(pVM);
+            return HMR0SetupVM(pVM);
 
         /*
@@ -981,5 +981,5 @@
             bool fVTxDisabled;
 
-            /* Safety precaution as HWACCM can disable the switcher. */
+            /* Safety precaution as HM can disable the switcher. */
             Assert(!pVM->vmm.s.fSwitcherDisabled);
             if (RT_UNLIKELY(pVM->vmm.s.fSwitcherDisabled))
@@ -999,5 +999,5 @@
 
             /* We might need to disable VT-x if the active switcher turns off paging. */
-            rc = HWACCMR0EnterSwitcher(pVM, pVM->vmm.s.enmSwitcher, &fVTxDisabled);
+            rc = HMR0EnterSwitcher(pVM, pVM->vmm.s.enmSwitcher, &fVTxDisabled);
             if (RT_FAILURE(rc))
                 return rc;
@@ -1006,5 +1006,5 @@
 
             /* Re-enable VT-x if previously turned off. */
-            HWACCMR0LeaveSwitcher(pVM, fVTxDisabled);
+            HMR0LeaveSwitcher(pVM, fVTxDisabled);
 
             /** @todo dispatch interrupts? */
@@ -1284,5 +1284,5 @@
             if (idCpu == NIL_VMCPUID)
                 return VERR_INVALID_CPU_ID;
-            return HWACCMR0TestSwitcher3264(pVM);
+            return HMR0TestSwitcher3264(pVM);
 #endif
         default:
Index: trunk/src/VBox/VMM/VMMR3/CPUM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 43387)
@@ -44,5 +44,5 @@
 #include <VBox/vmm/dbgf.h>
 #include <VBox/vmm/patm.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <VBox/vmm/ssm.h>
 #include "CPUMInternal.h"
@@ -1943,5 +1943,5 @@
      * intercept CPUID instructions for user mode applications.
      */
-    if (!HWACCMIsEnabled(pVM))
+    if (!HMIsEnabled(pVM))
     {
         /* CPUID(0) */
@@ -2510,5 +2510,5 @@
             {
                 PVMCPU      pVCpu  = &pVM->aCpus[iCpu];
-                bool const  fValid = HWACCMIsEnabled(pVM)
+                bool const  fValid = HMIsEnabled(pVM)
                                   || (   uVersion > CPUM_SAVED_STATE_VERSION_VER3_2
                                       && !(pVCpu->cpum.s.fChanged & CPUM_CHANGED_HIDDEN_SEL_REGS_INVALID));
@@ -3943,5 +3943,5 @@
             pState->pvPageGC = GCPtr & PAGE_BASE_GC_MASK;
             if (    MMHyperIsInsideArea(pState->pVM, pState->pvPageGC)
-                &&  !HWACCMIsEnabled(pState->pVM))
+                &&  !HMIsEnabled(pState->pVM))
             {
                 pState->pvPageR3 = MMHyperRCToR3(pState->pVM, (RTRCPTR)pState->pvPageGC);
Index: trunk/src/VBox/VMM/VMMR3/DBGF.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/DBGF.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/DBGF.cpp	(revision 43387)
@@ -77,5 +77,5 @@
 #endif
 #include <VBox/vmm/em.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include "DBGFInternal.h"
 #include <VBox/vmm/vm.h>
@@ -253,5 +253,5 @@
     int cWait = 10;
 # else
-    int cWait = HWACCMIsEnabled(pVM)
+    int cWait = HMIsEnabled(pVM)
              && (   enmEvent == DBGFEVENT_ASSERTION_HYPER
                  || enmEvent == DBGFEVENT_FATAL_ERROR)
Index: trunk/src/VBox/VMM/VMMR3/DBGFMem.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/DBGFMem.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/DBGFMem.cpp	(revision 43387)
@@ -24,5 +24,5 @@
 #include <VBox/vmm/pgm.h>
 #include <VBox/vmm/selm.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include "DBGFInternal.h"
 #include <VBox/vmm/vm.h>
@@ -421,5 +421,5 @@
     else
     {
-        if (HWACCMIsEnabled(pVM))
+        if (HMIsEnabled(pVM))
             rc = VERR_INVALID_STATE;
         else
Index: trunk/src/VBox/VMM/VMMR3/EM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/EM.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/EM.cpp	(revision 43387)
@@ -26,5 +26,5 @@
  *
  * The interpreted execution is only used to avoid switching between
- * raw-mode/hwaccm and the recompiler when fielding virtualization traps/faults.
+ * raw-mode/hm and the recompiler when fielding virtualization traps/faults.
  * The interpretation is thus implemented as part of EM.
  *
@@ -56,5 +56,5 @@
 #include <VBox/vmm/pdmcritsect.h>
 #include <VBox/vmm/pdmqueue.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <VBox/vmm/patm.h>
 #ifdef IEM_VERIFICATION_MODE
@@ -80,5 +80,5 @@
 *******************************************************************************/
 #if 0 /* Disabled till after 2.1.0 when we've time to test it. */
-#define EM_NOTIFY_HWACCM
+#define EM_NOTIFY_HM
 #endif
 
@@ -632,5 +632,5 @@
 
     /*
-     * Force rescheduling if in RAW, HWACCM or REM.
+     * Force rescheduling if in RAW, HM or REM.
      */
     return    pVCpu->em.s.enmState == EMSTATE_RAW
@@ -1187,5 +1187,5 @@
 
     X86EFLAGS EFlags = pCtx->eflags;
-    if (HWACCMIsEnabled(pVM))
+    if (HMIsEnabled(pVM))
     {
         /*
@@ -1196,5 +1196,5 @@
          */
         if (   EMIsHwVirtExecutionEnabled(pVM)
-            && HWACCMR3CanExecuteGuest(pVM, pCtx))
+            && HMR3CanExecuteGuest(pVM, pCtx))
             return EMSTATE_HWACC;
 
@@ -1689,5 +1689,5 @@
             &&  !TRPMHasTrap(pVCpu) /* an interrupt could already be scheduled for dispatching in the recompiler. */
             &&  PATMAreInterruptsEnabled(pVM)
-            &&  !HWACCMR3IsEventPending(pVCpu))
+            &&  !HMR3IsEventPending(pVCpu))
         {
             Assert(pVCpu->em.s.enmState != EMSTATE_WAIT_SIPI);
Index: trunk/src/VBox/VMM/VMMR3/EMHM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/EMHM.cpp	(revision 43387)
+++ trunk/src/VBox/VMM/VMMR3/EMHM.cpp	(revision 43387)
@@ -0,0 +1,602 @@
+/* $Id$ */
+/** @file
+ * EM - Execution Monitor / Manager - hardware virtualization
+ */
+
+/*
+ * 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;
+ * 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.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_EM
+#include <VBox/vmm/em.h>
+#include <VBox/vmm/vmm.h>
+#include <VBox/vmm/csam.h>
+#include <VBox/vmm/selm.h>
+#include <VBox/vmm/trpm.h>
+#include <VBox/vmm/iem.h>
+#include <VBox/vmm/iom.h>
+#include <VBox/vmm/dbgf.h>
+#include <VBox/vmm/pgm.h>
+#ifdef VBOX_WITH_REM
+# include <VBox/vmm/rem.h>
+#endif
+#include <VBox/vmm/tm.h>
+#include <VBox/vmm/mm.h>
+#include <VBox/vmm/ssm.h>
+#include <VBox/vmm/pdmapi.h>
+#include <VBox/vmm/pdmcritsect.h>
+#include <VBox/vmm/pdmqueue.h>
+#include <VBox/vmm/hm.h>
+#include "EMInternal.h"
+#include "internal/em.h"
+#include <VBox/vmm/vm.h>
+#include <VBox/vmm/cpumdis.h>
+#include <VBox/dis.h>
+#include <VBox/disopcode.h>
+#include <VBox/vmm/dbgf.h>
+#include "VMMTracing.h"
+
+#include <iprt/asm.h>
+
+
+/*******************************************************************************
+*   Defined Constants And Macros                                               *
+*******************************************************************************/
+#if 0 /* Disabled till after 2.1.0 when we've time to test it. */
+#define EM_NOTIFY_HM
+#endif
+
+
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
+DECLINLINE(int) emR3ExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC = VINF_SUCCESS);
+static int emR3ExecuteIOInstruction(PVM pVM, PVMCPU pVCpu);
+static int emR3HwaccmForcedActions(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+
+#define EMHANDLERC_WITH_HM
+#include "EMHandleRCTmpl.h"
+
+
+#if defined(DEBUG) && defined(SOME_UNUSED_FUNCTIONS)
+
+/**
+ * Steps hardware accelerated mode.
+ *
+ * @returns VBox status code.
+ * @param   pVM     Pointer to the VM.
+ * @param   pVCpu   Pointer to the VMCPU.
+ */
+static int emR3HwAccStep(PVM pVM, PVMCPU pVCpu)
+{
+    Assert(pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_HWACC);
+
+    int         rc;
+    PCPUMCTX    pCtx   = pVCpu->em.s.pCtx;
+    VMCPU_FF_CLEAR(pVCpu, (VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_TSS));
+
+    /*
+     * Check vital forced actions, but ignore pending interrupts and timers.
+     */
+    if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK)
+        ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
+    {
+        rc = emR3HwaccmForcedActions(pVM, pVCpu, pCtx);
+        if (rc != VINF_SUCCESS)
+            return rc;
+    }
+    /*
+     * Set flags for single stepping.
+     */
+    CPUMSetGuestEFlags(pVCpu, CPUMGetGuestEFlags(pVCpu) | X86_EFL_TF | X86_EFL_RF);
+
+    /*
+     * Single step.
+     * We do not start time or anything, if anything we should just do a few nanoseconds.
+     */
+    do
+    {
+        rc = VMMR3HwAccRunGC(pVM, pVCpu);
+    } while (   rc == VINF_SUCCESS
+             || rc == VINF_EM_RAW_INTERRUPT);
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK);
+
+    /*
+     * Make sure the trap flag is cleared.
+     * (Too bad if the guest is trying to single step too.)
+     */
+    CPUMSetGuestEFlags(pVCpu, CPUMGetGuestEFlags(pVCpu) & ~X86_EFL_TF);
+
+    /*
+     * Deal with the return codes.
+     */
+    rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
+    rc = emR3HwaccmHandleRC(pVM, pVCpu, pCtx, rc);
+    return rc;
+}
+
+
+static int emR3SingleStepExecHwAcc(PVM pVM, PVMCPU pVCpu, uint32_t cIterations)
+{
+    int     rc          = VINF_SUCCESS;
+    EMSTATE enmOldState = pVCpu->em.s.enmState;
+    pVCpu->em.s.enmState  = EMSTATE_DEBUG_GUEST_HWACC;
+
+    Log(("Single step BEGIN:\n"));
+    for (uint32_t i = 0; i < cIterations; i++)
+    {
+        DBGFR3PrgStep(pVCpu);
+        DBGFR3DisasInstrCurrentLog(pVCpu, "RSS: ");
+        rc = emR3HwAccStep(pVM, pVCpu);
+        if (    rc != VINF_SUCCESS
+            ||  !HMR3CanExecuteGuest(pVM, pVCpu->em.s.pCtx))
+            break;
+    }
+    Log(("Single step END: rc=%Rrc\n", rc));
+    CPUMSetGuestEFlags(pVCpu, CPUMGetGuestEFlags(pVCpu) & ~X86_EFL_TF);
+    pVCpu->em.s.enmState = enmOldState;
+    return rc == VINF_SUCCESS ? VINF_EM_RESCHEDULE_REM : rc;
+}
+
+#endif /* DEBUG */
+
+
+/**
+ * Executes one (or perhaps a few more) instruction(s).
+ *
+ * @returns VBox status code suitable for EM.
+ *
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   rcRC        Return code from RC.
+ * @param   pszPrefix   Disassembly prefix. If not NULL we'll disassemble the
+ *                      instruction and prefix the log output with this text.
+ */
+#ifdef LOG_ENABLED
+static int emR3ExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcRC, const char *pszPrefix)
+#else
+static int emR3ExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcRC)
+#endif
+{
+#ifdef LOG_ENABLED
+    PCPUMCTX pCtx = pVCpu->em.s.pCtx;
+#endif
+    int      rc;
+    NOREF(rcRC);
+
+    /*
+     *
+     * The simple solution is to use the recompiler.
+     * The better solution is to disassemble the current instruction and
+     * try handle as many as possible without using REM.
+     *
+     */
+
+#ifdef LOG_ENABLED
+    /*
+     * Disassemble the instruction if requested.
+     */
+    if (pszPrefix)
+    {
+        DBGFR3InfoLog(pVM, "cpumguest", pszPrefix);
+        DBGFR3DisasInstrCurrentLog(pVCpu, pszPrefix);
+    }
+#endif /* LOG_ENABLED */
+
+#if 0
+    /* Try our own instruction emulator before falling back to the recompiler. */
+    DISCPUSTATE Cpu;
+    rc = CPUMR3DisasmInstrCPU(pVM, pVCpu, pCtx, pCtx->rip, &Cpu, "GEN EMU");
+    if (RT_SUCCESS(rc))
+    {
+        switch (Cpu.pCurInstr->uOpcode)
+        {
+        /* @todo we can do more now */
+        case OP_MOV:
+        case OP_AND:
+        case OP_OR:
+        case OP_XOR:
+        case OP_POP:
+        case OP_INC:
+        case OP_DEC:
+        case OP_XCHG:
+            STAM_PROFILE_START(&pVCpu->em.s.StatMiscEmu, a);
+            rc = EMInterpretInstructionCpuUpdtPC(pVM, pVCpu, &Cpu, CPUMCTX2CORE(pCtx), 0);
+            if (RT_SUCCESS(rc))
+            {
+#ifdef EM_NOTIFY_HM
+                if (pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_HWACC)
+                    HMR3NotifyEmulated(pVCpu);
+#endif
+                STAM_PROFILE_STOP(&pVCpu->em.s.StatMiscEmu, a);
+                return rc;
+            }
+            if (rc != VERR_EM_INTERPRETER)
+                AssertMsgFailedReturn(("rc=%Rrc\n", rc), rc);
+            STAM_PROFILE_STOP(&pVCpu->em.s.StatMiscEmu, a);
+            break;
+        }
+    }
+#endif /* 0 */
+    STAM_PROFILE_START(&pVCpu->em.s.StatREMEmu, a);
+    Log(("EMINS: %04x:%RGv RSP=%RGv\n", pCtx->cs.Sel, (RTGCPTR)pCtx->rip, (RTGCPTR)pCtx->rsp));
+#ifdef VBOX_WITH_REM
+    EMRemLock(pVM);
+    /* Flush the recompiler TLB if the VCPU has changed. */
+    if (pVM->em.s.idLastRemCpu != pVCpu->idCpu)
+        CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_ALL);
+    pVM->em.s.idLastRemCpu = pVCpu->idCpu;
+
+    rc = REMR3EmulateInstruction(pVM, pVCpu);
+    EMRemUnlock(pVM);
+#else
+    rc = VBOXSTRICTRC_TODO(IEMExecOne(pVCpu)); NOREF(pVM);
+#endif
+    STAM_PROFILE_STOP(&pVCpu->em.s.StatREMEmu, a);
+
+#ifdef EM_NOTIFY_HM
+    if (pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_HWACC)
+        HMR3NotifyEmulated(pVCpu);
+#endif
+    return rc;
+}
+
+
+/**
+ * Executes one (or perhaps a few more) instruction(s).
+ * This is just a wrapper for discarding pszPrefix in non-logging builds.
+ *
+ * @returns VBox status code suitable for EM.
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   pszPrefix   Disassembly prefix. If not NULL we'll disassemble the
+ *                      instruction and prefix the log output with this text.
+ * @param   rcGC        GC return code
+ */
+DECLINLINE(int) emR3ExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC)
+{
+#ifdef LOG_ENABLED
+    return emR3ExecuteInstructionWorker(pVM, pVCpu, rcGC, pszPrefix);
+#else
+    return emR3ExecuteInstructionWorker(pVM, pVCpu, rcGC);
+#endif
+}
+
+/**
+ * Executes one (or perhaps a few more) IO instruction(s).
+ *
+ * @returns VBox status code suitable for EM.
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ */
+static int emR3ExecuteIOInstruction(PVM pVM, PVMCPU pVCpu)
+{
+    PCPUMCTX pCtx = pVCpu->em.s.pCtx;
+
+    STAM_PROFILE_START(&pVCpu->em.s.StatIOEmu, a);
+
+    /* Try to restart the io instruction that was refused in ring-0. */
+    VBOXSTRICTRC rcStrict = HMR3RestartPendingIOInstr(pVM, pVCpu, pCtx);
+    if (IOM_SUCCESS(rcStrict))
+    {
+        STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatIoRestarted);
+        STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
+        return VBOXSTRICTRC_TODO(rcStrict);     /* rip already updated. */
+    }
+    AssertMsgReturn(rcStrict == VERR_NOT_FOUND, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)),
+                    RT_SUCCESS_NP(rcStrict) ? VERR_IPE_UNEXPECTED_INFO_STATUS : VBOXSTRICTRC_TODO(rcStrict));
+
+    /** @todo probably we should fall back to the recompiler; otherwise we'll go back and forth between HC & GC
+     *   as io instructions tend to come in packages of more than one
+     */
+    DISCPUSTATE Cpu;
+    int rc2 = CPUMR3DisasmInstrCPU(pVM, pVCpu, pCtx, pCtx->rip, &Cpu, "IO EMU");
+    if (RT_SUCCESS(rc2))
+    {
+        rcStrict = VINF_EM_RAW_EMULATE_INSTR;
+
+        if (!(Cpu.fPrefix & (DISPREFIX_REP | DISPREFIX_REPNE)))
+        {
+            switch (Cpu.pCurInstr->uOpcode)
+            {
+                case OP_IN:
+                {
+                    STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatIn);
+                    rcStrict = IOMInterpretIN(pVM, CPUMCTX2CORE(pCtx), &Cpu);
+                    break;
+                }
+
+                case OP_OUT:
+                {
+                    STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatOut);
+                    rcStrict = IOMInterpretOUT(pVM, CPUMCTX2CORE(pCtx), &Cpu);
+                    break;
+                }
+            }
+        }
+        else if (Cpu.fPrefix & DISPREFIX_REP)
+        {
+            switch (Cpu.pCurInstr->uOpcode)
+            {
+                case OP_INSB:
+                case OP_INSWD:
+                {
+                    STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatIn);
+                    rcStrict = IOMInterpretINS(pVM, CPUMCTX2CORE(pCtx), &Cpu);
+                    break;
+                }
+
+                case OP_OUTSB:
+                case OP_OUTSWD:
+                {
+                    STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatOut);
+                    rcStrict = IOMInterpretOUTS(pVM, CPUMCTX2CORE(pCtx), &Cpu);
+                    break;
+                }
+            }
+        }
+
+        /*
+         * Handled the I/O return codes.
+         * (The unhandled cases end up with rcStrict == VINF_EM_RAW_EMULATE_INSTR.)
+         */
+        if (IOM_SUCCESS(rcStrict))
+        {
+            pCtx->rip += Cpu.cbInstr;
+            STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
+            return VBOXSTRICTRC_TODO(rcStrict);
+        }
+
+        if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
+        {
+            /* The active trap will be dispatched. */
+            Assert(TRPMHasTrap(pVCpu));
+            STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
+            return VINF_SUCCESS;
+        }
+        AssertMsg(rcStrict != VINF_TRPM_XCPT_DISPATCHED, ("Handle VINF_TRPM_XCPT_DISPATCHED\n"));
+
+        if (RT_FAILURE(rcStrict))
+        {
+            STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
+            return VBOXSTRICTRC_TODO(rcStrict);
+        }
+        AssertMsg(rcStrict == VINF_EM_RAW_EMULATE_INSTR || rcStrict == VINF_EM_RESCHEDULE_REM, ("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
+    }
+
+    STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
+    return emR3ExecuteInstruction(pVM, pVCpu, "IO: ");
+}
+
+
+/**
+ * Process raw-mode specific forced actions.
+ *
+ * This function is called when any FFs in the VM_FF_HIGH_PRIORITY_PRE_RAW_MASK is pending.
+ *
+ * @returns VBox status code. May return VINF_EM_NO_MEMORY but none of the other
+ *          EM statuses.
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   pCtx        Pointer to the guest CPU context.
+ */
+static int emR3HwaccmForcedActions(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+    /*
+     * Sync page directory.
+     */
+    if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL))
+    {
+        Assert(pVCpu->em.s.enmState != EMSTATE_WAIT_SIPI);
+        int rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
+        if (RT_FAILURE(rc))
+            return rc;
+
+        Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT));
+
+        /* Prefetch pages for EIP and ESP. */
+        /** @todo This is rather expensive. Should investigate if it really helps at all. */
+        rc = PGMPrefetchPage(pVCpu, SELMToFlat(pVM, DISSELREG_CS, CPUMCTX2CORE(pCtx), pCtx->rip));
+        if (rc == VINF_SUCCESS)
+            rc = PGMPrefetchPage(pVCpu, SELMToFlat(pVM, DISSELREG_SS, CPUMCTX2CORE(pCtx), pCtx->rsp));
+        if (rc != VINF_SUCCESS)
+        {
+            if (rc != VINF_PGM_SYNC_CR3)
+            {
+                AssertLogRelMsgReturn(RT_FAILURE(rc), ("%Rrc\n", rc), VERR_IPE_UNEXPECTED_INFO_STATUS);
+                return rc;
+            }
+            rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
+            if (RT_FAILURE(rc))
+                return rc;
+        }
+        /** @todo maybe prefetch the supervisor stack page as well */
+        Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT));
+    }
+
+    /*
+     * Allocate handy pages (just in case the above actions have consumed some pages).
+     */
+    if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_PGM_NEED_HANDY_PAGES, VM_FF_PGM_NO_MEMORY))
+    {
+        int rc = PGMR3PhysAllocateHandyPages(pVM);
+        if (RT_FAILURE(rc))
+            return rc;
+    }
+
+    /*
+     * Check whether we're out of memory now.
+     *
+     * This may stem from some of the above actions or operations that has been executed
+     * since we ran FFs. The allocate handy pages must for instance always be followed by
+     * this check.
+     */
+    if (VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY))
+        return VINF_EM_NO_MEMORY;
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Executes hardware accelerated raw code. (Intel VT-x & AMD-V)
+ *
+ * This function contains the raw-mode version of the inner
+ * execution loop (the outer loop being in EMR3ExecuteVM()).
+ *
+ * @returns VBox status code. The most important ones are: VINF_EM_RESCHEDULE, VINF_EM_RESCHEDULE_RAW,
+ *          VINF_EM_RESCHEDULE_REM, VINF_EM_SUSPEND, VINF_EM_RESET and VINF_EM_TERMINATE.
+ *
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   pfFFDone    Where to store an indicator telling whether or not
+ *                      FFs were done before returning.
+ */
+int emR3HwAccExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone)
+{
+    int      rc = VERR_IPE_UNINITIALIZED_STATUS;
+    PCPUMCTX pCtx = pVCpu->em.s.pCtx;
+
+    LogFlow(("emR3HwAccExecute%d: (cs:eip=%04x:%RGv)\n", pVCpu->idCpu, pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
+    *pfFFDone = false;
+
+    STAM_COUNTER_INC(&pVCpu->em.s.StatHwAccExecuteEntry);
+
+#ifdef EM_NOTIFY_HM
+    HMR3NotifyScheduled(pVCpu);
+#endif
+
+    /*
+     * Spin till we get a forced action which returns anything but VINF_SUCCESS.
+     */
+    for (;;)
+    {
+        STAM_PROFILE_ADV_START(&pVCpu->em.s.StatHwAccEntry, a);
+
+        /* Check if a forced reschedule is pending. */
+        if (HMR3IsRescheduleRequired(pVM, pCtx))
+        {
+            rc = VINF_EM_RESCHEDULE;
+            break;
+        }
+
+        /*
+         * Process high priority pre-execution raw-mode FFs.
+         */
+        VMCPU_FF_CLEAR(pVCpu, (VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_TSS)); /* not relevant in HM mode; shouldn't be set really. */
+        if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
+        {
+            rc = emR3HwaccmForcedActions(pVM, pVCpu, pCtx);
+            if (rc != VINF_SUCCESS)
+                break;
+        }
+
+#ifdef LOG_ENABLED
+        /*
+         * Log important stuff before entering GC.
+         */
+        if (TRPMHasTrap(pVCpu))
+            Log(("CPU%d: Pending hardware interrupt=0x%x cs:rip=%04X:%RGv\n", pVCpu->idCpu, TRPMGetTrapNo(pVCpu), pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
+
+        uint32_t cpl = CPUMGetGuestCPL(pVCpu);
+
+        if (pVM->cCpus == 1)
+        {
+            if (pCtx->eflags.Bits.u1VM)
+                Log(("HWV86: %08X IF=%d\n", pCtx->eip, pCtx->eflags.Bits.u1IF));
+            else if (CPUMIsGuestIn64BitCodeEx(pCtx))
+                Log(("HWR%d: %04X:%RGv ESP=%RGv IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pCtx->cs.Sel, (RTGCPTR)pCtx->rip, pCtx->rsp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER));
+            else
+                Log(("HWR%d: %04X:%08X ESP=%08X IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pCtx->cs.Sel,          pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER));
+        }
+        else
+        {
+            if (pCtx->eflags.Bits.u1VM)
+                Log(("HWV86-CPU%d: %08X IF=%d\n", pVCpu->idCpu, pCtx->eip, pCtx->eflags.Bits.u1IF));
+            else if (CPUMIsGuestIn64BitCodeEx(pCtx))
+                Log(("HWR%d-CPU%d: %04X:%RGv ESP=%RGv IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pVCpu->idCpu, pCtx->cs.Sel, (RTGCPTR)pCtx->rip, pCtx->rsp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER));
+            else
+                Log(("HWR%d-CPU%d: %04X:%08X ESP=%08X IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pVCpu->idCpu, pCtx->cs.Sel,          pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER));
+        }
+#endif /* LOG_ENABLED */
+
+        /*
+         * Execute the code.
+         */
+        STAM_PROFILE_ADV_STOP(&pVCpu->em.s.StatHwAccEntry, a);
+
+        if (RT_LIKELY(EMR3IsExecutionAllowed(pVM, pVCpu)))
+        {
+            STAM_PROFILE_START(&pVCpu->em.s.StatHwAccExec, x);
+            rc = VMMR3HwAccRunGC(pVM, pVCpu);
+            STAM_PROFILE_STOP(&pVCpu->em.s.StatHwAccExec, x);
+        }
+        else
+        {
+            /* Give up this time slice; virtual time continues */
+            STAM_REL_PROFILE_ADV_START(&pVCpu->em.s.StatCapped, u);
+            RTThreadSleep(5);
+            STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatCapped, u);
+            rc = VINF_SUCCESS;
+        }
+
+
+        /*
+         * Deal with high priority post execution FFs before doing anything else.
+         */
+        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK);
+        if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
+            rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
+
+        /*
+         * Process the returned status code.
+         */
+        if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
+            break;
+
+        rc = emR3HwaccmHandleRC(pVM, pVCpu, pCtx, rc);
+        if (rc != VINF_SUCCESS)
+            break;
+
+        /*
+         * Check and execute forced actions.
+         */
+#ifdef VBOX_HIGH_RES_TIMERS_HACK
+        TMTimerPollVoid(pVM, pVCpu);
+#endif
+        if (    VM_FF_ISPENDING(pVM, VM_FF_ALL_MASK)
+            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_MASK))
+        {
+            rc = emR3ForcedActions(pVM, pVCpu, rc);
+            VBOXVMM_EM_FF_ALL_RET(pVCpu, rc);
+            if (    rc != VINF_SUCCESS
+                &&  rc != VINF_EM_RESCHEDULE_HWACC)
+            {
+                *pfFFDone = true;
+                break;
+            }
+        }
+    }
+
+    /*
+     * Return to outer loop.
+     */
+#if defined(LOG_ENABLED) && defined(DEBUG)
+    RTLogFlush(NULL);
+#endif
+    return rc;
+}
+
Index: trunk/src/VBox/VMM/VMMR3/EMHwaccm.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/EMHwaccm.cpp	(revision 43379)
+++ 	(revision )
@@ -1,602 +1,0 @@
-/* $Id$ */
-/** @file
- * EM - Execution Monitor / Manager - hardware virtualization
- */
-
-/*
- * 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;
- * 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.
- */
-
-/*******************************************************************************
-*   Header Files                                                               *
-*******************************************************************************/
-#define LOG_GROUP LOG_GROUP_EM
-#include <VBox/vmm/em.h>
-#include <VBox/vmm/vmm.h>
-#include <VBox/vmm/csam.h>
-#include <VBox/vmm/selm.h>
-#include <VBox/vmm/trpm.h>
-#include <VBox/vmm/iem.h>
-#include <VBox/vmm/iom.h>
-#include <VBox/vmm/dbgf.h>
-#include <VBox/vmm/pgm.h>
-#ifdef VBOX_WITH_REM
-# include <VBox/vmm/rem.h>
-#endif
-#include <VBox/vmm/tm.h>
-#include <VBox/vmm/mm.h>
-#include <VBox/vmm/ssm.h>
-#include <VBox/vmm/pdmapi.h>
-#include <VBox/vmm/pdmcritsect.h>
-#include <VBox/vmm/pdmqueue.h>
-#include <VBox/vmm/hwaccm.h>
-#include "EMInternal.h"
-#include "internal/em.h"
-#include <VBox/vmm/vm.h>
-#include <VBox/vmm/cpumdis.h>
-#include <VBox/dis.h>
-#include <VBox/disopcode.h>
-#include <VBox/vmm/dbgf.h>
-#include "VMMTracing.h"
-
-#include <iprt/asm.h>
-
-
-/*******************************************************************************
-*   Defined Constants And Macros                                               *
-*******************************************************************************/
-#if 0 /* Disabled till after 2.1.0 when we've time to test it. */
-#define EM_NOTIFY_HWACCM
-#endif
-
-
-/*******************************************************************************
-*   Internal Functions                                                         *
-*******************************************************************************/
-DECLINLINE(int) emR3ExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC = VINF_SUCCESS);
-static int emR3ExecuteIOInstruction(PVM pVM, PVMCPU pVCpu);
-static int emR3HwaccmForcedActions(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-
-#define EMHANDLERC_WITH_HWACCM
-#include "EMHandleRCTmpl.h"
-
-
-#if defined(DEBUG) && defined(SOME_UNUSED_FUNCTIONS)
-
-/**
- * Steps hardware accelerated mode.
- *
- * @returns VBox status code.
- * @param   pVM     Pointer to the VM.
- * @param   pVCpu   Pointer to the VMCPU.
- */
-static int emR3HwAccStep(PVM pVM, PVMCPU pVCpu)
-{
-    Assert(pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_HWACC);
-
-    int         rc;
-    PCPUMCTX    pCtx   = pVCpu->em.s.pCtx;
-    VMCPU_FF_CLEAR(pVCpu, (VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_TSS));
-
-    /*
-     * Check vital forced actions, but ignore pending interrupts and timers.
-     */
-    if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK)
-        ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
-    {
-        rc = emR3HwaccmForcedActions(pVM, pVCpu, pCtx);
-        if (rc != VINF_SUCCESS)
-            return rc;
-    }
-    /*
-     * Set flags for single stepping.
-     */
-    CPUMSetGuestEFlags(pVCpu, CPUMGetGuestEFlags(pVCpu) | X86_EFL_TF | X86_EFL_RF);
-
-    /*
-     * Single step.
-     * We do not start time or anything, if anything we should just do a few nanoseconds.
-     */
-    do
-    {
-        rc = VMMR3HwAccRunGC(pVM, pVCpu);
-    } while (   rc == VINF_SUCCESS
-             || rc == VINF_EM_RAW_INTERRUPT);
-    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK);
-
-    /*
-     * Make sure the trap flag is cleared.
-     * (Too bad if the guest is trying to single step too.)
-     */
-    CPUMSetGuestEFlags(pVCpu, CPUMGetGuestEFlags(pVCpu) & ~X86_EFL_TF);
-
-    /*
-     * Deal with the return codes.
-     */
-    rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
-    rc = emR3HwaccmHandleRC(pVM, pVCpu, pCtx, rc);
-    return rc;
-}
-
-
-static int emR3SingleStepExecHwAcc(PVM pVM, PVMCPU pVCpu, uint32_t cIterations)
-{
-    int     rc          = VINF_SUCCESS;
-    EMSTATE enmOldState = pVCpu->em.s.enmState;
-    pVCpu->em.s.enmState  = EMSTATE_DEBUG_GUEST_HWACC;
-
-    Log(("Single step BEGIN:\n"));
-    for (uint32_t i = 0; i < cIterations; i++)
-    {
-        DBGFR3PrgStep(pVCpu);
-        DBGFR3DisasInstrCurrentLog(pVCpu, "RSS: ");
-        rc = emR3HwAccStep(pVM, pVCpu);
-        if (    rc != VINF_SUCCESS
-            ||  !HWACCMR3CanExecuteGuest(pVM, pVCpu->em.s.pCtx))
-            break;
-    }
-    Log(("Single step END: rc=%Rrc\n", rc));
-    CPUMSetGuestEFlags(pVCpu, CPUMGetGuestEFlags(pVCpu) & ~X86_EFL_TF);
-    pVCpu->em.s.enmState = enmOldState;
-    return rc == VINF_SUCCESS ? VINF_EM_RESCHEDULE_REM : rc;
-}
-
-#endif /* DEBUG */
-
-
-/**
- * Executes one (or perhaps a few more) instruction(s).
- *
- * @returns VBox status code suitable for EM.
- *
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   rcRC        Return code from RC.
- * @param   pszPrefix   Disassembly prefix. If not NULL we'll disassemble the
- *                      instruction and prefix the log output with this text.
- */
-#ifdef LOG_ENABLED
-static int emR3ExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcRC, const char *pszPrefix)
-#else
-static int emR3ExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcRC)
-#endif
-{
-#ifdef LOG_ENABLED
-    PCPUMCTX pCtx = pVCpu->em.s.pCtx;
-#endif
-    int      rc;
-    NOREF(rcRC);
-
-    /*
-     *
-     * The simple solution is to use the recompiler.
-     * The better solution is to disassemble the current instruction and
-     * try handle as many as possible without using REM.
-     *
-     */
-
-#ifdef LOG_ENABLED
-    /*
-     * Disassemble the instruction if requested.
-     */
-    if (pszPrefix)
-    {
-        DBGFR3InfoLog(pVM, "cpumguest", pszPrefix);
-        DBGFR3DisasInstrCurrentLog(pVCpu, pszPrefix);
-    }
-#endif /* LOG_ENABLED */
-
-#if 0
-    /* Try our own instruction emulator before falling back to the recompiler. */
-    DISCPUSTATE Cpu;
-    rc = CPUMR3DisasmInstrCPU(pVM, pVCpu, pCtx, pCtx->rip, &Cpu, "GEN EMU");
-    if (RT_SUCCESS(rc))
-    {
-        switch (Cpu.pCurInstr->uOpcode)
-        {
-        /* @todo we can do more now */
-        case OP_MOV:
-        case OP_AND:
-        case OP_OR:
-        case OP_XOR:
-        case OP_POP:
-        case OP_INC:
-        case OP_DEC:
-        case OP_XCHG:
-            STAM_PROFILE_START(&pVCpu->em.s.StatMiscEmu, a);
-            rc = EMInterpretInstructionCpuUpdtPC(pVM, pVCpu, &Cpu, CPUMCTX2CORE(pCtx), 0);
-            if (RT_SUCCESS(rc))
-            {
-#ifdef EM_NOTIFY_HWACCM
-                if (pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_HWACC)
-                    HWACCMR3NotifyEmulated(pVCpu);
-#endif
-                STAM_PROFILE_STOP(&pVCpu->em.s.StatMiscEmu, a);
-                return rc;
-            }
-            if (rc != VERR_EM_INTERPRETER)
-                AssertMsgFailedReturn(("rc=%Rrc\n", rc), rc);
-            STAM_PROFILE_STOP(&pVCpu->em.s.StatMiscEmu, a);
-            break;
-        }
-    }
-#endif /* 0 */
-    STAM_PROFILE_START(&pVCpu->em.s.StatREMEmu, a);
-    Log(("EMINS: %04x:%RGv RSP=%RGv\n", pCtx->cs.Sel, (RTGCPTR)pCtx->rip, (RTGCPTR)pCtx->rsp));
-#ifdef VBOX_WITH_REM
-    EMRemLock(pVM);
-    /* Flush the recompiler TLB if the VCPU has changed. */
-    if (pVM->em.s.idLastRemCpu != pVCpu->idCpu)
-        CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_ALL);
-    pVM->em.s.idLastRemCpu = pVCpu->idCpu;
-
-    rc = REMR3EmulateInstruction(pVM, pVCpu);
-    EMRemUnlock(pVM);
-#else
-    rc = VBOXSTRICTRC_TODO(IEMExecOne(pVCpu)); NOREF(pVM);
-#endif
-    STAM_PROFILE_STOP(&pVCpu->em.s.StatREMEmu, a);
-
-#ifdef EM_NOTIFY_HWACCM
-    if (pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_HWACC)
-        HWACCMR3NotifyEmulated(pVCpu);
-#endif
-    return rc;
-}
-
-
-/**
- * Executes one (or perhaps a few more) instruction(s).
- * This is just a wrapper for discarding pszPrefix in non-logging builds.
- *
- * @returns VBox status code suitable for EM.
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   pszPrefix   Disassembly prefix. If not NULL we'll disassemble the
- *                      instruction and prefix the log output with this text.
- * @param   rcGC        GC return code
- */
-DECLINLINE(int) emR3ExecuteInstruction(PVM pVM, PVMCPU pVCpu, const char *pszPrefix, int rcGC)
-{
-#ifdef LOG_ENABLED
-    return emR3ExecuteInstructionWorker(pVM, pVCpu, rcGC, pszPrefix);
-#else
-    return emR3ExecuteInstructionWorker(pVM, pVCpu, rcGC);
-#endif
-}
-
-/**
- * Executes one (or perhaps a few more) IO instruction(s).
- *
- * @returns VBox status code suitable for EM.
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- */
-static int emR3ExecuteIOInstruction(PVM pVM, PVMCPU pVCpu)
-{
-    PCPUMCTX pCtx = pVCpu->em.s.pCtx;
-
-    STAM_PROFILE_START(&pVCpu->em.s.StatIOEmu, a);
-
-    /* Try to restart the io instruction that was refused in ring-0. */
-    VBOXSTRICTRC rcStrict = HWACCMR3RestartPendingIOInstr(pVM, pVCpu, pCtx);
-    if (IOM_SUCCESS(rcStrict))
-    {
-        STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatIoRestarted);
-        STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
-        return VBOXSTRICTRC_TODO(rcStrict);     /* rip already updated. */
-    }
-    AssertMsgReturn(rcStrict == VERR_NOT_FOUND, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)),
-                    RT_SUCCESS_NP(rcStrict) ? VERR_IPE_UNEXPECTED_INFO_STATUS : VBOXSTRICTRC_TODO(rcStrict));
-
-    /** @todo probably we should fall back to the recompiler; otherwise we'll go back and forth between HC & GC
-     *   as io instructions tend to come in packages of more than one
-     */
-    DISCPUSTATE Cpu;
-    int rc2 = CPUMR3DisasmInstrCPU(pVM, pVCpu, pCtx, pCtx->rip, &Cpu, "IO EMU");
-    if (RT_SUCCESS(rc2))
-    {
-        rcStrict = VINF_EM_RAW_EMULATE_INSTR;
-
-        if (!(Cpu.fPrefix & (DISPREFIX_REP | DISPREFIX_REPNE)))
-        {
-            switch (Cpu.pCurInstr->uOpcode)
-            {
-                case OP_IN:
-                {
-                    STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatIn);
-                    rcStrict = IOMInterpretIN(pVM, CPUMCTX2CORE(pCtx), &Cpu);
-                    break;
-                }
-
-                case OP_OUT:
-                {
-                    STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatOut);
-                    rcStrict = IOMInterpretOUT(pVM, CPUMCTX2CORE(pCtx), &Cpu);
-                    break;
-                }
-            }
-        }
-        else if (Cpu.fPrefix & DISPREFIX_REP)
-        {
-            switch (Cpu.pCurInstr->uOpcode)
-            {
-                case OP_INSB:
-                case OP_INSWD:
-                {
-                    STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatIn);
-                    rcStrict = IOMInterpretINS(pVM, CPUMCTX2CORE(pCtx), &Cpu);
-                    break;
-                }
-
-                case OP_OUTSB:
-                case OP_OUTSWD:
-                {
-                    STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatOut);
-                    rcStrict = IOMInterpretOUTS(pVM, CPUMCTX2CORE(pCtx), &Cpu);
-                    break;
-                }
-            }
-        }
-
-        /*
-         * Handled the I/O return codes.
-         * (The unhandled cases end up with rcStrict == VINF_EM_RAW_EMULATE_INSTR.)
-         */
-        if (IOM_SUCCESS(rcStrict))
-        {
-            pCtx->rip += Cpu.cbInstr;
-            STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
-            return VBOXSTRICTRC_TODO(rcStrict);
-        }
-
-        if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
-        {
-            /* The active trap will be dispatched. */
-            Assert(TRPMHasTrap(pVCpu));
-            STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
-            return VINF_SUCCESS;
-        }
-        AssertMsg(rcStrict != VINF_TRPM_XCPT_DISPATCHED, ("Handle VINF_TRPM_XCPT_DISPATCHED\n"));
-
-        if (RT_FAILURE(rcStrict))
-        {
-            STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
-            return VBOXSTRICTRC_TODO(rcStrict);
-        }
-        AssertMsg(rcStrict == VINF_EM_RAW_EMULATE_INSTR || rcStrict == VINF_EM_RESCHEDULE_REM, ("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
-    }
-
-    STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);
-    return emR3ExecuteInstruction(pVM, pVCpu, "IO: ");
-}
-
-
-/**
- * Process raw-mode specific forced actions.
- *
- * This function is called when any FFs in the VM_FF_HIGH_PRIORITY_PRE_RAW_MASK is pending.
- *
- * @returns VBox status code. May return VINF_EM_NO_MEMORY but none of the other
- *          EM statuses.
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   pCtx        Pointer to the guest CPU context.
- */
-static int emR3HwaccmForcedActions(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
-    /*
-     * Sync page directory.
-     */
-    if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL))
-    {
-        Assert(pVCpu->em.s.enmState != EMSTATE_WAIT_SIPI);
-        int rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
-        if (RT_FAILURE(rc))
-            return rc;
-
-        Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT));
-
-        /* Prefetch pages for EIP and ESP. */
-        /** @todo This is rather expensive. Should investigate if it really helps at all. */
-        rc = PGMPrefetchPage(pVCpu, SELMToFlat(pVM, DISSELREG_CS, CPUMCTX2CORE(pCtx), pCtx->rip));
-        if (rc == VINF_SUCCESS)
-            rc = PGMPrefetchPage(pVCpu, SELMToFlat(pVM, DISSELREG_SS, CPUMCTX2CORE(pCtx), pCtx->rsp));
-        if (rc != VINF_SUCCESS)
-        {
-            if (rc != VINF_PGM_SYNC_CR3)
-            {
-                AssertLogRelMsgReturn(RT_FAILURE(rc), ("%Rrc\n", rc), VERR_IPE_UNEXPECTED_INFO_STATUS);
-                return rc;
-            }
-            rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
-            if (RT_FAILURE(rc))
-                return rc;
-        }
-        /** @todo maybe prefetch the supervisor stack page as well */
-        Assert(!VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT));
-    }
-
-    /*
-     * Allocate handy pages (just in case the above actions have consumed some pages).
-     */
-    if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_PGM_NEED_HANDY_PAGES, VM_FF_PGM_NO_MEMORY))
-    {
-        int rc = PGMR3PhysAllocateHandyPages(pVM);
-        if (RT_FAILURE(rc))
-            return rc;
-    }
-
-    /*
-     * Check whether we're out of memory now.
-     *
-     * This may stem from some of the above actions or operations that has been executed
-     * since we ran FFs. The allocate handy pages must for instance always be followed by
-     * this check.
-     */
-    if (VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY))
-        return VINF_EM_NO_MEMORY;
-
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Executes hardware accelerated raw code. (Intel VT-x & AMD-V)
- *
- * This function contains the raw-mode version of the inner
- * execution loop (the outer loop being in EMR3ExecuteVM()).
- *
- * @returns VBox status code. The most important ones are: VINF_EM_RESCHEDULE, VINF_EM_RESCHEDULE_RAW,
- *          VINF_EM_RESCHEDULE_REM, VINF_EM_SUSPEND, VINF_EM_RESET and VINF_EM_TERMINATE.
- *
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   pfFFDone    Where to store an indicator telling whether or not
- *                      FFs were done before returning.
- */
-int emR3HwAccExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone)
-{
-    int      rc = VERR_IPE_UNINITIALIZED_STATUS;
-    PCPUMCTX pCtx = pVCpu->em.s.pCtx;
-
-    LogFlow(("emR3HwAccExecute%d: (cs:eip=%04x:%RGv)\n", pVCpu->idCpu, pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
-    *pfFFDone = false;
-
-    STAM_COUNTER_INC(&pVCpu->em.s.StatHwAccExecuteEntry);
-
-#ifdef EM_NOTIFY_HWACCM
-    HWACCMR3NotifyScheduled(pVCpu);
-#endif
-
-    /*
-     * Spin till we get a forced action which returns anything but VINF_SUCCESS.
-     */
-    for (;;)
-    {
-        STAM_PROFILE_ADV_START(&pVCpu->em.s.StatHwAccEntry, a);
-
-        /* Check if a forced reschedule is pending. */
-        if (HWACCMR3IsRescheduleRequired(pVM, pCtx))
-        {
-            rc = VINF_EM_RESCHEDULE;
-            break;
-        }
-
-        /*
-         * Process high priority pre-execution raw-mode FFs.
-         */
-        VMCPU_FF_CLEAR(pVCpu, (VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_TSS)); /* not relevant in HWACCM mode; shouldn't be set really. */
-        if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK)
-            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
-        {
-            rc = emR3HwaccmForcedActions(pVM, pVCpu, pCtx);
-            if (rc != VINF_SUCCESS)
-                break;
-        }
-
-#ifdef LOG_ENABLED
-        /*
-         * Log important stuff before entering GC.
-         */
-        if (TRPMHasTrap(pVCpu))
-            Log(("CPU%d: Pending hardware interrupt=0x%x cs:rip=%04X:%RGv\n", pVCpu->idCpu, TRPMGetTrapNo(pVCpu), pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
-
-        uint32_t cpl = CPUMGetGuestCPL(pVCpu);
-
-        if (pVM->cCpus == 1)
-        {
-            if (pCtx->eflags.Bits.u1VM)
-                Log(("HWV86: %08X IF=%d\n", pCtx->eip, pCtx->eflags.Bits.u1IF));
-            else if (CPUMIsGuestIn64BitCodeEx(pCtx))
-                Log(("HWR%d: %04X:%RGv ESP=%RGv IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pCtx->cs.Sel, (RTGCPTR)pCtx->rip, pCtx->rsp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER));
-            else
-                Log(("HWR%d: %04X:%08X ESP=%08X IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pCtx->cs.Sel,          pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER));
-        }
-        else
-        {
-            if (pCtx->eflags.Bits.u1VM)
-                Log(("HWV86-CPU%d: %08X IF=%d\n", pVCpu->idCpu, pCtx->eip, pCtx->eflags.Bits.u1IF));
-            else if (CPUMIsGuestIn64BitCodeEx(pCtx))
-                Log(("HWR%d-CPU%d: %04X:%RGv ESP=%RGv IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pVCpu->idCpu, pCtx->cs.Sel, (RTGCPTR)pCtx->rip, pCtx->rsp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER));
-            else
-                Log(("HWR%d-CPU%d: %04X:%08X ESP=%08X IF=%d IOPL=%d CR0=%x CR4=%x EFER=%x\n", cpl, pVCpu->idCpu, pCtx->cs.Sel,          pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pCtx->eflags.Bits.u2IOPL, (uint32_t)pCtx->cr0, (uint32_t)pCtx->cr4, (uint32_t)pCtx->msrEFER));
-        }
-#endif /* LOG_ENABLED */
-
-        /*
-         * Execute the code.
-         */
-        STAM_PROFILE_ADV_STOP(&pVCpu->em.s.StatHwAccEntry, a);
-
-        if (RT_LIKELY(EMR3IsExecutionAllowed(pVM, pVCpu)))
-        {
-            STAM_PROFILE_START(&pVCpu->em.s.StatHwAccExec, x);
-            rc = VMMR3HwAccRunGC(pVM, pVCpu);
-            STAM_PROFILE_STOP(&pVCpu->em.s.StatHwAccExec, x);
-        }
-        else
-        {
-            /* Give up this time slice; virtual time continues */
-            STAM_REL_PROFILE_ADV_START(&pVCpu->em.s.StatCapped, u);
-            RTThreadSleep(5);
-            STAM_REL_PROFILE_ADV_STOP(&pVCpu->em.s.StatCapped, u);
-            rc = VINF_SUCCESS;
-        }
-
-
-        /*
-         * Deal with high priority post execution FFs before doing anything else.
-         */
-        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK);
-        if (    VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK)
-            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
-            rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
-
-        /*
-         * Process the returned status code.
-         */
-        if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
-            break;
-
-        rc = emR3HwaccmHandleRC(pVM, pVCpu, pCtx, rc);
-        if (rc != VINF_SUCCESS)
-            break;
-
-        /*
-         * Check and execute forced actions.
-         */
-#ifdef VBOX_HIGH_RES_TIMERS_HACK
-        TMTimerPollVoid(pVM, pVCpu);
-#endif
-        if (    VM_FF_ISPENDING(pVM, VM_FF_ALL_MASK)
-            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_MASK))
-        {
-            rc = emR3ForcedActions(pVM, pVCpu, rc);
-            VBOXVMM_EM_FF_ALL_RET(pVCpu, rc);
-            if (    rc != VINF_SUCCESS
-                &&  rc != VINF_EM_RESCHEDULE_HWACC)
-            {
-                *pfFFDone = true;
-                break;
-            }
-        }
-    }
-
-    /*
-     * Return to outer loop.
-     */
-#if defined(LOG_ENABLED) && defined(DEBUG)
-    RTLogFlush(NULL);
-#endif
-    return rc;
-}
-
Index: trunk/src/VBox/VMM/VMMR3/HM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/HM.cpp	(revision 43387)
+++ trunk/src/VBox/VMM/VMMR3/HM.cpp	(revision 43387)
@@ -0,0 +1,2935 @@
+/* $Id$ */
+/** @file
+ * HM - Intel/AMD VM Hardware Support Manager.
+ */
+
+/*
+ * 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;
+ * 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.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_HM
+#include <VBox/vmm/cpum.h>
+#include <VBox/vmm/stam.h>
+#include <VBox/vmm/mm.h>
+#include <VBox/vmm/pdmapi.h>
+#include <VBox/vmm/pgm.h>
+#include <VBox/vmm/ssm.h>
+#include <VBox/vmm/trpm.h>
+#include <VBox/vmm/dbgf.h>
+#include <VBox/vmm/iom.h>
+#include <VBox/vmm/patm.h>
+#include <VBox/vmm/csam.h>
+#include <VBox/vmm/selm.h>
+#ifdef VBOX_WITH_REM
+# include <VBox/vmm/rem.h>
+#endif
+#include <VBox/vmm/hm_vmx.h>
+#include <VBox/vmm/hm_svm.h>
+#include "HMInternal.h"
+#include <VBox/vmm/vm.h>
+#include <VBox/err.h>
+#include <VBox/param.h>
+
+#include <iprt/assert.h>
+#include <VBox/log.h>
+#include <iprt/asm.h>
+#include <iprt/asm-amd64-x86.h>
+#include <iprt/string.h>
+#include <iprt/env.h>
+#include <iprt/thread.h>
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+#ifdef VBOX_WITH_STATISTICS
+# define EXIT_REASON(def, val, str) #def " - " #val " - " str
+# define EXIT_REASON_NIL() NULL
+/** Exit reason descriptions for VT-x, used to describe statistics. */
+static const char * const g_apszVTxExitReasons[MAX_EXITREASON_STAT] =
+{
+    EXIT_REASON(VMX_EXIT_EXCEPTION          ,  0, "Exception or non-maskable interrupt (NMI)."),
+    EXIT_REASON(VMX_EXIT_EXTERNAL_IRQ       ,  1, "External interrupt."),
+    EXIT_REASON(VMX_EXIT_TRIPLE_FAULT       ,  2, "Triple fault."),
+    EXIT_REASON(VMX_EXIT_INIT_SIGNAL        ,  3, "INIT signal."),
+    EXIT_REASON(VMX_EXIT_SIPI               ,  4, "Start-up IPI (SIPI)."),
+    EXIT_REASON(VMX_EXIT_IO_SMI_IRQ         ,  5, "I/O system-management interrupt (SMI)."),
+    EXIT_REASON(VMX_EXIT_SMI_IRQ            ,  6, "Other SMI."),
+    EXIT_REASON(VMX_EXIT_IRQ_WINDOW         ,  7, "Interrupt window."),
+    EXIT_REASON_NIL(),
+    EXIT_REASON(VMX_EXIT_TASK_SWITCH        ,  9, "Task switch."),
+    EXIT_REASON(VMX_EXIT_CPUID              , 10, "Guest software attempted to execute CPUID."),
+    EXIT_REASON_NIL(),
+    EXIT_REASON(VMX_EXIT_HLT                , 12, "Guest software attempted to execute HLT."),
+    EXIT_REASON(VMX_EXIT_INVD               , 13, "Guest software attempted to execute INVD."),
+    EXIT_REASON(VMX_EXIT_INVLPG             , 14, "Guest software attempted to execute INVLPG."),
+    EXIT_REASON(VMX_EXIT_RDPMC              , 15, "Guest software attempted to execute RDPMC."),
+    EXIT_REASON(VMX_EXIT_RDTSC              , 16, "Guest software attempted to execute RDTSC."),
+    EXIT_REASON(VMX_EXIT_RSM                , 17, "Guest software attempted to execute RSM in SMM."),
+    EXIT_REASON(VMX_EXIT_VMCALL             , 18, "Guest software executed VMCALL."),
+    EXIT_REASON(VMX_EXIT_VMCLEAR            , 19, "Guest software executed VMCLEAR."),
+    EXIT_REASON(VMX_EXIT_VMLAUNCH           , 20, "Guest software executed VMLAUNCH."),
+    EXIT_REASON(VMX_EXIT_VMPTRLD            , 21, "Guest software executed VMPTRLD."),
+    EXIT_REASON(VMX_EXIT_VMPTRST            , 22, "Guest software executed VMPTRST."),
+    EXIT_REASON(VMX_EXIT_VMREAD             , 23, "Guest software executed VMREAD."),
+    EXIT_REASON(VMX_EXIT_VMRESUME           , 24, "Guest software executed VMRESUME."),
+    EXIT_REASON(VMX_EXIT_VMWRITE            , 25, "Guest software executed VMWRITE."),
+    EXIT_REASON(VMX_EXIT_VMXOFF             , 26, "Guest software executed VMXOFF."),
+    EXIT_REASON(VMX_EXIT_VMXON              , 27, "Guest software executed VMXON."),
+    EXIT_REASON(VMX_EXIT_CRX_MOVE           , 28, "Control-register accesses."),
+    EXIT_REASON(VMX_EXIT_DRX_MOVE           , 29, "Debug-register accesses."),
+    EXIT_REASON(VMX_EXIT_PORT_IO            , 30, "I/O instruction."),
+    EXIT_REASON(VMX_EXIT_RDMSR              , 31, "RDMSR. Guest software attempted to execute RDMSR."),
+    EXIT_REASON(VMX_EXIT_WRMSR              , 32, "WRMSR. Guest software attempted to execute WRMSR."),
+    EXIT_REASON(VMX_EXIT_ERR_INVALID_GUEST_STATE,  33, "VM-entry failure due to invalid guest state."),
+    EXIT_REASON(VMX_EXIT_ERR_MSR_LOAD       , 34, "VM-entry failure due to MSR loading."),
+    EXIT_REASON_NIL(),
+    EXIT_REASON(VMX_EXIT_MWAIT              , 36, "Guest software executed MWAIT."),
+    EXIT_REASON(VMX_EXIT_MTF                , 37, "Monitor Trap Flag."),
+    EXIT_REASON_NIL(),
+    EXIT_REASON(VMX_EXIT_MONITOR            , 39, "Guest software attempted to execute MONITOR."),
+    EXIT_REASON(VMX_EXIT_PAUSE              , 40, "Guest software attempted to execute PAUSE."),
+    EXIT_REASON(VMX_EXIT_ERR_MACHINE_CHECK  , 41, "VM-entry failure due to machine-check."),
+    EXIT_REASON_NIL(),
+    EXIT_REASON(VMX_EXIT_TPR                , 43, "TPR below threshold. Guest software executed MOV to CR8."),
+    EXIT_REASON(VMX_EXIT_APIC_ACCESS        , 44, "APIC access. Guest software attempted to access memory at a physical address on the APIC-access page."),
+    EXIT_REASON_NIL(),
+    EXIT_REASON(VMX_EXIT_XDTR_ACCESS        , 46, "Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT."),
+    EXIT_REASON(VMX_EXIT_TR_ACCESS          , 47, "Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR."),
+    EXIT_REASON(VMX_EXIT_EPT_VIOLATION      , 48, "EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures."),
+    EXIT_REASON(VMX_EXIT_EPT_MISCONFIG      , 49, "EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry."),
+    EXIT_REASON(VMX_EXIT_INVEPT             , 50, "INVEPT. Guest software attempted to execute INVEPT."),
+    EXIT_REASON(VMX_EXIT_RDTSCP             , 51, "Guest software attempted to execute RDTSCP."),
+    EXIT_REASON(VMX_EXIT_PREEMPTION_TIMER   , 52, "VMX-preemption timer expired. The preemption timer counted down to zero."),
+    EXIT_REASON(VMX_EXIT_INVVPID            , 53, "INVVPID. Guest software attempted to execute INVVPID."),
+    EXIT_REASON(VMX_EXIT_WBINVD             , 54, "WBINVD. Guest software attempted to execute WBINVD."),
+    EXIT_REASON(VMX_EXIT_XSETBV             , 55, "XSETBV. Guest software attempted to execute XSETBV."),
+    EXIT_REASON_NIL()
+};
+/** Exit reason descriptions for AMD-V, used to describe statistics. */
+static const char * const g_apszAmdVExitReasons[MAX_EXITREASON_STAT] =
+{
+    EXIT_REASON(SVM_EXIT_READ_CR0                   ,  0, "Read CR0."),
+    EXIT_REASON(SVM_EXIT_READ_CR1                   ,  1, "Read CR1."),
+    EXIT_REASON(SVM_EXIT_READ_CR2                   ,  2, "Read CR2."),
+    EXIT_REASON(SVM_EXIT_READ_CR3                   ,  3, "Read CR3."),
+    EXIT_REASON(SVM_EXIT_READ_CR4                   ,  4, "Read CR4."),
+    EXIT_REASON(SVM_EXIT_READ_CR5                   ,  5, "Read CR5."),
+    EXIT_REASON(SVM_EXIT_READ_CR6                   ,  6, "Read CR6."),
+    EXIT_REASON(SVM_EXIT_READ_CR7                   ,  7, "Read CR7."),
+    EXIT_REASON(SVM_EXIT_READ_CR8                   ,  8, "Read CR8."),
+    EXIT_REASON(SVM_EXIT_READ_CR9                   ,  9, "Read CR9."),
+    EXIT_REASON(SVM_EXIT_READ_CR10                  , 10, "Read CR10."),
+    EXIT_REASON(SVM_EXIT_READ_CR11                  , 11, "Read CR11."),
+    EXIT_REASON(SVM_EXIT_READ_CR12                  , 12, "Read CR12."),
+    EXIT_REASON(SVM_EXIT_READ_CR13                  , 13, "Read CR13."),
+    EXIT_REASON(SVM_EXIT_READ_CR14                  , 14, "Read CR14."),
+    EXIT_REASON(SVM_EXIT_READ_CR15                  , 15, "Read CR15."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR0                  , 16, "Write CR0."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR1                  , 17, "Write CR1."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR2                  , 18, "Write CR2."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR3                  , 19, "Write CR3."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR4                  , 20, "Write CR4."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR5                  , 21, "Write CR5."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR6                  , 22, "Write CR6."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR7                  , 23, "Write CR7."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR8                  , 24, "Write CR8."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR9                  , 25, "Write CR9."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR10                 , 26, "Write CR10."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR11                 , 27, "Write CR11."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR12                 , 28, "Write CR12."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR13                 , 29, "Write CR13."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR14                 , 30, "Write CR14."),
+    EXIT_REASON(SVM_EXIT_WRITE_CR15                 , 31, "Write CR15."),
+    EXIT_REASON(SVM_EXIT_READ_DR0                   , 32, "Read DR0."),
+    EXIT_REASON(SVM_EXIT_READ_DR1                   , 33, "Read DR1."),
+    EXIT_REASON(SVM_EXIT_READ_DR2                   , 34, "Read DR2."),
+    EXIT_REASON(SVM_EXIT_READ_DR3                   , 35, "Read DR3."),
+    EXIT_REASON(SVM_EXIT_READ_DR4                   , 36, "Read DR4."),
+    EXIT_REASON(SVM_EXIT_READ_DR5                   , 37, "Read DR5."),
+    EXIT_REASON(SVM_EXIT_READ_DR6                   , 38, "Read DR6."),
+    EXIT_REASON(SVM_EXIT_READ_DR7                   , 39, "Read DR7."),
+    EXIT_REASON(SVM_EXIT_READ_DR8                   , 40, "Read DR8."),
+    EXIT_REASON(SVM_EXIT_READ_DR9                   , 41, "Read DR9."),
+    EXIT_REASON(SVM_EXIT_READ_DR10                  , 42, "Read DR10."),
+    EXIT_REASON(SVM_EXIT_READ_DR11                  , 43, "Read DR11"),
+    EXIT_REASON(SVM_EXIT_READ_DR12                  , 44, "Read DR12."),
+    EXIT_REASON(SVM_EXIT_READ_DR13                  , 45, "Read DR13."),
+    EXIT_REASON(SVM_EXIT_READ_DR14                  , 46, "Read DR14."),
+    EXIT_REASON(SVM_EXIT_READ_DR15                  , 47, "Read DR15."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR0                  , 48, "Write DR0."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR1                  , 49, "Write DR1."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR2                  , 50, "Write DR2."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR3                  , 51, "Write DR3."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR4                  , 52, "Write DR4."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR5                  , 53, "Write DR5."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR6                  , 54, "Write DR6."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR7                  , 55, "Write DR7."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR8                  , 56, "Write DR8."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR9                  , 57, "Write DR9."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR10                 , 58, "Write DR10."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR11                 , 59, "Write DR11."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR12                 , 60, "Write DR12."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR13                 , 61, "Write DR13."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR14                 , 62, "Write DR14."),
+    EXIT_REASON(SVM_EXIT_WRITE_DR15                 , 63, "Write DR15."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_0                , 64, "Exception Vector 0  (0x0)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_1                , 65, "Exception Vector 1  (0x1)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_2                , 66, "Exception Vector 2  (0x2)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_3                , 67, "Exception Vector 3  (0x3)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_4                , 68, "Exception Vector 4  (0x4)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_5                , 69, "Exception Vector 5  (0x5)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_6                , 70, "Exception Vector 6  (0x6)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_7                , 71, "Exception Vector 7  (0x7)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_8                , 72, "Exception Vector 8  (0x8)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_9                , 73, "Exception Vector 9  (0x9)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_A                , 74, "Exception Vector 10 (0xA)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_B                , 75, "Exception Vector 11 (0xB)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_C                , 76, "Exception Vector 12 (0xC)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_D                , 77, "Exception Vector 13 (0xD)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_E                , 78, "Exception Vector 14 (0xE)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_F                , 79, "Exception Vector 15 (0xF)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_10               , 80, "Exception Vector 16 (0x10)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_11               , 81, "Exception Vector 17 (0x11)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_12               , 82, "Exception Vector 18 (0x12)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_13               , 83, "Exception Vector 19 (0x13)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_14               , 84, "Exception Vector 20 (0x14)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_15               , 85, "Exception Vector 22 (0x15)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_16               , 86, "Exception Vector 22 (0x16)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_17               , 87, "Exception Vector 23 (0x17)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_18               , 88, "Exception Vector 24 (0x18)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_19               , 89, "Exception Vector 25 (0x19)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_1A               , 90, "Exception Vector 26 (0x1A)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_1B               , 91, "Exception Vector 27 (0x1B)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_1C               , 92, "Exception Vector 28 (0x1C)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_1D               , 93, "Exception Vector 29 (0x1D)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_1E               , 94, "Exception Vector 30 (0x1E)."),
+    EXIT_REASON(SVM_EXIT_EXCEPTION_1F               , 95, "Exception Vector 31 (0x1F)."),
+    EXIT_REASON(SVM_EXIT_INTR                       , 96, "Physical maskable interrupt."),
+    EXIT_REASON(SVM_EXIT_NMI                        , 97, "Physical non-maskable interrupt."),
+    EXIT_REASON(SVM_EXIT_SMI                        , 98, "System management interrupt."),
+    EXIT_REASON(SVM_EXIT_INIT                       , 99, "Physical INIT signal."),
+    EXIT_REASON(SVM_EXIT_VINTR                      ,100, "Virtual interrupt."),
+    EXIT_REASON(SVM_EXIT_CR0_SEL_WRITE              ,101, "Write to CR0 that changed any bits other than CR0.TS or CR0.MP."),
+    EXIT_REASON(SVM_EXIT_IDTR_READ                  ,102, "Read IDTR"),
+    EXIT_REASON(SVM_EXIT_GDTR_READ                  ,103, "Read GDTR"),
+    EXIT_REASON(SVM_EXIT_LDTR_READ                  ,104, "Read LDTR."),
+    EXIT_REASON(SVM_EXIT_TR_READ                    ,105, "Read TR."),
+    EXIT_REASON(SVM_EXIT_TR_READ                    ,106, "Write IDTR."),
+    EXIT_REASON(SVM_EXIT_TR_READ                    ,107, "Write GDTR."),
+    EXIT_REASON(SVM_EXIT_TR_READ                    ,108, "Write LDTR."),
+    EXIT_REASON(SVM_EXIT_TR_READ                    ,109, "Write TR."),
+    EXIT_REASON(SVM_EXIT_RDTSC                      ,110, "RDTSC instruction."),
+    EXIT_REASON(SVM_EXIT_RDPMC                      ,111, "RDPMC instruction."),
+    EXIT_REASON(SVM_EXIT_PUSHF                      ,112, "PUSHF instruction."),
+    EXIT_REASON(SVM_EXIT_POPF                       ,113, "POPF instruction."),
+    EXIT_REASON(SVM_EXIT_CPUID                      ,114, "CPUID instruction."),
+    EXIT_REASON(SVM_EXIT_RSM                        ,115, "RSM instruction."),
+    EXIT_REASON(SVM_EXIT_IRET                       ,116, "IRET instruction."),
+    EXIT_REASON(SVM_EXIT_SWINT                      ,117, "Software interrupt (INTn instructions)."),
+    EXIT_REASON(SVM_EXIT_INVD                       ,118, "INVD instruction."),
+    EXIT_REASON(SVM_EXIT_PAUSE                      ,119, "PAUSE instruction."),
+    EXIT_REASON(SVM_EXIT_HLT                        ,120, "HLT instruction."),
+    EXIT_REASON(SVM_EXIT_INVLPG                     ,121, "INVLPG instruction."),
+    EXIT_REASON(SVM_EXIT_INVLPGA                    ,122, "INVLPGA instruction."),
+    EXIT_REASON(SVM_EXIT_IOIO                       ,123, "IN/OUT accessing protected port (EXITINFO1 field provides more information)."),
+    EXIT_REASON(SVM_EXIT_MSR                        ,124, "RDMSR or WRMSR access to protected MSR."),
+    EXIT_REASON(SVM_EXIT_TASK_SWITCH                ,125, "Task switch."),
+    EXIT_REASON(SVM_EXIT_FERR_FREEZE                ,126, "FP legacy handling enabled, and processor is frozen in an x87/mmx instruction waiting for an interrupt"),
+    EXIT_REASON(SVM_EXIT_SHUTDOWN                   ,127, "Shutdown."),
+    EXIT_REASON(SVM_EXIT_VMRUN                      ,128, "VMRUN instruction."),
+    EXIT_REASON(SVM_EXIT_VMMCALL                    ,129, "VMCALL instruction."),
+    EXIT_REASON(SVM_EXIT_VMLOAD                     ,130, "VMLOAD instruction."),
+    EXIT_REASON(SVM_EXIT_VMSAVE                     ,131, "VMSAVE instruction."),
+    EXIT_REASON(SVM_EXIT_STGI                       ,132, "STGI instruction."),
+    EXIT_REASON(SVM_EXIT_CLGI                       ,133, "CLGI instruction."),
+    EXIT_REASON(SVM_EXIT_SKINIT                     ,134, "SKINIT instruction."),
+    EXIT_REASON(SVM_EXIT_RDTSCP                     ,135, "RDTSCP instruction."),
+    EXIT_REASON(SVM_EXIT_ICEBP                      ,136, "ICEBP instruction."),
+    EXIT_REASON(SVM_EXIT_WBINVD                     ,137, "WBINVD instruction."),
+    EXIT_REASON(SVM_EXIT_MONITOR                    ,138, "MONITOR instruction."),
+    EXIT_REASON(SVM_EXIT_MWAIT_UNCOND               ,139, "MWAIT instruction unconditional."),
+    EXIT_REASON(SVM_EXIT_MWAIT_ARMED                ,140, "MWAIT instruction when armed."),
+    EXIT_REASON(SVM_EXIT_NPF                        ,1024, "Nested paging: host-level page fault occurred (EXITINFO1 contains fault errorcode; EXITINFO2 contains the guest physical address causing the fault)."),
+    EXIT_REASON_NIL()
+};
+# undef EXIT_REASON
+# undef EXIT_REASON_NIL
+#endif /* VBOX_WITH_STATISTICS */
+
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
+static DECLCALLBACK(int) hmR3Save(PVM pVM, PSSMHANDLE pSSM);
+static DECLCALLBACK(int) hmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
+static int hmR3InitCPU(PVM pVM);
+static int hmR3InitFinalizeR0(PVM pVM);
+static int hmR3TermCPU(PVM pVM);
+
+
+/**
+ * Initializes the HM.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR3DECL(int) HMR3Init(PVM pVM)
+{
+    LogFlow(("HMR3Init\n"));
+
+    /*
+     * Assert alignment and sizes.
+     */
+    AssertCompileMemberAlignment(VM, hm.s, 32);
+    AssertCompile(sizeof(pVM->hm.s) <= sizeof(pVM->hm.padding));
+
+    /* Some structure checks. */
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, ctrl.EventInject) == 0xA8, ("ctrl.EventInject offset = %x\n", RT_OFFSETOF(SVM_VMCB, ctrl.EventInject)));
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, ctrl.ExitIntInfo) == 0x88, ("ctrl.ExitIntInfo offset = %x\n", RT_OFFSETOF(SVM_VMCB, ctrl.ExitIntInfo)));
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, ctrl.TLBCtrl) == 0x58, ("ctrl.TLBCtrl offset = %x\n", RT_OFFSETOF(SVM_VMCB, ctrl.TLBCtrl)));
+
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest) == 0x400, ("guest offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest)));
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.TR) == 0x490, ("guest.TR offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.TR)));
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u8CPL) == 0x4CB, ("guest.u8CPL offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u8CPL)));
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64EFER) == 0x4D0, ("guest.u64EFER offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64EFER)));
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64CR4) == 0x548, ("guest.u64CR4 offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64CR4)));
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64RIP) == 0x578, ("guest.u64RIP offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64RIP)));
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64RSP) == 0x5D8, ("guest.u64RSP offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64RSP)));
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64CR2) == 0x640, ("guest.u64CR2 offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64CR2)));
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64GPAT) == 0x668, ("guest.u64GPAT offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64GPAT)));
+    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64LASTEXCPTO) == 0x690, ("guest.u64LASTEXCPTO offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64LASTEXCPTO)));
+    AssertReleaseMsg(sizeof(SVM_VMCB) == 0x1000, ("SVM_VMCB size = %x\n", sizeof(SVM_VMCB)));
+
+
+    /*
+     * Register the saved state data unit.
+     */
+    int rc = SSMR3RegisterInternal(pVM, "HM", 0, HM_SSM_VERSION, sizeof(HM),
+                                   NULL, NULL, NULL,
+                                   NULL, hmR3Save, NULL,
+                                   NULL, hmR3Load, NULL);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    /* Misc initialisation. */
+    pVM->hm.s.vmx.fSupported = false;
+    pVM->hm.s.svm.fSupported = false;
+    pVM->hm.s.vmx.fEnabled   = false;
+    pVM->hm.s.svm.fEnabled   = false;
+
+    pVM->hm.s.fNestedPaging  = false;
+    pVM->hm.s.fLargePages    = false;
+
+    /* Disabled by default. */
+    pVM->fHMEnabled = false;
+
+    /*
+     * Check CFGM options.
+     */
+    PCFGMNODE pRoot      = CFGMR3GetRoot(pVM);
+    PCFGMNODE pHWVirtExt = CFGMR3GetChild(pRoot, "HWVirtExt/");
+    /* Nested paging: disabled by default. */
+    rc = CFGMR3QueryBoolDef(pHWVirtExt, "EnableNestedPaging", &pVM->hm.s.fAllowNestedPaging, false);
+    AssertRC(rc);
+
+    /* Large pages: disabled by default. */
+    rc = CFGMR3QueryBoolDef(pHWVirtExt, "EnableLargePages", &pVM->hm.s.fLargePages, false);
+    AssertRC(rc);
+
+    /* VT-x VPID: disabled by default. */
+    rc = CFGMR3QueryBoolDef(pHWVirtExt, "EnableVPID", &pVM->hm.s.vmx.fAllowVPID, false);
+    AssertRC(rc);
+
+    /* HM support must be explicitely enabled in the configuration file. */
+    rc = CFGMR3QueryBoolDef(pHWVirtExt, "Enabled", &pVM->hm.s.fAllowed, false);
+    AssertRC(rc);
+
+    /* TPR patching for 32 bits (Windows) guests with IO-APIC: disabled by default. */
+    rc = CFGMR3QueryBoolDef(pHWVirtExt, "TPRPatchingEnabled", &pVM->hm.s.fTRPPatchingAllowed, false);
+    AssertRC(rc);
+
+#ifdef RT_OS_DARWIN
+    if (VMMIsHwVirtExtForced(pVM) != pVM->hm.s.fAllowed)
+#else
+    if (VMMIsHwVirtExtForced(pVM) && !pVM->hm.s.fAllowed)
+#endif
+    {
+        AssertLogRelMsgFailed(("VMMIsHwVirtExtForced=%RTbool fAllowed=%RTbool\n",
+                               VMMIsHwVirtExtForced(pVM), pVM->hm.s.fAllowed));
+        return VERR_HM_CONFIG_MISMATCH;
+    }
+
+    if (VMMIsHwVirtExtForced(pVM))
+        pVM->fHMEnabled = true;
+
+#if HC_ARCH_BITS == 32
+    /*
+     * 64-bit mode is configurable and it depends on both the kernel mode and VT-x.
+     * (To use the default, don't set 64bitEnabled in CFGM.)
+     */
+    rc = CFGMR3QueryBoolDef(pHWVirtExt, "64bitEnabled", &pVM->hm.s.fAllow64BitGuests, false);
+    AssertLogRelRCReturn(rc, rc);
+    if (pVM->hm.s.fAllow64BitGuests)
+    {
+# ifdef RT_OS_DARWIN
+        if (!VMMIsHwVirtExtForced(pVM))
+# else
+        if (!pVM->hm.s.fAllowed)
+# endif
+            return VM_SET_ERROR(pVM, VERR_INVALID_PARAMETER, "64-bit guest support was requested without also enabling HWVirtEx (VT-x/AMD-V).");
+    }
+#else
+    /*
+     * On 64-bit hosts 64-bit guest support is enabled by default, but allow this to be overridden
+     * via VBoxInternal/HWVirtExt/64bitEnabled=0. (ConsoleImpl2.cpp doesn't set this to false for 64-bit.)*
+     */
+    rc = CFGMR3QueryBoolDef(pHWVirtExt, "64bitEnabled", &pVM->hm.s.fAllow64BitGuests, true);
+    AssertLogRelRCReturn(rc, rc);
+#endif
+
+
+    /*
+     * Determine the init method for AMD-V and VT-x; either one global init for each host CPU
+     *  or local init each time we wish to execute guest code.
+     *
+     *  Default false for Mac OS X and Windows due to the higher risk of conflicts with other hypervisors.
+     */
+    rc = CFGMR3QueryBoolDef(pHWVirtExt, "Exclusive", &pVM->hm.s.fGlobalInit,
+#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS)
+                            false
+#else
+                            true
+#endif
+                           );
+
+    /* Max number of resume loops. */
+    rc = CFGMR3QueryU32Def(pHWVirtExt, "MaxResumeLoops", &pVM->hm.s.cMaxResumeLoops, 0 /* set by R0 later */);
+    AssertRC(rc);
+
+    return rc;
+}
+
+
+/**
+ * Initializes the per-VCPU HM.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ */
+static int hmR3InitCPU(PVM pVM)
+{
+    LogFlow(("HMR3InitCPU\n"));
+
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+
+        pVCpu->hm.s.fActive = false;
+    }
+
+#ifdef VBOX_WITH_STATISTICS
+    STAM_REG(pVM, &pVM->hm.s.StatTPRPatchSuccess,   STAMTYPE_COUNTER, "/HM/TPR/Patch/Success",  STAMUNIT_OCCURENCES,    "Number of times an instruction was successfully patched.");
+    STAM_REG(pVM, &pVM->hm.s.StatTPRPatchFailure,   STAMTYPE_COUNTER, "/HM/TPR/Patch/Failed",   STAMUNIT_OCCURENCES,    "Number of unsuccessful patch attempts.");
+    STAM_REG(pVM, &pVM->hm.s.StatTPRReplaceSuccess, STAMTYPE_COUNTER, "/HM/TPR/Replace/Success",STAMUNIT_OCCURENCES,    "Number of times an instruction was successfully patched.");
+    STAM_REG(pVM, &pVM->hm.s.StatTPRReplaceFailure, STAMTYPE_COUNTER, "/HM/TPR/Replace/Failed", STAMUNIT_OCCURENCES,    "Number of unsuccessful patch attempts.");
+
+    /*
+     * Statistics.
+     */
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+        int    rc;
+
+        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatPoke, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of RTMpPokeCpu",
+                             "/PROF/HM/CPU%d/Poke", i);
+        AssertRC(rc);
+        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatSpinPoke, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of poke wait",
+                             "/PROF/HM/CPU%d/PokeWait", i);
+        AssertRC(rc);
+        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatSpinPokeFailed, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of poke wait when RTMpPokeCpu fails",
+                             "/PROF/HM/CPU%d/PokeWaitFailed", i);
+        AssertRC(rc);
+        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatEntry, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of VMXR0RunGuestCode entry",
+                             "/PROF/HM/CPU%d/SwitchToGC", i);
+        AssertRC(rc);
+        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExit1, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of VMXR0RunGuestCode exit part 1",
+                             "/PROF/HM/CPU%d/SwitchFromGC_1", i);
+        AssertRC(rc);
+        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExit2, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of VMXR0RunGuestCode exit part 2",
+                             "/PROF/HM/CPU%d/SwitchFromGC_2", i);
+        AssertRC(rc);
+# if 1 /* temporary for tracking down darwin holdup. */
+        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExit2Sub1, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Temporary - I/O",
+                             "/PROF/HM/CPU%d/SwitchFromGC_2/Sub1", i);
+        AssertRC(rc);
+        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExit2Sub2, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Temporary - CRx RWs",
+                             "/PROF/HM/CPU%d/SwitchFromGC_2/Sub2", i);
+        AssertRC(rc);
+        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExit2Sub3, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Temporary - Exceptions",
+                             "/PROF/HM/CPU%d/SwitchFromGC_2/Sub3", i);
+        AssertRC(rc);
+# endif
+        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatInGC, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of vmlaunch",
+                             "/PROF/HM/CPU%d/InGC", i);
+        AssertRC(rc);
+
+# if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatWorldSwitch3264, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of the 32/64 switcher",
+                             "/PROF/HM/CPU%d/Switcher3264", i);
+        AssertRC(rc);
+# endif
+
+# define HM_REG_COUNTER(a, b) \
+        rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Profiling of vmlaunch", b, i); \
+        AssertRC(rc);
+
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitShadowNM,           "/HM/CPU%d/Exit/Trap/Shw/#NM");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestNM,            "/HM/CPU%d/Exit/Trap/Gst/#NM");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitShadowPF,           "/HM/CPU%d/Exit/Trap/Shw/#PF");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitShadowPFEM,         "/HM/CPU%d/Exit/Trap/Shw/#PF-EM");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestPF,            "/HM/CPU%d/Exit/Trap/Gst/#PF");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestUD,            "/HM/CPU%d/Exit/Trap/Gst/#UD");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestSS,            "/HM/CPU%d/Exit/Trap/Gst/#SS");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestNP,            "/HM/CPU%d/Exit/Trap/Gst/#NP");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestGP,            "/HM/CPU%d/Exit/Trap/Gst/#GP");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestMF,            "/HM/CPU%d/Exit/Trap/Gst/#MF");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestDE,            "/HM/CPU%d/Exit/Trap/Gst/#DE");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestDB,            "/HM/CPU%d/Exit/Trap/Gst/#DB");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestBP,            "/HM/CPU%d/Exit/Trap/Gst/#BP");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestXF,            "/HM/CPU%d/Exit/Trap/Gst/#XF");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestXcpUnk,        "/HM/CPU%d/Exit/Trap/Gst/Other");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitInvlpg,             "/HM/CPU%d/Exit/Instr/Invlpg");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitInvd,               "/HM/CPU%d/Exit/Instr/Invd");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCpuid,              "/HM/CPU%d/Exit/Instr/Cpuid");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitRdtsc,              "/HM/CPU%d/Exit/Instr/Rdtsc");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitRdtscp,             "/HM/CPU%d/Exit/Instr/Rdtscp");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitRdpmc,              "/HM/CPU%d/Exit/Instr/Rdpmc");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitRdmsr,              "/HM/CPU%d/Exit/Instr/Rdmsr");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitWrmsr,              "/HM/CPU%d/Exit/Instr/Wrmsr");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitMwait,              "/HM/CPU%d/Exit/Instr/Mwait");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitMonitor,            "/HM/CPU%d/Exit/Instr/Monitor");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitDRxWrite,           "/HM/CPU%d/Exit/Instr/DR/Write");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitDRxRead,            "/HM/CPU%d/Exit/Instr/DR/Read");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCLTS,               "/HM/CPU%d/Exit/Instr/CLTS");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitLMSW,               "/HM/CPU%d/Exit/Instr/LMSW");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCli,                "/HM/CPU%d/Exit/Instr/Cli");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitSti,                "/HM/CPU%d/Exit/Instr/Sti");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitPushf,              "/HM/CPU%d/Exit/Instr/Pushf");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitPopf,               "/HM/CPU%d/Exit/Instr/Popf");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitIret,               "/HM/CPU%d/Exit/Instr/Iret");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitInt,                "/HM/CPU%d/Exit/Instr/Int");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitHlt,                "/HM/CPU%d/Exit/Instr/Hlt");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitIOWrite,            "/HM/CPU%d/Exit/IO/Write");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitIORead,             "/HM/CPU%d/Exit/IO/Read");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitIOStringWrite,      "/HM/CPU%d/Exit/IO/WriteString");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitIOStringRead,       "/HM/CPU%d/Exit/IO/ReadString");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitIrqWindow,          "/HM/CPU%d/Exit/IrqWindow");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitMaxResume,          "/HM/CPU%d/Exit/MaxResume");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitPreemptPending,     "/HM/CPU%d/Exit/PreemptPending");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatExitMTF,                "/HM/CPU%d/Exit/MonitorTrapFlag");
+
+        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchGuestIrq,         "/HM/CPU%d/Switch/IrqPending");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchToR3,             "/HM/CPU%d/Switch/ToR3");
+
+        HM_REG_COUNTER(&pVCpu->hm.s.StatIntInject,              "/HM/CPU%d/Irq/Inject");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatIntReinject,            "/HM/CPU%d/Irq/Reinject");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatPendingHostIrq,         "/HM/CPU%d/Irq/PendingOnHost");
+
+        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushPage,              "/HM/CPU%d/Flush/Page");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushPageManual,        "/HM/CPU%d/Flush/Page/Virt");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushPhysPageManual,    "/HM/CPU%d/Flush/Page/Phys");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushTLB,               "/HM/CPU%d/Flush/TLB");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushTLBManual,         "/HM/CPU%d/Flush/TLB/Manual");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushTLBCRxChange,      "/HM/CPU%d/Flush/TLB/CRx");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushPageInvlpg,        "/HM/CPU%d/Flush/Page/Invlpg");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushTLBWorldSwitch,    "/HM/CPU%d/Flush/TLB/Switch");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatNoFlushTLBWorldSwitch,  "/HM/CPU%d/Flush/TLB/Skipped");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushASID,              "/HM/CPU%d/Flush/TLB/ASID");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushTLBInvlpga,        "/HM/CPU%d/Flush/TLB/PhysInvl");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatTlbShootdown,           "/HM/CPU%d/Flush/Shootdown/Page");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatTlbShootdownFlush,      "/HM/CPU%d/Flush/Shootdown/TLB");
+
+        HM_REG_COUNTER(&pVCpu->hm.s.StatTSCOffset,              "/HM/CPU%d/TSC/Offset");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatTSCIntercept,           "/HM/CPU%d/TSC/Intercept");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatTSCInterceptOverFlow,   "/HM/CPU%d/TSC/InterceptOverflow");
+
+        HM_REG_COUNTER(&pVCpu->hm.s.StatDRxArmed,               "/HM/CPU%d/Debug/Armed");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatDRxContextSwitch,       "/HM/CPU%d/Debug/ContextSwitch");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatDRxIOCheck,             "/HM/CPU%d/Debug/IOCheck");
+
+        HM_REG_COUNTER(&pVCpu->hm.s.StatLoadMinimal,            "/HM/CPU%d/Load/Minimal");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatLoadFull,               "/HM/CPU%d/Load/Full");
+
+#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+        HM_REG_COUNTER(&pVCpu->hm.s.StatFpu64SwitchBack,        "/HM/CPU%d/Switch64/Fpu");
+        HM_REG_COUNTER(&pVCpu->hm.s.StatDebug64SwitchBack,      "/HM/CPU%d/Switch64/Debug");
+#endif
+
+        for (unsigned j = 0; j < RT_ELEMENTS(pVCpu->hm.s.StatExitCRxWrite); j++)
+        {
+            rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitCRxWrite[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, "Profiling of CRx writes",
+                                "/HM/CPU%d/Exit/Instr/CR/Write/%x", i, j);
+            AssertRC(rc);
+            rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitCRxRead[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, "Profiling of CRx reads",
+                                "/HM/CPU%d/Exit/Instr/CR/Read/%x", i, j);
+            AssertRC(rc);
+        }
+
+#undef HM_REG_COUNTER
+
+        pVCpu->hm.s.paStatExitReason = NULL;
+
+        rc = MMHyperAlloc(pVM, MAX_EXITREASON_STAT*sizeof(*pVCpu->hm.s.paStatExitReason), 0, MM_TAG_HM, (void **)&pVCpu->hm.s.paStatExitReason);
+        AssertRC(rc);
+        if (RT_SUCCESS(rc))
+        {
+            const char * const *papszDesc = ASMIsIntelCpu() ? &g_apszVTxExitReasons[0] : &g_apszAmdVExitReasons[0];
+            for (int j = 0; j < MAX_EXITREASON_STAT; j++)
+            {
+                if (papszDesc[j])
+                {
+                    rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.paStatExitReason[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
+                                        papszDesc[j], "/HM/CPU%d/Exit/Reason/%02x", i, j);
+                    AssertRC(rc);
+                }
+            }
+            rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitReasonNPF, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, "Nested page fault", "/HM/CPU%d/Exit/Reason/#NPF", i);
+            AssertRC(rc);
+        }
+        pVCpu->hm.s.paStatExitReasonR0 = MMHyperR3ToR0(pVM, pVCpu->hm.s.paStatExitReason);
+# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
+        Assert(pVCpu->hm.s.paStatExitReasonR0 != NIL_RTR0PTR || !VMMIsHwVirtExtForced(pVM));
+# else
+        Assert(pVCpu->hm.s.paStatExitReasonR0 != NIL_RTR0PTR);
+# endif
+
+        rc = MMHyperAlloc(pVM, sizeof(STAMCOUNTER) * 256, 8, MM_TAG_HM, (void **)&pVCpu->hm.s.paStatInjectedIrqs);
+        AssertRCReturn(rc, rc);
+        pVCpu->hm.s.paStatInjectedIrqsR0 = MMHyperR3ToR0(pVM, pVCpu->hm.s.paStatInjectedIrqs);
+# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
+        Assert(pVCpu->hm.s.paStatInjectedIrqsR0 != NIL_RTR0PTR || !VMMIsHwVirtExtForced(pVM));
+# else
+        Assert(pVCpu->hm.s.paStatInjectedIrqsR0 != NIL_RTR0PTR);
+# endif
+        for (unsigned j = 0; j < 255; j++)
+            STAMR3RegisterF(pVM, &pVCpu->hm.s.paStatInjectedIrqs[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, "Forwarded interrupts.",
+                            (j < 0x20) ? "/HM/CPU%d/Interrupt/Trap/%02X" : "/HM/CPU%d/Interrupt/IRQ/%02X", i, j);
+
+    }
+#endif /* VBOX_WITH_STATISTICS */
+
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    /* Magic marker for searching in crash dumps. */
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+
+        PVMCSCACHE pCache = &pVCpu->hm.s.vmx.VMCSCache;
+        strcpy((char *)pCache->aMagic, "VMCSCACHE Magic");
+        pCache->uMagic = UINT64_C(0xDEADBEEFDEADBEEF);
+    }
+#endif
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Called when a init phase has completed.
+ *
+ * @returns VBox status code.
+ * @param   pVM                 The VM.
+ * @param   enmWhat             The phase that completed.
+ */
+VMMR3_INT_DECL(int) HMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
+{
+    switch (enmWhat)
+    {
+        case VMINITCOMPLETED_RING3:
+            return hmR3InitCPU(pVM);
+        case VMINITCOMPLETED_RING0:
+            return hmR3InitFinalizeR0(pVM);
+        default:
+            return VINF_SUCCESS;
+    }
+}
+
+
+/**
+ * Turns off normal raw mode features.
+ *
+ * @param   pVM         Pointer to the VM.
+ */
+static void hmR3DisableRawMode(PVM pVM)
+{
+    /* Disable PATM & CSAM. */
+    PATMR3AllowPatching(pVM, false);
+    CSAMDisableScanning(pVM);
+
+    /* Turn off IDT/LDT/GDT and TSS monitoring and sycing. */
+    SELMR3DisableMonitoring(pVM);
+    TRPMR3DisableMonitoring(pVM);
+
+    /* Disable the switcher code (safety precaution). */
+    VMMR3DisableSwitcher(pVM);
+
+    /* Disable mapping of the hypervisor into the shadow page table. */
+    PGMR3MappingsDisable(pVM);
+
+    /* Disable the switcher */
+    VMMR3DisableSwitcher(pVM);
+
+    /* Reinit the paging mode to force the new shadow mode. */
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+
+        PGMR3ChangeMode(pVM, pVCpu, PGMMODE_REAL);
+    }
+}
+
+
+/**
+ * Initialize VT-x or AMD-V.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ */
+static int hmR3InitFinalizeR0(PVM pVM)
+{
+    int rc;
+
+    /*
+     * Hack to allow users to work around broken BIOSes that incorrectly set EFER.SVME, which makes us believe somebody else
+     * is already using AMD-V.
+     */
+    if (    !pVM->hm.s.vmx.fSupported
+        &&  !pVM->hm.s.svm.fSupported
+        &&  pVM->hm.s.lLastError == VERR_SVM_IN_USE /* implies functional AMD-V */
+        &&  RTEnvExist("VBOX_HWVIRTEX_IGNORE_SVM_IN_USE"))
+    {
+        LogRel(("HM: VBOX_HWVIRTEX_IGNORE_SVM_IN_USE active!\n"));
+        pVM->hm.s.svm.fSupported        = true;
+        pVM->hm.s.svm.fIgnoreInUseError = true;
+    }
+    else
+    if (    !pVM->hm.s.vmx.fSupported
+        &&  !pVM->hm.s.svm.fSupported)
+    {
+        LogRel(("HM: No VT-x or AMD-V CPU extension found. Reason %Rrc\n", pVM->hm.s.lLastError));
+        LogRel(("HM: VMX MSR_IA32_FEATURE_CONTROL=%RX64\n", pVM->hm.s.vmx.msr.feature_ctrl));
+
+        if (VMMIsHwVirtExtForced(pVM))
+        {
+            switch (pVM->hm.s.lLastError)
+            {
+            case VERR_VMX_NO_VMX:
+                return VM_SET_ERROR(pVM, VERR_VMX_NO_VMX, "VT-x is not available.");
+            case VERR_VMX_IN_VMX_ROOT_MODE:
+                return VM_SET_ERROR(pVM, VERR_VMX_IN_VMX_ROOT_MODE, "VT-x is being used by another hypervisor.");
+            case VERR_SVM_IN_USE:
+                return VM_SET_ERROR(pVM, VERR_SVM_IN_USE, "AMD-V is being used by another hypervisor.");
+            case VERR_SVM_NO_SVM:
+                return VM_SET_ERROR(pVM, VERR_SVM_NO_SVM, "AMD-V is not available.");
+            case VERR_SVM_DISABLED:
+                return VM_SET_ERROR(pVM, VERR_SVM_DISABLED, "AMD-V is disabled in the BIOS.");
+            default:
+                return pVM->hm.s.lLastError;
+            }
+        }
+        return VINF_SUCCESS;
+    }
+
+    if (pVM->hm.s.vmx.fSupported)
+    {
+        rc = SUPR3QueryVTxSupported();
+        if (RT_FAILURE(rc))
+        {
+#ifdef RT_OS_LINUX
+            LogRel(("HM: The host kernel does not support VT-x -- Linux 2.6.13 or newer required!\n"));
+#else
+            LogRel(("HM: The host kernel does not support VT-x!\n"));
+#endif
+            if (   pVM->cCpus > 1
+                || VMMIsHwVirtExtForced(pVM))
+                return rc;
+
+            /* silently fall back to raw mode */
+            return VINF_SUCCESS;
+        }
+    }
+
+    if (!pVM->hm.s.fAllowed)
+        return VINF_SUCCESS;    /* nothing to do */
+
+    /* Enable VT-x or AMD-V on all host CPUs. */
+    rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HWACC_ENABLE, 0, NULL);
+    if (RT_FAILURE(rc))
+    {
+        LogRel(("HMR3InitFinalize: SUPR3CallVMMR0Ex VMMR0_DO_HWACC_ENABLE failed with %Rrc\n", rc));
+        return rc;
+    }
+    Assert(!pVM->fHMEnabled || VMMIsHwVirtExtForced(pVM));
+
+    pVM->hm.s.fHasIoApic = PDMHasIoApic(pVM);
+    /* No TPR patching is required when the IO-APIC is not enabled for this VM. (Main should have taken care of this already) */
+    if (!pVM->hm.s.fHasIoApic)
+    {
+        Assert(!pVM->hm.s.fTRPPatchingAllowed); /* paranoia */
+        pVM->hm.s.fTRPPatchingAllowed = false;
+    }
+
+    bool fOldBuffered = RTLogRelSetBuffering(true /*fBuffered*/);
+    if (pVM->hm.s.vmx.fSupported)
+    {
+        Log(("pVM->hm.s.vmx.fSupported = %d\n", pVM->hm.s.vmx.fSupported));
+
+        if (    pVM->hm.s.fInitialized == false
+            &&  pVM->hm.s.vmx.msr.feature_ctrl != 0)
+        {
+            uint64_t val;
+            RTGCPHYS GCPhys = 0;
+
+            LogRel(("HM: Host CR4=%08X\n", pVM->hm.s.vmx.hostCR4));
+            LogRel(("HM: MSR_IA32_FEATURE_CONTROL      = %RX64\n", pVM->hm.s.vmx.msr.feature_ctrl));
+            LogRel(("HM: MSR_IA32_VMX_BASIC_INFO       = %RX64\n", pVM->hm.s.vmx.msr.vmx_basic_info));
+            LogRel(("HM: VMCS id                       = %x\n", MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hm.s.vmx.msr.vmx_basic_info)));
+            LogRel(("HM: VMCS size                     = %x\n", MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(pVM->hm.s.vmx.msr.vmx_basic_info)));
+            LogRel(("HM: VMCS physical address limit   = %s\n", MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(pVM->hm.s.vmx.msr.vmx_basic_info) ? "< 4 GB" : "None"));
+            LogRel(("HM: VMCS memory type              = %x\n", MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(pVM->hm.s.vmx.msr.vmx_basic_info)));
+            LogRel(("HM: Dual monitor treatment        = %d\n", MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(pVM->hm.s.vmx.msr.vmx_basic_info)));
+
+            LogRel(("HM: MSR_IA32_VMX_PINBASED_CTLS    = %RX64\n", pVM->hm.s.vmx.msr.vmx_pin_ctls.u));
+            val = pVM->hm.s.vmx.msr.vmx_pin_ctls.n.allowed1;
+            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI)
+                LogRel(("HM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI\n"));
+            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
+                LogRel(("HM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER\n"));
+            val = pVM->hm.s.vmx.msr.vmx_pin_ctls.n.disallowed0;
+            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI)
+                LogRel(("HM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
+                LogRel(("HM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER *must* be set\n"));
+
+            LogRel(("HM: MSR_IA32_VMX_PROCBASED_CTLS   = %RX64\n", pVM->hm.s.vmx.msr.vmx_proc_ctls.u));
+            val = pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1;
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL\n"));
+
+            val = pVM->hm.s.vmx.msr.vmx_proc_ctls.n.disallowed0;
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
+                LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL *must* be set\n"));
+
+            if (pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
+            {
+                LogRel(("HM: MSR_IA32_VMX_PROCBASED_CTLS2  = %RX64\n", pVM->hm.s.vmx.msr.vmx_proc_ctls2.u));
+                val = pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1;
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_EPT)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_EPT\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_X2APIC)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_X2APIC\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_VPID)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_VPID\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT\n"));
+
+                val = pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.disallowed0;
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC *must* be set\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT *must* be set\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP *must* be set\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_X2APIC)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_X2APIC *must* be set\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_EPT)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_EPT *must* be set\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_VPID)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_VPID *must* be set\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT *must* be set\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE *must* be set\n"));
+                if (val & VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT)
+                    LogRel(("HM:    VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT *must* be set\n"));
+            }
+
+            LogRel(("HM: MSR_IA32_VMX_ENTRY_CTLS       = %RX64\n", pVM->hm.s.vmx.msr.vmx_entry.u));
+            val = pVM->hm.s.vmx.msr.vmx_entry.n.allowed1;
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR\n"));
+            val = pVM->hm.s.vmx.msr.vmx_entry.n.disallowed0;
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR *must* be set\n"));
+
+            LogRel(("HM: MSR_IA32_VMX_EXIT_CTLS        = %RX64\n", pVM->hm.s.vmx.msr.vmx_exit.u));
+            val = pVM->hm.s.vmx.msr.vmx_exit.n.allowed1;
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER\n"));
+            val = pVM->hm.s.vmx.msr.vmx_exit.n.disallowed0;
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64 *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR *must* be set\n"));
+            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER)
+                LogRel(("HM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER *must* be set\n"));
+
+            if (pVM->hm.s.vmx.msr.vmx_eptcaps)
+            {
+                LogRel(("HM: MSR_IA32_VMX_EPT_VPID_CAPS    = %RX64\n", pVM->hm.s.vmx.msr.vmx_eptcaps));
+
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_RWX_X_ONLY)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_RWX_X_ONLY\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_RWX_W_ONLY)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_RWX_W_ONLY\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_RWX_WX_ONLY)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_RWX_WX_ONLY\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_GAW_21_BITS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_GAW_21_BITS\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_GAW_30_BITS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_GAW_30_BITS\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_GAW_39_BITS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_GAW_39_BITS\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_GAW_48_BITS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_GAW_48_BITS\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_GAW_57_BITS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_GAW_57_BITS\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_EMT_UC)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_EMT_UC\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_EMT_WC)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_EMT_WC\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_EMT_WT)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_EMT_WT\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_EMT_WP)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_EMT_WP\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_EMT_WB)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_EMT_WB\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_SP_21_BITS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_SP_21_BITS\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_SP_30_BITS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_SP_30_BITS\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_SP_39_BITS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_SP_39_BITS\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_SP_48_BITS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_SP_48_BITS\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_INVEPT\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_SINGLE_CONTEXT)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_SINGLE_CONTEXT\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL_CONTEXTS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL_CONTEXTS\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_INVVPID\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS\n"));
+                if (pVM->hm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT_RETAIN_GLOBALS)
+                    LogRel(("HM:    MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT_RETAIN_GLOBALS\n"));
+            }
+
+            LogRel(("HM: MSR_IA32_VMX_MISC             = %RX64\n", pVM->hm.s.vmx.msr.vmx_misc));
+            if (MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(pVM->hm.s.vmx.msr.vmx_misc) == pVM->hm.s.vmx.cPreemptTimerShift)
+                LogRel(("HM:    MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT %x\n", MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(pVM->hm.s.vmx.msr.vmx_misc)));
+            else
+            {
+                LogRel(("HM:    MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT %x - erratum detected, using %x instead\n",
+                        MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(pVM->hm.s.vmx.msr.vmx_misc), pVM->hm.s.vmx.cPreemptTimerShift));
+            }
+            LogRel(("HM:    MSR_IA32_VMX_MISC_ACTIVITY_STATES %x\n", MSR_IA32_VMX_MISC_ACTIVITY_STATES(pVM->hm.s.vmx.msr.vmx_misc)));
+            LogRel(("HM:    MSR_IA32_VMX_MISC_CR3_TARGET      %x\n", MSR_IA32_VMX_MISC_CR3_TARGET(pVM->hm.s.vmx.msr.vmx_misc)));
+            LogRel(("HM:    MSR_IA32_VMX_MISC_MAX_MSR         %x\n", MSR_IA32_VMX_MISC_MAX_MSR(pVM->hm.s.vmx.msr.vmx_misc)));
+            LogRel(("HM:    MSR_IA32_VMX_MISC_MSEG_ID         %x\n", MSR_IA32_VMX_MISC_MSEG_ID(pVM->hm.s.vmx.msr.vmx_misc)));
+
+            LogRel(("HM: MSR_IA32_VMX_CR0_FIXED0       = %RX64\n", pVM->hm.s.vmx.msr.vmx_cr0_fixed0));
+            LogRel(("HM: MSR_IA32_VMX_CR0_FIXED1       = %RX64\n", pVM->hm.s.vmx.msr.vmx_cr0_fixed1));
+            LogRel(("HM: MSR_IA32_VMX_CR4_FIXED0       = %RX64\n", pVM->hm.s.vmx.msr.vmx_cr4_fixed0));
+            LogRel(("HM: MSR_IA32_VMX_CR4_FIXED1       = %RX64\n", pVM->hm.s.vmx.msr.vmx_cr4_fixed1));
+            LogRel(("HM: MSR_IA32_VMX_VMCS_ENUM        = %RX64\n", pVM->hm.s.vmx.msr.vmx_vmcs_enum));
+
+            LogRel(("HM: TPR shadow physaddr           = %RHp\n", pVM->hm.s.vmx.pAPICPhys));
+
+            /* Paranoia */
+            AssertRelease(MSR_IA32_VMX_MISC_MAX_MSR(pVM->hm.s.vmx.msr.vmx_misc) >= 512);
+
+            for (VMCPUID i = 0; i < pVM->cCpus; i++)
+            {
+                LogRel(("HM: VCPU%d: MSR bitmap physaddr    = %RHp\n", i, pVM->aCpus[i].hm.s.vmx.pMSRBitmapPhys));
+                LogRel(("HM: VCPU%d: VMCS physaddr          = %RHp\n", i, pVM->aCpus[i].hm.s.vmx.HCPhysVMCS));
+            }
+
+            if (pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_EPT)
+                pVM->hm.s.fNestedPaging = pVM->hm.s.fAllowNestedPaging;
+
+            if (pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VPID)
+                pVM->hm.s.vmx.fVPID = pVM->hm.s.vmx.fAllowVPID;
+
+            /*
+             * Disallow RDTSCP in the guest if there is no secondary process-based VM execution controls as otherwise
+             * RDTSCP would cause a #UD. There might be no CPUs out there where this happens, as RDTSCP was introduced
+             * in Nehalems and secondary VM exec. controls should be supported in all of them, but nonetheless it's Intel...
+             */
+            if (!(pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
+                && CPUMGetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_RDTSCP))
+            {
+                CPUMClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_RDTSCP);
+            }
+
+            /* Unrestricted guest execution relies on EPT. */
+            if (    pVM->hm.s.fNestedPaging
+                &&  (pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE))
+            {
+                pVM->hm.s.vmx.fUnrestrictedGuest = true;
+            }
+
+            /* Only try once. */
+            pVM->hm.s.fInitialized = true;
+
+            if (!pVM->hm.s.vmx.fUnrestrictedGuest)
+            {
+                /* Allocate three pages for the TSS we need for real mode emulation. (2 pages for the IO bitmap) */
+                rc = PDMR3VMMDevHeapAlloc(pVM, HM_VTX_TOTAL_DEVHEAP_MEM, (RTR3PTR *)&pVM->hm.s.vmx.pRealModeTSS);
+                if (RT_SUCCESS(rc))
+                {
+                    /* The I/O bitmap starts right after the virtual interrupt redirection bitmap. */
+                    ASMMemZero32(pVM->hm.s.vmx.pRealModeTSS, sizeof(*pVM->hm.s.vmx.pRealModeTSS));
+                    pVM->hm.s.vmx.pRealModeTSS->offIoBitmap = sizeof(*pVM->hm.s.vmx.pRealModeTSS);
+                    /* Bit set to 0 means redirection enabled. */
+                    memset(pVM->hm.s.vmx.pRealModeTSS->IntRedirBitmap, 0x0, sizeof(pVM->hm.s.vmx.pRealModeTSS->IntRedirBitmap));
+                    /* Allow all port IO, so the VT-x IO intercepts do their job. */
+                    memset(pVM->hm.s.vmx.pRealModeTSS + 1, 0, PAGE_SIZE*2);
+                    *((unsigned char *)pVM->hm.s.vmx.pRealModeTSS + HM_VTX_TSS_SIZE - 2) = 0xff;
+
+                    /*
+                     * Construct a 1024 element page directory with 4 MB pages for the identity mapped page table used in
+                     * real and protected mode without paging with EPT.
+                     */
+                    pVM->hm.s.vmx.pNonPagingModeEPTPageTable = (PX86PD)((char *)pVM->hm.s.vmx.pRealModeTSS + PAGE_SIZE * 3);
+                    for (unsigned i = 0; i < X86_PG_ENTRIES; i++)
+                    {
+                        pVM->hm.s.vmx.pNonPagingModeEPTPageTable->a[i].u  = _4M * i;
+                        pVM->hm.s.vmx.pNonPagingModeEPTPageTable->a[i].u |= X86_PDE4M_P | X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_A | X86_PDE4M_D | X86_PDE4M_PS | X86_PDE4M_G;
+                    }
+
+                    /* We convert it here every time as pci regions could be reconfigured. */
+                    rc = PDMVMMDevHeapR3ToGCPhys(pVM, pVM->hm.s.vmx.pRealModeTSS, &GCPhys);
+                    AssertRC(rc);
+                    LogRel(("HM: Real Mode TSS guest physaddr  = %RGp\n", GCPhys));
+
+                    rc = PDMVMMDevHeapR3ToGCPhys(pVM, pVM->hm.s.vmx.pNonPagingModeEPTPageTable, &GCPhys);
+                    AssertRC(rc);
+                    LogRel(("HM: Non-Paging Mode EPT CR3       = %RGp\n", GCPhys));
+                }
+                else
+                {
+                    LogRel(("HM: No real mode VT-x support (PDMR3VMMDevHeapAlloc returned %Rrc)\n", rc));
+                    pVM->hm.s.vmx.pRealModeTSS = NULL;
+                    pVM->hm.s.vmx.pNonPagingModeEPTPageTable = NULL;
+                }
+            }
+
+            rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HWACC_SETUP_VM, 0, NULL);
+            AssertRC(rc);
+            if (rc == VINF_SUCCESS)
+            {
+                pVM->fHMEnabled = true;
+                pVM->hm.s.vmx.fEnabled = true;
+                hmR3DisableRawMode(pVM);
+
+                CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SEP);
+#ifdef VBOX_ENABLE_64_BITS_GUESTS
+                if (pVM->hm.s.fAllow64BitGuests)
+                {
+                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE);
+                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LONG_MODE);
+                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SYSCALL);            /* 64 bits only on Intel CPUs */
+                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LAHF);
+                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
+                }
+                else
+                /* Turn on NXE if PAE has been enabled *and* the host has turned on NXE (we reuse the host EFER in the switcher) */
+                /* Todo: this needs to be fixed properly!! */
+                if (    CPUMGetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE)
+                    &&  (pVM->hm.s.vmx.hostEFER & MSR_K6_EFER_NXE))
+                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
+
+                LogRel((pVM->hm.s.fAllow64BitGuests
+                        ? "HM: 32-bit and 64-bit guests supported.\n"
+                        : "HM: 32-bit guests supported.\n"));
+#else
+                LogRel(("HM: 32-bit guests supported.\n"));
+#endif
+                LogRel(("HM: VMX enabled!\n"));
+                if (pVM->hm.s.fNestedPaging)
+                {
+                    LogRel(("HM: Enabled nested paging\n"));
+                    LogRel(("HM: EPT root page                 = %RHp\n", PGMGetHyperCR3(VMMGetCpu(pVM))));
+                    if (pVM->hm.s.vmx.enmFlushEPT == VMX_FLUSH_EPT_SINGLE_CONTEXT)
+                        LogRel(("HM: enmFlushEPT                   = VMX_FLUSH_EPT_SINGLE_CONTEXT\n"));
+                    else if (pVM->hm.s.vmx.enmFlushEPT == VMX_FLUSH_EPT_ALL_CONTEXTS)
+                        LogRel(("HM: enmFlushEPT                   = VMX_FLUSH_EPT_ALL_CONTEXTS\n"));
+                    else if (pVM->hm.s.vmx.enmFlushEPT == VMX_FLUSH_EPT_NOT_SUPPORTED)
+                        LogRel(("HM: enmFlushEPT                   = VMX_FLUSH_EPT_NOT_SUPPORTED\n"));
+                    else
+                        LogRel(("HM: enmFlushEPT                   = %d\n", pVM->hm.s.vmx.enmFlushEPT));
+
+                    if (pVM->hm.s.vmx.fUnrestrictedGuest)
+                        LogRel(("HM: Unrestricted guest execution enabled!\n"));
+
+#if HC_ARCH_BITS == 64
+                    if (pVM->hm.s.fLargePages)
+                    {
+                        /* Use large (2 MB) pages for our EPT PDEs where possible. */
+                        PGMSetLargePageUsage(pVM, true);
+                        LogRel(("HM: Large page support enabled!\n"));
+                    }
+#endif
+                }
+                else
+                    Assert(!pVM->hm.s.vmx.fUnrestrictedGuest);
+
+                if (pVM->hm.s.vmx.fVPID)
+                {
+                    LogRel(("HM: Enabled VPID\n"));
+                    if (pVM->hm.s.vmx.enmFlushVPID == VMX_FLUSH_VPID_INDIV_ADDR)
+                        LogRel(("HM: enmFlushVPID                  = VMX_FLUSH_VPID_INDIV_ADDR\n"));
+                    else if (pVM->hm.s.vmx.enmFlushVPID == VMX_FLUSH_VPID_SINGLE_CONTEXT)
+                        LogRel(("HM: enmFlushVPID                  = VMX_FLUSH_VPID_SINGLE_CONTEXT\n"));
+                    else if (pVM->hm.s.vmx.enmFlushVPID == VMX_FLUSH_VPID_ALL_CONTEXTS)
+                        LogRel(("HM: enmFlushVPID                  = VMX_FLUSH_VPID_ALL_CONTEXTS\n"));
+                    else if (pVM->hm.s.vmx.enmFlushVPID == VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS)
+                        LogRel(("HM: enmFlushVPID                  = VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS\n"));
+                    else
+                        LogRel(("HM: enmFlushVPID                  = %d\n", pVM->hm.s.vmx.enmFlushVPID));
+                }
+                else if (pVM->hm.s.vmx.enmFlushVPID == VMX_FLUSH_VPID_NOT_SUPPORTED)
+                    LogRel(("HM: Ignoring VPID capabilities of CPU.\n"));
+
+                /* TPR patching status logging. */
+                if (pVM->hm.s.fTRPPatchingAllowed)
+                {
+                    if (    (pVM->hm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
+                        &&  (pVM->hm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC))
+                    {
+                        pVM->hm.s.fTRPPatchingAllowed = false;  /* not necessary as we have a hardware solution. */
+                        LogRel(("HM: TPR Patching not required (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC).\n"));
+                    }
+                    else
+                    {
+                        uint32_t u32Eax, u32Dummy;
+
+                        /* TPR patching needs access to the MSR_K8_LSTAR msr. */
+                        ASMCpuId(0x80000000, &u32Eax, &u32Dummy, &u32Dummy, &u32Dummy);
+                        if (    u32Eax < 0x80000001
+                            ||  !(ASMCpuId_EDX(0x80000001) & X86_CPUID_EXT_FEATURE_EDX_LONG_MODE))
+                        {
+                            pVM->hm.s.fTRPPatchingAllowed = false;
+                            LogRel(("HM: TPR patching disabled (long mode not supported).\n"));
+                        }
+                    }
+                }
+                LogRel(("HM: TPR Patching %s.\n", (pVM->hm.s.fTRPPatchingAllowed) ? "enabled" : "disabled"));
+
+                /*
+                 * Check for preemption timer config override and log the state of it.
+                 */
+                if (pVM->hm.s.vmx.fUsePreemptTimer)
+                {
+                    PCFGMNODE pCfgHwAccM = CFGMR3GetChild(CFGMR3GetRoot(pVM), "HM");
+                    int rc2 = CFGMR3QueryBoolDef(pCfgHwAccM, "UsePreemptTimer", &pVM->hm.s.vmx.fUsePreemptTimer, true);
+                    AssertLogRelRC(rc2);
+                }
+                if (pVM->hm.s.vmx.fUsePreemptTimer)
+                    LogRel(("HM: Using the VMX-preemption timer (cPreemptTimerShift=%u)\n", pVM->hm.s.vmx.cPreemptTimerShift));
+            }
+            else
+            {
+                LogRel(("HM: VMX setup failed with rc=%Rrc!\n", rc));
+                LogRel(("HM: Last instruction error %x\n", pVM->aCpus[0].hm.s.vmx.lasterror.ulInstrError));
+                pVM->fHMEnabled = false;
+            }
+        }
+    }
+    else
+    if (pVM->hm.s.svm.fSupported)
+    {
+        Log(("pVM->hm.s.svm.fSupported = %d\n", pVM->hm.s.svm.fSupported));
+
+        if (pVM->hm.s.fInitialized == false)
+        {
+            /* Erratum 170 which requires a forced TLB flush for each world switch:
+             * See http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf
+             *
+             * All BH-G1/2 and DH-G1/2 models include a fix:
+             * Athlon X2:   0x6b 1/2
+             *              0x68 1/2
+             * Athlon 64:   0x7f 1
+             *              0x6f 2
+             * Sempron:     0x7f 1/2
+             *              0x6f 2
+             *              0x6c 2
+             *              0x7c 2
+             * Turion 64:   0x68 2
+             *
+             */
+            uint32_t u32Dummy;
+            uint32_t u32Version, u32Family, u32Model, u32Stepping, u32BaseFamily;
+            ASMCpuId(1, &u32Version, &u32Dummy, &u32Dummy, &u32Dummy);
+            u32BaseFamily= (u32Version >> 8) & 0xf;
+            u32Family    = u32BaseFamily + (u32BaseFamily == 0xf ? ((u32Version >> 20) & 0x7f) : 0);
+            u32Model     = ((u32Version >> 4) & 0xf);
+            u32Model     = u32Model | ((u32BaseFamily == 0xf ? (u32Version >> 16) & 0x0f : 0) << 4);
+            u32Stepping  = u32Version & 0xf;
+            if (    u32Family == 0xf
+                &&  !((u32Model == 0x68 || u32Model == 0x6b || u32Model == 0x7f) &&  u32Stepping >= 1)
+                &&  !((u32Model == 0x6f || u32Model == 0x6c || u32Model == 0x7c) &&  u32Stepping >= 2))
+            {
+                LogRel(("HM: AMD cpu with erratum 170 family %x model %x stepping %x\n", u32Family, u32Model, u32Stepping));
+            }
+
+            LogRel(("HM: cpuid 0x80000001.u32AMDFeatureECX = %RX32\n", pVM->hm.s.cpuid.u32AMDFeatureECX));
+            LogRel(("HM: cpuid 0x80000001.u32AMDFeatureEDX = %RX32\n", pVM->hm.s.cpuid.u32AMDFeatureEDX));
+            LogRel(("HM: AMD HWCR MSR                      = %RX64\n", pVM->hm.s.svm.msrHWCR));
+            LogRel(("HM: AMD-V revision                    = %X\n", pVM->hm.s.svm.u32Rev));
+            LogRel(("HM: AMD-V max ASID                    = %d\n", pVM->hm.s.uMaxASID));
+            LogRel(("HM: AMD-V features                    = %X\n", pVM->hm.s.svm.u32Features));
+            static const struct { uint32_t fFlag; const char *pszName; } s_aSvmFeatures[] =
+            {
+#define FLAG_NAME(a_Define) { a_Define, #a_Define }
+                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING),
+                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_LBR_VIRT),
+                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_SVM_LOCK),
+                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_NRIP_SAVE),
+                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_TSC_RATE_MSR),
+                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_VMCB_CLEAN),
+                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID),
+                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_DECODE_ASSIST),
+                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_SSE_3_5_DISABLE),
+                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER),
+                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER),
+#undef FLAG_NAME
+            };
+            uint32_t fSvmFeatures = pVM->hm.s.svm.u32Features;
+            for (unsigned i = 0; i < RT_ELEMENTS(s_aSvmFeatures); i++)
+                if (fSvmFeatures & s_aSvmFeatures[i].fFlag)
+                {
+                    LogRel(("HM:    %s\n", s_aSvmFeatures[i].pszName));
+                    fSvmFeatures &= ~s_aSvmFeatures[i].fFlag;
+                }
+            if (fSvmFeatures)
+                for (unsigned iBit = 0; iBit < 32; iBit++)
+                    if (RT_BIT_32(iBit) & fSvmFeatures)
+                        LogRel(("HM:    Reserved bit %u\n", iBit));
+
+            /* Only try once. */
+            pVM->hm.s.fInitialized = true;
+
+            if (pVM->hm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
+                pVM->hm.s.fNestedPaging = pVM->hm.s.fAllowNestedPaging;
+
+            rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HWACC_SETUP_VM, 0, NULL);
+            AssertRC(rc);
+            if (rc == VINF_SUCCESS)
+            {
+                pVM->fHMEnabled = true;
+                pVM->hm.s.svm.fEnabled = true;
+
+                if (pVM->hm.s.fNestedPaging)
+                {
+                    LogRel(("HM:    Enabled nested paging\n"));
+#if HC_ARCH_BITS == 64
+                    if (pVM->hm.s.fLargePages)
+                    {
+                        /* Use large (2 MB) pages for our nested paging PDEs where possible. */
+                        PGMSetLargePageUsage(pVM, true);
+                        LogRel(("HM:    Large page support enabled!\n"));
+                    }
+#endif
+                }
+
+                hmR3DisableRawMode(pVM);
+                CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SEP);
+                CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SYSCALL);
+#ifdef VBOX_ENABLE_64_BITS_GUESTS
+                if (pVM->hm.s.fAllow64BitGuests)
+                {
+                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE);
+                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LONG_MODE);
+                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
+                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LAHF);
+                }
+                else
+                /* Turn on NXE if PAE has been enabled. */
+                if (CPUMGetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE))
+                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
+#endif
+
+                LogRel((pVM->hm.s.fAllow64BitGuests
+                        ? "HM:    32-bit and 64-bit guest supported.\n"
+                        : "HM:    32-bit guest supported.\n"));
+
+                LogRel(("HM:    TPR Patching %s.\n", (pVM->hm.s.fTRPPatchingAllowed) ? "enabled" : "disabled"));
+            }
+            else
+            {
+                pVM->fHMEnabled = false;
+            }
+        }
+    }
+    if (pVM->fHMEnabled)
+        LogRel(("HM:    VT-x/AMD-V init method: %s\n", (pVM->hm.s.fGlobalInit) ? "GLOBAL" : "LOCAL"));
+    RTLogRelSetBuffering(fOldBuffered);
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * 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.
+ *
+ * @param   pVM     The VM.
+ */
+VMMR3DECL(void) HMR3Relocate(PVM pVM)
+{
+    Log(("HMR3Relocate to %RGv\n", MMHyperGetArea(pVM, 0)));
+
+    /* Fetch the current paging mode during the relocate callback during state loading. */
+    if (VMR3GetState(pVM) == VMSTATE_LOADING)
+    {
+        for (VMCPUID i = 0; i < pVM->cCpus; i++)
+        {
+            PVMCPU pVCpu = &pVM->aCpus[i];
+
+            pVCpu->hm.s.enmShadowMode            = PGMGetShadowMode(pVCpu);
+            Assert(pVCpu->hm.s.vmx.enmCurrGuestMode == PGMGetGuestMode(pVCpu));
+            pVCpu->hm.s.vmx.enmCurrGuestMode     = PGMGetGuestMode(pVCpu);
+        }
+    }
+#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+    if (pVM->fHMEnabled)
+    {
+        int rc;
+        switch (PGMGetHostMode(pVM))
+        {
+            case PGMMODE_32_BIT:
+                pVM->hm.s.pfnHost32ToGuest64R0 = VMMR3GetHostToGuestSwitcher(pVM, VMMSWITCHER_32_TO_AMD64);
+                break;
+
+            case PGMMODE_PAE:
+            case PGMMODE_PAE_NX:
+                pVM->hm.s.pfnHost32ToGuest64R0 = VMMR3GetHostToGuestSwitcher(pVM, VMMSWITCHER_PAE_TO_AMD64);
+                break;
+
+            default:
+                AssertFailed();
+                break;
+        }
+        rc = PDMR3LdrGetSymbolRC(pVM, NULL,       "VMXGCStartVM64", &pVM->hm.s.pfnVMXGCStartVM64);
+        AssertReleaseMsgRC(rc, ("VMXGCStartVM64 -> rc=%Rrc\n", rc));
+
+        rc = PDMR3LdrGetSymbolRC(pVM, NULL,       "SVMGCVMRun64",   &pVM->hm.s.pfnSVMGCVMRun64);
+        AssertReleaseMsgRC(rc, ("SVMGCVMRun64 -> rc=%Rrc\n", rc));
+
+        rc = PDMR3LdrGetSymbolRC(pVM, NULL,       "HMSaveGuestFPU64",   &pVM->hm.s.pfnSaveGuestFPU64);
+        AssertReleaseMsgRC(rc, ("HMSetupFPU64 -> rc=%Rrc\n", rc));
+
+        rc = PDMR3LdrGetSymbolRC(pVM, NULL,       "HMSaveGuestDebug64",   &pVM->hm.s.pfnSaveGuestDebug64);
+        AssertReleaseMsgRC(rc, ("HMSetupDebug64 -> rc=%Rrc\n", rc));
+
+# ifdef DEBUG
+        rc = PDMR3LdrGetSymbolRC(pVM, NULL,       "HMTestSwitcher64",   &pVM->hm.s.pfnTest64);
+        AssertReleaseMsgRC(rc, ("HMTestSwitcher64 -> rc=%Rrc\n", rc));
+# endif
+    }
+#endif
+    return;
+}
+
+
+/**
+ * Checks if hardware accelerated raw mode is allowed.
+ *
+ * @returns true if hardware acceleration is allowed, otherwise false.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR3DECL(bool) HMR3IsAllowed(PVM pVM)
+{
+    return pVM->hm.s.fAllowed;
+}
+
+
+/**
+ * Notification callback which is called whenever there is a chance that a CR3
+ * value might have changed.
+ *
+ * This is called by PGM.
+ *
+ * @param   pVM            Pointer to the VM.
+ * @param   pVCpu          Pointer to the VMCPU.
+ * @param   enmShadowMode  New shadow paging mode.
+ * @param   enmGuestMode   New guest paging mode.
+ */
+VMMR3DECL(void) HMR3PagingModeChanged(PVM pVM, PVMCPU pVCpu, PGMMODE enmShadowMode, PGMMODE enmGuestMode)
+{
+    /* Ignore page mode changes during state loading. */
+    if (VMR3GetState(pVCpu->pVMR3) == VMSTATE_LOADING)
+        return;
+
+    pVCpu->hm.s.enmShadowMode = enmShadowMode;
+
+    if (   pVM->hm.s.vmx.fEnabled
+        && pVM->fHMEnabled)
+    {
+        if (    pVCpu->hm.s.vmx.enmLastSeenGuestMode == PGMMODE_REAL
+            &&  enmGuestMode >= PGMMODE_PROTECTED)
+        {
+            PCPUMCTX pCtx;
+
+            pCtx = CPUMQueryGuestCtxPtr(pVCpu);
+
+            /* After a real mode switch to protected mode we must force
+               CPL to 0. Our real mode emulation had to set it to 3. */
+            pCtx->ss.Attr.n.u2Dpl  = 0;
+        }
+    }
+
+    if (pVCpu->hm.s.vmx.enmCurrGuestMode != enmGuestMode)
+    {
+        /* Keep track of paging mode changes. */
+        pVCpu->hm.s.vmx.enmPrevGuestMode = pVCpu->hm.s.vmx.enmCurrGuestMode;
+        pVCpu->hm.s.vmx.enmCurrGuestMode = enmGuestMode;
+
+        /* Did we miss a change, because all code was executed in the recompiler? */
+        if (pVCpu->hm.s.vmx.enmLastSeenGuestMode == enmGuestMode)
+        {
+            Log(("HMR3PagingModeChanged missed %s->%s transition (prev %s)\n", PGMGetModeName(pVCpu->hm.s.vmx.enmPrevGuestMode), PGMGetModeName(pVCpu->hm.s.vmx.enmCurrGuestMode), PGMGetModeName(pVCpu->hm.s.vmx.enmLastSeenGuestMode)));
+            pVCpu->hm.s.vmx.enmLastSeenGuestMode = pVCpu->hm.s.vmx.enmPrevGuestMode;
+        }
+    }
+
+    /* Reset the contents of the read cache. */
+    PVMCSCACHE pCache = &pVCpu->hm.s.vmx.VMCSCache;
+    for (unsigned j = 0; j < pCache->Read.cValidEntries; j++)
+        pCache->Read.aFieldVal[j] = 0;
+}
+
+
+/**
+ * Terminates the HM.
+ *
+ * Termination means cleaning up and freeing all resources,
+ * the VM itself is, at this point, powered off or suspended.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR3DECL(int) HMR3Term(PVM pVM)
+{
+    if (pVM->hm.s.vmx.pRealModeTSS)
+    {
+        PDMR3VMMDevHeapFree(pVM, pVM->hm.s.vmx.pRealModeTSS);
+        pVM->hm.s.vmx.pRealModeTSS       = 0;
+    }
+    hmR3TermCPU(pVM);
+    return 0;
+}
+
+
+/**
+ * Terminates the per-VCPU HM.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ */
+static int hmR3TermCPU(PVM pVM)
+{
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i]; NOREF(pVCpu);
+
+#ifdef VBOX_WITH_STATISTICS
+        if (pVCpu->hm.s.paStatExitReason)
+        {
+            MMHyperFree(pVM, pVCpu->hm.s.paStatExitReason);
+            pVCpu->hm.s.paStatExitReason   = NULL;
+            pVCpu->hm.s.paStatExitReasonR0 = NIL_RTR0PTR;
+        }
+        if (pVCpu->hm.s.paStatInjectedIrqs)
+        {
+            MMHyperFree(pVM, pVCpu->hm.s.paStatInjectedIrqs);
+            pVCpu->hm.s.paStatInjectedIrqs   = NULL;
+            pVCpu->hm.s.paStatInjectedIrqsR0 = NIL_RTR0PTR;
+        }
+#endif
+
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+        memset(pVCpu->hm.s.vmx.VMCSCache.aMagic, 0, sizeof(pVCpu->hm.s.vmx.VMCSCache.aMagic));
+        pVCpu->hm.s.vmx.VMCSCache.uMagic = 0;
+        pVCpu->hm.s.vmx.VMCSCache.uPos = 0xffffffff;
+#endif
+    }
+    return 0;
+}
+
+
+/**
+ * Resets a virtual CPU.
+ *
+ * Used by HMR3Reset and CPU hot plugging.
+ *
+ * @param   pVCpu   The CPU to reset.
+ */
+VMMR3DECL(void) HMR3ResetCpu(PVMCPU pVCpu)
+{
+    /* On first entry we'll sync everything. */
+    pVCpu->hm.s.fContextUseFlags = HM_CHANGED_ALL;
+
+    pVCpu->hm.s.vmx.cr0_mask = 0;
+    pVCpu->hm.s.vmx.cr4_mask = 0;
+
+    pVCpu->hm.s.fActive        = false;
+    pVCpu->hm.s.Event.fPending = false;
+
+    /* Reset state information for real-mode emulation in VT-x. */
+    pVCpu->hm.s.vmx.enmLastSeenGuestMode = PGMMODE_REAL;
+    pVCpu->hm.s.vmx.enmPrevGuestMode     = PGMMODE_REAL;
+    pVCpu->hm.s.vmx.enmCurrGuestMode     = PGMMODE_REAL;
+
+    /* Reset the contents of the read cache. */
+    PVMCSCACHE pCache = &pVCpu->hm.s.vmx.VMCSCache;
+    for (unsigned j = 0; j < pCache->Read.cValidEntries; j++)
+        pCache->Read.aFieldVal[j] = 0;
+
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    /* Magic marker for searching in crash dumps. */
+    strcpy((char *)pCache->aMagic, "VMCSCACHE Magic");
+    pCache->uMagic = UINT64_C(0xDEADBEEFDEADBEEF);
+#endif
+}
+
+
+/**
+ * The VM is being reset.
+ *
+ * For the HM component this means that any GDT/LDT/TSS monitors
+ * needs to be removed.
+ *
+ * @param   pVM     Pointer to the VM.
+ */
+VMMR3DECL(void) HMR3Reset(PVM pVM)
+{
+    LogFlow(("HMR3Reset:\n"));
+
+    if (pVM->fHMEnabled)
+        hmR3DisableRawMode(pVM);
+
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
+
+        HMR3ResetCpu(pVCpu);
+    }
+
+    /* Clear all patch information. */
+    pVM->hm.s.pGuestPatchMem         = 0;
+    pVM->hm.s.pFreeGuestPatchMem     = 0;
+    pVM->hm.s.cbGuestPatchMem        = 0;
+    pVM->hm.s.cPatches           = 0;
+    pVM->hm.s.PatchTree          = 0;
+    pVM->hm.s.fTPRPatchingActive = false;
+    ASMMemZero32(pVM->hm.s.aPatches, sizeof(pVM->hm.s.aPatches));
+}
+
+
+/**
+ * Callback to patch a TPR instruction (vmmcall or mov cr8).
+ *
+ * @returns VBox strict status code.
+ * @param   pVM     Pointer to the VM.
+ * @param   pVCpu   The VMCPU for the EMT we're being called on.
+ * @param   pvUser  Unused.
+ */
+DECLCALLBACK(VBOXSTRICTRC) hmR3RemovePatches(PVM pVM, PVMCPU pVCpu, void *pvUser)
+{
+    VMCPUID idCpu = (VMCPUID)(uintptr_t)pvUser;
+
+    /* Only execute the handler on the VCPU the original patch request was issued. */
+    if (pVCpu->idCpu != idCpu)
+        return VINF_SUCCESS;
+
+    Log(("hmR3RemovePatches\n"));
+    for (unsigned i = 0; i < pVM->hm.s.cPatches; i++)
+    {
+        uint8_t         abInstr[15];
+        PHMTPRPATCH pPatch = &pVM->hm.s.aPatches[i];
+        RTGCPTR         pInstrGC = (RTGCPTR)pPatch->Core.Key;
+        int             rc;
+
+#ifdef LOG_ENABLED
+        char            szOutput[256];
+
+        rc = DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, CPUMGetGuestCS(pVCpu), pInstrGC, DBGF_DISAS_FLAGS_DEFAULT_MODE,
+                                szOutput, sizeof(szOutput), NULL);
+        if (RT_SUCCESS(rc))
+            Log(("Patched instr: %s\n", szOutput));
+#endif
+
+        /* Check if the instruction is still the same. */
+        rc = PGMPhysSimpleReadGCPtr(pVCpu, abInstr, pInstrGC, pPatch->cbNewOp);
+        if (rc != VINF_SUCCESS)
+        {
+            Log(("Patched code removed? (rc=%Rrc0\n", rc));
+            continue;   /* swapped out or otherwise removed; skip it. */
+        }
+
+        if (memcmp(abInstr, pPatch->aNewOpcode, pPatch->cbNewOp))
+        {
+            Log(("Patched instruction was changed! (rc=%Rrc0\n", rc));
+            continue;   /* skip it. */
+        }
+
+        rc = PGMPhysSimpleWriteGCPtr(pVCpu, pInstrGC, pPatch->aOpcode, pPatch->cbOp);
+        AssertRC(rc);
+
+#ifdef LOG_ENABLED
+        rc = DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, CPUMGetGuestCS(pVCpu), pInstrGC, DBGF_DISAS_FLAGS_DEFAULT_MODE,
+                                szOutput, sizeof(szOutput), NULL);
+        if (RT_SUCCESS(rc))
+            Log(("Original instr: %s\n", szOutput));
+#endif
+    }
+    pVM->hm.s.cPatches           = 0;
+    pVM->hm.s.PatchTree          = 0;
+    pVM->hm.s.pFreeGuestPatchMem = pVM->hm.s.pGuestPatchMem;
+    pVM->hm.s.fTPRPatchingActive = false;
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Worker for enabling patching in a VT-x/AMD-V guest.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   idCpu       VCPU to execute hmR3RemovePatches on.
+ * @param   pPatchMem   Patch memory range.
+ * @param   cbPatchMem  Size of the memory range.
+ */
+static int hmR3EnablePatching(PVM pVM, VMCPUID idCpu, RTRCPTR pPatchMem, unsigned cbPatchMem)
+{
+    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE, hmR3RemovePatches, (void *)(uintptr_t)idCpu);
+    AssertRC(rc);
+
+    pVM->hm.s.pGuestPatchMem      = pPatchMem;
+    pVM->hm.s.pFreeGuestPatchMem  = pPatchMem;
+    pVM->hm.s.cbGuestPatchMem     = cbPatchMem;
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Enable patching in a VT-x/AMD-V guest
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   pPatchMem   Patch memory range.
+ * @param   cbPatchMem  Size of the memory range.
+ */
+VMMR3DECL(int)  HMR3EnablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem)
+{
+    VM_ASSERT_EMT(pVM);
+    Log(("HMR3EnablePatching %RGv size %x\n", pPatchMem, cbPatchMem));
+    if (pVM->cCpus > 1)
+    {
+        /* We own the IOM lock here and could cause a deadlock by waiting for a VCPU that is blocking on the IOM lock. */
+        int rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE,
+                                   (PFNRT)hmR3EnablePatching, 4, pVM, VMMGetCpuId(pVM), (RTRCPTR)pPatchMem, cbPatchMem);
+        AssertRC(rc);
+        return rc;
+    }
+    return hmR3EnablePatching(pVM, VMMGetCpuId(pVM), (RTRCPTR)pPatchMem, cbPatchMem);
+}
+
+
+/**
+ * Disable patching in a VT-x/AMD-V guest.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   pPatchMem   Patch memory range.
+ * @param   cbPatchMem  Size of the memory range.
+ */
+VMMR3DECL(int)  HMR3DisablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem)
+{
+    Log(("HMR3DisablePatching %RGv size %x\n", pPatchMem, cbPatchMem));
+
+    Assert(pVM->hm.s.pGuestPatchMem == pPatchMem);
+    Assert(pVM->hm.s.cbGuestPatchMem == cbPatchMem);
+
+    /* @todo Potential deadlock when other VCPUs are waiting on the IOM lock (we own it)!! */
+    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE, hmR3RemovePatches, (void *)(uintptr_t)VMMGetCpuId(pVM));
+    AssertRC(rc);
+
+    pVM->hm.s.pGuestPatchMem      = 0;
+    pVM->hm.s.pFreeGuestPatchMem  = 0;
+    pVM->hm.s.cbGuestPatchMem     = 0;
+    pVM->hm.s.fTPRPatchingActive = false;
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Callback to patch a TPR instruction (vmmcall or mov cr8).
+ *
+ * @returns VBox strict status code.
+ * @param   pVM     Pointer to the VM.
+ * @param   pVCpu   The VMCPU for the EMT we're being called on.
+ * @param   pvUser  User specified CPU context.
+ *
+ */
+DECLCALLBACK(VBOXSTRICTRC) hmR3ReplaceTprInstr(PVM pVM, PVMCPU pVCpu, void *pvUser)
+{
+    /*
+     * Only execute the handler on the VCPU the original patch request was
+     * issued. (The other CPU(s) might not yet have switched to protected
+     * mode, nor have the correct memory context.)
+     */
+    VMCPUID         idCpu  = (VMCPUID)(uintptr_t)pvUser;
+    if (pVCpu->idCpu != idCpu)
+        return VINF_SUCCESS;
+
+    /*
+     * We're racing other VCPUs here, so don't try patch the instruction twice
+     * and make sure there is still room for our patch record.
+     */
+    PCPUMCTX        pCtx   = CPUMQueryGuestCtxPtr(pVCpu);
+    PHMTPRPATCH pPatch = (PHMTPRPATCH)RTAvloU32Get(&pVM->hm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
+    if (pPatch)
+    {
+        Log(("hmR3ReplaceTprInstr: already patched %RGv\n", pCtx->rip));
+        return VINF_SUCCESS;
+    }
+    uint32_t const  idx = pVM->hm.s.cPatches;
+    if (idx >= RT_ELEMENTS(pVM->hm.s.aPatches))
+    {
+        Log(("hmR3ReplaceTprInstr: no available patch slots (%RGv)\n", pCtx->rip));
+        return VINF_SUCCESS;
+    }
+    pPatch = &pVM->hm.s.aPatches[idx];
+
+    Log(("hmR3ReplaceTprInstr: rip=%RGv idxPatch=%u\n", pCtx->rip, idx));
+
+    /*
+     * Disassembler the instruction and get cracking.
+     */
+    DBGFR3DisasInstrCurrentLog(pVCpu, "hmR3ReplaceTprInstr");
+    PDISCPUSTATE    pDis = &pVCpu->hm.s.DisState;
+    uint32_t        cbOp;
+    int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
+    AssertRC(rc);
+    if (    rc == VINF_SUCCESS
+        &&  pDis->pCurInstr->uOpcode == OP_MOV
+        &&  cbOp >= 3)
+    {
+        static uint8_t const s_abVMMCall[3] = { 0x0f, 0x01, 0xd9 };
+
+        rc = PGMPhysSimpleReadGCPtr(pVCpu, pPatch->aOpcode, pCtx->rip, cbOp);
+        AssertRC(rc);
+
+        pPatch->cbOp = cbOp;
+
+        if (pDis->Param1.fUse == DISUSE_DISPLACEMENT32)
+        {
+            /* write. */
+            if (pDis->Param2.fUse == DISUSE_REG_GEN32)
+            {
+                pPatch->enmType     = HMTPRINSTR_WRITE_REG;
+                pPatch->uSrcOperand = pDis->Param2.Base.idxGenReg;
+                Log(("hmR3ReplaceTprInstr: HMTPRINSTR_WRITE_REG %u\n", pDis->Param2.Base.idxGenReg));
+            }
+            else
+            {
+                Assert(pDis->Param2.fUse == DISUSE_IMMEDIATE32);
+                pPatch->enmType     = HMTPRINSTR_WRITE_IMM;
+                pPatch->uSrcOperand = pDis->Param2.uValue;
+                Log(("hmR3ReplaceTprInstr: HMTPRINSTR_WRITE_IMM %#llx\n", pDis->Param2.uValue));
+            }
+            rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, s_abVMMCall, sizeof(s_abVMMCall));
+            AssertRC(rc);
+
+            memcpy(pPatch->aNewOpcode, s_abVMMCall, sizeof(s_abVMMCall));
+            pPatch->cbNewOp = sizeof(s_abVMMCall);
+        }
+        else
+        {
+            /*
+             * TPR Read.
+             *
+             * Found:
+             *   mov eax, dword [fffe0080]        (5 bytes)
+             * Check if next instruction is:
+             *   shr eax, 4
+             */
+            Assert(pDis->Param1.fUse == DISUSE_REG_GEN32);
+
+            uint8_t  const idxMmioReg = pDis->Param1.Base.idxGenReg;
+            uint8_t  const cbOpMmio   = cbOp;
+            uint64_t const uSavedRip  = pCtx->rip;
+
+            pCtx->rip += cbOp;
+            rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
+            DBGFR3DisasInstrCurrentLog(pVCpu, "Following read");
+            pCtx->rip = uSavedRip;
+
+            if (    rc == VINF_SUCCESS
+                &&  pDis->pCurInstr->uOpcode == OP_SHR
+                &&  pDis->Param1.fUse == DISUSE_REG_GEN32
+                &&  pDis->Param1.Base.idxGenReg == idxMmioReg
+                &&  pDis->Param2.fUse == DISUSE_IMMEDIATE8
+                &&  pDis->Param2.uValue == 4
+                &&  cbOpMmio + cbOp < sizeof(pVM->hm.s.aPatches[idx].aOpcode))
+            {
+                uint8_t abInstr[15];
+
+                /* Replacing two instructions now. */
+                rc = PGMPhysSimpleReadGCPtr(pVCpu, &pPatch->aOpcode, pCtx->rip, cbOpMmio + cbOp);
+                AssertRC(rc);
+
+                pPatch->cbOp = cbOpMmio + cbOp;
+
+                /* 0xF0, 0x0F, 0x20, 0xC0 = mov eax, cr8 */
+                abInstr[0] = 0xF0;
+                abInstr[1] = 0x0F;
+                abInstr[2] = 0x20;
+                abInstr[3] = 0xC0 | pDis->Param1.Base.idxGenReg;
+                for (unsigned i = 4; i < pPatch->cbOp; i++)
+                    abInstr[i] = 0x90;  /* nop */
+
+                rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, abInstr, pPatch->cbOp);
+                AssertRC(rc);
+
+                memcpy(pPatch->aNewOpcode, abInstr, pPatch->cbOp);
+                pPatch->cbNewOp = pPatch->cbOp;
+
+                Log(("Acceptable read/shr candidate!\n"));
+                pPatch->enmType = HMTPRINSTR_READ_SHR4;
+            }
+            else
+            {
+                pPatch->enmType     = HMTPRINSTR_READ;
+                pPatch->uDstOperand = idxMmioReg;
+
+                rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, s_abVMMCall, sizeof(s_abVMMCall));
+                AssertRC(rc);
+
+                memcpy(pPatch->aNewOpcode, s_abVMMCall, sizeof(s_abVMMCall));
+                pPatch->cbNewOp = sizeof(s_abVMMCall);
+                Log(("hmR3ReplaceTprInstr: HMTPRINSTR_READ %u\n", pPatch->uDstOperand));
+            }
+        }
+
+        pPatch->Core.Key = pCtx->eip;
+        rc = RTAvloU32Insert(&pVM->hm.s.PatchTree, &pPatch->Core);
+        AssertRC(rc);
+
+        pVM->hm.s.cPatches++;
+        STAM_COUNTER_INC(&pVM->hm.s.StatTPRReplaceSuccess);
+        return VINF_SUCCESS;
+    }
+
+    /*
+     * Save invalid patch, so we will not try again.
+     */
+    Log(("hmR3ReplaceTprInstr: Failed to patch instr!\n"));
+    pPatch->Core.Key = pCtx->eip;
+    pPatch->enmType  = HMTPRINSTR_INVALID;
+    rc = RTAvloU32Insert(&pVM->hm.s.PatchTree, &pPatch->Core);
+    AssertRC(rc);
+    pVM->hm.s.cPatches++;
+    STAM_COUNTER_INC(&pVM->hm.s.StatTPRReplaceFailure);
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Callback to patch a TPR instruction (jump to generated code).
+ *
+ * @returns VBox strict status code.
+ * @param   pVM     Pointer to the VM.
+ * @param   pVCpu   The VMCPU for the EMT we're being called on.
+ * @param   pvUser  User specified CPU context.
+ *
+ */
+DECLCALLBACK(VBOXSTRICTRC) hmR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, void *pvUser)
+{
+    /*
+     * Only execute the handler on the VCPU the original patch request was
+     * issued. (The other CPU(s) might not yet have switched to protected
+     * mode, nor have the correct memory context.)
+     */
+    VMCPUID         idCpu  = (VMCPUID)(uintptr_t)pvUser;
+    if (pVCpu->idCpu != idCpu)
+        return VINF_SUCCESS;
+
+    /*
+     * We're racing other VCPUs here, so don't try patch the instruction twice
+     * and make sure there is still room for our patch record.
+     */
+    PCPUMCTX        pCtx   = CPUMQueryGuestCtxPtr(pVCpu);
+    PHMTPRPATCH pPatch = (PHMTPRPATCH)RTAvloU32Get(&pVM->hm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
+    if (pPatch)
+    {
+        Log(("hmR3PatchTprInstr: already patched %RGv\n", pCtx->rip));
+        return VINF_SUCCESS;
+    }
+    uint32_t const  idx = pVM->hm.s.cPatches;
+    if (idx >= RT_ELEMENTS(pVM->hm.s.aPatches))
+    {
+        Log(("hmR3PatchTprInstr: no available patch slots (%RGv)\n", pCtx->rip));
+        return VINF_SUCCESS;
+    }
+    pPatch = &pVM->hm.s.aPatches[idx];
+
+    Log(("hmR3PatchTprInstr: rip=%RGv idxPatch=%u\n", pCtx->rip, idx));
+    DBGFR3DisasInstrCurrentLog(pVCpu, "hmR3PatchTprInstr");
+
+    /*
+     * Disassemble the instruction and get cracking.
+     */
+    PDISCPUSTATE    pDis   = &pVCpu->hm.s.DisState;
+    uint32_t        cbOp;
+    int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
+    AssertRC(rc);
+    if (    rc == VINF_SUCCESS
+        &&  pDis->pCurInstr->uOpcode == OP_MOV
+        &&  cbOp >= 5)
+    {
+        uint8_t         aPatch[64];
+        uint32_t        off = 0;
+
+        rc = PGMPhysSimpleReadGCPtr(pVCpu, pPatch->aOpcode, pCtx->rip, cbOp);
+        AssertRC(rc);
+
+        pPatch->cbOp    = cbOp;
+        pPatch->enmType = HMTPRINSTR_JUMP_REPLACEMENT;
+
+        if (pDis->Param1.fUse == DISUSE_DISPLACEMENT32)
+        {
+            /*
+                * TPR write:
+                *
+                * push ECX                      [51]
+                * push EDX                      [52]
+                * push EAX                      [50]
+                * xor EDX,EDX                   [31 D2]
+                * mov EAX,EAX                   [89 C0]
+                *  or
+                * mov EAX,0000000CCh            [B8 CC 00 00 00]
+                * mov ECX,0C0000082h            [B9 82 00 00 C0]
+                * wrmsr                         [0F 30]
+                * pop EAX                       [58]
+                * pop EDX                       [5A]
+                * pop ECX                       [59]
+                * jmp return_address            [E9 return_address]
+                *
+                */
+            bool fUsesEax = (pDis->Param2.fUse == DISUSE_REG_GEN32 && pDis->Param2.Base.idxGenReg == DISGREG_EAX);
+
+            aPatch[off++] = 0x51;    /* push ecx */
+            aPatch[off++] = 0x52;    /* push edx */
+            if (!fUsesEax)
+                aPatch[off++] = 0x50;    /* push eax */
+            aPatch[off++] = 0x31;    /* xor edx, edx */
+            aPatch[off++] = 0xD2;
+            if (pDis->Param2.fUse == DISUSE_REG_GEN32)
+            {
+                if (!fUsesEax)
+                {
+                    aPatch[off++] = 0x89;    /* mov eax, src_reg */
+                    aPatch[off++] = MAKE_MODRM(3, pDis->Param2.Base.idxGenReg, DISGREG_EAX);
+                }
+            }
+            else
+            {
+                Assert(pDis->Param2.fUse == DISUSE_IMMEDIATE32);
+                aPatch[off++] = 0xB8;    /* mov eax, immediate */
+                *(uint32_t *)&aPatch[off] = pDis->Param2.uValue;
+                off += sizeof(uint32_t);
+            }
+            aPatch[off++] = 0xB9;    /* mov ecx, 0xc0000082 */
+            *(uint32_t *)&aPatch[off] = MSR_K8_LSTAR;
+            off += sizeof(uint32_t);
+
+            aPatch[off++] = 0x0F;    /* wrmsr */
+            aPatch[off++] = 0x30;
+            if (!fUsesEax)
+                aPatch[off++] = 0x58;    /* pop eax */
+            aPatch[off++] = 0x5A;    /* pop edx */
+            aPatch[off++] = 0x59;    /* pop ecx */
+        }
+        else
+        {
+            /*
+                * TPR read:
+                *
+                * push ECX                      [51]
+                * push EDX                      [52]
+                * push EAX                      [50]
+                * mov ECX,0C0000082h            [B9 82 00 00 C0]
+                * rdmsr                         [0F 32]
+                * mov EAX,EAX                   [89 C0]
+                * pop EAX                       [58]
+                * pop EDX                       [5A]
+                * pop ECX                       [59]
+                * jmp return_address            [E9 return_address]
+                *
+                */
+            Assert(pDis->Param1.fUse == DISUSE_REG_GEN32);
+
+            if (pDis->Param1.Base.idxGenReg != DISGREG_ECX)
+                aPatch[off++] = 0x51;    /* push ecx */
+            if (pDis->Param1.Base.idxGenReg != DISGREG_EDX )
+                aPatch[off++] = 0x52;    /* push edx */
+            if (pDis->Param1.Base.idxGenReg != DISGREG_EAX)
+                aPatch[off++] = 0x50;    /* push eax */
+
+            aPatch[off++] = 0x31;    /* xor edx, edx */
+            aPatch[off++] = 0xD2;
+
+            aPatch[off++] = 0xB9;    /* mov ecx, 0xc0000082 */
+            *(uint32_t *)&aPatch[off] = MSR_K8_LSTAR;
+            off += sizeof(uint32_t);
+
+            aPatch[off++] = 0x0F;    /* rdmsr */
+            aPatch[off++] = 0x32;
+
+            if (pDis->Param1.Base.idxGenReg != DISGREG_EAX)
+            {
+                aPatch[off++] = 0x89;    /* mov dst_reg, eax */
+                aPatch[off++] = MAKE_MODRM(3, DISGREG_EAX, pDis->Param1.Base.idxGenReg);
+            }
+
+            if (pDis->Param1.Base.idxGenReg != DISGREG_EAX)
+                aPatch[off++] = 0x58;    /* pop eax */
+            if (pDis->Param1.Base.idxGenReg != DISGREG_EDX )
+                aPatch[off++] = 0x5A;    /* pop edx */
+            if (pDis->Param1.Base.idxGenReg != DISGREG_ECX)
+                aPatch[off++] = 0x59;    /* pop ecx */
+        }
+        aPatch[off++] = 0xE9;    /* jmp return_address */
+        *(RTRCUINTPTR *)&aPatch[off] = ((RTRCUINTPTR)pCtx->eip + cbOp) - ((RTRCUINTPTR)pVM->hm.s.pFreeGuestPatchMem + off + 4);
+        off += sizeof(RTRCUINTPTR);
+
+        if (pVM->hm.s.pFreeGuestPatchMem + off <= pVM->hm.s.pGuestPatchMem + pVM->hm.s.cbGuestPatchMem)
+        {
+            /* Write new code to the patch buffer. */
+            rc = PGMPhysSimpleWriteGCPtr(pVCpu, pVM->hm.s.pFreeGuestPatchMem, aPatch, off);
+            AssertRC(rc);
+
+#ifdef LOG_ENABLED
+            uint32_t cbCurInstr;
+            for (RTGCPTR GCPtrInstr = pVM->hm.s.pFreeGuestPatchMem;
+                 GCPtrInstr < pVM->hm.s.pFreeGuestPatchMem + off;
+                 GCPtrInstr += RT_MAX(cbCurInstr, 1))
+            {
+                char     szOutput[256];
+                rc = DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, pCtx->cs.Sel, GCPtrInstr, DBGF_DISAS_FLAGS_DEFAULT_MODE,
+                                        szOutput, sizeof(szOutput), &cbCurInstr);
+                if (RT_SUCCESS(rc))
+                    Log(("Patch instr %s\n", szOutput));
+                else
+                    Log(("%RGv: rc=%Rrc\n", GCPtrInstr, rc));
+            }
+#endif
+
+            pPatch->aNewOpcode[0] = 0xE9;
+            *(RTRCUINTPTR *)&pPatch->aNewOpcode[1] = ((RTRCUINTPTR)pVM->hm.s.pFreeGuestPatchMem) - ((RTRCUINTPTR)pCtx->eip + 5);
+
+            /* Overwrite the TPR instruction with a jump. */
+            rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->eip, pPatch->aNewOpcode, 5);
+            AssertRC(rc);
+
+            DBGFR3DisasInstrCurrentLog(pVCpu, "Jump");
+
+            pVM->hm.s.pFreeGuestPatchMem += off;
+            pPatch->cbNewOp = 5;
+
+            pPatch->Core.Key = pCtx->eip;
+            rc = RTAvloU32Insert(&pVM->hm.s.PatchTree, &pPatch->Core);
+            AssertRC(rc);
+
+            pVM->hm.s.cPatches++;
+            pVM->hm.s.fTPRPatchingActive = true;
+            STAM_COUNTER_INC(&pVM->hm.s.StatTPRPatchSuccess);
+            return VINF_SUCCESS;
+        }
+
+        Log(("Ran out of space in our patch buffer!\n"));
+    }
+    else
+        Log(("hmR3PatchTprInstr: Failed to patch instr!\n"));
+
+
+    /*
+     * Save invalid patch, so we will not try again.
+     */
+    pPatch = &pVM->hm.s.aPatches[idx];
+    pPatch->Core.Key = pCtx->eip;
+    pPatch->enmType  = HMTPRINSTR_INVALID;
+    rc = RTAvloU32Insert(&pVM->hm.s.PatchTree, &pPatch->Core);
+    AssertRC(rc);
+    pVM->hm.s.cPatches++;
+    STAM_COUNTER_INC(&pVM->hm.s.StatTPRPatchFailure);
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Attempt to patch TPR mmio instructions.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   pCtx        Pointer to the guest CPU context.
+ */
+VMMR3DECL(int) HMR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+    NOREF(pCtx);
+    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE,
+                                pVM->hm.s.pGuestPatchMem ? hmR3PatchTprInstr : hmR3ReplaceTprInstr,
+                                (void *)(uintptr_t)pVCpu->idCpu);
+    AssertRC(rc);
+    return rc;
+}
+
+
+/**
+ * Force execution of the current IO code in the recompiler.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   pCtx        Partial VM execution context.
+ */
+VMMR3DECL(int) HMR3EmulateIoBlock(PVM pVM, PCPUMCTX pCtx)
+{
+    PVMCPU pVCpu = VMMGetCpu(pVM);
+
+    Assert(pVM->fHMEnabled);
+    Log(("HMR3EmulateIoBlock\n"));
+
+    /* This is primarily intended to speed up Grub, so we don't care about paged protected mode. */
+    if (HMCanEmulateIoBlockEx(pCtx))
+    {
+        Log(("HMR3EmulateIoBlock -> enabled\n"));
+        pVCpu->hm.s.EmulateIoBlock.fEnabled         = true;
+        pVCpu->hm.s.EmulateIoBlock.GCPtrFunctionEip = pCtx->rip;
+        pVCpu->hm.s.EmulateIoBlock.cr0              = pCtx->cr0;
+        return VINF_EM_RESCHEDULE_REM;
+    }
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Checks if we can currently use hardware accelerated raw mode.
+ *
+ * @returns true if we can currently use hardware acceleration, otherwise false.
+ * @param   pVM         Pointer to the VM.
+ * @param   pCtx        Partial VM execution context.
+ */
+VMMR3DECL(bool) HMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx)
+{
+    PVMCPU pVCpu = VMMGetCpu(pVM);
+
+    Assert(pVM->fHMEnabled);
+
+    /* If we're still executing the IO code, then return false. */
+    if (    RT_UNLIKELY(pVCpu->hm.s.EmulateIoBlock.fEnabled)
+        &&  pCtx->rip <  pVCpu->hm.s.EmulateIoBlock.GCPtrFunctionEip + 0x200
+        &&  pCtx->rip >  pVCpu->hm.s.EmulateIoBlock.GCPtrFunctionEip - 0x200
+        &&  pCtx->cr0 == pVCpu->hm.s.EmulateIoBlock.cr0)
+        return false;
+
+    pVCpu->hm.s.EmulateIoBlock.fEnabled = false;
+
+    /* AMD-V supports real & protected mode with or without paging. */
+    if (pVM->hm.s.svm.fEnabled)
+    {
+        pVCpu->hm.s.fActive = true;
+        return true;
+    }
+
+    pVCpu->hm.s.fActive = false;
+
+    /* Note! The context supplied by REM is partial. If we add more checks here, be sure to verify that REM provides this info! */
+    Assert((pVM->hm.s.vmx.fUnrestrictedGuest && !pVM->hm.s.vmx.pRealModeTSS) || (!pVM->hm.s.vmx.fUnrestrictedGuest && pVM->hm.s.vmx.pRealModeTSS));
+
+    bool fSupportsRealMode = pVM->hm.s.vmx.fUnrestrictedGuest || PDMVMMDevHeapIsEnabled(pVM);
+    if (!pVM->hm.s.vmx.fUnrestrictedGuest)
+    {
+        /*
+         * The VMM device heap is a requirement for emulating real mode or protected mode without paging with the unrestricted
+         * guest execution feature i missing (VT-x only).
+         */
+        if (fSupportsRealMode)
+        {
+            if (CPUMIsGuestInRealModeEx(pCtx))
+            {
+                /* In V86 mode (VT-x or not), the CPU enforces real-mode compatible selector
+                 * bases and limits, i.e. limit must be 64K and base must be selector * 16.
+                 * If this is not true, we cannot execute real mode as V86 and have to fall
+                 * back to emulation.
+                 */
+                if (   pCtx->cs.Sel != (pCtx->cs.u64Base >> 4)
+                    || pCtx->ds.Sel != (pCtx->ds.u64Base >> 4)
+                    || pCtx->es.Sel != (pCtx->es.u64Base >> 4)
+                    || pCtx->ss.Sel != (pCtx->ss.u64Base >> 4)
+                    || pCtx->fs.Sel != (pCtx->fs.u64Base >> 4)
+                    || pCtx->gs.Sel != (pCtx->gs.u64Base >> 4)
+                    || (pCtx->cs.u32Limit != 0xffff)
+                    || (pCtx->ds.u32Limit != 0xffff)
+                    || (pCtx->es.u32Limit != 0xffff)
+                    || (pCtx->ss.u32Limit != 0xffff)
+                    || (pCtx->fs.u32Limit != 0xffff)
+                    || (pCtx->gs.u32Limit != 0xffff))
+                {
+                    return false;
+                }
+            }
+            else
+            {
+                PGMMODE enmGuestMode = PGMGetGuestMode(pVCpu);
+                /* Verify the requirements for executing code in protected
+                   mode. VT-x can't handle the CPU state right after a switch
+                   from real to protected mode. (all sorts of RPL & DPL assumptions) */
+                if (    pVCpu->hm.s.vmx.enmLastSeenGuestMode == PGMMODE_REAL
+                    &&  enmGuestMode >= PGMMODE_PROTECTED)
+                {
+                    if (   (pCtx->cs.Sel & X86_SEL_RPL)
+                        || (pCtx->ds.Sel & X86_SEL_RPL)
+                        || (pCtx->es.Sel & X86_SEL_RPL)
+                        || (pCtx->fs.Sel & X86_SEL_RPL)
+                        || (pCtx->gs.Sel & X86_SEL_RPL)
+                        || (pCtx->ss.Sel & X86_SEL_RPL))
+                    {
+                        return false;
+                    }
+                }
+                /* VT-x also chokes on invalid tr or ldtr selectors (minix) */
+                if (    pCtx->gdtr.cbGdt
+                    &&  (   pCtx->tr.Sel > pCtx->gdtr.cbGdt
+                         || pCtx->ldtr.Sel > pCtx->gdtr.cbGdt))
+                {
+                        return false;
+                }
+            }
+        }
+        else
+        {
+            if (    !CPUMIsGuestInLongModeEx(pCtx)
+                &&  !pVM->hm.s.vmx.fUnrestrictedGuest)
+            {
+                /** @todo   This should (probably) be set on every excursion to the REM,
+                 *          however it's too risky right now. So, only apply it when we go
+                 *          back to REM for real mode execution. (The XP hack below doesn't
+                 *          work reliably without this.)
+                 *  Update: Implemented in EM.cpp, see #ifdef EM_NOTIFY_HM.  */
+                pVM->aCpus[0].hm.s.fContextUseFlags |= HM_CHANGED_ALL_GUEST;
+
+                if (    !pVM->hm.s.fNestedPaging        /* requires a fake PD for real *and* protected mode without paging - stored in the VMM device heap*/
+                    ||  CPUMIsGuestInRealModeEx(pCtx))      /* requires a fake TSS for real mode - stored in the VMM device heap */
+                    return false;
+
+                /* Too early for VT-x; Solaris guests will fail with a guru meditation otherwise; same for XP. */
+                if (pCtx->idtr.pIdt == 0 || pCtx->idtr.cbIdt == 0 || pCtx->tr.Sel == 0)
+                    return false;
+
+                /* The guest is about to complete the switch to protected mode. Wait a bit longer. */
+                /* Windows XP; switch to protected mode; all selectors are marked not present in the
+                 * hidden registers (possible recompiler bug; see load_seg_vm) */
+                if (pCtx->cs.Attr.n.u1Present == 0)
+                    return false;
+                if (pCtx->ss.Attr.n.u1Present == 0)
+                    return false;
+
+                /* Windows XP: possible same as above, but new recompiler requires new heuristics?
+                   VT-x doesn't seem to like something about the guest state and this stuff avoids it. */
+                /** @todo This check is actually wrong, it doesn't take the direction of the
+                 *        stack segment into account. But, it does the job for now. */
+                if (pCtx->rsp >= pCtx->ss.u32Limit)
+                    return false;
+#if 0
+                if (    pCtx->cs.Sel >= pCtx->gdtr.cbGdt
+                    ||  pCtx->ss.Sel >= pCtx->gdtr.cbGdt
+                    ||  pCtx->ds.Sel >= pCtx->gdtr.cbGdt
+                    ||  pCtx->es.Sel >= pCtx->gdtr.cbGdt
+                    ||  pCtx->fs.Sel >= pCtx->gdtr.cbGdt
+                    ||  pCtx->gs.Sel >= pCtx->gdtr.cbGdt)
+                    return false;
+#endif
+            }
+        }
+    }
+
+    if (pVM->hm.s.vmx.fEnabled)
+    {
+        uint32_t mask;
+
+        /* if bit N is set in cr0_fixed0, then it must be set in the guest's cr0. */
+        mask = (uint32_t)pVM->hm.s.vmx.msr.vmx_cr0_fixed0;
+        /* Note: We ignore the NE bit here on purpose; see vmmr0\hmr0.cpp for details. */
+        mask &= ~X86_CR0_NE;
+
+        if (fSupportsRealMode)
+        {
+            /* Note: We ignore the PE & PG bits here on purpose; we emulate real and protected mode without paging. */
+            mask &= ~(X86_CR0_PG|X86_CR0_PE);
+        }
+        else
+        {
+            /* We support protected mode without paging using identity mapping. */
+            mask &= ~X86_CR0_PG;
+        }
+        if ((pCtx->cr0 & mask) != mask)
+            return false;
+
+        /* if bit N is cleared in cr0_fixed1, then it must be zero in the guest's cr0. */
+        mask = (uint32_t)~pVM->hm.s.vmx.msr.vmx_cr0_fixed1;
+        if ((pCtx->cr0 & mask) != 0)
+            return false;
+
+        /* if bit N is set in cr4_fixed0, then it must be set in the guest's cr4. */
+        mask  = (uint32_t)pVM->hm.s.vmx.msr.vmx_cr4_fixed0;
+        mask &= ~X86_CR4_VMXE;
+        if ((pCtx->cr4 & mask) != mask)
+            return false;
+
+        /* if bit N is cleared in cr4_fixed1, then it must be zero in the guest's cr4. */
+        mask = (uint32_t)~pVM->hm.s.vmx.msr.vmx_cr4_fixed1;
+        if ((pCtx->cr4 & mask) != 0)
+            return false;
+
+        pVCpu->hm.s.fActive = true;
+        return true;
+    }
+
+    return false;
+}
+
+
+/**
+ * Checks if we need to reschedule due to VMM device heap changes.
+ *
+ * @returns true if a reschedule is required, otherwise false.
+ * @param   pVM         Pointer to the VM.
+ * @param   pCtx        VM execution context.
+ */
+VMMR3DECL(bool) HMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx)
+{
+    /*
+     * The VMM device heap is a requirement for emulating real mode or protected mode without paging
+     * when the unrestricted guest execution feature is missing (VT-x only).
+     */
+    if (    pVM->hm.s.vmx.fEnabled
+        &&  !pVM->hm.s.vmx.fUnrestrictedGuest
+        &&  !CPUMIsGuestInPagedProtectedModeEx(pCtx)
+        &&  !PDMVMMDevHeapIsEnabled(pVM)
+        &&  (pVM->hm.s.fNestedPaging || CPUMIsGuestInRealModeEx(pCtx)))
+        return true;
+
+    return false;
+}
+
+
+/**
+ * Notification from EM about a rescheduling into hardware assisted execution
+ * mode.
+ *
+ * @param   pVCpu       Pointer to the current VMCPU.
+ */
+VMMR3DECL(void) HMR3NotifyScheduled(PVMCPU pVCpu)
+{
+    pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_ALL_GUEST;
+}
+
+
+/**
+ * Notification from EM about returning from instruction emulation (REM / EM).
+ *
+ * @param   pVCpu       Pointer to the VMCPU.
+ */
+VMMR3DECL(void) HMR3NotifyEmulated(PVMCPU pVCpu)
+{
+    pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_ALL_GUEST;
+}
+
+
+/**
+ * Checks if we are currently using hardware accelerated raw mode.
+ *
+ * @returns true if hardware acceleration is being used, otherwise false.
+ * @param   pVCpu        Pointer to the VMCPU.
+ */
+VMMR3DECL(bool) HMR3IsActive(PVMCPU pVCpu)
+{
+    return pVCpu->hm.s.fActive;
+}
+
+
+/**
+ * Checks if we are currently using nested paging.
+ *
+ * @returns true if nested paging is being used, otherwise false.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR3DECL(bool) HMR3IsNestedPagingActive(PVM pVM)
+{
+    return pVM->hm.s.fNestedPaging;
+}
+
+
+/**
+ * Checks if we are currently using VPID in VT-x mode.
+ *
+ * @returns true if VPID is being used, otherwise false.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR3DECL(bool) HMR3IsVPIDActive(PVM pVM)
+{
+    return pVM->hm.s.vmx.fVPID;
+}
+
+
+/**
+ * Checks if internal events are pending. In that case we are not allowed to dispatch interrupts.
+ *
+ * @returns true if an internal event is pending, otherwise false.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR3DECL(bool) HMR3IsEventPending(PVMCPU pVCpu)
+{
+    return HMIsEnabled(pVCpu->pVMR3) && pVCpu->hm.s.Event.fPending;
+}
+
+
+/**
+ * Checks if the VMX-preemption timer is being used.
+ *
+ * @returns true if the VMX-preemption timer is being used, otherwise false.
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR3DECL(bool) HMR3IsVmxPreemptionTimerUsed(PVM pVM)
+{
+    return HMIsEnabled(pVM)
+        && pVM->hm.s.vmx.fEnabled
+        && pVM->hm.s.vmx.fUsePreemptTimer;
+}
+
+
+/**
+ * Restart an I/O instruction that was refused in ring-0
+ *
+ * @returns Strict VBox status code. Informational status codes other than the one documented
+ *          here are to be treated as internal failure. Use IOM_SUCCESS() to check for success.
+ * @retval  VINF_SUCCESS                Success.
+ * @retval  VINF_EM_FIRST-VINF_EM_LAST  Success with some exceptions (see IOM_SUCCESS()), the
+ *                                      status code must be passed on to EM.
+ * @retval  VERR_NOT_FOUND if no pending I/O instruction.
+ *
+ * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the VMCPU.
+ * @param   pCtx        Pointer to the guest CPU context.
+ */
+VMMR3DECL(VBOXSTRICTRC) HMR3RestartPendingIOInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+    HMPENDINGIO enmType = pVCpu->hm.s.PendingIO.enmType;
+
+    pVCpu->hm.s.PendingIO.enmType = HMPENDINGIO_INVALID;
+
+    if (    pVCpu->hm.s.PendingIO.GCPtrRip != pCtx->rip
+        ||  enmType  == HMPENDINGIO_INVALID)
+        return VERR_NOT_FOUND;
+
+    VBOXSTRICTRC rcStrict;
+    switch (enmType)
+    {
+        case HMPENDINGIO_PORT_READ:
+        {
+            uint32_t uAndVal = pVCpu->hm.s.PendingIO.s.Port.uAndVal;
+            uint32_t u32Val  = 0;
+
+            rcStrict = IOMIOPortRead(pVM, pVCpu->hm.s.PendingIO.s.Port.uPort,
+                                     &u32Val,
+                                     pVCpu->hm.s.PendingIO.s.Port.cbSize);
+            if (IOM_SUCCESS(rcStrict))
+            {
+                /* Write back to the EAX register. */
+                pCtx->eax = (pCtx->eax & ~uAndVal) | (u32Val & uAndVal);
+                pCtx->rip = pVCpu->hm.s.PendingIO.GCPtrRipNext;
+            }
+            break;
+        }
+
+        case HMPENDINGIO_PORT_WRITE:
+            rcStrict = IOMIOPortWrite(pVM, pVCpu->hm.s.PendingIO.s.Port.uPort,
+                                      pCtx->eax & pVCpu->hm.s.PendingIO.s.Port.uAndVal,
+                                      pVCpu->hm.s.PendingIO.s.Port.cbSize);
+            if (IOM_SUCCESS(rcStrict))
+                pCtx->rip = pVCpu->hm.s.PendingIO.GCPtrRipNext;
+            break;
+
+        default:
+            AssertLogRelFailedReturn(VERR_HM_UNKNOWN_IO_INSTRUCTION);
+    }
+
+    return rcStrict;
+}
+
+
+/**
+ * Inject an NMI into a running VM (only VCPU 0!)
+ *
+ * @returns boolean
+ * @param   pVM         Pointer to the VM.
+ */
+VMMR3DECL(int)  HMR3InjectNMI(PVM pVM)
+{
+    VMCPU_FF_SET(&pVM->aCpus[0], VMCPU_FF_INTERRUPT_NMI);
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Check fatal VT-x/AMD-V error and produce some meaningful
+ * log release message.
+ *
+ * @param   pVM         Pointer to the VM.
+ * @param   iStatusCode VBox status code.
+ */
+VMMR3DECL(void) HMR3CheckError(PVM pVM, int iStatusCode)
+{
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+    {
+        switch (iStatusCode)
+        {
+            case VERR_VMX_INVALID_VMCS_FIELD:
+                break;
+
+            case VERR_VMX_INVALID_VMCS_PTR:
+                LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Current pointer %RGp vs %RGp\n", i, pVM->aCpus[i].hm.s.vmx.lasterror.u64VMCSPhys, pVM->aCpus[i].hm.s.vmx.HCPhysVMCS));
+                LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Current VMCS version %x\n", i, pVM->aCpus[i].hm.s.vmx.lasterror.ulVMCSRevision));
+                LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Entered Cpu %d\n", i, pVM->aCpus[i].hm.s.vmx.lasterror.idEnteredCpu));
+                LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Current Cpu %d\n", i, pVM->aCpus[i].hm.s.vmx.lasterror.idCurrentCpu));
+                break;
+
+            case VERR_VMX_UNABLE_TO_START_VM:
+                LogRel(("VERR_VMX_UNABLE_TO_START_VM: CPU%d instruction error %x\n", i, pVM->aCpus[i].hm.s.vmx.lasterror.ulInstrError));
+                LogRel(("VERR_VMX_UNABLE_TO_START_VM: CPU%d exit reason       %x\n", i, pVM->aCpus[i].hm.s.vmx.lasterror.ulExitReason));
+                if (pVM->aCpus[i].hm.s.vmx.lasterror.ulInstrError == VMX_ERROR_VMENTRY_INVALID_CONTROL_FIELDS)
+                {
+                    LogRel(("VERR_VMX_UNABLE_TO_START_VM: Cpu%d MSRBitmapPhys %RHp\n", i, pVM->aCpus[i].hm.s.vmx.pMSRBitmapPhys));
+#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
+                    LogRel(("VERR_VMX_UNABLE_TO_START_VM: Cpu%d GuestMSRPhys  %RHp\n", i, pVM->aCpus[i].hm.s.vmx.pGuestMSRPhys));
+                    LogRel(("VERR_VMX_UNABLE_TO_START_VM: Cpu%d HostMsrPhys   %RHp\n", i, pVM->aCpus[i].hm.s.vmx.pHostMSRPhys));
+                    LogRel(("VERR_VMX_UNABLE_TO_START_VM: Cpu%d Cached MSRs   %x\n",   i, pVM->aCpus[i].hm.s.vmx.cCachedMSRs));
+#endif
+                }
+                /** @todo Log VM-entry event injection control fields
+                 *        VMX_VMCS_CTRL_ENTRY_IRQ_INFO, VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE
+                 *        and VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH from the VMCS. */
+                break;
+
+            case VERR_VMX_UNABLE_TO_RESUME_VM:
+                LogRel(("VERR_VMX_UNABLE_TO_RESUME_VM: CPU%d instruction error %x\n", i, pVM->aCpus[i].hm.s.vmx.lasterror.ulInstrError));
+                LogRel(("VERR_VMX_UNABLE_TO_RESUME_VM: CPU%d exit reason       %x\n", i, pVM->aCpus[i].hm.s.vmx.lasterror.ulExitReason));
+                break;
+
+            case VERR_VMX_INVALID_VMXON_PTR:
+                break;
+        }
+    }
+
+    if (iStatusCode == VERR_VMX_UNABLE_TO_START_VM)
+    {
+        LogRel(("VERR_VMX_UNABLE_TO_START_VM: VM-entry allowed    %x\n", pVM->hm.s.vmx.msr.vmx_entry.n.allowed1));
+        LogRel(("VERR_VMX_UNABLE_TO_START_VM: VM-entry disallowed %x\n", pVM->hm.s.vmx.msr.vmx_entry.n.disallowed0));
+    }
+}
+
+
+/**
+ * Execute state save operation.
+ *
+ * @returns VBox status code.
+ * @param   pVM             Pointer to the VM.
+ * @param   pSSM            SSM operation handle.
+ */
+static DECLCALLBACK(int) hmR3Save(PVM pVM, PSSMHANDLE pSSM)
+{
+    int rc;
+
+    Log(("hmR3Save:\n"));
+
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+    {
+        /*
+         * Save the basic bits - fortunately all the other things can be resynced on load.
+         */
+        rc = SSMR3PutU32(pSSM, pVM->aCpus[i].hm.s.Event.fPending);
+        AssertRCReturn(rc, rc);
+        rc = SSMR3PutU32(pSSM, pVM->aCpus[i].hm.s.Event.errCode);
+        AssertRCReturn(rc, rc);
+        rc = SSMR3PutU64(pSSM, pVM->aCpus[i].hm.s.Event.intInfo);
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutU32(pSSM, pVM->aCpus[i].hm.s.vmx.enmLastSeenGuestMode);
+        AssertRCReturn(rc, rc);
+        rc = SSMR3PutU32(pSSM, pVM->aCpus[i].hm.s.vmx.enmCurrGuestMode);
+        AssertRCReturn(rc, rc);
+        rc = SSMR3PutU32(pSSM, pVM->aCpus[i].hm.s.vmx.enmPrevGuestMode);
+        AssertRCReturn(rc, rc);
+    }
+#ifdef VBOX_HM_WITH_GUEST_PATCHING
+    rc = SSMR3PutGCPtr(pSSM, pVM->hm.s.pGuestPatchMem);
+    AssertRCReturn(rc, rc);
+    rc = SSMR3PutGCPtr(pSSM, pVM->hm.s.pFreeGuestPatchMem);
+    AssertRCReturn(rc, rc);
+    rc = SSMR3PutU32(pSSM, pVM->hm.s.cbGuestPatchMem);
+    AssertRCReturn(rc, rc);
+
+    /* Store all the guest patch records too. */
+    rc = SSMR3PutU32(pSSM, pVM->hm.s.cPatches);
+    AssertRCReturn(rc, rc);
+
+    for (unsigned i = 0; i < pVM->hm.s.cPatches; i++)
+    {
+        PHMTPRPATCH pPatch = &pVM->hm.s.aPatches[i];
+
+        rc = SSMR3PutU32(pSSM, pPatch->Core.Key);
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutMem(pSSM, pPatch->aOpcode, sizeof(pPatch->aOpcode));
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutU32(pSSM, pPatch->cbOp);
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutMem(pSSM, pPatch->aNewOpcode, sizeof(pPatch->aNewOpcode));
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutU32(pSSM, pPatch->cbNewOp);
+        AssertRCReturn(rc, rc);
+
+        AssertCompileSize(HMTPRINSTR, 4);
+        rc = SSMR3PutU32(pSSM, (uint32_t)pPatch->enmType);
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutU32(pSSM, pPatch->uSrcOperand);
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutU32(pSSM, pPatch->uDstOperand);
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutU32(pSSM, pPatch->pJumpTarget);
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutU32(pSSM, pPatch->cFaults);
+        AssertRCReturn(rc, rc);
+    }
+#endif
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Execute state load operation.
+ *
+ * @returns VBox status code.
+ * @param   pVM             Pointer to the VM.
+ * @param   pSSM            SSM operation handle.
+ * @param   uVersion        Data layout version.
+ * @param   uPass           The data pass.
+ */
+static DECLCALLBACK(int) hmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
+{
+    int rc;
+
+    Log(("hmR3Load:\n"));
+    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
+
+    /*
+     * Validate version.
+     */
+    if (   uVersion != HM_SSM_VERSION
+        && uVersion != HM_SSM_VERSION_NO_PATCHING
+        && uVersion != HM_SSM_VERSION_2_0_X)
+    {
+        AssertMsgFailed(("hmR3Load: Invalid version uVersion=%d!\n", uVersion));
+        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
+    }
+    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+    {
+        rc = SSMR3GetU32(pSSM, &pVM->aCpus[i].hm.s.Event.fPending);
+        AssertRCReturn(rc, rc);
+        rc = SSMR3GetU32(pSSM, &pVM->aCpus[i].hm.s.Event.errCode);
+        AssertRCReturn(rc, rc);
+        rc = SSMR3GetU64(pSSM, &pVM->aCpus[i].hm.s.Event.intInfo);
+        AssertRCReturn(rc, rc);
+
+        if (uVersion >= HM_SSM_VERSION_NO_PATCHING)
+        {
+            uint32_t val;
+
+            rc = SSMR3GetU32(pSSM, &val);
+            AssertRCReturn(rc, rc);
+            pVM->aCpus[i].hm.s.vmx.enmLastSeenGuestMode = (PGMMODE)val;
+
+            rc = SSMR3GetU32(pSSM, &val);
+            AssertRCReturn(rc, rc);
+            pVM->aCpus[i].hm.s.vmx.enmCurrGuestMode = (PGMMODE)val;
+
+            rc = SSMR3GetU32(pSSM, &val);
+            AssertRCReturn(rc, rc);
+            pVM->aCpus[i].hm.s.vmx.enmPrevGuestMode = (PGMMODE)val;
+        }
+    }
+#ifdef VBOX_HM_WITH_GUEST_PATCHING
+    if (uVersion > HM_SSM_VERSION_NO_PATCHING)
+    {
+        rc = SSMR3GetGCPtr(pSSM, &pVM->hm.s.pGuestPatchMem);
+        AssertRCReturn(rc, rc);
+        rc = SSMR3GetGCPtr(pSSM, &pVM->hm.s.pFreeGuestPatchMem);
+        AssertRCReturn(rc, rc);
+        rc = SSMR3GetU32(pSSM, &pVM->hm.s.cbGuestPatchMem);
+        AssertRCReturn(rc, rc);
+
+        /* Fetch all TPR patch records. */
+        rc = SSMR3GetU32(pSSM, &pVM->hm.s.cPatches);
+        AssertRCReturn(rc, rc);
+
+        for (unsigned i = 0; i < pVM->hm.s.cPatches; i++)
+        {
+            PHMTPRPATCH pPatch = &pVM->hm.s.aPatches[i];
+
+            rc = SSMR3GetU32(pSSM, &pPatch->Core.Key);
+            AssertRCReturn(rc, rc);
+
+            rc = SSMR3GetMem(pSSM, pPatch->aOpcode, sizeof(pPatch->aOpcode));
+            AssertRCReturn(rc, rc);
+
+            rc = SSMR3GetU32(pSSM, &pPatch->cbOp);
+            AssertRCReturn(rc, rc);
+
+            rc = SSMR3GetMem(pSSM, pPatch->aNewOpcode, sizeof(pPatch->aNewOpcode));
+            AssertRCReturn(rc, rc);
+
+            rc = SSMR3GetU32(pSSM, &pPatch->cbNewOp);
+            AssertRCReturn(rc, rc);
+
+            rc = SSMR3GetU32(pSSM, (uint32_t *)&pPatch->enmType);
+            AssertRCReturn(rc, rc);
+
+            if (pPatch->enmType == HMTPRINSTR_JUMP_REPLACEMENT)
+                pVM->hm.s.fTPRPatchingActive = true;
+
+            Assert(pPatch->enmType == HMTPRINSTR_JUMP_REPLACEMENT || pVM->hm.s.fTPRPatchingActive == false);
+
+            rc = SSMR3GetU32(pSSM, &pPatch->uSrcOperand);
+            AssertRCReturn(rc, rc);
+
+            rc = SSMR3GetU32(pSSM, &pPatch->uDstOperand);
+            AssertRCReturn(rc, rc);
+
+            rc = SSMR3GetU32(pSSM, &pPatch->cFaults);
+            AssertRCReturn(rc, rc);
+
+            rc = SSMR3GetU32(pSSM, &pPatch->pJumpTarget);
+            AssertRCReturn(rc, rc);
+
+            Log(("hmR3Load: patch %d\n", i));
+            Log(("Key       = %x\n", pPatch->Core.Key));
+            Log(("cbOp      = %d\n", pPatch->cbOp));
+            Log(("cbNewOp   = %d\n", pPatch->cbNewOp));
+            Log(("type      = %d\n", pPatch->enmType));
+            Log(("srcop     = %d\n", pPatch->uSrcOperand));
+            Log(("dstop     = %d\n", pPatch->uDstOperand));
+            Log(("cFaults   = %d\n", pPatch->cFaults));
+            Log(("target    = %x\n", pPatch->pJumpTarget));
+            rc = RTAvloU32Insert(&pVM->hm.s.PatchTree, &pPatch->Core);
+            AssertRC(rc);
+        }
+    }
+#endif
+
+    /* Recheck all VCPUs if we can go straight into hm execution mode. */
+    if (HMIsEnabled(pVM))
+    {
+        for (VMCPUID i = 0; i < pVM->cCpus; i++)
+        {
+            PVMCPU pVCpu = &pVM->aCpus[i];
+
+            HMR3CanExecuteGuest(pVM, CPUMQueryGuestCtxPtr(pVCpu));
+        }
+    }
+    return VINF_SUCCESS;
+}
+
Index: trunk/src/VBox/VMM/VMMR3/HWACCM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/HWACCM.cpp	(revision 43379)
+++ 	(revision )
@@ -1,2935 +1,0 @@
-/* $Id$ */
-/** @file
- * HWACCM - Intel/AMD VM Hardware Support Manager.
- */
-
-/*
- * 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;
- * 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.
- */
-
-/*******************************************************************************
-*   Header Files                                                               *
-*******************************************************************************/
-#define LOG_GROUP LOG_GROUP_HWACCM
-#include <VBox/vmm/cpum.h>
-#include <VBox/vmm/stam.h>
-#include <VBox/vmm/mm.h>
-#include <VBox/vmm/pdmapi.h>
-#include <VBox/vmm/pgm.h>
-#include <VBox/vmm/ssm.h>
-#include <VBox/vmm/trpm.h>
-#include <VBox/vmm/dbgf.h>
-#include <VBox/vmm/iom.h>
-#include <VBox/vmm/patm.h>
-#include <VBox/vmm/csam.h>
-#include <VBox/vmm/selm.h>
-#ifdef VBOX_WITH_REM
-# include <VBox/vmm/rem.h>
-#endif
-#include <VBox/vmm/hwacc_vmx.h>
-#include <VBox/vmm/hwacc_svm.h>
-#include "HWACCMInternal.h"
-#include <VBox/vmm/vm.h>
-#include <VBox/err.h>
-#include <VBox/param.h>
-
-#include <iprt/assert.h>
-#include <VBox/log.h>
-#include <iprt/asm.h>
-#include <iprt/asm-amd64-x86.h>
-#include <iprt/string.h>
-#include <iprt/env.h>
-#include <iprt/thread.h>
-
-/*******************************************************************************
-*   Global Variables                                                           *
-*******************************************************************************/
-#ifdef VBOX_WITH_STATISTICS
-# define EXIT_REASON(def, val, str) #def " - " #val " - " str
-# define EXIT_REASON_NIL() NULL
-/** Exit reason descriptions for VT-x, used to describe statistics. */
-static const char * const g_apszVTxExitReasons[MAX_EXITREASON_STAT] =
-{
-    EXIT_REASON(VMX_EXIT_EXCEPTION          ,  0, "Exception or non-maskable interrupt (NMI)."),
-    EXIT_REASON(VMX_EXIT_EXTERNAL_IRQ       ,  1, "External interrupt."),
-    EXIT_REASON(VMX_EXIT_TRIPLE_FAULT       ,  2, "Triple fault."),
-    EXIT_REASON(VMX_EXIT_INIT_SIGNAL        ,  3, "INIT signal."),
-    EXIT_REASON(VMX_EXIT_SIPI               ,  4, "Start-up IPI (SIPI)."),
-    EXIT_REASON(VMX_EXIT_IO_SMI_IRQ         ,  5, "I/O system-management interrupt (SMI)."),
-    EXIT_REASON(VMX_EXIT_SMI_IRQ            ,  6, "Other SMI."),
-    EXIT_REASON(VMX_EXIT_IRQ_WINDOW         ,  7, "Interrupt window."),
-    EXIT_REASON_NIL(),
-    EXIT_REASON(VMX_EXIT_TASK_SWITCH        ,  9, "Task switch."),
-    EXIT_REASON(VMX_EXIT_CPUID              , 10, "Guest software attempted to execute CPUID."),
-    EXIT_REASON_NIL(),
-    EXIT_REASON(VMX_EXIT_HLT                , 12, "Guest software attempted to execute HLT."),
-    EXIT_REASON(VMX_EXIT_INVD               , 13, "Guest software attempted to execute INVD."),
-    EXIT_REASON(VMX_EXIT_INVLPG             , 14, "Guest software attempted to execute INVLPG."),
-    EXIT_REASON(VMX_EXIT_RDPMC              , 15, "Guest software attempted to execute RDPMC."),
-    EXIT_REASON(VMX_EXIT_RDTSC              , 16, "Guest software attempted to execute RDTSC."),
-    EXIT_REASON(VMX_EXIT_RSM                , 17, "Guest software attempted to execute RSM in SMM."),
-    EXIT_REASON(VMX_EXIT_VMCALL             , 18, "Guest software executed VMCALL."),
-    EXIT_REASON(VMX_EXIT_VMCLEAR            , 19, "Guest software executed VMCLEAR."),
-    EXIT_REASON(VMX_EXIT_VMLAUNCH           , 20, "Guest software executed VMLAUNCH."),
-    EXIT_REASON(VMX_EXIT_VMPTRLD            , 21, "Guest software executed VMPTRLD."),
-    EXIT_REASON(VMX_EXIT_VMPTRST            , 22, "Guest software executed VMPTRST."),
-    EXIT_REASON(VMX_EXIT_VMREAD             , 23, "Guest software executed VMREAD."),
-    EXIT_REASON(VMX_EXIT_VMRESUME           , 24, "Guest software executed VMRESUME."),
-    EXIT_REASON(VMX_EXIT_VMWRITE            , 25, "Guest software executed VMWRITE."),
-    EXIT_REASON(VMX_EXIT_VMXOFF             , 26, "Guest software executed VMXOFF."),
-    EXIT_REASON(VMX_EXIT_VMXON              , 27, "Guest software executed VMXON."),
-    EXIT_REASON(VMX_EXIT_CRX_MOVE           , 28, "Control-register accesses."),
-    EXIT_REASON(VMX_EXIT_DRX_MOVE           , 29, "Debug-register accesses."),
-    EXIT_REASON(VMX_EXIT_PORT_IO            , 30, "I/O instruction."),
-    EXIT_REASON(VMX_EXIT_RDMSR              , 31, "RDMSR. Guest software attempted to execute RDMSR."),
-    EXIT_REASON(VMX_EXIT_WRMSR              , 32, "WRMSR. Guest software attempted to execute WRMSR."),
-    EXIT_REASON(VMX_EXIT_ERR_INVALID_GUEST_STATE,  33, "VM-entry failure due to invalid guest state."),
-    EXIT_REASON(VMX_EXIT_ERR_MSR_LOAD       , 34, "VM-entry failure due to MSR loading."),
-    EXIT_REASON_NIL(),
-    EXIT_REASON(VMX_EXIT_MWAIT              , 36, "Guest software executed MWAIT."),
-    EXIT_REASON(VMX_EXIT_MTF                , 37, "Monitor Trap Flag."),
-    EXIT_REASON_NIL(),
-    EXIT_REASON(VMX_EXIT_MONITOR            , 39, "Guest software attempted to execute MONITOR."),
-    EXIT_REASON(VMX_EXIT_PAUSE              , 40, "Guest software attempted to execute PAUSE."),
-    EXIT_REASON(VMX_EXIT_ERR_MACHINE_CHECK  , 41, "VM-entry failure due to machine-check."),
-    EXIT_REASON_NIL(),
-    EXIT_REASON(VMX_EXIT_TPR                , 43, "TPR below threshold. Guest software executed MOV to CR8."),
-    EXIT_REASON(VMX_EXIT_APIC_ACCESS        , 44, "APIC access. Guest software attempted to access memory at a physical address on the APIC-access page."),
-    EXIT_REASON_NIL(),
-    EXIT_REASON(VMX_EXIT_XDTR_ACCESS        , 46, "Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT."),
-    EXIT_REASON(VMX_EXIT_TR_ACCESS          , 47, "Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR."),
-    EXIT_REASON(VMX_EXIT_EPT_VIOLATION      , 48, "EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures."),
-    EXIT_REASON(VMX_EXIT_EPT_MISCONFIG      , 49, "EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry."),
-    EXIT_REASON(VMX_EXIT_INVEPT             , 50, "INVEPT. Guest software attempted to execute INVEPT."),
-    EXIT_REASON(VMX_EXIT_RDTSCP             , 51, "Guest software attempted to execute RDTSCP."),
-    EXIT_REASON(VMX_EXIT_PREEMPTION_TIMER   , 52, "VMX-preemption timer expired. The preemption timer counted down to zero."),
-    EXIT_REASON(VMX_EXIT_INVVPID            , 53, "INVVPID. Guest software attempted to execute INVVPID."),
-    EXIT_REASON(VMX_EXIT_WBINVD             , 54, "WBINVD. Guest software attempted to execute WBINVD."),
-    EXIT_REASON(VMX_EXIT_XSETBV             , 55, "XSETBV. Guest software attempted to execute XSETBV."),
-    EXIT_REASON_NIL()
-};
-/** Exit reason descriptions for AMD-V, used to describe statistics. */
-static const char * const g_apszAmdVExitReasons[MAX_EXITREASON_STAT] =
-{
-    EXIT_REASON(SVM_EXIT_READ_CR0                   ,  0, "Read CR0."),
-    EXIT_REASON(SVM_EXIT_READ_CR1                   ,  1, "Read CR1."),
-    EXIT_REASON(SVM_EXIT_READ_CR2                   ,  2, "Read CR2."),
-    EXIT_REASON(SVM_EXIT_READ_CR3                   ,  3, "Read CR3."),
-    EXIT_REASON(SVM_EXIT_READ_CR4                   ,  4, "Read CR4."),
-    EXIT_REASON(SVM_EXIT_READ_CR5                   ,  5, "Read CR5."),
-    EXIT_REASON(SVM_EXIT_READ_CR6                   ,  6, "Read CR6."),
-    EXIT_REASON(SVM_EXIT_READ_CR7                   ,  7, "Read CR7."),
-    EXIT_REASON(SVM_EXIT_READ_CR8                   ,  8, "Read CR8."),
-    EXIT_REASON(SVM_EXIT_READ_CR9                   ,  9, "Read CR9."),
-    EXIT_REASON(SVM_EXIT_READ_CR10                  , 10, "Read CR10."),
-    EXIT_REASON(SVM_EXIT_READ_CR11                  , 11, "Read CR11."),
-    EXIT_REASON(SVM_EXIT_READ_CR12                  , 12, "Read CR12."),
-    EXIT_REASON(SVM_EXIT_READ_CR13                  , 13, "Read CR13."),
-    EXIT_REASON(SVM_EXIT_READ_CR14                  , 14, "Read CR14."),
-    EXIT_REASON(SVM_EXIT_READ_CR15                  , 15, "Read CR15."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR0                  , 16, "Write CR0."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR1                  , 17, "Write CR1."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR2                  , 18, "Write CR2."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR3                  , 19, "Write CR3."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR4                  , 20, "Write CR4."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR5                  , 21, "Write CR5."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR6                  , 22, "Write CR6."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR7                  , 23, "Write CR7."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR8                  , 24, "Write CR8."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR9                  , 25, "Write CR9."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR10                 , 26, "Write CR10."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR11                 , 27, "Write CR11."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR12                 , 28, "Write CR12."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR13                 , 29, "Write CR13."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR14                 , 30, "Write CR14."),
-    EXIT_REASON(SVM_EXIT_WRITE_CR15                 , 31, "Write CR15."),
-    EXIT_REASON(SVM_EXIT_READ_DR0                   , 32, "Read DR0."),
-    EXIT_REASON(SVM_EXIT_READ_DR1                   , 33, "Read DR1."),
-    EXIT_REASON(SVM_EXIT_READ_DR2                   , 34, "Read DR2."),
-    EXIT_REASON(SVM_EXIT_READ_DR3                   , 35, "Read DR3."),
-    EXIT_REASON(SVM_EXIT_READ_DR4                   , 36, "Read DR4."),
-    EXIT_REASON(SVM_EXIT_READ_DR5                   , 37, "Read DR5."),
-    EXIT_REASON(SVM_EXIT_READ_DR6                   , 38, "Read DR6."),
-    EXIT_REASON(SVM_EXIT_READ_DR7                   , 39, "Read DR7."),
-    EXIT_REASON(SVM_EXIT_READ_DR8                   , 40, "Read DR8."),
-    EXIT_REASON(SVM_EXIT_READ_DR9                   , 41, "Read DR9."),
-    EXIT_REASON(SVM_EXIT_READ_DR10                  , 42, "Read DR10."),
-    EXIT_REASON(SVM_EXIT_READ_DR11                  , 43, "Read DR11"),
-    EXIT_REASON(SVM_EXIT_READ_DR12                  , 44, "Read DR12."),
-    EXIT_REASON(SVM_EXIT_READ_DR13                  , 45, "Read DR13."),
-    EXIT_REASON(SVM_EXIT_READ_DR14                  , 46, "Read DR14."),
-    EXIT_REASON(SVM_EXIT_READ_DR15                  , 47, "Read DR15."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR0                  , 48, "Write DR0."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR1                  , 49, "Write DR1."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR2                  , 50, "Write DR2."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR3                  , 51, "Write DR3."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR4                  , 52, "Write DR4."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR5                  , 53, "Write DR5."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR6                  , 54, "Write DR6."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR7                  , 55, "Write DR7."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR8                  , 56, "Write DR8."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR9                  , 57, "Write DR9."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR10                 , 58, "Write DR10."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR11                 , 59, "Write DR11."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR12                 , 60, "Write DR12."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR13                 , 61, "Write DR13."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR14                 , 62, "Write DR14."),
-    EXIT_REASON(SVM_EXIT_WRITE_DR15                 , 63, "Write DR15."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_0                , 64, "Exception Vector 0  (0x0)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_1                , 65, "Exception Vector 1  (0x1)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_2                , 66, "Exception Vector 2  (0x2)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_3                , 67, "Exception Vector 3  (0x3)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_4                , 68, "Exception Vector 4  (0x4)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_5                , 69, "Exception Vector 5  (0x5)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_6                , 70, "Exception Vector 6  (0x6)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_7                , 71, "Exception Vector 7  (0x7)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_8                , 72, "Exception Vector 8  (0x8)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_9                , 73, "Exception Vector 9  (0x9)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_A                , 74, "Exception Vector 10 (0xA)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_B                , 75, "Exception Vector 11 (0xB)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_C                , 76, "Exception Vector 12 (0xC)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_D                , 77, "Exception Vector 13 (0xD)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_E                , 78, "Exception Vector 14 (0xE)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_F                , 79, "Exception Vector 15 (0xF)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_10               , 80, "Exception Vector 16 (0x10)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_11               , 81, "Exception Vector 17 (0x11)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_12               , 82, "Exception Vector 18 (0x12)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_13               , 83, "Exception Vector 19 (0x13)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_14               , 84, "Exception Vector 20 (0x14)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_15               , 85, "Exception Vector 22 (0x15)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_16               , 86, "Exception Vector 22 (0x16)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_17               , 87, "Exception Vector 23 (0x17)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_18               , 88, "Exception Vector 24 (0x18)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_19               , 89, "Exception Vector 25 (0x19)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_1A               , 90, "Exception Vector 26 (0x1A)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_1B               , 91, "Exception Vector 27 (0x1B)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_1C               , 92, "Exception Vector 28 (0x1C)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_1D               , 93, "Exception Vector 29 (0x1D)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_1E               , 94, "Exception Vector 30 (0x1E)."),
-    EXIT_REASON(SVM_EXIT_EXCEPTION_1F               , 95, "Exception Vector 31 (0x1F)."),
-    EXIT_REASON(SVM_EXIT_INTR                       , 96, "Physical maskable interrupt."),
-    EXIT_REASON(SVM_EXIT_NMI                        , 97, "Physical non-maskable interrupt."),
-    EXIT_REASON(SVM_EXIT_SMI                        , 98, "System management interrupt."),
-    EXIT_REASON(SVM_EXIT_INIT                       , 99, "Physical INIT signal."),
-    EXIT_REASON(SVM_EXIT_VINTR                      ,100, "Virtual interrupt."),
-    EXIT_REASON(SVM_EXIT_CR0_SEL_WRITE              ,101, "Write to CR0 that changed any bits other than CR0.TS or CR0.MP."),
-    EXIT_REASON(SVM_EXIT_IDTR_READ                  ,102, "Read IDTR"),
-    EXIT_REASON(SVM_EXIT_GDTR_READ                  ,103, "Read GDTR"),
-    EXIT_REASON(SVM_EXIT_LDTR_READ                  ,104, "Read LDTR."),
-    EXIT_REASON(SVM_EXIT_TR_READ                    ,105, "Read TR."),
-    EXIT_REASON(SVM_EXIT_TR_READ                    ,106, "Write IDTR."),
-    EXIT_REASON(SVM_EXIT_TR_READ                    ,107, "Write GDTR."),
-    EXIT_REASON(SVM_EXIT_TR_READ                    ,108, "Write LDTR."),
-    EXIT_REASON(SVM_EXIT_TR_READ                    ,109, "Write TR."),
-    EXIT_REASON(SVM_EXIT_RDTSC                      ,110, "RDTSC instruction."),
-    EXIT_REASON(SVM_EXIT_RDPMC                      ,111, "RDPMC instruction."),
-    EXIT_REASON(SVM_EXIT_PUSHF                      ,112, "PUSHF instruction."),
-    EXIT_REASON(SVM_EXIT_POPF                       ,113, "POPF instruction."),
-    EXIT_REASON(SVM_EXIT_CPUID                      ,114, "CPUID instruction."),
-    EXIT_REASON(SVM_EXIT_RSM                        ,115, "RSM instruction."),
-    EXIT_REASON(SVM_EXIT_IRET                       ,116, "IRET instruction."),
-    EXIT_REASON(SVM_EXIT_SWINT                      ,117, "Software interrupt (INTn instructions)."),
-    EXIT_REASON(SVM_EXIT_INVD                       ,118, "INVD instruction."),
-    EXIT_REASON(SVM_EXIT_PAUSE                      ,119, "PAUSE instruction."),
-    EXIT_REASON(SVM_EXIT_HLT                        ,120, "HLT instruction."),
-    EXIT_REASON(SVM_EXIT_INVLPG                     ,121, "INVLPG instruction."),
-    EXIT_REASON(SVM_EXIT_INVLPGA                    ,122, "INVLPGA instruction."),
-    EXIT_REASON(SVM_EXIT_IOIO                       ,123, "IN/OUT accessing protected port (EXITINFO1 field provides more information)."),
-    EXIT_REASON(SVM_EXIT_MSR                        ,124, "RDMSR or WRMSR access to protected MSR."),
-    EXIT_REASON(SVM_EXIT_TASK_SWITCH                ,125, "Task switch."),
-    EXIT_REASON(SVM_EXIT_FERR_FREEZE                ,126, "FP legacy handling enabled, and processor is frozen in an x87/mmx instruction waiting for an interrupt"),
-    EXIT_REASON(SVM_EXIT_SHUTDOWN                   ,127, "Shutdown."),
-    EXIT_REASON(SVM_EXIT_VMRUN                      ,128, "VMRUN instruction."),
-    EXIT_REASON(SVM_EXIT_VMMCALL                    ,129, "VMCALL instruction."),
-    EXIT_REASON(SVM_EXIT_VMLOAD                     ,130, "VMLOAD instruction."),
-    EXIT_REASON(SVM_EXIT_VMSAVE                     ,131, "VMSAVE instruction."),
-    EXIT_REASON(SVM_EXIT_STGI                       ,132, "STGI instruction."),
-    EXIT_REASON(SVM_EXIT_CLGI                       ,133, "CLGI instruction."),
-    EXIT_REASON(SVM_EXIT_SKINIT                     ,134, "SKINIT instruction."),
-    EXIT_REASON(SVM_EXIT_RDTSCP                     ,135, "RDTSCP instruction."),
-    EXIT_REASON(SVM_EXIT_ICEBP                      ,136, "ICEBP instruction."),
-    EXIT_REASON(SVM_EXIT_WBINVD                     ,137, "WBINVD instruction."),
-    EXIT_REASON(SVM_EXIT_MONITOR                    ,138, "MONITOR instruction."),
-    EXIT_REASON(SVM_EXIT_MWAIT_UNCOND               ,139, "MWAIT instruction unconditional."),
-    EXIT_REASON(SVM_EXIT_MWAIT_ARMED                ,140, "MWAIT instruction when armed."),
-    EXIT_REASON(SVM_EXIT_NPF                        ,1024, "Nested paging: host-level page fault occurred (EXITINFO1 contains fault errorcode; EXITINFO2 contains the guest physical address causing the fault)."),
-    EXIT_REASON_NIL()
-};
-# undef EXIT_REASON
-# undef EXIT_REASON_NIL
-#endif /* VBOX_WITH_STATISTICS */
-
-/*******************************************************************************
-*   Internal Functions                                                         *
-*******************************************************************************/
-static DECLCALLBACK(int) hwaccmR3Save(PVM pVM, PSSMHANDLE pSSM);
-static DECLCALLBACK(int) hwaccmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
-static int hwaccmR3InitCPU(PVM pVM);
-static int hwaccmR3InitFinalizeR0(PVM pVM);
-static int hwaccmR3TermCPU(PVM pVM);
-
-
-/**
- * Initializes the HWACCM.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- */
-VMMR3DECL(int) HWACCMR3Init(PVM pVM)
-{
-    LogFlow(("HWACCMR3Init\n"));
-
-    /*
-     * Assert alignment and sizes.
-     */
-    AssertCompileMemberAlignment(VM, hwaccm.s, 32);
-    AssertCompile(sizeof(pVM->hwaccm.s) <= sizeof(pVM->hwaccm.padding));
-
-    /* Some structure checks. */
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, ctrl.EventInject) == 0xA8, ("ctrl.EventInject offset = %x\n", RT_OFFSETOF(SVM_VMCB, ctrl.EventInject)));
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, ctrl.ExitIntInfo) == 0x88, ("ctrl.ExitIntInfo offset = %x\n", RT_OFFSETOF(SVM_VMCB, ctrl.ExitIntInfo)));
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, ctrl.TLBCtrl) == 0x58, ("ctrl.TLBCtrl offset = %x\n", RT_OFFSETOF(SVM_VMCB, ctrl.TLBCtrl)));
-
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest) == 0x400, ("guest offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest)));
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.TR) == 0x490, ("guest.TR offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.TR)));
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u8CPL) == 0x4CB, ("guest.u8CPL offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u8CPL)));
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64EFER) == 0x4D0, ("guest.u64EFER offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64EFER)));
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64CR4) == 0x548, ("guest.u64CR4 offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64CR4)));
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64RIP) == 0x578, ("guest.u64RIP offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64RIP)));
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64RSP) == 0x5D8, ("guest.u64RSP offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64RSP)));
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64CR2) == 0x640, ("guest.u64CR2 offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64CR2)));
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64GPAT) == 0x668, ("guest.u64GPAT offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64GPAT)));
-    AssertReleaseMsg(RT_OFFSETOF(SVM_VMCB, guest.u64LASTEXCPTO) == 0x690, ("guest.u64LASTEXCPTO offset = %x\n", RT_OFFSETOF(SVM_VMCB, guest.u64LASTEXCPTO)));
-    AssertReleaseMsg(sizeof(SVM_VMCB) == 0x1000, ("SVM_VMCB size = %x\n", sizeof(SVM_VMCB)));
-
-
-    /*
-     * Register the saved state data unit.
-     */
-    int rc = SSMR3RegisterInternal(pVM, "HWACCM", 0, HWACCM_SSM_VERSION, sizeof(HWACCM),
-                                   NULL, NULL, NULL,
-                                   NULL, hwaccmR3Save, NULL,
-                                   NULL, hwaccmR3Load, NULL);
-    if (RT_FAILURE(rc))
-        return rc;
-
-    /* Misc initialisation. */
-    pVM->hwaccm.s.vmx.fSupported = false;
-    pVM->hwaccm.s.svm.fSupported = false;
-    pVM->hwaccm.s.vmx.fEnabled   = false;
-    pVM->hwaccm.s.svm.fEnabled   = false;
-
-    pVM->hwaccm.s.fNestedPaging  = false;
-    pVM->hwaccm.s.fLargePages    = false;
-
-    /* Disabled by default. */
-    pVM->fHWACCMEnabled = false;
-
-    /*
-     * Check CFGM options.
-     */
-    PCFGMNODE pRoot      = CFGMR3GetRoot(pVM);
-    PCFGMNODE pHWVirtExt = CFGMR3GetChild(pRoot, "HWVirtExt/");
-    /* Nested paging: disabled by default. */
-    rc = CFGMR3QueryBoolDef(pHWVirtExt, "EnableNestedPaging", &pVM->hwaccm.s.fAllowNestedPaging, false);
-    AssertRC(rc);
-
-    /* Large pages: disabled by default. */
-    rc = CFGMR3QueryBoolDef(pHWVirtExt, "EnableLargePages", &pVM->hwaccm.s.fLargePages, false);
-    AssertRC(rc);
-
-    /* VT-x VPID: disabled by default. */
-    rc = CFGMR3QueryBoolDef(pHWVirtExt, "EnableVPID", &pVM->hwaccm.s.vmx.fAllowVPID, false);
-    AssertRC(rc);
-
-    /* HWACCM support must be explicitely enabled in the configuration file. */
-    rc = CFGMR3QueryBoolDef(pHWVirtExt, "Enabled", &pVM->hwaccm.s.fAllowed, false);
-    AssertRC(rc);
-
-    /* TPR patching for 32 bits (Windows) guests with IO-APIC: disabled by default. */
-    rc = CFGMR3QueryBoolDef(pHWVirtExt, "TPRPatchingEnabled", &pVM->hwaccm.s.fTRPPatchingAllowed, false);
-    AssertRC(rc);
-
-#ifdef RT_OS_DARWIN
-    if (VMMIsHwVirtExtForced(pVM) != pVM->hwaccm.s.fAllowed)
-#else
-    if (VMMIsHwVirtExtForced(pVM) && !pVM->hwaccm.s.fAllowed)
-#endif
-    {
-        AssertLogRelMsgFailed(("VMMIsHwVirtExtForced=%RTbool fAllowed=%RTbool\n",
-                               VMMIsHwVirtExtForced(pVM), pVM->hwaccm.s.fAllowed));
-        return VERR_HWACCM_CONFIG_MISMATCH;
-    }
-
-    if (VMMIsHwVirtExtForced(pVM))
-        pVM->fHWACCMEnabled = true;
-
-#if HC_ARCH_BITS == 32
-    /*
-     * 64-bit mode is configurable and it depends on both the kernel mode and VT-x.
-     * (To use the default, don't set 64bitEnabled in CFGM.)
-     */
-    rc = CFGMR3QueryBoolDef(pHWVirtExt, "64bitEnabled", &pVM->hwaccm.s.fAllow64BitGuests, false);
-    AssertLogRelRCReturn(rc, rc);
-    if (pVM->hwaccm.s.fAllow64BitGuests)
-    {
-# ifdef RT_OS_DARWIN
-        if (!VMMIsHwVirtExtForced(pVM))
-# else
-        if (!pVM->hwaccm.s.fAllowed)
-# endif
-            return VM_SET_ERROR(pVM, VERR_INVALID_PARAMETER, "64-bit guest support was requested without also enabling HWVirtEx (VT-x/AMD-V).");
-    }
-#else
-    /*
-     * On 64-bit hosts 64-bit guest support is enabled by default, but allow this to be overridden
-     * via VBoxInternal/HWVirtExt/64bitEnabled=0. (ConsoleImpl2.cpp doesn't set this to false for 64-bit.)*
-     */
-    rc = CFGMR3QueryBoolDef(pHWVirtExt, "64bitEnabled", &pVM->hwaccm.s.fAllow64BitGuests, true);
-    AssertLogRelRCReturn(rc, rc);
-#endif
-
-
-    /*
-     * Determine the init method for AMD-V and VT-x; either one global init for each host CPU
-     *  or local init each time we wish to execute guest code.
-     *
-     *  Default false for Mac OS X and Windows due to the higher risk of conflicts with other hypervisors.
-     */
-    rc = CFGMR3QueryBoolDef(pHWVirtExt, "Exclusive", &pVM->hwaccm.s.fGlobalInit,
-#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS)
-                            false
-#else
-                            true
-#endif
-                           );
-
-    /* Max number of resume loops. */
-    rc = CFGMR3QueryU32Def(pHWVirtExt, "MaxResumeLoops", &pVM->hwaccm.s.cMaxResumeLoops, 0 /* set by R0 later */);
-    AssertRC(rc);
-
-    return rc;
-}
-
-
-/**
- * Initializes the per-VCPU HWACCM.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- */
-static int hwaccmR3InitCPU(PVM pVM)
-{
-    LogFlow(("HWACCMR3InitCPU\n"));
-
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
-
-        pVCpu->hwaccm.s.fActive = false;
-    }
-
-#ifdef VBOX_WITH_STATISTICS
-    STAM_REG(pVM, &pVM->hwaccm.s.StatTPRPatchSuccess,   STAMTYPE_COUNTER, "/HWACCM/TPR/Patch/Success",  STAMUNIT_OCCURENCES,    "Number of times an instruction was successfully patched.");
-    STAM_REG(pVM, &pVM->hwaccm.s.StatTPRPatchFailure,   STAMTYPE_COUNTER, "/HWACCM/TPR/Patch/Failed",   STAMUNIT_OCCURENCES,    "Number of unsuccessful patch attempts.");
-    STAM_REG(pVM, &pVM->hwaccm.s.StatTPRReplaceSuccess, STAMTYPE_COUNTER, "/HWACCM/TPR/Replace/Success",STAMUNIT_OCCURENCES,    "Number of times an instruction was successfully patched.");
-    STAM_REG(pVM, &pVM->hwaccm.s.StatTPRReplaceFailure, STAMTYPE_COUNTER, "/HWACCM/TPR/Replace/Failed", STAMUNIT_OCCURENCES,    "Number of unsuccessful patch attempts.");
-
-    /*
-     * Statistics.
-     */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
-        int    rc;
-
-        rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatPoke, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of RTMpPokeCpu",
-                             "/PROF/HWACCM/CPU%d/Poke", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatSpinPoke, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of poke wait",
-                             "/PROF/HWACCM/CPU%d/PokeWait", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatSpinPokeFailed, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of poke wait when RTMpPokeCpu fails",
-                             "/PROF/HWACCM/CPU%d/PokeWaitFailed", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatEntry, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of VMXR0RunGuestCode entry",
-                             "/PROF/HWACCM/CPU%d/SwitchToGC", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatExit1, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of VMXR0RunGuestCode exit part 1",
-                             "/PROF/HWACCM/CPU%d/SwitchFromGC_1", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatExit2, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of VMXR0RunGuestCode exit part 2",
-                             "/PROF/HWACCM/CPU%d/SwitchFromGC_2", i);
-        AssertRC(rc);
-# if 1 /* temporary for tracking down darwin holdup. */
-        rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatExit2Sub1, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Temporary - I/O",
-                             "/PROF/HWACCM/CPU%d/SwitchFromGC_2/Sub1", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatExit2Sub2, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Temporary - CRx RWs",
-                             "/PROF/HWACCM/CPU%d/SwitchFromGC_2/Sub2", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatExit2Sub3, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Temporary - Exceptions",
-                             "/PROF/HWACCM/CPU%d/SwitchFromGC_2/Sub3", i);
-        AssertRC(rc);
-# endif
-        rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatInGC, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of vmlaunch",
-                             "/PROF/HWACCM/CPU%d/InGC", i);
-        AssertRC(rc);
-
-# if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
-        rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatWorldSwitch3264, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, "Profiling of the 32/64 switcher",
-                             "/PROF/HWACCM/CPU%d/Switcher3264", i);
-        AssertRC(rc);
-# endif
-
-# define HWACCM_REG_COUNTER(a, b) \
-        rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Profiling of vmlaunch", b, i); \
-        AssertRC(rc);
-
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitShadowNM,           "/HWACCM/CPU%d/Exit/Trap/Shw/#NM");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestNM,            "/HWACCM/CPU%d/Exit/Trap/Gst/#NM");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitShadowPF,           "/HWACCM/CPU%d/Exit/Trap/Shw/#PF");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitShadowPFEM,         "/HWACCM/CPU%d/Exit/Trap/Shw/#PF-EM");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestPF,            "/HWACCM/CPU%d/Exit/Trap/Gst/#PF");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestUD,            "/HWACCM/CPU%d/Exit/Trap/Gst/#UD");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestSS,            "/HWACCM/CPU%d/Exit/Trap/Gst/#SS");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestNP,            "/HWACCM/CPU%d/Exit/Trap/Gst/#NP");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestGP,            "/HWACCM/CPU%d/Exit/Trap/Gst/#GP");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestMF,            "/HWACCM/CPU%d/Exit/Trap/Gst/#MF");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestDE,            "/HWACCM/CPU%d/Exit/Trap/Gst/#DE");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestDB,            "/HWACCM/CPU%d/Exit/Trap/Gst/#DB");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestBP,            "/HWACCM/CPU%d/Exit/Trap/Gst/#BP");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestXF,            "/HWACCM/CPU%d/Exit/Trap/Gst/#XF");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitGuestXcpUnk,        "/HWACCM/CPU%d/Exit/Trap/Gst/Other");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitInvlpg,             "/HWACCM/CPU%d/Exit/Instr/Invlpg");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitInvd,               "/HWACCM/CPU%d/Exit/Instr/Invd");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitCpuid,              "/HWACCM/CPU%d/Exit/Instr/Cpuid");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitRdtsc,              "/HWACCM/CPU%d/Exit/Instr/Rdtsc");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitRdtscp,             "/HWACCM/CPU%d/Exit/Instr/Rdtscp");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitRdpmc,              "/HWACCM/CPU%d/Exit/Instr/Rdpmc");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitRdmsr,              "/HWACCM/CPU%d/Exit/Instr/Rdmsr");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitWrmsr,              "/HWACCM/CPU%d/Exit/Instr/Wrmsr");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitMwait,              "/HWACCM/CPU%d/Exit/Instr/Mwait");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitMonitor,            "/HWACCM/CPU%d/Exit/Instr/Monitor");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitDRxWrite,           "/HWACCM/CPU%d/Exit/Instr/DR/Write");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitDRxRead,            "/HWACCM/CPU%d/Exit/Instr/DR/Read");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitCLTS,               "/HWACCM/CPU%d/Exit/Instr/CLTS");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitLMSW,               "/HWACCM/CPU%d/Exit/Instr/LMSW");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitCli,                "/HWACCM/CPU%d/Exit/Instr/Cli");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitSti,                "/HWACCM/CPU%d/Exit/Instr/Sti");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitPushf,              "/HWACCM/CPU%d/Exit/Instr/Pushf");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitPopf,               "/HWACCM/CPU%d/Exit/Instr/Popf");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitIret,               "/HWACCM/CPU%d/Exit/Instr/Iret");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitInt,                "/HWACCM/CPU%d/Exit/Instr/Int");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitHlt,                "/HWACCM/CPU%d/Exit/Instr/Hlt");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitIOWrite,            "/HWACCM/CPU%d/Exit/IO/Write");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitIORead,             "/HWACCM/CPU%d/Exit/IO/Read");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitIOStringWrite,      "/HWACCM/CPU%d/Exit/IO/WriteString");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitIOStringRead,       "/HWACCM/CPU%d/Exit/IO/ReadString");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitIrqWindow,          "/HWACCM/CPU%d/Exit/IrqWindow");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitMaxResume,          "/HWACCM/CPU%d/Exit/MaxResume");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitPreemptPending,     "/HWACCM/CPU%d/Exit/PreemptPending");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatExitMTF,                "/HWACCM/CPU%d/Exit/MonitorTrapFlag");
-
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatSwitchGuestIrq,         "/HWACCM/CPU%d/Switch/IrqPending");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatSwitchToR3,             "/HWACCM/CPU%d/Switch/ToR3");
-
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatIntInject,              "/HWACCM/CPU%d/Irq/Inject");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatIntReinject,            "/HWACCM/CPU%d/Irq/Reinject");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatPendingHostIrq,         "/HWACCM/CPU%d/Irq/PendingOnHost");
-
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushPage,              "/HWACCM/CPU%d/Flush/Page");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushPageManual,        "/HWACCM/CPU%d/Flush/Page/Virt");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushPhysPageManual,    "/HWACCM/CPU%d/Flush/Page/Phys");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushTLB,               "/HWACCM/CPU%d/Flush/TLB");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushTLBManual,         "/HWACCM/CPU%d/Flush/TLB/Manual");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushTLBCRxChange,      "/HWACCM/CPU%d/Flush/TLB/CRx");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushPageInvlpg,        "/HWACCM/CPU%d/Flush/Page/Invlpg");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushTLBWorldSwitch,    "/HWACCM/CPU%d/Flush/TLB/Switch");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatNoFlushTLBWorldSwitch,  "/HWACCM/CPU%d/Flush/TLB/Skipped");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushASID,              "/HWACCM/CPU%d/Flush/TLB/ASID");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushTLBInvlpga,        "/HWACCM/CPU%d/Flush/TLB/PhysInvl");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTlbShootdown,           "/HWACCM/CPU%d/Flush/Shootdown/Page");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTlbShootdownFlush,      "/HWACCM/CPU%d/Flush/Shootdown/TLB");
-
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTSCOffset,              "/HWACCM/CPU%d/TSC/Offset");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTSCIntercept,           "/HWACCM/CPU%d/TSC/Intercept");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTSCInterceptOverFlow,   "/HWACCM/CPU%d/TSC/InterceptOverflow");
-
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatDRxArmed,               "/HWACCM/CPU%d/Debug/Armed");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatDRxContextSwitch,       "/HWACCM/CPU%d/Debug/ContextSwitch");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatDRxIOCheck,             "/HWACCM/CPU%d/Debug/IOCheck");
-
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatLoadMinimal,            "/HWACCM/CPU%d/Load/Minimal");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatLoadFull,               "/HWACCM/CPU%d/Load/Full");
-
-#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFpu64SwitchBack,        "/HWACCM/CPU%d/Switch64/Fpu");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatDebug64SwitchBack,      "/HWACCM/CPU%d/Switch64/Debug");
-#endif
-
-        for (unsigned j = 0; j < RT_ELEMENTS(pVCpu->hwaccm.s.StatExitCRxWrite); j++)
-        {
-            rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatExitCRxWrite[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, "Profiling of CRx writes",
-                                "/HWACCM/CPU%d/Exit/Instr/CR/Write/%x", i, j);
-            AssertRC(rc);
-            rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatExitCRxRead[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, "Profiling of CRx reads",
-                                "/HWACCM/CPU%d/Exit/Instr/CR/Read/%x", i, j);
-            AssertRC(rc);
-        }
-
-#undef HWACCM_REG_COUNTER
-
-        pVCpu->hwaccm.s.paStatExitReason = NULL;
-
-        rc = MMHyperAlloc(pVM, MAX_EXITREASON_STAT*sizeof(*pVCpu->hwaccm.s.paStatExitReason), 0, MM_TAG_HWACCM, (void **)&pVCpu->hwaccm.s.paStatExitReason);
-        AssertRC(rc);
-        if (RT_SUCCESS(rc))
-        {
-            const char * const *papszDesc = ASMIsIntelCpu() ? &g_apszVTxExitReasons[0] : &g_apszAmdVExitReasons[0];
-            for (int j = 0; j < MAX_EXITREASON_STAT; j++)
-            {
-                if (papszDesc[j])
-                {
-                    rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.paStatExitReason[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
-                                        papszDesc[j], "/HWACCM/CPU%d/Exit/Reason/%02x", i, j);
-                    AssertRC(rc);
-                }
-            }
-            rc = STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.StatExitReasonNPF, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, "Nested page fault", "/HWACCM/CPU%d/Exit/Reason/#NPF", i);
-            AssertRC(rc);
-        }
-        pVCpu->hwaccm.s.paStatExitReasonR0 = MMHyperR3ToR0(pVM, pVCpu->hwaccm.s.paStatExitReason);
-# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
-        Assert(pVCpu->hwaccm.s.paStatExitReasonR0 != NIL_RTR0PTR || !VMMIsHwVirtExtForced(pVM));
-# else
-        Assert(pVCpu->hwaccm.s.paStatExitReasonR0 != NIL_RTR0PTR);
-# endif
-
-        rc = MMHyperAlloc(pVM, sizeof(STAMCOUNTER) * 256, 8, MM_TAG_HWACCM, (void **)&pVCpu->hwaccm.s.paStatInjectedIrqs);
-        AssertRCReturn(rc, rc);
-        pVCpu->hwaccm.s.paStatInjectedIrqsR0 = MMHyperR3ToR0(pVM, pVCpu->hwaccm.s.paStatInjectedIrqs);
-# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
-        Assert(pVCpu->hwaccm.s.paStatInjectedIrqsR0 != NIL_RTR0PTR || !VMMIsHwVirtExtForced(pVM));
-# else
-        Assert(pVCpu->hwaccm.s.paStatInjectedIrqsR0 != NIL_RTR0PTR);
-# endif
-        for (unsigned j = 0; j < 255; j++)
-            STAMR3RegisterF(pVM, &pVCpu->hwaccm.s.paStatInjectedIrqs[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, "Forwarded interrupts.",
-                            (j < 0x20) ? "/HWACCM/CPU%d/Interrupt/Trap/%02X" : "/HWACCM/CPU%d/Interrupt/IRQ/%02X", i, j);
-
-    }
-#endif /* VBOX_WITH_STATISTICS */
-
-#ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    /* Magic marker for searching in crash dumps. */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
-
-        PVMCSCACHE pCache = &pVCpu->hwaccm.s.vmx.VMCSCache;
-        strcpy((char *)pCache->aMagic, "VMCSCACHE Magic");
-        pCache->uMagic = UINT64_C(0xDEADBEEFDEADBEEF);
-    }
-#endif
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Called when a init phase has completed.
- *
- * @returns VBox status code.
- * @param   pVM                 The VM.
- * @param   enmWhat             The phase that completed.
- */
-VMMR3_INT_DECL(int) HWACCMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
-{
-    switch (enmWhat)
-    {
-        case VMINITCOMPLETED_RING3:
-            return hwaccmR3InitCPU(pVM);
-        case VMINITCOMPLETED_RING0:
-            return hwaccmR3InitFinalizeR0(pVM);
-        default:
-            return VINF_SUCCESS;
-    }
-}
-
-
-/**
- * Turns off normal raw mode features.
- *
- * @param   pVM         Pointer to the VM.
- */
-static void hwaccmR3DisableRawMode(PVM pVM)
-{
-    /* Disable PATM & CSAM. */
-    PATMR3AllowPatching(pVM, false);
-    CSAMDisableScanning(pVM);
-
-    /* Turn off IDT/LDT/GDT and TSS monitoring and sycing. */
-    SELMR3DisableMonitoring(pVM);
-    TRPMR3DisableMonitoring(pVM);
-
-    /* Disable the switcher code (safety precaution). */
-    VMMR3DisableSwitcher(pVM);
-
-    /* Disable mapping of the hypervisor into the shadow page table. */
-    PGMR3MappingsDisable(pVM);
-
-    /* Disable the switcher */
-    VMMR3DisableSwitcher(pVM);
-
-    /* Reinit the paging mode to force the new shadow mode. */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
-
-        PGMR3ChangeMode(pVM, pVCpu, PGMMODE_REAL);
-    }
-}
-
-
-/**
- * Initialize VT-x or AMD-V.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- */
-static int hwaccmR3InitFinalizeR0(PVM pVM)
-{
-    int rc;
-
-    /*
-     * Hack to allow users to work around broken BIOSes that incorrectly set EFER.SVME, which makes us believe somebody else
-     * is already using AMD-V.
-     */
-    if (    !pVM->hwaccm.s.vmx.fSupported
-        &&  !pVM->hwaccm.s.svm.fSupported
-        &&  pVM->hwaccm.s.lLastError == VERR_SVM_IN_USE /* implies functional AMD-V */
-        &&  RTEnvExist("VBOX_HWVIRTEX_IGNORE_SVM_IN_USE"))
-    {
-        LogRel(("HWACCM: VBOX_HWVIRTEX_IGNORE_SVM_IN_USE active!\n"));
-        pVM->hwaccm.s.svm.fSupported        = true;
-        pVM->hwaccm.s.svm.fIgnoreInUseError = true;
-    }
-    else
-    if (    !pVM->hwaccm.s.vmx.fSupported
-        &&  !pVM->hwaccm.s.svm.fSupported)
-    {
-        LogRel(("HWACCM: No VT-x or AMD-V CPU extension found. Reason %Rrc\n", pVM->hwaccm.s.lLastError));
-        LogRel(("HWACCM: VMX MSR_IA32_FEATURE_CONTROL=%RX64\n", pVM->hwaccm.s.vmx.msr.feature_ctrl));
-
-        if (VMMIsHwVirtExtForced(pVM))
-        {
-            switch (pVM->hwaccm.s.lLastError)
-            {
-            case VERR_VMX_NO_VMX:
-                return VM_SET_ERROR(pVM, VERR_VMX_NO_VMX, "VT-x is not available.");
-            case VERR_VMX_IN_VMX_ROOT_MODE:
-                return VM_SET_ERROR(pVM, VERR_VMX_IN_VMX_ROOT_MODE, "VT-x is being used by another hypervisor.");
-            case VERR_SVM_IN_USE:
-                return VM_SET_ERROR(pVM, VERR_SVM_IN_USE, "AMD-V is being used by another hypervisor.");
-            case VERR_SVM_NO_SVM:
-                return VM_SET_ERROR(pVM, VERR_SVM_NO_SVM, "AMD-V is not available.");
-            case VERR_SVM_DISABLED:
-                return VM_SET_ERROR(pVM, VERR_SVM_DISABLED, "AMD-V is disabled in the BIOS.");
-            default:
-                return pVM->hwaccm.s.lLastError;
-            }
-        }
-        return VINF_SUCCESS;
-    }
-
-    if (pVM->hwaccm.s.vmx.fSupported)
-    {
-        rc = SUPR3QueryVTxSupported();
-        if (RT_FAILURE(rc))
-        {
-#ifdef RT_OS_LINUX
-            LogRel(("HWACCM: The host kernel does not support VT-x -- Linux 2.6.13 or newer required!\n"));
-#else
-            LogRel(("HWACCM: The host kernel does not support VT-x!\n"));
-#endif
-            if (   pVM->cCpus > 1
-                || VMMIsHwVirtExtForced(pVM))
-                return rc;
-
-            /* silently fall back to raw mode */
-            return VINF_SUCCESS;
-        }
-    }
-
-    if (!pVM->hwaccm.s.fAllowed)
-        return VINF_SUCCESS;    /* nothing to do */
-
-    /* Enable VT-x or AMD-V on all host CPUs. */
-    rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HWACC_ENABLE, 0, NULL);
-    if (RT_FAILURE(rc))
-    {
-        LogRel(("HWACCMR3InitFinalize: SUPR3CallVMMR0Ex VMMR0_DO_HWACC_ENABLE failed with %Rrc\n", rc));
-        return rc;
-    }
-    Assert(!pVM->fHWACCMEnabled || VMMIsHwVirtExtForced(pVM));
-
-    pVM->hwaccm.s.fHasIoApic = PDMHasIoApic(pVM);
-    /* No TPR patching is required when the IO-APIC is not enabled for this VM. (Main should have taken care of this already) */
-    if (!pVM->hwaccm.s.fHasIoApic)
-    {
-        Assert(!pVM->hwaccm.s.fTRPPatchingAllowed); /* paranoia */
-        pVM->hwaccm.s.fTRPPatchingAllowed = false;
-    }
-
-    bool fOldBuffered = RTLogRelSetBuffering(true /*fBuffered*/);
-    if (pVM->hwaccm.s.vmx.fSupported)
-    {
-        Log(("pVM->hwaccm.s.vmx.fSupported = %d\n", pVM->hwaccm.s.vmx.fSupported));
-
-        if (    pVM->hwaccm.s.fInitialized == false
-            &&  pVM->hwaccm.s.vmx.msr.feature_ctrl != 0)
-        {
-            uint64_t val;
-            RTGCPHYS GCPhys = 0;
-
-            LogRel(("HWACCM: Host CR4=%08X\n", pVM->hwaccm.s.vmx.hostCR4));
-            LogRel(("HWACCM: MSR_IA32_FEATURE_CONTROL      = %RX64\n", pVM->hwaccm.s.vmx.msr.feature_ctrl));
-            LogRel(("HWACCM: MSR_IA32_VMX_BASIC_INFO       = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_basic_info));
-            LogRel(("HWACCM: VMCS id                       = %x\n", MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info)));
-            LogRel(("HWACCM: VMCS size                     = %x\n", MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(pVM->hwaccm.s.vmx.msr.vmx_basic_info)));
-            LogRel(("HWACCM: VMCS physical address limit   = %s\n", MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(pVM->hwaccm.s.vmx.msr.vmx_basic_info) ? "< 4 GB" : "None"));
-            LogRel(("HWACCM: VMCS memory type              = %x\n", MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(pVM->hwaccm.s.vmx.msr.vmx_basic_info)));
-            LogRel(("HWACCM: Dual monitor treatment        = %d\n", MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(pVM->hwaccm.s.vmx.msr.vmx_basic_info)));
-
-            LogRel(("HWACCM: MSR_IA32_VMX_PINBASED_CTLS    = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.u));
-            val = pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.allowed1;
-            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI\n"));
-            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER\n"));
-            val = pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.disallowed0;
-            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER *must* be set\n"));
-
-            LogRel(("HWACCM: MSR_IA32_VMX_PROCBASED_CTLS   = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.u));
-            val = pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1;
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL\n"));
-
-            val = pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.disallowed0;
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL *must* be set\n"));
-
-            if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
-            {
-                LogRel(("HWACCM: MSR_IA32_VMX_PROCBASED_CTLS2  = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.u));
-                val = pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1;
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_EPT)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_EPT\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_X2APIC)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_X2APIC\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_VPID)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_VPID\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT\n"));
-
-                val = pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.disallowed0;
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC *must* be set\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT *must* be set\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP *must* be set\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_X2APIC)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_X2APIC *must* be set\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_EPT)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_EPT *must* be set\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_VPID)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_VPID *must* be set\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT *must* be set\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE *must* be set\n"));
-                if (val & VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT)
-                    LogRel(("HWACCM:    VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT *must* be set\n"));
-            }
-
-            LogRel(("HWACCM: MSR_IA32_VMX_ENTRY_CTLS       = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_entry.u));
-            val = pVM->hwaccm.s.vmx.msr.vmx_entry.n.allowed1;
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR\n"));
-            val = pVM->hwaccm.s.vmx.msr.vmx_entry.n.disallowed0;
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR *must* be set\n"));
-
-            LogRel(("HWACCM: MSR_IA32_VMX_EXIT_CTLS        = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_exit.u));
-            val = pVM->hwaccm.s.vmx.msr.vmx_exit.n.allowed1;
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER\n"));
-            val = pVM->hwaccm.s.vmx.msr.vmx_exit.n.disallowed0;
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64 *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR *must* be set\n"));
-            if (val & VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER)
-                LogRel(("HWACCM:    VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER *must* be set\n"));
-
-            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps)
-            {
-                LogRel(("HWACCM: MSR_IA32_VMX_EPT_VPID_CAPS    = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_eptcaps));
-
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_RWX_X_ONLY)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_RWX_X_ONLY\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_RWX_W_ONLY)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_RWX_W_ONLY\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_RWX_WX_ONLY)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_RWX_WX_ONLY\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_GAW_21_BITS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_GAW_21_BITS\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_GAW_30_BITS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_GAW_30_BITS\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_GAW_39_BITS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_GAW_39_BITS\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_GAW_48_BITS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_GAW_48_BITS\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_GAW_57_BITS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_GAW_57_BITS\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_EMT_UC)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_EMT_UC\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_EMT_WC)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_EMT_WC\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_EMT_WT)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_EMT_WT\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_EMT_WP)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_EMT_WP\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_EMT_WB)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_EMT_WB\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_SP_21_BITS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_SP_21_BITS\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_SP_30_BITS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_SP_30_BITS\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_SP_39_BITS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_SP_39_BITS\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_SP_48_BITS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_SP_48_BITS\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_INVEPT\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_SINGLE_CONTEXT)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_SINGLE_CONTEXT\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL_CONTEXTS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL_CONTEXTS\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_INVVPID\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS\n"));
-                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT_RETAIN_GLOBALS)
-                    LogRel(("HWACCM:    MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT_RETAIN_GLOBALS\n"));
-            }
-
-            LogRel(("HWACCM: MSR_IA32_VMX_MISC             = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_misc));
-            if (MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(pVM->hwaccm.s.vmx.msr.vmx_misc) == pVM->hwaccm.s.vmx.cPreemptTimerShift)
-                LogRel(("HWACCM:    MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT %x\n", MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(pVM->hwaccm.s.vmx.msr.vmx_misc)));
-            else
-            {
-                LogRel(("HWACCM:    MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT %x - erratum detected, using %x instead\n",
-                        MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(pVM->hwaccm.s.vmx.msr.vmx_misc), pVM->hwaccm.s.vmx.cPreemptTimerShift));
-            }
-            LogRel(("HWACCM:    MSR_IA32_VMX_MISC_ACTIVITY_STATES %x\n", MSR_IA32_VMX_MISC_ACTIVITY_STATES(pVM->hwaccm.s.vmx.msr.vmx_misc)));
-            LogRel(("HWACCM:    MSR_IA32_VMX_MISC_CR3_TARGET      %x\n", MSR_IA32_VMX_MISC_CR3_TARGET(pVM->hwaccm.s.vmx.msr.vmx_misc)));
-            LogRel(("HWACCM:    MSR_IA32_VMX_MISC_MAX_MSR         %x\n", MSR_IA32_VMX_MISC_MAX_MSR(pVM->hwaccm.s.vmx.msr.vmx_misc)));
-            LogRel(("HWACCM:    MSR_IA32_VMX_MISC_MSEG_ID         %x\n", MSR_IA32_VMX_MISC_MSEG_ID(pVM->hwaccm.s.vmx.msr.vmx_misc)));
-
-            LogRel(("HWACCM: MSR_IA32_VMX_CR0_FIXED0       = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed0));
-            LogRel(("HWACCM: MSR_IA32_VMX_CR0_FIXED1       = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed1));
-            LogRel(("HWACCM: MSR_IA32_VMX_CR4_FIXED0       = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed0));
-            LogRel(("HWACCM: MSR_IA32_VMX_CR4_FIXED1       = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed1));
-            LogRel(("HWACCM: MSR_IA32_VMX_VMCS_ENUM        = %RX64\n", pVM->hwaccm.s.vmx.msr.vmx_vmcs_enum));
-
-            LogRel(("HWACCM: TPR shadow physaddr           = %RHp\n", pVM->hwaccm.s.vmx.pAPICPhys));
-
-            /* Paranoia */
-            AssertRelease(MSR_IA32_VMX_MISC_MAX_MSR(pVM->hwaccm.s.vmx.msr.vmx_misc) >= 512);
-
-            for (VMCPUID i = 0; i < pVM->cCpus; i++)
-            {
-                LogRel(("HWACCM: VCPU%d: MSR bitmap physaddr    = %RHp\n", i, pVM->aCpus[i].hwaccm.s.vmx.pMSRBitmapPhys));
-                LogRel(("HWACCM: VCPU%d: VMCS physaddr          = %RHp\n", i, pVM->aCpus[i].hwaccm.s.vmx.HCPhysVMCS));
-            }
-
-            if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_EPT)
-                pVM->hwaccm.s.fNestedPaging = pVM->hwaccm.s.fAllowNestedPaging;
-
-            if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VPID)
-                pVM->hwaccm.s.vmx.fVPID = pVM->hwaccm.s.vmx.fAllowVPID;
-
-            /*
-             * Disallow RDTSCP in the guest if there is no secondary process-based VM execution controls as otherwise
-             * RDTSCP would cause a #UD. There might be no CPUs out there where this happens, as RDTSCP was introduced
-             * in Nehalems and secondary VM exec. controls should be supported in all of them, but nonetheless it's Intel...
-             */
-            if (!(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
-                && CPUMGetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_RDTSCP))
-            {
-                CPUMClearGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_RDTSCP);
-            }
-
-            /* Unrestricted guest execution relies on EPT. */
-            if (    pVM->hwaccm.s.fNestedPaging
-                &&  (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE))
-            {
-                pVM->hwaccm.s.vmx.fUnrestrictedGuest = true;
-            }
-
-            /* Only try once. */
-            pVM->hwaccm.s.fInitialized = true;
-
-            if (!pVM->hwaccm.s.vmx.fUnrestrictedGuest)
-            {
-                /* Allocate three pages for the TSS we need for real mode emulation. (2 pages for the IO bitmap) */
-                rc = PDMR3VMMDevHeapAlloc(pVM, HWACCM_VTX_TOTAL_DEVHEAP_MEM, (RTR3PTR *)&pVM->hwaccm.s.vmx.pRealModeTSS);
-                if (RT_SUCCESS(rc))
-                {
-                    /* The I/O bitmap starts right after the virtual interrupt redirection bitmap. */
-                    ASMMemZero32(pVM->hwaccm.s.vmx.pRealModeTSS, sizeof(*pVM->hwaccm.s.vmx.pRealModeTSS));
-                    pVM->hwaccm.s.vmx.pRealModeTSS->offIoBitmap = sizeof(*pVM->hwaccm.s.vmx.pRealModeTSS);
-                    /* Bit set to 0 means redirection enabled. */
-                    memset(pVM->hwaccm.s.vmx.pRealModeTSS->IntRedirBitmap, 0x0, sizeof(pVM->hwaccm.s.vmx.pRealModeTSS->IntRedirBitmap));
-                    /* Allow all port IO, so the VT-x IO intercepts do their job. */
-                    memset(pVM->hwaccm.s.vmx.pRealModeTSS + 1, 0, PAGE_SIZE*2);
-                    *((unsigned char *)pVM->hwaccm.s.vmx.pRealModeTSS + HWACCM_VTX_TSS_SIZE - 2) = 0xff;
-
-                    /*
-                     * Construct a 1024 element page directory with 4 MB pages for the identity mapped page table used in
-                     * real and protected mode without paging with EPT.
-                     */
-                    pVM->hwaccm.s.vmx.pNonPagingModeEPTPageTable = (PX86PD)((char *)pVM->hwaccm.s.vmx.pRealModeTSS + PAGE_SIZE * 3);
-                    for (unsigned i = 0; i < X86_PG_ENTRIES; i++)
-                    {
-                        pVM->hwaccm.s.vmx.pNonPagingModeEPTPageTable->a[i].u  = _4M * i;
-                        pVM->hwaccm.s.vmx.pNonPagingModeEPTPageTable->a[i].u |= X86_PDE4M_P | X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_A | X86_PDE4M_D | X86_PDE4M_PS | X86_PDE4M_G;
-                    }
-
-                    /* We convert it here every time as pci regions could be reconfigured. */
-                    rc = PDMVMMDevHeapR3ToGCPhys(pVM, pVM->hwaccm.s.vmx.pRealModeTSS, &GCPhys);
-                    AssertRC(rc);
-                    LogRel(("HWACCM: Real Mode TSS guest physaddr  = %RGp\n", GCPhys));
-
-                    rc = PDMVMMDevHeapR3ToGCPhys(pVM, pVM->hwaccm.s.vmx.pNonPagingModeEPTPageTable, &GCPhys);
-                    AssertRC(rc);
-                    LogRel(("HWACCM: Non-Paging Mode EPT CR3       = %RGp\n", GCPhys));
-                }
-                else
-                {
-                    LogRel(("HWACCM: No real mode VT-x support (PDMR3VMMDevHeapAlloc returned %Rrc)\n", rc));
-                    pVM->hwaccm.s.vmx.pRealModeTSS = NULL;
-                    pVM->hwaccm.s.vmx.pNonPagingModeEPTPageTable = NULL;
-                }
-            }
-
-            rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HWACC_SETUP_VM, 0, NULL);
-            AssertRC(rc);
-            if (rc == VINF_SUCCESS)
-            {
-                pVM->fHWACCMEnabled = true;
-                pVM->hwaccm.s.vmx.fEnabled = true;
-                hwaccmR3DisableRawMode(pVM);
-
-                CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SEP);
-#ifdef VBOX_ENABLE_64_BITS_GUESTS
-                if (pVM->hwaccm.s.fAllow64BitGuests)
-                {
-                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE);
-                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LONG_MODE);
-                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SYSCALL);            /* 64 bits only on Intel CPUs */
-                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LAHF);
-                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
-                }
-                else
-                /* Turn on NXE if PAE has been enabled *and* the host has turned on NXE (we reuse the host EFER in the switcher) */
-                /* Todo: this needs to be fixed properly!! */
-                if (    CPUMGetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE)
-                    &&  (pVM->hwaccm.s.vmx.hostEFER & MSR_K6_EFER_NXE))
-                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
-
-                LogRel((pVM->hwaccm.s.fAllow64BitGuests
-                        ? "HWACCM: 32-bit and 64-bit guests supported.\n"
-                        : "HWACCM: 32-bit guests supported.\n"));
-#else
-                LogRel(("HWACCM: 32-bit guests supported.\n"));
-#endif
-                LogRel(("HWACCM: VMX enabled!\n"));
-                if (pVM->hwaccm.s.fNestedPaging)
-                {
-                    LogRel(("HWACCM: Enabled nested paging\n"));
-                    LogRel(("HWACCM: EPT root page                 = %RHp\n", PGMGetHyperCR3(VMMGetCpu(pVM))));
-                    if (pVM->hwaccm.s.vmx.enmFlushEPT == VMX_FLUSH_EPT_SINGLE_CONTEXT)
-                        LogRel(("HWACCM: enmFlushEPT                   = VMX_FLUSH_EPT_SINGLE_CONTEXT\n"));
-                    else if (pVM->hwaccm.s.vmx.enmFlushEPT == VMX_FLUSH_EPT_ALL_CONTEXTS)
-                        LogRel(("HWACCM: enmFlushEPT                   = VMX_FLUSH_EPT_ALL_CONTEXTS\n"));
-                    else if (pVM->hwaccm.s.vmx.enmFlushEPT == VMX_FLUSH_EPT_NOT_SUPPORTED)
-                        LogRel(("HWACCM: enmFlushEPT                   = VMX_FLUSH_EPT_NOT_SUPPORTED\n"));
-                    else
-                        LogRel(("HWACCM: enmFlushEPT                   = %d\n", pVM->hwaccm.s.vmx.enmFlushEPT));
-
-                    if (pVM->hwaccm.s.vmx.fUnrestrictedGuest)
-                        LogRel(("HWACCM: Unrestricted guest execution enabled!\n"));
-
-#if HC_ARCH_BITS == 64
-                    if (pVM->hwaccm.s.fLargePages)
-                    {
-                        /* Use large (2 MB) pages for our EPT PDEs where possible. */
-                        PGMSetLargePageUsage(pVM, true);
-                        LogRel(("HWACCM: Large page support enabled!\n"));
-                    }
-#endif
-                }
-                else
-                    Assert(!pVM->hwaccm.s.vmx.fUnrestrictedGuest);
-
-                if (pVM->hwaccm.s.vmx.fVPID)
-                {
-                    LogRel(("HWACCM: Enabled VPID\n"));
-                    if (pVM->hwaccm.s.vmx.enmFlushVPID == VMX_FLUSH_VPID_INDIV_ADDR)
-                        LogRel(("HWACCM: enmFlushVPID                  = VMX_FLUSH_VPID_INDIV_ADDR\n"));
-                    else if (pVM->hwaccm.s.vmx.enmFlushVPID == VMX_FLUSH_VPID_SINGLE_CONTEXT)
-                        LogRel(("HWACCM: enmFlushVPID                  = VMX_FLUSH_VPID_SINGLE_CONTEXT\n"));
-                    else if (pVM->hwaccm.s.vmx.enmFlushVPID == VMX_FLUSH_VPID_ALL_CONTEXTS)
-                        LogRel(("HWACCM: enmFlushVPID                  = VMX_FLUSH_VPID_ALL_CONTEXTS\n"));
-                    else if (pVM->hwaccm.s.vmx.enmFlushVPID == VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS)
-                        LogRel(("HWACCM: enmFlushVPID                  = VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS\n"));
-                    else
-                        LogRel(("HWACCM: enmFlushVPID                  = %d\n", pVM->hwaccm.s.vmx.enmFlushVPID));
-                }
-                else if (pVM->hwaccm.s.vmx.enmFlushVPID == VMX_FLUSH_VPID_NOT_SUPPORTED)
-                    LogRel(("HWACCM: Ignoring VPID capabilities of CPU.\n"));
-
-                /* TPR patching status logging. */
-                if (pVM->hwaccm.s.fTRPPatchingAllowed)
-                {
-                    if (    (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
-                        &&  (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC))
-                    {
-                        pVM->hwaccm.s.fTRPPatchingAllowed = false;  /* not necessary as we have a hardware solution. */
-                        LogRel(("HWACCM: TPR Patching not required (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC).\n"));
-                    }
-                    else
-                    {
-                        uint32_t u32Eax, u32Dummy;
-
-                        /* TPR patching needs access to the MSR_K8_LSTAR msr. */
-                        ASMCpuId(0x80000000, &u32Eax, &u32Dummy, &u32Dummy, &u32Dummy);
-                        if (    u32Eax < 0x80000001
-                            ||  !(ASMCpuId_EDX(0x80000001) & X86_CPUID_EXT_FEATURE_EDX_LONG_MODE))
-                        {
-                            pVM->hwaccm.s.fTRPPatchingAllowed = false;
-                            LogRel(("HWACCM: TPR patching disabled (long mode not supported).\n"));
-                        }
-                    }
-                }
-                LogRel(("HWACCM: TPR Patching %s.\n", (pVM->hwaccm.s.fTRPPatchingAllowed) ? "enabled" : "disabled"));
-
-                /*
-                 * Check for preemption timer config override and log the state of it.
-                 */
-                if (pVM->hwaccm.s.vmx.fUsePreemptTimer)
-                {
-                    PCFGMNODE pCfgHwAccM = CFGMR3GetChild(CFGMR3GetRoot(pVM), "HWACCM");
-                    int rc2 = CFGMR3QueryBoolDef(pCfgHwAccM, "UsePreemptTimer", &pVM->hwaccm.s.vmx.fUsePreemptTimer, true);
-                    AssertLogRelRC(rc2);
-                }
-                if (pVM->hwaccm.s.vmx.fUsePreemptTimer)
-                    LogRel(("HWACCM: Using the VMX-preemption timer (cPreemptTimerShift=%u)\n", pVM->hwaccm.s.vmx.cPreemptTimerShift));
-            }
-            else
-            {
-                LogRel(("HWACCM: VMX setup failed with rc=%Rrc!\n", rc));
-                LogRel(("HWACCM: Last instruction error %x\n", pVM->aCpus[0].hwaccm.s.vmx.lasterror.ulInstrError));
-                pVM->fHWACCMEnabled = false;
-            }
-        }
-    }
-    else
-    if (pVM->hwaccm.s.svm.fSupported)
-    {
-        Log(("pVM->hwaccm.s.svm.fSupported = %d\n", pVM->hwaccm.s.svm.fSupported));
-
-        if (pVM->hwaccm.s.fInitialized == false)
-        {
-            /* Erratum 170 which requires a forced TLB flush for each world switch:
-             * See http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf
-             *
-             * All BH-G1/2 and DH-G1/2 models include a fix:
-             * Athlon X2:   0x6b 1/2
-             *              0x68 1/2
-             * Athlon 64:   0x7f 1
-             *              0x6f 2
-             * Sempron:     0x7f 1/2
-             *              0x6f 2
-             *              0x6c 2
-             *              0x7c 2
-             * Turion 64:   0x68 2
-             *
-             */
-            uint32_t u32Dummy;
-            uint32_t u32Version, u32Family, u32Model, u32Stepping, u32BaseFamily;
-            ASMCpuId(1, &u32Version, &u32Dummy, &u32Dummy, &u32Dummy);
-            u32BaseFamily= (u32Version >> 8) & 0xf;
-            u32Family    = u32BaseFamily + (u32BaseFamily == 0xf ? ((u32Version >> 20) & 0x7f) : 0);
-            u32Model     = ((u32Version >> 4) & 0xf);
-            u32Model     = u32Model | ((u32BaseFamily == 0xf ? (u32Version >> 16) & 0x0f : 0) << 4);
-            u32Stepping  = u32Version & 0xf;
-            if (    u32Family == 0xf
-                &&  !((u32Model == 0x68 || u32Model == 0x6b || u32Model == 0x7f) &&  u32Stepping >= 1)
-                &&  !((u32Model == 0x6f || u32Model == 0x6c || u32Model == 0x7c) &&  u32Stepping >= 2))
-            {
-                LogRel(("HWACMM: AMD cpu with erratum 170 family %x model %x stepping %x\n", u32Family, u32Model, u32Stepping));
-            }
-
-            LogRel(("HWACMM: cpuid 0x80000001.u32AMDFeatureECX = %RX32\n", pVM->hwaccm.s.cpuid.u32AMDFeatureECX));
-            LogRel(("HWACMM: cpuid 0x80000001.u32AMDFeatureEDX = %RX32\n", pVM->hwaccm.s.cpuid.u32AMDFeatureEDX));
-            LogRel(("HWACCM: AMD HWCR MSR                      = %RX64\n", pVM->hwaccm.s.svm.msrHWCR));
-            LogRel(("HWACCM: AMD-V revision                    = %X\n", pVM->hwaccm.s.svm.u32Rev));
-            LogRel(("HWACCM: AMD-V max ASID                    = %d\n", pVM->hwaccm.s.uMaxASID));
-            LogRel(("HWACCM: AMD-V features                    = %X\n", pVM->hwaccm.s.svm.u32Features));
-            static const struct { uint32_t fFlag; const char *pszName; } s_aSvmFeatures[] =
-            {
-#define FLAG_NAME(a_Define) { a_Define, #a_Define }
-                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING),
-                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_LBR_VIRT),
-                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_SVM_LOCK),
-                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_NRIP_SAVE),
-                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_TSC_RATE_MSR),
-                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_VMCB_CLEAN),
-                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID),
-                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_DECODE_ASSIST),
-                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_SSE_3_5_DISABLE),
-                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER),
-                FLAG_NAME(AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER),
-#undef FLAG_NAME
-            };
-            uint32_t fSvmFeatures = pVM->hwaccm.s.svm.u32Features;
-            for (unsigned i = 0; i < RT_ELEMENTS(s_aSvmFeatures); i++)
-                if (fSvmFeatures & s_aSvmFeatures[i].fFlag)
-                {
-                    LogRel(("HWACCM:    %s\n", s_aSvmFeatures[i].pszName));
-                    fSvmFeatures &= ~s_aSvmFeatures[i].fFlag;
-                }
-            if (fSvmFeatures)
-                for (unsigned iBit = 0; iBit < 32; iBit++)
-                    if (RT_BIT_32(iBit) & fSvmFeatures)
-                        LogRel(("HWACCM:    Reserved bit %u\n", iBit));
-
-            /* Only try once. */
-            pVM->hwaccm.s.fInitialized = true;
-
-            if (pVM->hwaccm.s.svm.u32Features & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING)
-                pVM->hwaccm.s.fNestedPaging = pVM->hwaccm.s.fAllowNestedPaging;
-
-            rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HWACC_SETUP_VM, 0, NULL);
-            AssertRC(rc);
-            if (rc == VINF_SUCCESS)
-            {
-                pVM->fHWACCMEnabled = true;
-                pVM->hwaccm.s.svm.fEnabled = true;
-
-                if (pVM->hwaccm.s.fNestedPaging)
-                {
-                    LogRel(("HWACCM:    Enabled nested paging\n"));
-#if HC_ARCH_BITS == 64
-                    if (pVM->hwaccm.s.fLargePages)
-                    {
-                        /* Use large (2 MB) pages for our nested paging PDEs where possible. */
-                        PGMSetLargePageUsage(pVM, true);
-                        LogRel(("HWACCM:    Large page support enabled!\n"));
-                    }
-#endif
-                }
-
-                hwaccmR3DisableRawMode(pVM);
-                CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SEP);
-                CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SYSCALL);
-#ifdef VBOX_ENABLE_64_BITS_GUESTS
-                if (pVM->hwaccm.s.fAllow64BitGuests)
-                {
-                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE);
-                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LONG_MODE);
-                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
-                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LAHF);
-                }
-                else
-                /* Turn on NXE if PAE has been enabled. */
-                if (CPUMGetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE))
-                    CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
-#endif
-
-                LogRel((pVM->hwaccm.s.fAllow64BitGuests
-                        ? "HWACCM:    32-bit and 64-bit guest supported.\n"
-                        : "HWACCM:    32-bit guest supported.\n"));
-
-                LogRel(("HWACCM:    TPR Patching %s.\n", (pVM->hwaccm.s.fTRPPatchingAllowed) ? "enabled" : "disabled"));
-            }
-            else
-            {
-                pVM->fHWACCMEnabled = false;
-            }
-        }
-    }
-    if (pVM->fHWACCMEnabled)
-        LogRel(("HWACCM:    VT-x/AMD-V init method: %s\n", (pVM->hwaccm.s.fGlobalInit) ? "GLOBAL" : "LOCAL"));
-    RTLogRelSetBuffering(fOldBuffered);
-    return VINF_SUCCESS;
-}
-
-
-/**
- * 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.
- *
- * @param   pVM     The VM.
- */
-VMMR3DECL(void) HWACCMR3Relocate(PVM pVM)
-{
-    Log(("HWACCMR3Relocate to %RGv\n", MMHyperGetArea(pVM, 0)));
-
-    /* Fetch the current paging mode during the relocate callback during state loading. */
-    if (VMR3GetState(pVM) == VMSTATE_LOADING)
-    {
-        for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        {
-            PVMCPU pVCpu = &pVM->aCpus[i];
-
-            pVCpu->hwaccm.s.enmShadowMode            = PGMGetShadowMode(pVCpu);
-            Assert(pVCpu->hwaccm.s.vmx.enmCurrGuestMode == PGMGetGuestMode(pVCpu));
-            pVCpu->hwaccm.s.vmx.enmCurrGuestMode     = PGMGetGuestMode(pVCpu);
-        }
-    }
-#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
-    if (pVM->fHWACCMEnabled)
-    {
-        int rc;
-        switch (PGMGetHostMode(pVM))
-        {
-            case PGMMODE_32_BIT:
-                pVM->hwaccm.s.pfnHost32ToGuest64R0 = VMMR3GetHostToGuestSwitcher(pVM, VMMSWITCHER_32_TO_AMD64);
-                break;
-
-            case PGMMODE_PAE:
-            case PGMMODE_PAE_NX:
-                pVM->hwaccm.s.pfnHost32ToGuest64R0 = VMMR3GetHostToGuestSwitcher(pVM, VMMSWITCHER_PAE_TO_AMD64);
-                break;
-
-            default:
-                AssertFailed();
-                break;
-        }
-        rc = PDMR3LdrGetSymbolRC(pVM, NULL,       "VMXGCStartVM64", &pVM->hwaccm.s.pfnVMXGCStartVM64);
-        AssertReleaseMsgRC(rc, ("VMXGCStartVM64 -> rc=%Rrc\n", rc));
-
-        rc = PDMR3LdrGetSymbolRC(pVM, NULL,       "SVMGCVMRun64",   &pVM->hwaccm.s.pfnSVMGCVMRun64);
-        AssertReleaseMsgRC(rc, ("SVMGCVMRun64 -> rc=%Rrc\n", rc));
-
-        rc = PDMR3LdrGetSymbolRC(pVM, NULL,       "HWACCMSaveGuestFPU64",   &pVM->hwaccm.s.pfnSaveGuestFPU64);
-        AssertReleaseMsgRC(rc, ("HWACCMSetupFPU64 -> rc=%Rrc\n", rc));
-
-        rc = PDMR3LdrGetSymbolRC(pVM, NULL,       "HWACCMSaveGuestDebug64",   &pVM->hwaccm.s.pfnSaveGuestDebug64);
-        AssertReleaseMsgRC(rc, ("HWACCMSetupDebug64 -> rc=%Rrc\n", rc));
-
-# ifdef DEBUG
-        rc = PDMR3LdrGetSymbolRC(pVM, NULL,       "HWACCMTestSwitcher64",   &pVM->hwaccm.s.pfnTest64);
-        AssertReleaseMsgRC(rc, ("HWACCMTestSwitcher64 -> rc=%Rrc\n", rc));
-# endif
-    }
-#endif
-    return;
-}
-
-
-/**
- * Checks if hardware accelerated raw mode is allowed.
- *
- * @returns true if hardware acceleration is allowed, otherwise false.
- * @param   pVM         Pointer to the VM.
- */
-VMMR3DECL(bool) HWACCMR3IsAllowed(PVM pVM)
-{
-    return pVM->hwaccm.s.fAllowed;
-}
-
-
-/**
- * Notification callback which is called whenever there is a chance that a CR3
- * value might have changed.
- *
- * This is called by PGM.
- *
- * @param   pVM            Pointer to the VM.
- * @param   pVCpu          Pointer to the VMCPU.
- * @param   enmShadowMode  New shadow paging mode.
- * @param   enmGuestMode   New guest paging mode.
- */
-VMMR3DECL(void) HWACCMR3PagingModeChanged(PVM pVM, PVMCPU pVCpu, PGMMODE enmShadowMode, PGMMODE enmGuestMode)
-{
-    /* Ignore page mode changes during state loading. */
-    if (VMR3GetState(pVCpu->pVMR3) == VMSTATE_LOADING)
-        return;
-
-    pVCpu->hwaccm.s.enmShadowMode = enmShadowMode;
-
-    if (   pVM->hwaccm.s.vmx.fEnabled
-        && pVM->fHWACCMEnabled)
-    {
-        if (    pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode == PGMMODE_REAL
-            &&  enmGuestMode >= PGMMODE_PROTECTED)
-        {
-            PCPUMCTX pCtx;
-
-            pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-
-            /* After a real mode switch to protected mode we must force
-               CPL to 0. Our real mode emulation had to set it to 3. */
-            pCtx->ss.Attr.n.u2Dpl  = 0;
-        }
-    }
-
-    if (pVCpu->hwaccm.s.vmx.enmCurrGuestMode != enmGuestMode)
-    {
-        /* Keep track of paging mode changes. */
-        pVCpu->hwaccm.s.vmx.enmPrevGuestMode = pVCpu->hwaccm.s.vmx.enmCurrGuestMode;
-        pVCpu->hwaccm.s.vmx.enmCurrGuestMode = enmGuestMode;
-
-        /* Did we miss a change, because all code was executed in the recompiler? */
-        if (pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode == enmGuestMode)
-        {
-            Log(("HWACCMR3PagingModeChanged missed %s->%s transition (prev %s)\n", PGMGetModeName(pVCpu->hwaccm.s.vmx.enmPrevGuestMode), PGMGetModeName(pVCpu->hwaccm.s.vmx.enmCurrGuestMode), PGMGetModeName(pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode)));
-            pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode = pVCpu->hwaccm.s.vmx.enmPrevGuestMode;
-        }
-    }
-
-    /* Reset the contents of the read cache. */
-    PVMCSCACHE pCache = &pVCpu->hwaccm.s.vmx.VMCSCache;
-    for (unsigned j = 0; j < pCache->Read.cValidEntries; j++)
-        pCache->Read.aFieldVal[j] = 0;
-}
-
-
-/**
- * Terminates the HWACCM.
- *
- * Termination means cleaning up and freeing all resources,
- * the VM itself is, at this point, powered off or suspended.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- */
-VMMR3DECL(int) HWACCMR3Term(PVM pVM)
-{
-    if (pVM->hwaccm.s.vmx.pRealModeTSS)
-    {
-        PDMR3VMMDevHeapFree(pVM, pVM->hwaccm.s.vmx.pRealModeTSS);
-        pVM->hwaccm.s.vmx.pRealModeTSS       = 0;
-    }
-    hwaccmR3TermCPU(pVM);
-    return 0;
-}
-
-
-/**
- * Terminates the per-VCPU HWACCM.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- */
-static int hwaccmR3TermCPU(PVM pVM)
-{
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i]; NOREF(pVCpu);
-
-#ifdef VBOX_WITH_STATISTICS
-        if (pVCpu->hwaccm.s.paStatExitReason)
-        {
-            MMHyperFree(pVM, pVCpu->hwaccm.s.paStatExitReason);
-            pVCpu->hwaccm.s.paStatExitReason   = NULL;
-            pVCpu->hwaccm.s.paStatExitReasonR0 = NIL_RTR0PTR;
-        }
-        if (pVCpu->hwaccm.s.paStatInjectedIrqs)
-        {
-            MMHyperFree(pVM, pVCpu->hwaccm.s.paStatInjectedIrqs);
-            pVCpu->hwaccm.s.paStatInjectedIrqs   = NULL;
-            pVCpu->hwaccm.s.paStatInjectedIrqsR0 = NIL_RTR0PTR;
-        }
-#endif
-
-#ifdef VBOX_WITH_CRASHDUMP_MAGIC
-        memset(pVCpu->hwaccm.s.vmx.VMCSCache.aMagic, 0, sizeof(pVCpu->hwaccm.s.vmx.VMCSCache.aMagic));
-        pVCpu->hwaccm.s.vmx.VMCSCache.uMagic = 0;
-        pVCpu->hwaccm.s.vmx.VMCSCache.uPos = 0xffffffff;
-#endif
-    }
-    return 0;
-}
-
-
-/**
- * Resets a virtual CPU.
- *
- * Used by HWACCMR3Reset and CPU hot plugging.
- *
- * @param   pVCpu   The CPU to reset.
- */
-VMMR3DECL(void) HWACCMR3ResetCpu(PVMCPU pVCpu)
-{
-    /* On first entry we'll sync everything. */
-    pVCpu->hwaccm.s.fContextUseFlags = HWACCM_CHANGED_ALL;
-
-    pVCpu->hwaccm.s.vmx.cr0_mask = 0;
-    pVCpu->hwaccm.s.vmx.cr4_mask = 0;
-
-    pVCpu->hwaccm.s.fActive        = false;
-    pVCpu->hwaccm.s.Event.fPending = false;
-
-    /* Reset state information for real-mode emulation in VT-x. */
-    pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode = PGMMODE_REAL;
-    pVCpu->hwaccm.s.vmx.enmPrevGuestMode     = PGMMODE_REAL;
-    pVCpu->hwaccm.s.vmx.enmCurrGuestMode     = PGMMODE_REAL;
-
-    /* Reset the contents of the read cache. */
-    PVMCSCACHE pCache = &pVCpu->hwaccm.s.vmx.VMCSCache;
-    for (unsigned j = 0; j < pCache->Read.cValidEntries; j++)
-        pCache->Read.aFieldVal[j] = 0;
-
-#ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    /* Magic marker for searching in crash dumps. */
-    strcpy((char *)pCache->aMagic, "VMCSCACHE Magic");
-    pCache->uMagic = UINT64_C(0xDEADBEEFDEADBEEF);
-#endif
-}
-
-
-/**
- * The VM is being reset.
- *
- * For the HWACCM component this means that any GDT/LDT/TSS monitors
- * needs to be removed.
- *
- * @param   pVM     Pointer to the VM.
- */
-VMMR3DECL(void) HWACCMR3Reset(PVM pVM)
-{
-    LogFlow(("HWACCMR3Reset:\n"));
-
-    if (pVM->fHWACCMEnabled)
-        hwaccmR3DisableRawMode(pVM);
-
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
-
-        HWACCMR3ResetCpu(pVCpu);
-    }
-
-    /* Clear all patch information. */
-    pVM->hwaccm.s.pGuestPatchMem         = 0;
-    pVM->hwaccm.s.pFreeGuestPatchMem     = 0;
-    pVM->hwaccm.s.cbGuestPatchMem        = 0;
-    pVM->hwaccm.s.cPatches           = 0;
-    pVM->hwaccm.s.PatchTree          = 0;
-    pVM->hwaccm.s.fTPRPatchingActive = false;
-    ASMMemZero32(pVM->hwaccm.s.aPatches, sizeof(pVM->hwaccm.s.aPatches));
-}
-
-
-/**
- * Callback to patch a TPR instruction (vmmcall or mov cr8).
- *
- * @returns VBox strict status code.
- * @param   pVM     Pointer to the VM.
- * @param   pVCpu   The VMCPU for the EMT we're being called on.
- * @param   pvUser  Unused.
- */
-DECLCALLBACK(VBOXSTRICTRC) hwaccmR3RemovePatches(PVM pVM, PVMCPU pVCpu, void *pvUser)
-{
-    VMCPUID idCpu = (VMCPUID)(uintptr_t)pvUser;
-
-    /* Only execute the handler on the VCPU the original patch request was issued. */
-    if (pVCpu->idCpu != idCpu)
-        return VINF_SUCCESS;
-
-    Log(("hwaccmR3RemovePatches\n"));
-    for (unsigned i = 0; i < pVM->hwaccm.s.cPatches; i++)
-    {
-        uint8_t         abInstr[15];
-        PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.aPatches[i];
-        RTGCPTR         pInstrGC = (RTGCPTR)pPatch->Core.Key;
-        int             rc;
-
-#ifdef LOG_ENABLED
-        char            szOutput[256];
-
-        rc = DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, CPUMGetGuestCS(pVCpu), pInstrGC, DBGF_DISAS_FLAGS_DEFAULT_MODE,
-                                szOutput, sizeof(szOutput), NULL);
-        if (RT_SUCCESS(rc))
-            Log(("Patched instr: %s\n", szOutput));
-#endif
-
-        /* Check if the instruction is still the same. */
-        rc = PGMPhysSimpleReadGCPtr(pVCpu, abInstr, pInstrGC, pPatch->cbNewOp);
-        if (rc != VINF_SUCCESS)
-        {
-            Log(("Patched code removed? (rc=%Rrc0\n", rc));
-            continue;   /* swapped out or otherwise removed; skip it. */
-        }
-
-        if (memcmp(abInstr, pPatch->aNewOpcode, pPatch->cbNewOp))
-        {
-            Log(("Patched instruction was changed! (rc=%Rrc0\n", rc));
-            continue;   /* skip it. */
-        }
-
-        rc = PGMPhysSimpleWriteGCPtr(pVCpu, pInstrGC, pPatch->aOpcode, pPatch->cbOp);
-        AssertRC(rc);
-
-#ifdef LOG_ENABLED
-        rc = DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, CPUMGetGuestCS(pVCpu), pInstrGC, DBGF_DISAS_FLAGS_DEFAULT_MODE,
-                                szOutput, sizeof(szOutput), NULL);
-        if (RT_SUCCESS(rc))
-            Log(("Original instr: %s\n", szOutput));
-#endif
-    }
-    pVM->hwaccm.s.cPatches           = 0;
-    pVM->hwaccm.s.PatchTree          = 0;
-    pVM->hwaccm.s.pFreeGuestPatchMem = pVM->hwaccm.s.pGuestPatchMem;
-    pVM->hwaccm.s.fTPRPatchingActive = false;
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Worker for enabling patching in a VT-x/AMD-V guest.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   idCpu       VCPU to execute hwaccmR3RemovePatches on.
- * @param   pPatchMem   Patch memory range.
- * @param   cbPatchMem  Size of the memory range.
- */
-static int hwaccmR3EnablePatching(PVM pVM, VMCPUID idCpu, RTRCPTR pPatchMem, unsigned cbPatchMem)
-{
-    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE, hwaccmR3RemovePatches, (void *)(uintptr_t)idCpu);
-    AssertRC(rc);
-
-    pVM->hwaccm.s.pGuestPatchMem      = pPatchMem;
-    pVM->hwaccm.s.pFreeGuestPatchMem  = pPatchMem;
-    pVM->hwaccm.s.cbGuestPatchMem     = cbPatchMem;
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Enable patching in a VT-x/AMD-V guest
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   pPatchMem   Patch memory range.
- * @param   cbPatchMem  Size of the memory range.
- */
-VMMR3DECL(int)  HWACMMR3EnablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem)
-{
-    VM_ASSERT_EMT(pVM);
-    Log(("HWACMMR3EnablePatching %RGv size %x\n", pPatchMem, cbPatchMem));
-    if (pVM->cCpus > 1)
-    {
-        /* We own the IOM lock here and could cause a deadlock by waiting for a VCPU that is blocking on the IOM lock. */
-        int rc = VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE,
-                                   (PFNRT)hwaccmR3EnablePatching, 4, pVM, VMMGetCpuId(pVM), (RTRCPTR)pPatchMem, cbPatchMem);
-        AssertRC(rc);
-        return rc;
-    }
-    return hwaccmR3EnablePatching(pVM, VMMGetCpuId(pVM), (RTRCPTR)pPatchMem, cbPatchMem);
-}
-
-
-/**
- * Disable patching in a VT-x/AMD-V guest.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   pPatchMem   Patch memory range.
- * @param   cbPatchMem  Size of the memory range.
- */
-VMMR3DECL(int)  HWACMMR3DisablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem)
-{
-    Log(("HWACMMR3DisablePatching %RGv size %x\n", pPatchMem, cbPatchMem));
-
-    Assert(pVM->hwaccm.s.pGuestPatchMem == pPatchMem);
-    Assert(pVM->hwaccm.s.cbGuestPatchMem == cbPatchMem);
-
-    /* @todo Potential deadlock when other VCPUs are waiting on the IOM lock (we own it)!! */
-    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE, hwaccmR3RemovePatches, (void *)(uintptr_t)VMMGetCpuId(pVM));
-    AssertRC(rc);
-
-    pVM->hwaccm.s.pGuestPatchMem      = 0;
-    pVM->hwaccm.s.pFreeGuestPatchMem  = 0;
-    pVM->hwaccm.s.cbGuestPatchMem     = 0;
-    pVM->hwaccm.s.fTPRPatchingActive = false;
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Callback to patch a TPR instruction (vmmcall or mov cr8).
- *
- * @returns VBox strict status code.
- * @param   pVM     Pointer to the VM.
- * @param   pVCpu   The VMCPU for the EMT we're being called on.
- * @param   pvUser  User specified CPU context.
- *
- */
-DECLCALLBACK(VBOXSTRICTRC) hwaccmR3ReplaceTprInstr(PVM pVM, PVMCPU pVCpu, void *pvUser)
-{
-    /*
-     * Only execute the handler on the VCPU the original patch request was
-     * issued. (The other CPU(s) might not yet have switched to protected
-     * mode, nor have the correct memory context.)
-     */
-    VMCPUID         idCpu  = (VMCPUID)(uintptr_t)pvUser;
-    if (pVCpu->idCpu != idCpu)
-        return VINF_SUCCESS;
-
-    /*
-     * We're racing other VCPUs here, so don't try patch the instruction twice
-     * and make sure there is still room for our patch record.
-     */
-    PCPUMCTX        pCtx   = CPUMQueryGuestCtxPtr(pVCpu);
-    PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
-    if (pPatch)
-    {
-        Log(("hwaccmR3ReplaceTprInstr: already patched %RGv\n", pCtx->rip));
-        return VINF_SUCCESS;
-    }
-    uint32_t const  idx = pVM->hwaccm.s.cPatches;
-    if (idx >= RT_ELEMENTS(pVM->hwaccm.s.aPatches))
-    {
-        Log(("hwaccmR3ReplaceTprInstr: no available patch slots (%RGv)\n", pCtx->rip));
-        return VINF_SUCCESS;
-    }
-    pPatch = &pVM->hwaccm.s.aPatches[idx];
-
-    Log(("hwaccmR3ReplaceTprInstr: rip=%RGv idxPatch=%u\n", pCtx->rip, idx));
-
-    /*
-     * Disassembler the instruction and get cracking.
-     */
-    DBGFR3DisasInstrCurrentLog(pVCpu, "hwaccmR3ReplaceTprInstr");
-    PDISCPUSTATE    pDis = &pVCpu->hwaccm.s.DisState;
-    uint32_t        cbOp;
-    int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
-    AssertRC(rc);
-    if (    rc == VINF_SUCCESS
-        &&  pDis->pCurInstr->uOpcode == OP_MOV
-        &&  cbOp >= 3)
-    {
-        static uint8_t const s_abVMMCall[3] = { 0x0f, 0x01, 0xd9 };
-
-        rc = PGMPhysSimpleReadGCPtr(pVCpu, pPatch->aOpcode, pCtx->rip, cbOp);
-        AssertRC(rc);
-
-        pPatch->cbOp = cbOp;
-
-        if (pDis->Param1.fUse == DISUSE_DISPLACEMENT32)
-        {
-            /* write. */
-            if (pDis->Param2.fUse == DISUSE_REG_GEN32)
-            {
-                pPatch->enmType     = HWACCMTPRINSTR_WRITE_REG;
-                pPatch->uSrcOperand = pDis->Param2.Base.idxGenReg;
-                Log(("hwaccmR3ReplaceTprInstr: HWACCMTPRINSTR_WRITE_REG %u\n", pDis->Param2.Base.idxGenReg));
-            }
-            else
-            {
-                Assert(pDis->Param2.fUse == DISUSE_IMMEDIATE32);
-                pPatch->enmType     = HWACCMTPRINSTR_WRITE_IMM;
-                pPatch->uSrcOperand = pDis->Param2.uValue;
-                Log(("hwaccmR3ReplaceTprInstr: HWACCMTPRINSTR_WRITE_IMM %#llx\n", pDis->Param2.uValue));
-            }
-            rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, s_abVMMCall, sizeof(s_abVMMCall));
-            AssertRC(rc);
-
-            memcpy(pPatch->aNewOpcode, s_abVMMCall, sizeof(s_abVMMCall));
-            pPatch->cbNewOp = sizeof(s_abVMMCall);
-        }
-        else
-        {
-            /*
-             * TPR Read.
-             *
-             * Found:
-             *   mov eax, dword [fffe0080]        (5 bytes)
-             * Check if next instruction is:
-             *   shr eax, 4
-             */
-            Assert(pDis->Param1.fUse == DISUSE_REG_GEN32);
-
-            uint8_t  const idxMmioReg = pDis->Param1.Base.idxGenReg;
-            uint8_t  const cbOpMmio   = cbOp;
-            uint64_t const uSavedRip  = pCtx->rip;
-
-            pCtx->rip += cbOp;
-            rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
-            DBGFR3DisasInstrCurrentLog(pVCpu, "Following read");
-            pCtx->rip = uSavedRip;
-
-            if (    rc == VINF_SUCCESS
-                &&  pDis->pCurInstr->uOpcode == OP_SHR
-                &&  pDis->Param1.fUse == DISUSE_REG_GEN32
-                &&  pDis->Param1.Base.idxGenReg == idxMmioReg
-                &&  pDis->Param2.fUse == DISUSE_IMMEDIATE8
-                &&  pDis->Param2.uValue == 4
-                &&  cbOpMmio + cbOp < sizeof(pVM->hwaccm.s.aPatches[idx].aOpcode))
-            {
-                uint8_t abInstr[15];
-
-                /* Replacing two instructions now. */
-                rc = PGMPhysSimpleReadGCPtr(pVCpu, &pPatch->aOpcode, pCtx->rip, cbOpMmio + cbOp);
-                AssertRC(rc);
-
-                pPatch->cbOp = cbOpMmio + cbOp;
-
-                /* 0xF0, 0x0F, 0x20, 0xC0 = mov eax, cr8 */
-                abInstr[0] = 0xF0;
-                abInstr[1] = 0x0F;
-                abInstr[2] = 0x20;
-                abInstr[3] = 0xC0 | pDis->Param1.Base.idxGenReg;
-                for (unsigned i = 4; i < pPatch->cbOp; i++)
-                    abInstr[i] = 0x90;  /* nop */
-
-                rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, abInstr, pPatch->cbOp);
-                AssertRC(rc);
-
-                memcpy(pPatch->aNewOpcode, abInstr, pPatch->cbOp);
-                pPatch->cbNewOp = pPatch->cbOp;
-
-                Log(("Acceptable read/shr candidate!\n"));
-                pPatch->enmType = HWACCMTPRINSTR_READ_SHR4;
-            }
-            else
-            {
-                pPatch->enmType     = HWACCMTPRINSTR_READ;
-                pPatch->uDstOperand = idxMmioReg;
-
-                rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, s_abVMMCall, sizeof(s_abVMMCall));
-                AssertRC(rc);
-
-                memcpy(pPatch->aNewOpcode, s_abVMMCall, sizeof(s_abVMMCall));
-                pPatch->cbNewOp = sizeof(s_abVMMCall);
-                Log(("hwaccmR3ReplaceTprInstr: HWACCMTPRINSTR_READ %u\n", pPatch->uDstOperand));
-            }
-        }
-
-        pPatch->Core.Key = pCtx->eip;
-        rc = RTAvloU32Insert(&pVM->hwaccm.s.PatchTree, &pPatch->Core);
-        AssertRC(rc);
-
-        pVM->hwaccm.s.cPatches++;
-        STAM_COUNTER_INC(&pVM->hwaccm.s.StatTPRReplaceSuccess);
-        return VINF_SUCCESS;
-    }
-
-    /*
-     * Save invalid patch, so we will not try again.
-     */
-    Log(("hwaccmR3ReplaceTprInstr: Failed to patch instr!\n"));
-    pPatch->Core.Key = pCtx->eip;
-    pPatch->enmType  = HWACCMTPRINSTR_INVALID;
-    rc = RTAvloU32Insert(&pVM->hwaccm.s.PatchTree, &pPatch->Core);
-    AssertRC(rc);
-    pVM->hwaccm.s.cPatches++;
-    STAM_COUNTER_INC(&pVM->hwaccm.s.StatTPRReplaceFailure);
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Callback to patch a TPR instruction (jump to generated code).
- *
- * @returns VBox strict status code.
- * @param   pVM     Pointer to the VM.
- * @param   pVCpu   The VMCPU for the EMT we're being called on.
- * @param   pvUser  User specified CPU context.
- *
- */
-DECLCALLBACK(VBOXSTRICTRC) hwaccmR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, void *pvUser)
-{
-    /*
-     * Only execute the handler on the VCPU the original patch request was
-     * issued. (The other CPU(s) might not yet have switched to protected
-     * mode, nor have the correct memory context.)
-     */
-    VMCPUID         idCpu  = (VMCPUID)(uintptr_t)pvUser;
-    if (pVCpu->idCpu != idCpu)
-        return VINF_SUCCESS;
-
-    /*
-     * We're racing other VCPUs here, so don't try patch the instruction twice
-     * and make sure there is still room for our patch record.
-     */
-    PCPUMCTX        pCtx   = CPUMQueryGuestCtxPtr(pVCpu);
-    PHWACCMTPRPATCH pPatch = (PHWACCMTPRPATCH)RTAvloU32Get(&pVM->hwaccm.s.PatchTree, (AVLOU32KEY)pCtx->eip);
-    if (pPatch)
-    {
-        Log(("hwaccmR3PatchTprInstr: already patched %RGv\n", pCtx->rip));
-        return VINF_SUCCESS;
-    }
-    uint32_t const  idx = pVM->hwaccm.s.cPatches;
-    if (idx >= RT_ELEMENTS(pVM->hwaccm.s.aPatches))
-    {
-        Log(("hwaccmR3PatchTprInstr: no available patch slots (%RGv)\n", pCtx->rip));
-        return VINF_SUCCESS;
-    }
-    pPatch = &pVM->hwaccm.s.aPatches[idx];
-
-    Log(("hwaccmR3PatchTprInstr: rip=%RGv idxPatch=%u\n", pCtx->rip, idx));
-    DBGFR3DisasInstrCurrentLog(pVCpu, "hwaccmR3PatchTprInstr");
-
-    /*
-     * Disassemble the instruction and get cracking.
-     */
-    PDISCPUSTATE    pDis   = &pVCpu->hwaccm.s.DisState;
-    uint32_t        cbOp;
-    int rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
-    AssertRC(rc);
-    if (    rc == VINF_SUCCESS
-        &&  pDis->pCurInstr->uOpcode == OP_MOV
-        &&  cbOp >= 5)
-    {
-        uint8_t         aPatch[64];
-        uint32_t        off = 0;
-
-        rc = PGMPhysSimpleReadGCPtr(pVCpu, pPatch->aOpcode, pCtx->rip, cbOp);
-        AssertRC(rc);
-
-        pPatch->cbOp    = cbOp;
-        pPatch->enmType = HWACCMTPRINSTR_JUMP_REPLACEMENT;
-
-        if (pDis->Param1.fUse == DISUSE_DISPLACEMENT32)
-        {
-            /*
-                * TPR write:
-                *
-                * push ECX                      [51]
-                * push EDX                      [52]
-                * push EAX                      [50]
-                * xor EDX,EDX                   [31 D2]
-                * mov EAX,EAX                   [89 C0]
-                *  or
-                * mov EAX,0000000CCh            [B8 CC 00 00 00]
-                * mov ECX,0C0000082h            [B9 82 00 00 C0]
-                * wrmsr                         [0F 30]
-                * pop EAX                       [58]
-                * pop EDX                       [5A]
-                * pop ECX                       [59]
-                * jmp return_address            [E9 return_address]
-                *
-                */
-            bool fUsesEax = (pDis->Param2.fUse == DISUSE_REG_GEN32 && pDis->Param2.Base.idxGenReg == DISGREG_EAX);
-
-            aPatch[off++] = 0x51;    /* push ecx */
-            aPatch[off++] = 0x52;    /* push edx */
-            if (!fUsesEax)
-                aPatch[off++] = 0x50;    /* push eax */
-            aPatch[off++] = 0x31;    /* xor edx, edx */
-            aPatch[off++] = 0xD2;
-            if (pDis->Param2.fUse == DISUSE_REG_GEN32)
-            {
-                if (!fUsesEax)
-                {
-                    aPatch[off++] = 0x89;    /* mov eax, src_reg */
-                    aPatch[off++] = MAKE_MODRM(3, pDis->Param2.Base.idxGenReg, DISGREG_EAX);
-                }
-            }
-            else
-            {
-                Assert(pDis->Param2.fUse == DISUSE_IMMEDIATE32);
-                aPatch[off++] = 0xB8;    /* mov eax, immediate */
-                *(uint32_t *)&aPatch[off] = pDis->Param2.uValue;
-                off += sizeof(uint32_t);
-            }
-            aPatch[off++] = 0xB9;    /* mov ecx, 0xc0000082 */
-            *(uint32_t *)&aPatch[off] = MSR_K8_LSTAR;
-            off += sizeof(uint32_t);
-
-            aPatch[off++] = 0x0F;    /* wrmsr */
-            aPatch[off++] = 0x30;
-            if (!fUsesEax)
-                aPatch[off++] = 0x58;    /* pop eax */
-            aPatch[off++] = 0x5A;    /* pop edx */
-            aPatch[off++] = 0x59;    /* pop ecx */
-        }
-        else
-        {
-            /*
-                * TPR read:
-                *
-                * push ECX                      [51]
-                * push EDX                      [52]
-                * push EAX                      [50]
-                * mov ECX,0C0000082h            [B9 82 00 00 C0]
-                * rdmsr                         [0F 32]
-                * mov EAX,EAX                   [89 C0]
-                * pop EAX                       [58]
-                * pop EDX                       [5A]
-                * pop ECX                       [59]
-                * jmp return_address            [E9 return_address]
-                *
-                */
-            Assert(pDis->Param1.fUse == DISUSE_REG_GEN32);
-
-            if (pDis->Param1.Base.idxGenReg != DISGREG_ECX)
-                aPatch[off++] = 0x51;    /* push ecx */
-            if (pDis->Param1.Base.idxGenReg != DISGREG_EDX )
-                aPatch[off++] = 0x52;    /* push edx */
-            if (pDis->Param1.Base.idxGenReg != DISGREG_EAX)
-                aPatch[off++] = 0x50;    /* push eax */
-
-            aPatch[off++] = 0x31;    /* xor edx, edx */
-            aPatch[off++] = 0xD2;
-
-            aPatch[off++] = 0xB9;    /* mov ecx, 0xc0000082 */
-            *(uint32_t *)&aPatch[off] = MSR_K8_LSTAR;
-            off += sizeof(uint32_t);
-
-            aPatch[off++] = 0x0F;    /* rdmsr */
-            aPatch[off++] = 0x32;
-
-            if (pDis->Param1.Base.idxGenReg != DISGREG_EAX)
-            {
-                aPatch[off++] = 0x89;    /* mov dst_reg, eax */
-                aPatch[off++] = MAKE_MODRM(3, DISGREG_EAX, pDis->Param1.Base.idxGenReg);
-            }
-
-            if (pDis->Param1.Base.idxGenReg != DISGREG_EAX)
-                aPatch[off++] = 0x58;    /* pop eax */
-            if (pDis->Param1.Base.idxGenReg != DISGREG_EDX )
-                aPatch[off++] = 0x5A;    /* pop edx */
-            if (pDis->Param1.Base.idxGenReg != DISGREG_ECX)
-                aPatch[off++] = 0x59;    /* pop ecx */
-        }
-        aPatch[off++] = 0xE9;    /* jmp return_address */
-        *(RTRCUINTPTR *)&aPatch[off] = ((RTRCUINTPTR)pCtx->eip + cbOp) - ((RTRCUINTPTR)pVM->hwaccm.s.pFreeGuestPatchMem + off + 4);
-        off += sizeof(RTRCUINTPTR);
-
-        if (pVM->hwaccm.s.pFreeGuestPatchMem + off <= pVM->hwaccm.s.pGuestPatchMem + pVM->hwaccm.s.cbGuestPatchMem)
-        {
-            /* Write new code to the patch buffer. */
-            rc = PGMPhysSimpleWriteGCPtr(pVCpu, pVM->hwaccm.s.pFreeGuestPatchMem, aPatch, off);
-            AssertRC(rc);
-
-#ifdef LOG_ENABLED
-            uint32_t cbCurInstr;
-            for (RTGCPTR GCPtrInstr = pVM->hwaccm.s.pFreeGuestPatchMem;
-                 GCPtrInstr < pVM->hwaccm.s.pFreeGuestPatchMem + off;
-                 GCPtrInstr += RT_MAX(cbCurInstr, 1))
-            {
-                char     szOutput[256];
-                rc = DBGFR3DisasInstrEx(pVM, pVCpu->idCpu, pCtx->cs.Sel, GCPtrInstr, DBGF_DISAS_FLAGS_DEFAULT_MODE,
-                                        szOutput, sizeof(szOutput), &cbCurInstr);
-                if (RT_SUCCESS(rc))
-                    Log(("Patch instr %s\n", szOutput));
-                else
-                    Log(("%RGv: rc=%Rrc\n", GCPtrInstr, rc));
-            }
-#endif
-
-            pPatch->aNewOpcode[0] = 0xE9;
-            *(RTRCUINTPTR *)&pPatch->aNewOpcode[1] = ((RTRCUINTPTR)pVM->hwaccm.s.pFreeGuestPatchMem) - ((RTRCUINTPTR)pCtx->eip + 5);
-
-            /* Overwrite the TPR instruction with a jump. */
-            rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->eip, pPatch->aNewOpcode, 5);
-            AssertRC(rc);
-
-            DBGFR3DisasInstrCurrentLog(pVCpu, "Jump");
-
-            pVM->hwaccm.s.pFreeGuestPatchMem += off;
-            pPatch->cbNewOp = 5;
-
-            pPatch->Core.Key = pCtx->eip;
-            rc = RTAvloU32Insert(&pVM->hwaccm.s.PatchTree, &pPatch->Core);
-            AssertRC(rc);
-
-            pVM->hwaccm.s.cPatches++;
-            pVM->hwaccm.s.fTPRPatchingActive = true;
-            STAM_COUNTER_INC(&pVM->hwaccm.s.StatTPRPatchSuccess);
-            return VINF_SUCCESS;
-        }
-
-        Log(("Ran out of space in our patch buffer!\n"));
-    }
-    else
-        Log(("hwaccmR3PatchTprInstr: Failed to patch instr!\n"));
-
-
-    /*
-     * Save invalid patch, so we will not try again.
-     */
-    pPatch = &pVM->hwaccm.s.aPatches[idx];
-    pPatch->Core.Key = pCtx->eip;
-    pPatch->enmType  = HWACCMTPRINSTR_INVALID;
-    rc = RTAvloU32Insert(&pVM->hwaccm.s.PatchTree, &pPatch->Core);
-    AssertRC(rc);
-    pVM->hwaccm.s.cPatches++;
-    STAM_COUNTER_INC(&pVM->hwaccm.s.StatTPRPatchFailure);
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Attempt to patch TPR mmio instructions.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   pCtx        Pointer to the guest CPU context.
- */
-VMMR3DECL(int) HWACCMR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
-    NOREF(pCtx);
-    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE,
-                                pVM->hwaccm.s.pGuestPatchMem ? hwaccmR3PatchTprInstr : hwaccmR3ReplaceTprInstr,
-                                (void *)(uintptr_t)pVCpu->idCpu);
-    AssertRC(rc);
-    return rc;
-}
-
-
-/**
- * Force execution of the current IO code in the recompiler.
- *
- * @returns VBox status code.
- * @param   pVM         Pointer to the VM.
- * @param   pCtx        Partial VM execution context.
- */
-VMMR3DECL(int) HWACCMR3EmulateIoBlock(PVM pVM, PCPUMCTX pCtx)
-{
-    PVMCPU pVCpu = VMMGetCpu(pVM);
-
-    Assert(pVM->fHWACCMEnabled);
-    Log(("HWACCMR3EmulateIoBlock\n"));
-
-    /* This is primarily intended to speed up Grub, so we don't care about paged protected mode. */
-    if (HWACCMCanEmulateIoBlockEx(pCtx))
-    {
-        Log(("HWACCMR3EmulateIoBlock -> enabled\n"));
-        pVCpu->hwaccm.s.EmulateIoBlock.fEnabled         = true;
-        pVCpu->hwaccm.s.EmulateIoBlock.GCPtrFunctionEip = pCtx->rip;
-        pVCpu->hwaccm.s.EmulateIoBlock.cr0              = pCtx->cr0;
-        return VINF_EM_RESCHEDULE_REM;
-    }
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Checks if we can currently use hardware accelerated raw mode.
- *
- * @returns true if we can currently use hardware acceleration, otherwise false.
- * @param   pVM         Pointer to the VM.
- * @param   pCtx        Partial VM execution context.
- */
-VMMR3DECL(bool) HWACCMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx)
-{
-    PVMCPU pVCpu = VMMGetCpu(pVM);
-
-    Assert(pVM->fHWACCMEnabled);
-
-    /* If we're still executing the IO code, then return false. */
-    if (    RT_UNLIKELY(pVCpu->hwaccm.s.EmulateIoBlock.fEnabled)
-        &&  pCtx->rip <  pVCpu->hwaccm.s.EmulateIoBlock.GCPtrFunctionEip + 0x200
-        &&  pCtx->rip >  pVCpu->hwaccm.s.EmulateIoBlock.GCPtrFunctionEip - 0x200
-        &&  pCtx->cr0 == pVCpu->hwaccm.s.EmulateIoBlock.cr0)
-        return false;
-
-    pVCpu->hwaccm.s.EmulateIoBlock.fEnabled = false;
-
-    /* AMD-V supports real & protected mode with or without paging. */
-    if (pVM->hwaccm.s.svm.fEnabled)
-    {
-        pVCpu->hwaccm.s.fActive = true;
-        return true;
-    }
-
-    pVCpu->hwaccm.s.fActive = false;
-
-    /* Note! The context supplied by REM is partial. If we add more checks here, be sure to verify that REM provides this info! */
-    Assert((pVM->hwaccm.s.vmx.fUnrestrictedGuest && !pVM->hwaccm.s.vmx.pRealModeTSS) || (!pVM->hwaccm.s.vmx.fUnrestrictedGuest && pVM->hwaccm.s.vmx.pRealModeTSS));
-
-    bool fSupportsRealMode = pVM->hwaccm.s.vmx.fUnrestrictedGuest || PDMVMMDevHeapIsEnabled(pVM);
-    if (!pVM->hwaccm.s.vmx.fUnrestrictedGuest)
-    {
-        /*
-         * The VMM device heap is a requirement for emulating real mode or protected mode without paging with the unrestricted
-         * guest execution feature i missing (VT-x only).
-         */
-        if (fSupportsRealMode)
-        {
-            if (CPUMIsGuestInRealModeEx(pCtx))
-            {
-                /* In V86 mode (VT-x or not), the CPU enforces real-mode compatible selector
-                 * bases and limits, i.e. limit must be 64K and base must be selector * 16.
-                 * If this is not true, we cannot execute real mode as V86 and have to fall
-                 * back to emulation.
-                 */
-                if (   pCtx->cs.Sel != (pCtx->cs.u64Base >> 4)
-                    || pCtx->ds.Sel != (pCtx->ds.u64Base >> 4)
-                    || pCtx->es.Sel != (pCtx->es.u64Base >> 4)
-                    || pCtx->ss.Sel != (pCtx->ss.u64Base >> 4)
-                    || pCtx->fs.Sel != (pCtx->fs.u64Base >> 4)
-                    || pCtx->gs.Sel != (pCtx->gs.u64Base >> 4)
-                    || (pCtx->cs.u32Limit != 0xffff)
-                    || (pCtx->ds.u32Limit != 0xffff)
-                    || (pCtx->es.u32Limit != 0xffff)
-                    || (pCtx->ss.u32Limit != 0xffff)
-                    || (pCtx->fs.u32Limit != 0xffff)
-                    || (pCtx->gs.u32Limit != 0xffff))
-                {
-                    return false;
-                }
-            }
-            else
-            {
-                PGMMODE enmGuestMode = PGMGetGuestMode(pVCpu);
-                /* Verify the requirements for executing code in protected
-                   mode. VT-x can't handle the CPU state right after a switch
-                   from real to protected mode. (all sorts of RPL & DPL assumptions) */
-                if (    pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode == PGMMODE_REAL
-                    &&  enmGuestMode >= PGMMODE_PROTECTED)
-                {
-                    if (   (pCtx->cs.Sel & X86_SEL_RPL)
-                        || (pCtx->ds.Sel & X86_SEL_RPL)
-                        || (pCtx->es.Sel & X86_SEL_RPL)
-                        || (pCtx->fs.Sel & X86_SEL_RPL)
-                        || (pCtx->gs.Sel & X86_SEL_RPL)
-                        || (pCtx->ss.Sel & X86_SEL_RPL))
-                    {
-                        return false;
-                    }
-                }
-                /* VT-x also chokes on invalid tr or ldtr selectors (minix) */
-                if (    pCtx->gdtr.cbGdt
-                    &&  (   pCtx->tr.Sel > pCtx->gdtr.cbGdt
-                         || pCtx->ldtr.Sel > pCtx->gdtr.cbGdt))
-                {
-                        return false;
-                }
-            }
-        }
-        else
-        {
-            if (    !CPUMIsGuestInLongModeEx(pCtx)
-                &&  !pVM->hwaccm.s.vmx.fUnrestrictedGuest)
-            {
-                /** @todo   This should (probably) be set on every excursion to the REM,
-                 *          however it's too risky right now. So, only apply it when we go
-                 *          back to REM for real mode execution. (The XP hack below doesn't
-                 *          work reliably without this.)
-                 *  Update: Implemented in EM.cpp, see #ifdef EM_NOTIFY_HWACCM.  */
-                pVM->aCpus[0].hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_ALL_GUEST;
-
-                if (    !pVM->hwaccm.s.fNestedPaging        /* requires a fake PD for real *and* protected mode without paging - stored in the VMM device heap*/
-                    ||  CPUMIsGuestInRealModeEx(pCtx))      /* requires a fake TSS for real mode - stored in the VMM device heap */
-                    return false;
-
-                /* Too early for VT-x; Solaris guests will fail with a guru meditation otherwise; same for XP. */
-                if (pCtx->idtr.pIdt == 0 || pCtx->idtr.cbIdt == 0 || pCtx->tr.Sel == 0)
-                    return false;
-
-                /* The guest is about to complete the switch to protected mode. Wait a bit longer. */
-                /* Windows XP; switch to protected mode; all selectors are marked not present in the
-                 * hidden registers (possible recompiler bug; see load_seg_vm) */
-                if (pCtx->cs.Attr.n.u1Present == 0)
-                    return false;
-                if (pCtx->ss.Attr.n.u1Present == 0)
-                    return false;
-
-                /* Windows XP: possible same as above, but new recompiler requires new heuristics?
-                   VT-x doesn't seem to like something about the guest state and this stuff avoids it. */
-                /** @todo This check is actually wrong, it doesn't take the direction of the
-                 *        stack segment into account. But, it does the job for now. */
-                if (pCtx->rsp >= pCtx->ss.u32Limit)
-                    return false;
-#if 0
-                if (    pCtx->cs.Sel >= pCtx->gdtr.cbGdt
-                    ||  pCtx->ss.Sel >= pCtx->gdtr.cbGdt
-                    ||  pCtx->ds.Sel >= pCtx->gdtr.cbGdt
-                    ||  pCtx->es.Sel >= pCtx->gdtr.cbGdt
-                    ||  pCtx->fs.Sel >= pCtx->gdtr.cbGdt
-                    ||  pCtx->gs.Sel >= pCtx->gdtr.cbGdt)
-                    return false;
-#endif
-            }
-        }
-    }
-
-    if (pVM->hwaccm.s.vmx.fEnabled)
-    {
-        uint32_t mask;
-
-        /* if bit N is set in cr0_fixed0, then it must be set in the guest's cr0. */
-        mask = (uint32_t)pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed0;
-        /* Note: We ignore the NE bit here on purpose; see vmmr0\hwaccmr0.cpp for details. */
-        mask &= ~X86_CR0_NE;
-
-        if (fSupportsRealMode)
-        {
-            /* Note: We ignore the PE & PG bits here on purpose; we emulate real and protected mode without paging. */
-            mask &= ~(X86_CR0_PG|X86_CR0_PE);
-        }
-        else
-        {
-            /* We support protected mode without paging using identity mapping. */
-            mask &= ~X86_CR0_PG;
-        }
-        if ((pCtx->cr0 & mask) != mask)
-            return false;
-
-        /* if bit N is cleared in cr0_fixed1, then it must be zero in the guest's cr0. */
-        mask = (uint32_t)~pVM->hwaccm.s.vmx.msr.vmx_cr0_fixed1;
-        if ((pCtx->cr0 & mask) != 0)
-            return false;
-
-        /* if bit N is set in cr4_fixed0, then it must be set in the guest's cr4. */
-        mask  = (uint32_t)pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed0;
-        mask &= ~X86_CR4_VMXE;
-        if ((pCtx->cr4 & mask) != mask)
-            return false;
-
-        /* if bit N is cleared in cr4_fixed1, then it must be zero in the guest's cr4. */
-        mask = (uint32_t)~pVM->hwaccm.s.vmx.msr.vmx_cr4_fixed1;
-        if ((pCtx->cr4 & mask) != 0)
-            return false;
-
-        pVCpu->hwaccm.s.fActive = true;
-        return true;
-    }
-
-    return false;
-}
-
-
-/**
- * Checks if we need to reschedule due to VMM device heap changes.
- *
- * @returns true if a reschedule is required, otherwise false.
- * @param   pVM         Pointer to the VM.
- * @param   pCtx        VM execution context.
- */
-VMMR3DECL(bool) HWACCMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx)
-{
-    /*
-     * The VMM device heap is a requirement for emulating real mode or protected mode without paging
-     * when the unrestricted guest execution feature is missing (VT-x only).
-     */
-    if (    pVM->hwaccm.s.vmx.fEnabled
-        &&  !pVM->hwaccm.s.vmx.fUnrestrictedGuest
-        &&  !CPUMIsGuestInPagedProtectedModeEx(pCtx)
-        &&  !PDMVMMDevHeapIsEnabled(pVM)
-        &&  (pVM->hwaccm.s.fNestedPaging || CPUMIsGuestInRealModeEx(pCtx)))
-        return true;
-
-    return false;
-}
-
-
-/**
- * Notification from EM about a rescheduling into hardware assisted execution
- * mode.
- *
- * @param   pVCpu       Pointer to the current VMCPU.
- */
-VMMR3DECL(void) HWACCMR3NotifyScheduled(PVMCPU pVCpu)
-{
-    pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_ALL_GUEST;
-}
-
-
-/**
- * Notification from EM about returning from instruction emulation (REM / EM).
- *
- * @param   pVCpu       Pointer to the VMCPU.
- */
-VMMR3DECL(void) HWACCMR3NotifyEmulated(PVMCPU pVCpu)
-{
-    pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_ALL_GUEST;
-}
-
-
-/**
- * Checks if we are currently using hardware accelerated raw mode.
- *
- * @returns true if hardware acceleration is being used, otherwise false.
- * @param   pVCpu        Pointer to the VMCPU.
- */
-VMMR3DECL(bool) HWACCMR3IsActive(PVMCPU pVCpu)
-{
-    return pVCpu->hwaccm.s.fActive;
-}
-
-
-/**
- * Checks if we are currently using nested paging.
- *
- * @returns true if nested paging is being used, otherwise false.
- * @param   pVM         Pointer to the VM.
- */
-VMMR3DECL(bool) HWACCMR3IsNestedPagingActive(PVM pVM)
-{
-    return pVM->hwaccm.s.fNestedPaging;
-}
-
-
-/**
- * Checks if we are currently using VPID in VT-x mode.
- *
- * @returns true if VPID is being used, otherwise false.
- * @param   pVM         Pointer to the VM.
- */
-VMMR3DECL(bool) HWACCMR3IsVPIDActive(PVM pVM)
-{
-    return pVM->hwaccm.s.vmx.fVPID;
-}
-
-
-/**
- * Checks if internal events are pending. In that case we are not allowed to dispatch interrupts.
- *
- * @returns true if an internal event is pending, otherwise false.
- * @param   pVM         Pointer to the VM.
- */
-VMMR3DECL(bool) HWACCMR3IsEventPending(PVMCPU pVCpu)
-{
-    return HWACCMIsEnabled(pVCpu->pVMR3) && pVCpu->hwaccm.s.Event.fPending;
-}
-
-
-/**
- * Checks if the VMX-preemption timer is being used.
- *
- * @returns true if the VMX-preemption timer is being used, otherwise false.
- * @param   pVM         Pointer to the VM.
- */
-VMMR3DECL(bool) HWACCMR3IsVmxPreemptionTimerUsed(PVM pVM)
-{
-    return HWACCMIsEnabled(pVM)
-        && pVM->hwaccm.s.vmx.fEnabled
-        && pVM->hwaccm.s.vmx.fUsePreemptTimer;
-}
-
-
-/**
- * Restart an I/O instruction that was refused in ring-0
- *
- * @returns Strict VBox status code. Informational status codes other than the one documented
- *          here are to be treated as internal failure. Use IOM_SUCCESS() to check for success.
- * @retval  VINF_SUCCESS                Success.
- * @retval  VINF_EM_FIRST-VINF_EM_LAST  Success with some exceptions (see IOM_SUCCESS()), the
- *                                      status code must be passed on to EM.
- * @retval  VERR_NOT_FOUND if no pending I/O instruction.
- *
- * @param   pVM         Pointer to the VM.
- * @param   pVCpu       Pointer to the VMCPU.
- * @param   pCtx        Pointer to the guest CPU context.
- */
-VMMR3DECL(VBOXSTRICTRC) HWACCMR3RestartPendingIOInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
-{
-    HWACCMPENDINGIO enmType = pVCpu->hwaccm.s.PendingIO.enmType;
-
-    pVCpu->hwaccm.s.PendingIO.enmType = HWACCMPENDINGIO_INVALID;
-
-    if (    pVCpu->hwaccm.s.PendingIO.GCPtrRip != pCtx->rip
-        ||  enmType  == HWACCMPENDINGIO_INVALID)
-        return VERR_NOT_FOUND;
-
-    VBOXSTRICTRC rcStrict;
-    switch (enmType)
-    {
-        case HWACCMPENDINGIO_PORT_READ:
-        {
-            uint32_t uAndVal = pVCpu->hwaccm.s.PendingIO.s.Port.uAndVal;
-            uint32_t u32Val  = 0;
-
-            rcStrict = IOMIOPortRead(pVM, pVCpu->hwaccm.s.PendingIO.s.Port.uPort,
-                                     &u32Val,
-                                     pVCpu->hwaccm.s.PendingIO.s.Port.cbSize);
-            if (IOM_SUCCESS(rcStrict))
-            {
-                /* Write back to the EAX register. */
-                pCtx->eax = (pCtx->eax & ~uAndVal) | (u32Val & uAndVal);
-                pCtx->rip = pVCpu->hwaccm.s.PendingIO.GCPtrRipNext;
-            }
-            break;
-        }
-
-        case HWACCMPENDINGIO_PORT_WRITE:
-            rcStrict = IOMIOPortWrite(pVM, pVCpu->hwaccm.s.PendingIO.s.Port.uPort,
-                                      pCtx->eax & pVCpu->hwaccm.s.PendingIO.s.Port.uAndVal,
-                                      pVCpu->hwaccm.s.PendingIO.s.Port.cbSize);
-            if (IOM_SUCCESS(rcStrict))
-                pCtx->rip = pVCpu->hwaccm.s.PendingIO.GCPtrRipNext;
-            break;
-
-        default:
-            AssertLogRelFailedReturn(VERR_HM_UNKNOWN_IO_INSTRUCTION);
-    }
-
-    return rcStrict;
-}
-
-
-/**
- * Inject an NMI into a running VM (only VCPU 0!)
- *
- * @returns boolean
- * @param   pVM         Pointer to the VM.
- */
-VMMR3DECL(int)  HWACCMR3InjectNMI(PVM pVM)
-{
-    VMCPU_FF_SET(&pVM->aCpus[0], VMCPU_FF_INTERRUPT_NMI);
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Check fatal VT-x/AMD-V error and produce some meaningful
- * log release message.
- *
- * @param   pVM         Pointer to the VM.
- * @param   iStatusCode VBox status code.
- */
-VMMR3DECL(void) HWACCMR3CheckError(PVM pVM, int iStatusCode)
-{
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        switch (iStatusCode)
-        {
-            case VERR_VMX_INVALID_VMCS_FIELD:
-                break;
-
-            case VERR_VMX_INVALID_VMCS_PTR:
-                LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Current pointer %RGp vs %RGp\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.u64VMCSPhys, pVM->aCpus[i].hwaccm.s.vmx.HCPhysVMCS));
-                LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Current VMCS version %x\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.ulVMCSRevision));
-                LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Entered Cpu %d\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.idEnteredCpu));
-                LogRel(("VERR_VMX_INVALID_VMCS_PTR: CPU%d Current Cpu %d\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.idCurrentCpu));
-                break;
-
-            case VERR_VMX_UNABLE_TO_START_VM:
-                LogRel(("VERR_VMX_UNABLE_TO_START_VM: CPU%d instruction error %x\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.ulInstrError));
-                LogRel(("VERR_VMX_UNABLE_TO_START_VM: CPU%d exit reason       %x\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.ulExitReason));
-                if (pVM->aCpus[i].hwaccm.s.vmx.lasterror.ulInstrError == VMX_ERROR_VMENTRY_INVALID_CONTROL_FIELDS)
-                {
-                    LogRel(("VERR_VMX_UNABLE_TO_START_VM: Cpu%d MSRBitmapPhys %RHp\n", i, pVM->aCpus[i].hwaccm.s.vmx.pMSRBitmapPhys));
-#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
-                    LogRel(("VERR_VMX_UNABLE_TO_START_VM: Cpu%d GuestMSRPhys  %RHp\n", i, pVM->aCpus[i].hwaccm.s.vmx.pGuestMSRPhys));
-                    LogRel(("VERR_VMX_UNABLE_TO_START_VM: Cpu%d HostMsrPhys   %RHp\n", i, pVM->aCpus[i].hwaccm.s.vmx.pHostMSRPhys));
-                    LogRel(("VERR_VMX_UNABLE_TO_START_VM: Cpu%d Cached MSRs   %x\n",   i, pVM->aCpus[i].hwaccm.s.vmx.cCachedMSRs));
-#endif
-                }
-                /** @todo Log VM-entry event injection control fields
-                 *        VMX_VMCS_CTRL_ENTRY_IRQ_INFO, VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE
-                 *        and VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH from the VMCS. */
-                break;
-
-            case VERR_VMX_UNABLE_TO_RESUME_VM:
-                LogRel(("VERR_VMX_UNABLE_TO_RESUME_VM: CPU%d instruction error %x\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.ulInstrError));
-                LogRel(("VERR_VMX_UNABLE_TO_RESUME_VM: CPU%d exit reason       %x\n", i, pVM->aCpus[i].hwaccm.s.vmx.lasterror.ulExitReason));
-                break;
-
-            case VERR_VMX_INVALID_VMXON_PTR:
-                break;
-        }
-    }
-
-    if (iStatusCode == VERR_VMX_UNABLE_TO_START_VM)
-    {
-        LogRel(("VERR_VMX_UNABLE_TO_START_VM: VM-entry allowed    %x\n", pVM->hwaccm.s.vmx.msr.vmx_entry.n.allowed1));
-        LogRel(("VERR_VMX_UNABLE_TO_START_VM: VM-entry disallowed %x\n", pVM->hwaccm.s.vmx.msr.vmx_entry.n.disallowed0));
-    }
-}
-
-
-/**
- * Execute state save operation.
- *
- * @returns VBox status code.
- * @param   pVM             Pointer to the VM.
- * @param   pSSM            SSM operation handle.
- */
-static DECLCALLBACK(int) hwaccmR3Save(PVM pVM, PSSMHANDLE pSSM)
-{
-    int rc;
-
-    Log(("hwaccmR3Save:\n"));
-
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        /*
-         * Save the basic bits - fortunately all the other things can be resynced on load.
-         */
-        rc = SSMR3PutU32(pSSM, pVM->aCpus[i].hwaccm.s.Event.fPending);
-        AssertRCReturn(rc, rc);
-        rc = SSMR3PutU32(pSSM, pVM->aCpus[i].hwaccm.s.Event.errCode);
-        AssertRCReturn(rc, rc);
-        rc = SSMR3PutU64(pSSM, pVM->aCpus[i].hwaccm.s.Event.intInfo);
-        AssertRCReturn(rc, rc);
-
-        rc = SSMR3PutU32(pSSM, pVM->aCpus[i].hwaccm.s.vmx.enmLastSeenGuestMode);
-        AssertRCReturn(rc, rc);
-        rc = SSMR3PutU32(pSSM, pVM->aCpus[i].hwaccm.s.vmx.enmCurrGuestMode);
-        AssertRCReturn(rc, rc);
-        rc = SSMR3PutU32(pSSM, pVM->aCpus[i].hwaccm.s.vmx.enmPrevGuestMode);
-        AssertRCReturn(rc, rc);
-    }
-#ifdef VBOX_HWACCM_WITH_GUEST_PATCHING
-    rc = SSMR3PutGCPtr(pSSM, pVM->hwaccm.s.pGuestPatchMem);
-    AssertRCReturn(rc, rc);
-    rc = SSMR3PutGCPtr(pSSM, pVM->hwaccm.s.pFreeGuestPatchMem);
-    AssertRCReturn(rc, rc);
-    rc = SSMR3PutU32(pSSM, pVM->hwaccm.s.cbGuestPatchMem);
-    AssertRCReturn(rc, rc);
-
-    /* Store all the guest patch records too. */
-    rc = SSMR3PutU32(pSSM, pVM->hwaccm.s.cPatches);
-    AssertRCReturn(rc, rc);
-
-    for (unsigned i = 0; i < pVM->hwaccm.s.cPatches; i++)
-    {
-        PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.aPatches[i];
-
-        rc = SSMR3PutU32(pSSM, pPatch->Core.Key);
-        AssertRCReturn(rc, rc);
-
-        rc = SSMR3PutMem(pSSM, pPatch->aOpcode, sizeof(pPatch->aOpcode));
-        AssertRCReturn(rc, rc);
-
-        rc = SSMR3PutU32(pSSM, pPatch->cbOp);
-        AssertRCReturn(rc, rc);
-
-        rc = SSMR3PutMem(pSSM, pPatch->aNewOpcode, sizeof(pPatch->aNewOpcode));
-        AssertRCReturn(rc, rc);
-
-        rc = SSMR3PutU32(pSSM, pPatch->cbNewOp);
-        AssertRCReturn(rc, rc);
-
-        AssertCompileSize(HWACCMTPRINSTR, 4);
-        rc = SSMR3PutU32(pSSM, (uint32_t)pPatch->enmType);
-        AssertRCReturn(rc, rc);
-
-        rc = SSMR3PutU32(pSSM, pPatch->uSrcOperand);
-        AssertRCReturn(rc, rc);
-
-        rc = SSMR3PutU32(pSSM, pPatch->uDstOperand);
-        AssertRCReturn(rc, rc);
-
-        rc = SSMR3PutU32(pSSM, pPatch->pJumpTarget);
-        AssertRCReturn(rc, rc);
-
-        rc = SSMR3PutU32(pSSM, pPatch->cFaults);
-        AssertRCReturn(rc, rc);
-    }
-#endif
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Execute state load operation.
- *
- * @returns VBox status code.
- * @param   pVM             Pointer to the VM.
- * @param   pSSM            SSM operation handle.
- * @param   uVersion        Data layout version.
- * @param   uPass           The data pass.
- */
-static DECLCALLBACK(int) hwaccmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
-{
-    int rc;
-
-    Log(("hwaccmR3Load:\n"));
-    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
-
-    /*
-     * Validate version.
-     */
-    if (   uVersion != HWACCM_SSM_VERSION
-        && uVersion != HWACCM_SSM_VERSION_NO_PATCHING
-        && uVersion != HWACCM_SSM_VERSION_2_0_X)
-    {
-        AssertMsgFailed(("hwaccmR3Load: Invalid version uVersion=%d!\n", uVersion));
-        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
-    }
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        rc = SSMR3GetU32(pSSM, &pVM->aCpus[i].hwaccm.s.Event.fPending);
-        AssertRCReturn(rc, rc);
-        rc = SSMR3GetU32(pSSM, &pVM->aCpus[i].hwaccm.s.Event.errCode);
-        AssertRCReturn(rc, rc);
-        rc = SSMR3GetU64(pSSM, &pVM->aCpus[i].hwaccm.s.Event.intInfo);
-        AssertRCReturn(rc, rc);
-
-        if (uVersion >= HWACCM_SSM_VERSION_NO_PATCHING)
-        {
-            uint32_t val;
-
-            rc = SSMR3GetU32(pSSM, &val);
-            AssertRCReturn(rc, rc);
-            pVM->aCpus[i].hwaccm.s.vmx.enmLastSeenGuestMode = (PGMMODE)val;
-
-            rc = SSMR3GetU32(pSSM, &val);
-            AssertRCReturn(rc, rc);
-            pVM->aCpus[i].hwaccm.s.vmx.enmCurrGuestMode = (PGMMODE)val;
-
-            rc = SSMR3GetU32(pSSM, &val);
-            AssertRCReturn(rc, rc);
-            pVM->aCpus[i].hwaccm.s.vmx.enmPrevGuestMode = (PGMMODE)val;
-        }
-    }
-#ifdef VBOX_HWACCM_WITH_GUEST_PATCHING
-    if (uVersion > HWACCM_SSM_VERSION_NO_PATCHING)
-    {
-        rc = SSMR3GetGCPtr(pSSM, &pVM->hwaccm.s.pGuestPatchMem);
-        AssertRCReturn(rc, rc);
-        rc = SSMR3GetGCPtr(pSSM, &pVM->hwaccm.s.pFreeGuestPatchMem);
-        AssertRCReturn(rc, rc);
-        rc = SSMR3GetU32(pSSM, &pVM->hwaccm.s.cbGuestPatchMem);
-        AssertRCReturn(rc, rc);
-
-        /* Fetch all TPR patch records. */
-        rc = SSMR3GetU32(pSSM, &pVM->hwaccm.s.cPatches);
-        AssertRCReturn(rc, rc);
-
-        for (unsigned i = 0; i < pVM->hwaccm.s.cPatches; i++)
-        {
-            PHWACCMTPRPATCH pPatch = &pVM->hwaccm.s.aPatches[i];
-
-            rc = SSMR3GetU32(pSSM, &pPatch->Core.Key);
-            AssertRCReturn(rc, rc);
-
-            rc = SSMR3GetMem(pSSM, pPatch->aOpcode, sizeof(pPatch->aOpcode));
-            AssertRCReturn(rc, rc);
-
-            rc = SSMR3GetU32(pSSM, &pPatch->cbOp);
-            AssertRCReturn(rc, rc);
-
-            rc = SSMR3GetMem(pSSM, pPatch->aNewOpcode, sizeof(pPatch->aNewOpcode));
-            AssertRCReturn(rc, rc);
-
-            rc = SSMR3GetU32(pSSM, &pPatch->cbNewOp);
-            AssertRCReturn(rc, rc);
-
-            rc = SSMR3GetU32(pSSM, (uint32_t *)&pPatch->enmType);
-            AssertRCReturn(rc, rc);
-
-            if (pPatch->enmType == HWACCMTPRINSTR_JUMP_REPLACEMENT)
-                pVM->hwaccm.s.fTPRPatchingActive = true;
-
-            Assert(pPatch->enmType == HWACCMTPRINSTR_JUMP_REPLACEMENT || pVM->hwaccm.s.fTPRPatchingActive == false);
-
-            rc = SSMR3GetU32(pSSM, &pPatch->uSrcOperand);
-            AssertRCReturn(rc, rc);
-
-            rc = SSMR3GetU32(pSSM, &pPatch->uDstOperand);
-            AssertRCReturn(rc, rc);
-
-            rc = SSMR3GetU32(pSSM, &pPatch->cFaults);
-            AssertRCReturn(rc, rc);
-
-            rc = SSMR3GetU32(pSSM, &pPatch->pJumpTarget);
-            AssertRCReturn(rc, rc);
-
-            Log(("hwaccmR3Load: patch %d\n", i));
-            Log(("Key       = %x\n", pPatch->Core.Key));
-            Log(("cbOp      = %d\n", pPatch->cbOp));
-            Log(("cbNewOp   = %d\n", pPatch->cbNewOp));
-            Log(("type      = %d\n", pPatch->enmType));
-            Log(("srcop     = %d\n", pPatch->uSrcOperand));
-            Log(("dstop     = %d\n", pPatch->uDstOperand));
-            Log(("cFaults   = %d\n", pPatch->cFaults));
-            Log(("target    = %x\n", pPatch->pJumpTarget));
-            rc = RTAvloU32Insert(&pVM->hwaccm.s.PatchTree, &pPatch->Core);
-            AssertRC(rc);
-        }
-    }
-#endif
-
-    /* Recheck all VCPUs if we can go straight into hwaccm execution mode. */
-    if (HWACCMIsEnabled(pVM))
-    {
-        for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        {
-            PVMCPU pVCpu = &pVM->aCpus[i];
-
-            HWACCMR3CanExecuteGuest(pVM, CPUMQueryGuestCtxPtr(pVCpu));
-        }
-    }
-    return VINF_SUCCESS;
-}
-
Index: trunk/src/VBox/VMM/VMMR3/IOM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/IOM.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/IOM.cpp	(revision 43387)
@@ -53,5 +53,5 @@
  *
  *
- * @section sec_iom_hwaccm     Hardware Assisted Virtualization Mode
+ * @section sec_iom_hm     Hardware Assisted Virtualization Mode
  *
  * When running in hardware assisted virtualization mode we'll be doing much the
Index: trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp	(revision 43387)
@@ -32,5 +32,5 @@
 #include <VBox/param.h>
 #include <VBox/err.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <VBox/VBoxTpG.h>
 
Index: trunk/src/VBox/VMM/VMMR3/PGM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PGM.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/PGM.cpp	(revision 43387)
@@ -622,5 +622,5 @@
 #include <VBox/vmm/selm.h>
 #include <VBox/vmm/ssm.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include "PGMInternal.h"
 #include <VBox/vmm/vm.h>
@@ -2239,11 +2239,11 @@
     switch (enmWhat)
     {
-        case VMINITCOMPLETED_HWACCM:
+        case VMINITCOMPLETED_HM:
 #ifdef VBOX_WITH_PCI_PASSTHROUGH
             if (pVM->pgm.s.fPciPassthrough)
             {
                 AssertLogRelReturn(pVM->pgm.s.fRamPreAlloc, VERR_PCI_PASSTHROUGH_NO_RAM_PREALLOC);
-                AssertLogRelReturn(HWACCMIsEnabled(pVM), VERR_PCI_PASSTHROUGH_NO_HWACCM);
-                AssertLogRelReturn(HWACCMIsNestedPagingActive(pVM), VERR_PCI_PASSTHROUGH_NO_NESTED_PAGING);
+                AssertLogRelReturn(HMIsEnabled(pVM), VERR_PCI_PASSTHROUGH_NO_HM);
+                AssertLogRelReturn(HMIsNestedPagingActive(pVM), VERR_PCI_PASSTHROUGH_NO_NESTED_PAGING);
 
                 /*
@@ -2578,5 +2578,5 @@
             VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
             pgmR3RefreshShadowModeAfterA20Change(pVCpu);
-            HWACCMFlushTLB(pVCpu);
+            HMFlushTLB(pVCpu);
 #endif
         }
@@ -3173,5 +3173,5 @@
         case PGMMODE_PROTECTED:
             if (    enmShadowMode != PGMMODE_INVALID
-                && !HWACCMIsEnabled(pVM) /* always switch in hwaccm mode! */)
+                && !HMIsEnabled(pVM) /* always switch in hm mode! */)
                 break; /* (no change) */
 
@@ -3328,7 +3328,7 @@
     }
     /* Override the shadow mode is nested paging is active. */
-    pVM->pgm.s.fNestedPaging = HWACCMIsNestedPagingActive(pVM);
+    pVM->pgm.s.fNestedPaging = HMIsNestedPagingActive(pVM);
     if (pVM->pgm.s.fNestedPaging)
-        enmShadowMode = HWACCMGetShwPagingMode(pVM);
+        enmShadowMode = HMGetShwPagingMode(pVM);
 
     *penmSwitcher = enmSwitcher;
@@ -3629,6 +3629,6 @@
     }
 
-    /* Notify HWACCM as well. */
-    HWACCMR3PagingModeChanged(pVM, pVCpu, pVCpu->pgm.s.enmShadowMode, pVCpu->pgm.s.enmGuestMode);
+    /* Notify HM as well. */
+    HMR3PagingModeChanged(pVM, pVCpu, pVCpu->pgm.s.enmShadowMode, pVCpu->pgm.s.enmGuestMode);
     return rc;
 }
Index: trunk/src/VBox/VMM/VMMR3/PGMBth.h
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PGMBth.h	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/PGMBth.h	(revision 43387)
@@ -132,5 +132,5 @@
     PVM pVM = pVCpu->pVMR3;
 
-    Assert(HWACCMIsNestedPagingActive(pVM) == pVM->pgm.s.fNestedPaging);
+    Assert(HMIsNestedPagingActive(pVM) == pVM->pgm.s.fNestedPaging);
     Assert(!pVM->pgm.s.fNestedPaging);
 
Index: trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp	(revision 43387)
@@ -52,5 +52,5 @@
 #include <VBox/param.h>
 #include <VBox/err.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 
 
@@ -240,5 +240,5 @@
 
     /* Not supported/relevant for VT-x and AMD-V. */
-    if (HWACCMIsEnabled(pVM))
+    if (HMIsEnabled(pVM))
         return VERR_NOT_IMPLEMENTED;
 
@@ -293,5 +293,5 @@
 
     /* Not supported/relevant for VT-x and AMD-V. */
-    if (HWACCMIsEnabled(pVM))
+    if (HMIsEnabled(pVM))
         return VERR_NOT_IMPLEMENTED;
 
@@ -581,7 +581,7 @@
             "Hypervisor Virtual handlers:\n"
             "%*s %*s %*s %*s Type       Description\n",
-            - (int)sizeof(RTGCPTR) * 2,     "From", 
-            - (int)sizeof(RTGCPTR) * 2 - 3, "- To (excl)", 
-            - (int)sizeof(RTHCPTR) * 2 - 1, "HandlerHC", 
+            - (int)sizeof(RTGCPTR) * 2,     "From",
+            - (int)sizeof(RTGCPTR) * 2 - 3, "- To (excl)",
+            - (int)sizeof(RTHCPTR) * 2 - 1, "HandlerHC",
             - (int)sizeof(RTRCPTR) * 2 - 1, "HandlerGC");
         RTAvlroGCPtrDoWithAll(&pVM->pgm.s.pTreesR3->HyperVirtHandlers, true, pgmR3InfoHandlersVirtualOne, &Args);
Index: trunk/src/VBox/VMM/VMMR3/PGMMap.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PGMMap.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/PGMMap.cpp	(revision 43387)
@@ -512,5 +512,5 @@
     if (!pgmMapAreMappingsEnabled(pVM))
     {
-        Assert(HWACCMIsEnabled(pVM));
+        Assert(HMIsEnabled(pVM));
         return VINF_SUCCESS;
     }
@@ -674,5 +674,5 @@
 
 /**
- * Interface for disabling the guest mappings when switching to HWACCM mode
+ * Interface for disabling the guest mappings when switching to HM mode
  * during VM creation and VM reset.
  *
Index: trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp	(revision 43387)
@@ -3795,5 +3795,5 @@
         VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
         pgmR3RefreshShadowModeAfterA20Change(pVCpu);
-        HWACCMFlushTLB(pVCpu);
+        HMFlushTLB(pVCpu);
 #endif
         STAM_REL_COUNTER_INC(&pVCpu->pgm.s.cA20Changes);
@@ -4326,5 +4326,5 @@
  *
  * @remarks The VINF_EM_NO_MEMORY status is for the benefit of the FF processing
- *          in EM.cpp and shouldn't be propagated outside TRPM, HWACCM, EM and
+ *          in EM.cpp and shouldn't be propagated outside TRPM, HM, EM and
  *          pgmPhysEnsureHandyPage. There is one exception to this in the \#PF
  *          handler.
Index: trunk/src/VBox/VMM/VMMR3/PGMPool.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PGMPool.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/PGMPool.cpp	(revision 43387)
@@ -459,6 +459,6 @@
     /** @todo change the pool to handle ROOT page allocations specially when
      *        required. */
-    bool fCanUseHighMemory = HWACCMIsNestedPagingActive(pVM)
-                          && HWACCMGetShwPagingMode(pVM) == PGMMODE_EPT;
+    bool fCanUseHighMemory = HMIsNestedPagingActive(pVM)
+                          && HMGetShwPagingMode(pVM) == PGMMODE_EPT;
 
     pgmLock(pVM);
Index: trunk/src/VBox/VMM/VMMR3/PGMShw.h
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PGMShw.h	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/PGMShw.h	(revision 43387)
@@ -188,5 +188,5 @@
     PVM          pVM       = pVCpu->pVMR3;
 
-    Assert(HWACCMIsNestedPagingActive(pVM) == pVM->pgm.s.fNestedPaging);
+    Assert(HMIsNestedPagingActive(pVM) == pVM->pgm.s.fNestedPaging);
     Assert(pVM->pgm.s.fNestedPaging);
     Assert(!pVCpu->pgm.s.pShwPageCR3R3);
Index: trunk/src/VBox/VMM/VMMR3/TRPM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/TRPM.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/TRPM.cpp	(revision 43387)
@@ -93,5 +93,5 @@
 # include <VBox/vmm/rem.h>
 #endif
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 
 #include <VBox/err.h>
@@ -1523,5 +1523,5 @@
         {
 # ifndef IEM_VERIFICATION_MODE
-            if (HWACCMIsEnabled(pVM))
+            if (HMIsEnabled(pVM))
 # endif
             {
@@ -1529,5 +1529,5 @@
                 AssertRC(rc);
                 STAM_COUNTER_INC(&pVM->trpm.s.paStatForwardedIRQR3[u8Interrupt]);
-                return HWACCMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HWACC : VINF_EM_RESCHEDULE_REM;
+                return HMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HWACC : VINF_EM_RESCHEDULE_REM;
             }
             /* If the guest gate is not patched, then we will check (again) if we can patch it. */
@@ -1564,8 +1564,8 @@
         {
             AssertRC(rc);
-            return HWACCMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HWACC : VINF_EM_RESCHEDULE_REM; /* (Heed the halted state if this is changed!) */
+            return HMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HWACC : VINF_EM_RESCHEDULE_REM; /* (Heed the halted state if this is changed!) */
         }
 #else
-        if (HWACCMR3IsActive(pVCpu))
+        if (HMR3IsActive(pVCpu))
         {
             uint8_t u8Interrupt;
Index: trunk/src/VBox/VMM/VMMR3/VM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 43387)
@@ -66,5 +66,5 @@
 #include <VBox/vmm/ssm.h>
 #include <VBox/vmm/ftm.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include "VMInternal.h"
 #include <VBox/vmm/vm.h>
@@ -302,5 +302,5 @@
 
 #ifndef RT_OS_DARWIN
-                case VERR_HWACCM_CONFIG_MISMATCH:
+                case VERR_HM_CONFIG_MISMATCH:
                     pszError = N_("VT-x/AMD-V is either not available on your host or disabled. "
                                   "This hardware extension is required by the VM configuration");
@@ -355,5 +355,5 @@
                     break;
 
-                case VERR_PCI_PASSTHROUGH_NO_HWACCM:
+                case VERR_PCI_PASSTHROUGH_NO_HM:
                     pszError = N_("PCI passthrough requires VT-x/AMD-V");
                     break;
@@ -656,5 +656,5 @@
             rc = CFGMR3QueryBoolDef(pRoot, "HwVirtExtForced", &pVM->fHwVirtExtForced, false);
             if (RT_SUCCESS(rc) && pVM->fHwVirtExtForced)
-                pVM->fHWACCMEnabled = true;
+                pVM->fHMEnabled = true;
 
             /*
@@ -913,5 +913,5 @@
         if (RT_SUCCESS(rc))
         {
-            rc = HWACCMR3Init(pVM);
+            rc = HMR3Init(pVM);
             if (RT_SUCCESS(rc))
             {
@@ -1029,5 +1029,5 @@
                     AssertRC(rc2);
                 }
-                int rc2 = HWACCMR3Term(pVM);
+                int rc2 = HMR3Term(pVM);
                 AssertRC(rc2);
             }
@@ -1071,9 +1071,9 @@
         rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_RING0);
     if (RT_SUCCESS(rc))
-        rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_HWACCM);
-
-    /** @todo Move this to the VMINITCOMPLETED_HWACCM notification handler. */
+        rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_HM);
+
+    /** @todo Move this to the VMINITCOMPLETED_HM notification handler. */
     if (RT_SUCCESS(rc))
-        CPUMR3SetHWVirtEx(pVM, HWACCMIsEnabled(pVM));
+        CPUMR3SetHWVirtEx(pVM, HMIsEnabled(pVM));
 
     LogFlow(("vmR3InitRing0: returns %Rrc\n", rc));
@@ -1125,5 +1125,5 @@
     int rc = VMMR3InitCompleted(pVM, enmWhat);
     if (RT_SUCCESS(rc))
-        rc = HWACCMR3InitCompleted(pVM, enmWhat);
+        rc = HMR3InitCompleted(pVM, enmWhat);
     if (RT_SUCCESS(rc))
         rc = PGMR3InitCompleted(pVM, enmWhat);
@@ -1188,5 +1188,5 @@
     PGMR3Relocate(pVM, 0);              /* Repeat after PDM relocation. */
     CPUMR3Relocate(pVM);
-    HWACCMR3Relocate(pVM);
+    HMR3Relocate(pVM);
     SELMR3Relocate(pVM);
     VMMR3Relocate(pVM, offDelta);
@@ -2454,5 +2454,5 @@
         AssertRC(rc);
 #endif
-        rc = HWACCMR3Term(pVM);
+        rc = HMR3Term(pVM);
         AssertRC(rc);
         rc = PGMR3Term(pVM);
@@ -2863,5 +2863,5 @@
         TMR3Reset(pVM);
         EMR3Reset(pVM);
-        HWACCMR3Reset(pVM);                 /* This must come *after* PATM, CSAM, CPUM, SELM and TRPM. */
+        HMR3Reset(pVM);                 /* This must come *after* PATM, CSAM, CPUM, SELM and TRPM. */
 
 #ifdef LOG_ENABLED
@@ -4444,5 +4444,5 @@
     CPUMR3ResetCpu(pVCpu);
     EMR3ResetCpu(pVCpu);
-    HWACCMR3ResetCpu(pVCpu);
+    HMR3ResetCpu(pVCpu);
     return VINF_EM_WAIT_SIPI;
 }
Index: trunk/src/VBox/VMM/VMMR3/VMM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/VMM.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/VMM.cpp	(revision 43387)
@@ -105,5 +105,5 @@
 #include <VBox/param.h>
 #include <VBox/version.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <iprt/assert.h>
 #include <iprt/alloc.h>
@@ -210,5 +210,5 @@
     AssertRCReturn(rc, rc);
 
-    /* GC switchers are enabled by default. Turned off by HWACCM. */
+    /* GC switchers are enabled by default. Turned off by HM. */
     pVM->vmm.s.fSwitcherDisabled = false;
 
@@ -448,5 +448,5 @@
     STAM_REG(pVM, &pVM->vmm.s.StatRZRetPGMFlushPending,     STAMTYPE_COUNTER, "/VMM/RZRet/PGMFlushPending",     STAMUNIT_OCCURENCES, "Number of VINF_PGM_POOL_FLUSH_PENDING returns.");
     STAM_REG(pVM, &pVM->vmm.s.StatRZRetPendingRequest,      STAMTYPE_COUNTER, "/VMM/RZRet/PendingRequest",      STAMUNIT_OCCURENCES, "Number of VINF_EM_PENDING_REQUEST returns.");
-    STAM_REG(pVM, &pVM->vmm.s.StatRZRetPatchTPR,            STAMTYPE_COUNTER, "/VMM/RZRet/PatchTPR",            STAMUNIT_OCCURENCES, "Number of VINF_EM_HWACCM_PATCH_TPR_INSTR returns.");
+    STAM_REG(pVM, &pVM->vmm.s.StatRZRetPatchTPR,            STAMTYPE_COUNTER, "/VMM/RZRet/PatchTPR",            STAMUNIT_OCCURENCES, "Number of VINF_EM_HM_PATCH_TPR_INSTR returns.");
     STAM_REG(pVM, &pVM->vmm.s.StatRZRetCallRing3,           STAMTYPE_COUNTER, "/VMM/RZCallR3/Misc",             STAMUNIT_OCCURENCES, "Number of Other ring-3 calls.");
     STAM_REG(pVM, &pVM->vmm.s.StatRZCallPDMLock,            STAMTYPE_COUNTER, "/VMM/RZCallR3/PDMLock",          STAMUNIT_OCCURENCES, "Number of VMMCALLRING3_PDM_LOCK calls.");
@@ -681,5 +681,5 @@
              */
             if (   pVM->vmm.s.fUsePeriodicPreemptionTimers
-                && HWACCMR3IsVmxPreemptionTimerUsed(pVM))
+                && HMR3IsVmxPreemptionTimerUsed(pVM))
                 pVM->vmm.s.fUsePeriodicPreemptionTimers = false;
             LogRel(("VMM: fUsePeriodicPreemptionTimers=%RTbool\n", pVM->vmm.s.fUsePeriodicPreemptionTimers));
@@ -937,5 +937,5 @@
 VMMR3DECL(const char *) VMMR3GetRZAssertMsg1(PVM pVM)
 {
-    if (HWACCMIsEnabled(pVM))
+    if (HMIsEnabled(pVM))
         return pVM->vmm.s.szRing0AssertMsg1;
 
@@ -957,5 +957,5 @@
 VMMR3DECL(const char *) VMMR3GetRZAssertMsg2(PVM pVM)
 {
-    if (HWACCMIsEnabled(pVM))
+    if (HMIsEnabled(pVM))
         return pVM->vmm.s.szRing0AssertMsg2;
 
@@ -1403,6 +1403,6 @@
 {
     VM_ASSERT_EMT(pVM);
-    if (HWACCMIsEnabled(pVM))
-        return HWACMMR3EnablePatching(pVM, pPatchMem, cbPatchMem);
+    if (HMIsEnabled(pVM))
+        return HMR3EnablePatching(pVM, pPatchMem, cbPatchMem);
 
     return VERR_NOT_SUPPORTED;
@@ -1419,6 +1419,6 @@
 VMMR3DECL(int) VMMR3DeregisterPatchMemory(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem)
 {
-    if (HWACCMIsEnabled(pVM))
-        return HWACMMR3DisablePatching(pVM, pPatchMem, cbPatchMem);
+    if (HMIsEnabled(pVM))
+        return HMR3DisablePatching(pVM, pPatchMem, cbPatchMem);
 
     return VINF_SUCCESS;
@@ -2339,5 +2339,5 @@
         PRINT_GROUP(VMCPU_FF_,NORMAL_PRIORITY,_MASK);
         PRINT_GROUP(VMCPU_FF_,RESUME_GUEST,_MASK);
-        PRINT_GROUP(VMCPU_FF_,HWACCM_TO_R3,_MASK);
+        PRINT_GROUP(VMCPU_FF_,HM_TO_R3,_MASK);
         PRINT_GROUP(VMCPU_FF_,ALL_REM,_MASK);
         if (c)
Index: trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp	(revision 43387)
@@ -34,5 +34,5 @@
 #include <VBox/param.h>
 #include <VBox/version.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <iprt/assert.h>
 #include <iprt/time.h>
@@ -301,5 +301,5 @@
             RTGCUINTPTR     uCR2       = 0xdeadface;
             int rc2 = TRPMQueryTrapAll(pVCpu, &u8TrapNo, &enmType, &uErrorCode, &uCR2);
-            if (!HWACCMIsEnabled(pVM))
+            if (!HMIsEnabled(pVM))
             {
                 if (RT_SUCCESS(rc2))
@@ -320,5 +320,5 @@
              * Dump the relevant hypervisor registers and stack.
              */
-            if (HWACCMIsEnabled(pVM))
+            if (HMIsEnabled(pVM))
             {
                 if (   rcErr == VERR_VMM_RING0_ASSERTION /* fInRing3Call has already been cleared here. */
@@ -592,5 +592,5 @@
                                 pVCpu->vmm.s.pbEMTStackRC, pVCpu->vmm.s.pbEMTStackBottomRC,
                                 VMM_STACK_SIZE, pVCpu->vmm.s.pbEMTStackR3);
-            } /* !HWACCMIsEnabled */
+            } /* !HMIsEnabled */
             break;
         }
Index: trunk/src/VBox/VMM/VMMR3/VMMTests.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/VMMTests.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMR3/VMMTests.cpp	(revision 43387)
@@ -34,5 +34,5 @@
 #include <VBox/err.h>
 #include <VBox/param.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 
 #include <iprt/assert.h>
@@ -477,5 +477,5 @@
     PVMCPU   pVCpu = &pVM->aCpus[0];
 
-    if (!HWACCMR3IsAllowed(pVM))
+    if (!HMR3IsAllowed(pVM))
     {
         RTPrintf("VMM: Hardware accelerated test not available!\n");
@@ -542,5 +542,5 @@
             CPUMSetHyperState(pVCpu, pVM->vmm.s.pfnCallTrampolineRC, pVCpu->vmm.s.pbEMTStackBottomRC, 0, 0);
             CPUMPushHyper(pVCpu, 0);
-            CPUMPushHyper(pVCpu, VMMGC_DO_TESTCASE_HWACCM_NOP);
+            CPUMPushHyper(pVCpu, VMMGC_DO_TESTCASE_HM_NOP);
             CPUMPushHyper(pVCpu, pVM->pVMRC);
             CPUMPushHyper(pVCpu, 3 * sizeof(RTRCPTR));    /* stack frame size */
Index: trunk/src/VBox/VMM/VMMRC/HMRCA.asm
===================================================================
--- trunk/src/VBox/VMM/VMMRC/HMRCA.asm	(revision 43387)
+++ trunk/src/VBox/VMM/VMMRC/HMRCA.asm	(revision 43387)
@@ -0,0 +1,586 @@
+; $Id$
+;; @file
+; VMXM - GC vmx helpers
+;
+
+;
+; 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;
+; 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.
+;
+
+;*******************************************************************************
+;* Header Files                                                                *
+;*******************************************************************************
+%undef RT_ARCH_X86
+%define RT_ARCH_AMD64
+%include "VBox/asmdefs.mac"
+%include "VBox/err.mac"
+%include "VBox/vmm/hm_vmx.mac"
+%include "VBox/vmm/cpum.mac"
+%include "iprt/x86.mac"
+%include "HMInternal.mac"
+
+%ifdef RT_OS_OS2 ;; @todo fix OMF support in yasm and kick nasm out completely.
+ %macro vmwrite 2,
+    int3
+ %endmacro
+ %define vmlaunch int3
+ %define vmresume int3
+ %define vmsave int3
+ %define vmload int3
+ %define vmrun int3
+ %define clgi int3
+ %define stgi int3
+ %macro invlpga 2,
+    int3
+ %endmacro
+%endif
+
+;; @def MYPUSHSEGS
+; Macro saving all segment registers on the stack.
+; @param 1  full width register name
+
+;; @def MYPOPSEGS
+; Macro restoring all segment registers on the stack
+; @param 1  full width register name
+
+  ; Load the corresponding guest MSR (trashes rdx & rcx)
+  %macro LOADGUESTMSR 2
+    mov     rcx, %1
+    mov     edx, dword [rsi + %2 + 4]
+    mov     eax, dword [rsi + %2]
+    wrmsr
+  %endmacro
+
+  ; Save a guest MSR (trashes rdx & rcx)
+  ; Only really useful for gs kernel base as that one can be changed behind our back (swapgs)
+  %macro SAVEGUESTMSR 2
+    mov     rcx, %1
+    rdmsr
+    mov     dword [rsi + %2], eax
+    mov     dword [rsi + %2 + 4], edx
+  %endmacro
+
+ %macro MYPUSHSEGS 1
+    mov     %1, es
+    push    %1
+    mov     %1, ds
+    push    %1
+ %endmacro
+
+ %macro MYPOPSEGS 1
+    pop     %1
+    mov     ds, %1
+    pop     %1
+    mov     es, %1
+ %endmacro
+
+BEGINCODE
+BITS 64
+
+
+;/**
+; * Prepares for and executes VMLAUNCH/VMRESUME (64 bits guest mode)
+; *
+; * @returns VBox status code
+; * @param   HCPhysCpuPage  VMXON physical address  [rsp+8]
+; * @param   HCPhysVMCS     VMCS physical address   [rsp+16]
+; * @param   pCache         VMCS cache              [rsp+24]
+; * @param   pCtx           Guest context (rsi)
+; */
+BEGINPROC VMXGCStartVM64
+    push    rbp
+    mov     rbp, rsp
+
+    ; Make sure VT-x instructions are allowed
+    mov     rax, cr4
+    or      rax, X86_CR4_VMXE
+    mov     cr4, rax
+
+    ;/* Enter VMX Root Mode */
+    vmxon   [rbp + 8 + 8]
+    jnc     .vmxon_success
+    mov     rax, VERR_VMX_INVALID_VMXON_PTR
+    jmp     .vmstart64_vmxon_failed
+
+.vmxon_success:
+    jnz     .vmxon_success2
+    mov     rax, VERR_VMX_GENERIC
+    jmp     .vmstart64_vmxon_failed
+
+.vmxon_success2:
+    ; Activate the VMCS pointer
+    vmptrld [rbp + 16 + 8]
+    jnc     .vmptrld_success
+    mov     rax, VERR_VMX_INVALID_VMCS_PTR
+    jmp     .vmstart64_vmxoff_end
+
+.vmptrld_success:
+    jnz     .vmptrld_success2
+    mov     rax, VERR_VMX_GENERIC
+    jmp     .vmstart64_vmxoff_end
+
+.vmptrld_success2:
+
+    ; Save the VMCS pointer on the stack
+    push    qword [rbp + 16 + 8];
+
+    ;/* Save segment registers */
+    MYPUSHSEGS rax
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    ; Flush the VMCS write cache first (before any other vmreads/vmwrites!)
+    mov     rbx, [rbp + 24 + 8]                             ; pCache
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     qword [rbx + VMCSCACHE.uPos], 2
+%endif
+
+%ifdef DEBUG
+    mov     rax, [rbp + 8 + 8]                              ; HCPhysCpuPage
+    mov     [rbx + VMCSCACHE.TestIn.HCPhysCpuPage], rax
+    mov     rax, [rbp + 16 + 8]                             ; HCPhysVMCS
+    mov     [rbx + VMCSCACHE.TestIn.HCPhysVMCS], rax
+    mov     [rbx + VMCSCACHE.TestIn.pCache], rbx
+    mov     [rbx + VMCSCACHE.TestIn.pCtx], rsi
+%endif
+
+    mov     ecx, [rbx + VMCSCACHE.Write.cValidEntries]
+    cmp     ecx, 0
+    je      .no_cached_writes
+    mov     rdx, rcx
+    mov     rcx, 0
+    jmp     .cached_write
+
+ALIGN(16)
+.cached_write:
+    mov     eax, [rbx + VMCSCACHE.Write.aField + rcx*4]
+    vmwrite rax, qword [rbx + VMCSCACHE.Write.aFieldVal + rcx*8]
+    inc     rcx
+    cmp     rcx, rdx
+    jl     .cached_write
+
+    mov     dword [rbx + VMCSCACHE.Write.cValidEntries], 0
+.no_cached_writes:
+
+ %ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     qword [rbx + VMCSCACHE.uPos], 3
+ %endif
+    ; Save the pCache pointer
+    push    xBX
+%endif
+
+    ; Save the host state that's relevant in the temporary 64 bits mode
+    mov     rdx, cr0
+    mov     eax, VMX_VMCS_HOST_CR0
+    vmwrite rax, rdx
+
+    mov     rdx, cr3
+    mov     eax, VMX_VMCS_HOST_CR3
+    vmwrite rax, rdx
+
+    mov     rdx, cr4
+    mov     eax, VMX_VMCS_HOST_CR4
+    vmwrite rax, rdx
+
+    mov     rdx, cs
+    mov     eax, VMX_VMCS_HOST_FIELD_CS
+    vmwrite rax, rdx
+
+    mov     rdx, ss
+    mov     eax, VMX_VMCS_HOST_FIELD_SS
+    vmwrite rax, rdx
+
+    sub     rsp, 8*2
+    sgdt    [rsp]
+    mov     eax, VMX_VMCS_HOST_GDTR_BASE
+    vmwrite rax, [rsp+2]
+    add     rsp, 8*2
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     qword [rbx + VMCSCACHE.uPos], 4
+%endif
+
+    ; hopefully we can ignore TR (we restore it anyway on the way back to 32 bits mode)
+
+    ;/* First we have to save some final CPU context registers. */
+    lea     rdx, [.vmlaunch64_done wrt rip]
+    mov     rax, VMX_VMCS_HOST_RIP  ;/* return address (too difficult to continue after VMLAUNCH?) */
+    vmwrite rax, rdx
+    ;/* Note: assumes success... */
+
+    ;/* Manual save and restore:
+    ; * - General purpose registers except RIP, RSP
+    ; *
+    ; * Trashed:
+    ; * - CR2 (we don't care)
+    ; * - LDTR (reset to 0)
+    ; * - DRx (presumably not changed at all)
+    ; * - DR7 (reset to 0x400)
+    ; * - EFLAGS (reset to RT_BIT(1); not relevant)
+    ; *
+    ; */
+
+    ; Load the guest LSTAR, CSTAR, SFMASK & KERNEL_GSBASE MSRs
+    ;; @todo use the automatic load feature for MSRs
+    LOADGUESTMSR MSR_K8_LSTAR,          CPUMCTX.msrLSTAR
+    LOADGUESTMSR MSR_K6_STAR,           CPUMCTX.msrSTAR
+    LOADGUESTMSR MSR_K8_SF_MASK,        CPUMCTX.msrSFMASK
+    LOADGUESTMSR MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     qword [rbx + VMCSCACHE.uPos], 5
+%endif
+
+    ; Save the pCtx pointer
+    push    rsi
+
+    ; Restore CR2
+    mov     rbx, qword [rsi + CPUMCTX.cr2]
+    mov     cr2, rbx
+
+    mov     eax, VMX_VMCS_HOST_RSP
+    vmwrite rax, rsp
+    ;/* Note: assumes success... */
+    ;/* Don't mess with ESP anymore!! */
+
+    ;/* Restore Guest's general purpose registers. */
+    mov     rax, qword [rsi + CPUMCTX.eax]
+    mov     rbx, qword [rsi + CPUMCTX.ebx]
+    mov     rcx, qword [rsi + CPUMCTX.ecx]
+    mov     rdx, qword [rsi + CPUMCTX.edx]
+    mov     rbp, qword [rsi + CPUMCTX.ebp]
+    mov     r8,  qword [rsi + CPUMCTX.r8]
+    mov     r9,  qword [rsi + CPUMCTX.r9]
+    mov     r10, qword [rsi + CPUMCTX.r10]
+    mov     r11, qword [rsi + CPUMCTX.r11]
+    mov     r12, qword [rsi + CPUMCTX.r12]
+    mov     r13, qword [rsi + CPUMCTX.r13]
+    mov     r14, qword [rsi + CPUMCTX.r14]
+    mov     r15, qword [rsi + CPUMCTX.r15]
+
+    ;/* Restore rdi & rsi. */
+    mov     rdi, qword [rsi + CPUMCTX.edi]
+    mov     rsi, qword [rsi + CPUMCTX.esi]
+
+    vmlaunch
+    jmp     .vmlaunch64_done;      ;/* here if vmlaunch detected a failure. */
+
+ALIGNCODE(16)
+.vmlaunch64_done:
+    jc      near .vmstart64_invalid_vmxon_ptr
+    jz      near .vmstart64_start_failed
+
+    push    rdi
+    mov     rdi, [rsp + 8]         ; pCtx
+
+    mov     qword [rdi + CPUMCTX.eax], rax
+    mov     qword [rdi + CPUMCTX.ebx], rbx
+    mov     qword [rdi + CPUMCTX.ecx], rcx
+    mov     qword [rdi + CPUMCTX.edx], rdx
+    mov     qword [rdi + CPUMCTX.esi], rsi
+    mov     qword [rdi + CPUMCTX.ebp], rbp
+    mov     qword [rdi + CPUMCTX.r8],  r8
+    mov     qword [rdi + CPUMCTX.r9],  r9
+    mov     qword [rdi + CPUMCTX.r10], r10
+    mov     qword [rdi + CPUMCTX.r11], r11
+    mov     qword [rdi + CPUMCTX.r12], r12
+    mov     qword [rdi + CPUMCTX.r13], r13
+    mov     qword [rdi + CPUMCTX.r14], r14
+    mov     qword [rdi + CPUMCTX.r15], r15
+
+    pop     rax                                 ; the guest edi we pushed above
+    mov     qword [rdi + CPUMCTX.edi], rax
+
+    pop     rsi         ; pCtx (needed in rsi by the macros below)
+
+    ;; @todo use the automatic load feature for MSRs
+    SAVEGUESTMSR MSR_K8_LSTAR,          CPUMCTX.msrLSTAR
+    SAVEGUESTMSR MSR_K6_STAR,           CPUMCTX.msrSTAR
+    SAVEGUESTMSR MSR_K8_SF_MASK,        CPUMCTX.msrSFMASK
+    SAVEGUESTMSR MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    pop     rdi         ; saved pCache
+
+ %ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 7
+ %endif
+ %ifdef DEBUG
+    mov     [rdi + VMCSCACHE.TestOut.pCache], rdi
+    mov     [rdi + VMCSCACHE.TestOut.pCtx], rsi
+    mov     rax, cr8
+    mov     [rdi + VMCSCACHE.TestOut.cr8], rax
+ %endif
+
+    mov     ecx, [rdi + VMCSCACHE.Read.cValidEntries]
+    cmp     ecx, 0  ; can't happen
+    je      .no_cached_reads
+    jmp     .cached_read
+
+ALIGN(16)
+.cached_read:
+    dec     rcx
+    mov     eax, [rdi + VMCSCACHE.Read.aField + rcx*4]
+    vmread  qword [rdi + VMCSCACHE.Read.aFieldVal + rcx*8], rax
+    cmp     rcx, 0
+    jnz     .cached_read
+.no_cached_reads:
+
+    ; Save CR2 for EPT
+    mov     rax, cr2
+    mov     [rdi + VMCSCACHE.cr2], rax
+ %ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 8
+ %endif
+%endif
+
+    ; Restore segment registers
+    MYPOPSEGS rax
+
+    mov     eax, VINF_SUCCESS
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 9
+%endif
+.vmstart64_end:
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+ %ifdef DEBUG
+    mov     rdx, [rsp]                             ; HCPhysVMCS
+    mov     [rdi + VMCSCACHE.TestOut.HCPhysVMCS], rdx
+ %endif
+%endif
+
+    ; Write back the data and disable the VMCS
+    vmclear qword [rsp]  ;Pushed pVMCS
+    add     rsp, 8
+
+.vmstart64_vmxoff_end:
+    ; Disable VMX root mode
+    vmxoff
+.vmstart64_vmxon_failed:
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+ %ifdef DEBUG
+    cmp     eax, VINF_SUCCESS
+    jne     .skip_flags_save
+
+    pushf
+    pop     rdx
+    mov     [rdi + VMCSCACHE.TestOut.eflags], rdx
+  %ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 12
+  %endif
+.skip_flags_save:
+ %endif
+%endif
+    pop     rbp
+    ret
+
+
+.vmstart64_invalid_vmxon_ptr:
+    pop     rsi         ; pCtx (needed in rsi by the macros below)
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    pop     rdi         ; pCache
+ %ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 10
+ %endif
+
+ %ifdef DEBUG
+    mov     [rdi + VMCSCACHE.TestOut.pCache], rdi
+    mov     [rdi + VMCSCACHE.TestOut.pCtx], rsi
+ %endif
+%endif
+
+    ; Restore segment registers
+    MYPOPSEGS rax
+
+    ; Restore all general purpose host registers.
+    mov     eax, VERR_VMX_INVALID_VMXON_PTR
+    jmp     .vmstart64_end
+
+.vmstart64_start_failed:
+    pop     rsi         ; pCtx (needed in rsi by the macros below)
+
+%ifdef VMX_USE_CACHED_VMCS_ACCESSES
+    pop     rdi         ; pCache
+
+ %ifdef DEBUG
+    mov     [rdi + VMCSCACHE.TestOut.pCache], rdi
+    mov     [rdi + VMCSCACHE.TestOut.pCtx], rsi
+ %endif
+ %ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 11
+ %endif
+%endif
+
+    ; Restore segment registers
+    MYPOPSEGS rax
+
+    ; Restore all general purpose host registers.
+    mov     eax, VERR_VMX_UNABLE_TO_START_VM
+    jmp     .vmstart64_end
+ENDPROC VMXGCStartVM64
+
+
+;/**
+; * Prepares for and executes VMRUN (64 bits guests)
+; *
+; * @returns VBox status code
+; * @param   HCPhysVMCB     Physical address of host VMCB       (rsp+8)
+; * @param   HCPhysVMCB     Physical address of guest VMCB      (rsp+16)
+; * @param   pCtx           Guest context                       (rsi)
+; */
+BEGINPROC SVMGCVMRun64
+    push    rbp
+    mov     rbp, rsp
+    pushf
+
+    ;/* Manual save and restore:
+    ; * - General purpose registers except RIP, RSP, RAX
+    ; *
+    ; * Trashed:
+    ; * - CR2 (we don't care)
+    ; * - LDTR (reset to 0)
+    ; * - DRx (presumably not changed at all)
+    ; * - DR7 (reset to 0x400)
+    ; */
+
+    ;/* Save the Guest CPU context pointer. */
+    push    rsi                     ; push for saving the state at the end
+
+    ; save host fs, gs, sysenter msr etc
+    mov     rax, [rbp + 8 + 8]              ; pVMCBHostPhys (64 bits physical address)
+    push    rax                             ; save for the vmload after vmrun
+    vmsave
+
+    ; setup eax for VMLOAD
+    mov     rax, [rbp + 8 + 8 + RTHCPHYS_CB]   ; pVMCBPhys (64 bits physical address)
+
+    ;/* Restore Guest's general purpose registers. */
+    ;/* RAX is loaded from the VMCB by VMRUN */
+    mov     rbx, qword [rsi + CPUMCTX.ebx]
+    mov     rcx, qword [rsi + CPUMCTX.ecx]
+    mov     rdx, qword [rsi + CPUMCTX.edx]
+    mov     rdi, qword [rsi + CPUMCTX.edi]
+    mov     rbp, qword [rsi + CPUMCTX.ebp]
+    mov     r8,  qword [rsi + CPUMCTX.r8]
+    mov     r9,  qword [rsi + CPUMCTX.r9]
+    mov     r10, qword [rsi + CPUMCTX.r10]
+    mov     r11, qword [rsi + CPUMCTX.r11]
+    mov     r12, qword [rsi + CPUMCTX.r12]
+    mov     r13, qword [rsi + CPUMCTX.r13]
+    mov     r14, qword [rsi + CPUMCTX.r14]
+    mov     r15, qword [rsi + CPUMCTX.r15]
+    mov     rsi, qword [rsi + CPUMCTX.esi]
+
+    ; Clear the global interrupt flag & execute sti to make sure external interrupts cause a world switch
+    clgi
+    sti
+
+    ; load guest fs, gs, sysenter msr etc
+    vmload
+    ; run the VM
+    vmrun
+
+    ;/* RAX is in the VMCB already; we can use it here. */
+
+    ; save guest fs, gs, sysenter msr etc
+    vmsave
+
+    ; load host fs, gs, sysenter msr etc
+    pop     rax                     ; pushed above
+    vmload
+
+    ; Set the global interrupt flag again, but execute cli to make sure IF=0.
+    cli
+    stgi
+
+    pop     rax                     ; pCtx
+
+    mov     qword [rax + CPUMCTX.ebx], rbx
+    mov     qword [rax + CPUMCTX.ecx], rcx
+    mov     qword [rax + CPUMCTX.edx], rdx
+    mov     qword [rax + CPUMCTX.esi], rsi
+    mov     qword [rax + CPUMCTX.edi], rdi
+    mov     qword [rax + CPUMCTX.ebp], rbp
+    mov     qword [rax + CPUMCTX.r8],  r8
+    mov     qword [rax + CPUMCTX.r9],  r9
+    mov     qword [rax + CPUMCTX.r10], r10
+    mov     qword [rax + CPUMCTX.r11], r11
+    mov     qword [rax + CPUMCTX.r12], r12
+    mov     qword [rax + CPUMCTX.r13], r13
+    mov     qword [rax + CPUMCTX.r14], r14
+    mov     qword [rax + CPUMCTX.r15], r15
+
+    mov     eax, VINF_SUCCESS
+
+    popf
+    pop     rbp
+    ret
+ENDPROC SVMGCVMRun64
+
+;/**
+; * Saves the guest FPU context
+; *
+; * @returns VBox status code
+; * @param   pCtx       Guest context [rsi]
+; */
+BEGINPROC HMSaveGuestFPU64
+    mov     rax, cr0
+    mov     rcx, rax                    ; save old CR0
+    and     rax, ~(X86_CR0_TS | X86_CR0_EM)
+    mov     cr0, rax
+
+    fxsave  [rsi + CPUMCTX.fpu]
+
+    mov     cr0, rcx                    ; and restore old CR0 again
+
+    mov     eax, VINF_SUCCESS
+    ret
+ENDPROC HMSaveGuestFPU64
+
+;/**
+; * Saves the guest debug context (DR0-3, DR6)
+; *
+; * @returns VBox status code
+; * @param   pCtx       Guest context [rsi]
+; */
+BEGINPROC HMSaveGuestDebug64
+    mov rax, dr0
+    mov qword [rsi + CPUMCTX.dr + 0*8], rax
+    mov rax, dr1
+    mov qword [rsi + CPUMCTX.dr + 1*8], rax
+    mov rax, dr2
+    mov qword [rsi + CPUMCTX.dr + 2*8], rax
+    mov rax, dr3
+    mov qword [rsi + CPUMCTX.dr + 3*8], rax
+    mov rax, dr6
+    mov qword [rsi + CPUMCTX.dr + 6*8], rax
+    mov eax, VINF_SUCCESS
+    ret
+ENDPROC HMSaveGuestDebug64
+
+;/**
+; * Dummy callback handler
+; *
+; * @returns VBox status code
+; * @param   param1     Parameter 1 [rsp+8]
+; * @param   param2     Parameter 2 [rsp+12]
+; * @param   param3     Parameter 3 [rsp+16]
+; * @param   param4     Parameter 4 [rsp+20]
+; * @param   param5     Parameter 5 [rsp+24]
+; * @param   pCtx       Guest context [rsi]
+; */
+BEGINPROC HMTestSwitcher64
+    mov eax, [rsp+8]
+    ret
+ENDPROC HMTestSwitcher64
Index: trunk/src/VBox/VMM/VMMRC/HWACCMRCA.asm
===================================================================
--- trunk/src/VBox/VMM/VMMRC/HWACCMRCA.asm	(revision 43379)
+++ 	(revision )
@@ -1,586 +1,0 @@
-; $Id$
-;; @file
-; VMXM - GC vmx helpers
-;
-
-;
-; 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;
-; 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.
-;
-
-;*******************************************************************************
-;* Header Files                                                                *
-;*******************************************************************************
-%undef RT_ARCH_X86
-%define RT_ARCH_AMD64
-%include "VBox/asmdefs.mac"
-%include "VBox/err.mac"
-%include "VBox/vmm/hwacc_vmx.mac"
-%include "VBox/vmm/cpum.mac"
-%include "iprt/x86.mac"
-%include "HWACCMInternal.mac"
-
-%ifdef RT_OS_OS2 ;; @todo fix OMF support in yasm and kick nasm out completely.
- %macro vmwrite 2,
-    int3
- %endmacro
- %define vmlaunch int3
- %define vmresume int3
- %define vmsave int3
- %define vmload int3
- %define vmrun int3
- %define clgi int3
- %define stgi int3
- %macro invlpga 2,
-    int3
- %endmacro
-%endif
-
-;; @def MYPUSHSEGS
-; Macro saving all segment registers on the stack.
-; @param 1  full width register name
-
-;; @def MYPOPSEGS
-; Macro restoring all segment registers on the stack
-; @param 1  full width register name
-
-  ; Load the corresponding guest MSR (trashes rdx & rcx)
-  %macro LOADGUESTMSR 2
-    mov     rcx, %1
-    mov     edx, dword [rsi + %2 + 4]
-    mov     eax, dword [rsi + %2]
-    wrmsr
-  %endmacro
-
-  ; Save a guest MSR (trashes rdx & rcx)
-  ; Only really useful for gs kernel base as that one can be changed behind our back (swapgs)
-  %macro SAVEGUESTMSR 2
-    mov     rcx, %1
-    rdmsr
-    mov     dword [rsi + %2], eax
-    mov     dword [rsi + %2 + 4], edx
-  %endmacro
-
- %macro MYPUSHSEGS 1
-    mov     %1, es
-    push    %1
-    mov     %1, ds
-    push    %1
- %endmacro
-
- %macro MYPOPSEGS 1
-    pop     %1
-    mov     ds, %1
-    pop     %1
-    mov     es, %1
- %endmacro
-
-BEGINCODE
-BITS 64
-
-
-;/**
-; * Prepares for and executes VMLAUNCH/VMRESUME (64 bits guest mode)
-; *
-; * @returns VBox status code
-; * @param   HCPhysCpuPage  VMXON physical address  [rsp+8]
-; * @param   HCPhysVMCS     VMCS physical address   [rsp+16]
-; * @param   pCache         VMCS cache              [rsp+24]
-; * @param   pCtx           Guest context (rsi)
-; */
-BEGINPROC VMXGCStartVM64
-    push    rbp
-    mov     rbp, rsp
-
-    ; Make sure VT-x instructions are allowed
-    mov     rax, cr4
-    or      rax, X86_CR4_VMXE
-    mov     cr4, rax
-
-    ;/* Enter VMX Root Mode */
-    vmxon   [rbp + 8 + 8]
-    jnc     .vmxon_success
-    mov     rax, VERR_VMX_INVALID_VMXON_PTR
-    jmp     .vmstart64_vmxon_failed
-
-.vmxon_success:
-    jnz     .vmxon_success2
-    mov     rax, VERR_VMX_GENERIC
-    jmp     .vmstart64_vmxon_failed
-
-.vmxon_success2:
-    ; Activate the VMCS pointer
-    vmptrld [rbp + 16 + 8]
-    jnc     .vmptrld_success
-    mov     rax, VERR_VMX_INVALID_VMCS_PTR
-    jmp     .vmstart64_vmxoff_end
-
-.vmptrld_success:
-    jnz     .vmptrld_success2
-    mov     rax, VERR_VMX_GENERIC
-    jmp     .vmstart64_vmxoff_end
-
-.vmptrld_success2:
-
-    ; Save the VMCS pointer on the stack
-    push    qword [rbp + 16 + 8];
-
-    ;/* Save segment registers */
-    MYPUSHSEGS rax
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    ; Flush the VMCS write cache first (before any other vmreads/vmwrites!)
-    mov     rbx, [rbp + 24 + 8]                             ; pCache
-
-%ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    mov     qword [rbx + VMCSCACHE.uPos], 2
-%endif
-
-%ifdef DEBUG
-    mov     rax, [rbp + 8 + 8]                              ; HCPhysCpuPage
-    mov     [rbx + VMCSCACHE.TestIn.HCPhysCpuPage], rax
-    mov     rax, [rbp + 16 + 8]                             ; HCPhysVMCS
-    mov     [rbx + VMCSCACHE.TestIn.HCPhysVMCS], rax
-    mov     [rbx + VMCSCACHE.TestIn.pCache], rbx
-    mov     [rbx + VMCSCACHE.TestIn.pCtx], rsi
-%endif
-
-    mov     ecx, [rbx + VMCSCACHE.Write.cValidEntries]
-    cmp     ecx, 0
-    je      .no_cached_writes
-    mov     rdx, rcx
-    mov     rcx, 0
-    jmp     .cached_write
-
-ALIGN(16)
-.cached_write:
-    mov     eax, [rbx + VMCSCACHE.Write.aField + rcx*4]
-    vmwrite rax, qword [rbx + VMCSCACHE.Write.aFieldVal + rcx*8]
-    inc     rcx
-    cmp     rcx, rdx
-    jl     .cached_write
-
-    mov     dword [rbx + VMCSCACHE.Write.cValidEntries], 0
-.no_cached_writes:
-
- %ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    mov     qword [rbx + VMCSCACHE.uPos], 3
- %endif
-    ; Save the pCache pointer
-    push    xBX
-%endif
-
-    ; Save the host state that's relevant in the temporary 64 bits mode
-    mov     rdx, cr0
-    mov     eax, VMX_VMCS_HOST_CR0
-    vmwrite rax, rdx
-
-    mov     rdx, cr3
-    mov     eax, VMX_VMCS_HOST_CR3
-    vmwrite rax, rdx
-
-    mov     rdx, cr4
-    mov     eax, VMX_VMCS_HOST_CR4
-    vmwrite rax, rdx
-
-    mov     rdx, cs
-    mov     eax, VMX_VMCS_HOST_FIELD_CS
-    vmwrite rax, rdx
-
-    mov     rdx, ss
-    mov     eax, VMX_VMCS_HOST_FIELD_SS
-    vmwrite rax, rdx
-
-    sub     rsp, 8*2
-    sgdt    [rsp]
-    mov     eax, VMX_VMCS_HOST_GDTR_BASE
-    vmwrite rax, [rsp+2]
-    add     rsp, 8*2
-
-%ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    mov     qword [rbx + VMCSCACHE.uPos], 4
-%endif
-
-    ; hopefully we can ignore TR (we restore it anyway on the way back to 32 bits mode)
-
-    ;/* First we have to save some final CPU context registers. */
-    lea     rdx, [.vmlaunch64_done wrt rip]
-    mov     rax, VMX_VMCS_HOST_RIP  ;/* return address (too difficult to continue after VMLAUNCH?) */
-    vmwrite rax, rdx
-    ;/* Note: assumes success... */
-
-    ;/* Manual save and restore:
-    ; * - General purpose registers except RIP, RSP
-    ; *
-    ; * Trashed:
-    ; * - CR2 (we don't care)
-    ; * - LDTR (reset to 0)
-    ; * - DRx (presumably not changed at all)
-    ; * - DR7 (reset to 0x400)
-    ; * - EFLAGS (reset to RT_BIT(1); not relevant)
-    ; *
-    ; */
-
-    ; Load the guest LSTAR, CSTAR, SFMASK & KERNEL_GSBASE MSRs
-    ;; @todo use the automatic load feature for MSRs
-    LOADGUESTMSR MSR_K8_LSTAR,          CPUMCTX.msrLSTAR
-    LOADGUESTMSR MSR_K6_STAR,           CPUMCTX.msrSTAR
-    LOADGUESTMSR MSR_K8_SF_MASK,        CPUMCTX.msrSFMASK
-    LOADGUESTMSR MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
-
-%ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    mov     qword [rbx + VMCSCACHE.uPos], 5
-%endif
-
-    ; Save the pCtx pointer
-    push    rsi
-
-    ; Restore CR2
-    mov     rbx, qword [rsi + CPUMCTX.cr2]
-    mov     cr2, rbx
-
-    mov     eax, VMX_VMCS_HOST_RSP
-    vmwrite rax, rsp
-    ;/* Note: assumes success... */
-    ;/* Don't mess with ESP anymore!! */
-
-    ;/* Restore Guest's general purpose registers. */
-    mov     rax, qword [rsi + CPUMCTX.eax]
-    mov     rbx, qword [rsi + CPUMCTX.ebx]
-    mov     rcx, qword [rsi + CPUMCTX.ecx]
-    mov     rdx, qword [rsi + CPUMCTX.edx]
-    mov     rbp, qword [rsi + CPUMCTX.ebp]
-    mov     r8,  qword [rsi + CPUMCTX.r8]
-    mov     r9,  qword [rsi + CPUMCTX.r9]
-    mov     r10, qword [rsi + CPUMCTX.r10]
-    mov     r11, qword [rsi + CPUMCTX.r11]
-    mov     r12, qword [rsi + CPUMCTX.r12]
-    mov     r13, qword [rsi + CPUMCTX.r13]
-    mov     r14, qword [rsi + CPUMCTX.r14]
-    mov     r15, qword [rsi + CPUMCTX.r15]
-
-    ;/* Restore rdi & rsi. */
-    mov     rdi, qword [rsi + CPUMCTX.edi]
-    mov     rsi, qword [rsi + CPUMCTX.esi]
-
-    vmlaunch
-    jmp     .vmlaunch64_done;      ;/* here if vmlaunch detected a failure. */
-
-ALIGNCODE(16)
-.vmlaunch64_done:
-    jc      near .vmstart64_invalid_vmxon_ptr
-    jz      near .vmstart64_start_failed
-
-    push    rdi
-    mov     rdi, [rsp + 8]         ; pCtx
-
-    mov     qword [rdi + CPUMCTX.eax], rax
-    mov     qword [rdi + CPUMCTX.ebx], rbx
-    mov     qword [rdi + CPUMCTX.ecx], rcx
-    mov     qword [rdi + CPUMCTX.edx], rdx
-    mov     qword [rdi + CPUMCTX.esi], rsi
-    mov     qword [rdi + CPUMCTX.ebp], rbp
-    mov     qword [rdi + CPUMCTX.r8],  r8
-    mov     qword [rdi + CPUMCTX.r9],  r9
-    mov     qword [rdi + CPUMCTX.r10], r10
-    mov     qword [rdi + CPUMCTX.r11], r11
-    mov     qword [rdi + CPUMCTX.r12], r12
-    mov     qword [rdi + CPUMCTX.r13], r13
-    mov     qword [rdi + CPUMCTX.r14], r14
-    mov     qword [rdi + CPUMCTX.r15], r15
-
-    pop     rax                                 ; the guest edi we pushed above
-    mov     qword [rdi + CPUMCTX.edi], rax
-
-    pop     rsi         ; pCtx (needed in rsi by the macros below)
-
-    ;; @todo use the automatic load feature for MSRs
-    SAVEGUESTMSR MSR_K8_LSTAR,          CPUMCTX.msrLSTAR
-    SAVEGUESTMSR MSR_K6_STAR,           CPUMCTX.msrSTAR
-    SAVEGUESTMSR MSR_K8_SF_MASK,        CPUMCTX.msrSFMASK
-    SAVEGUESTMSR MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    pop     rdi         ; saved pCache
-
- %ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    mov     dword [rdi + VMCSCACHE.uPos], 7
- %endif
- %ifdef DEBUG
-    mov     [rdi + VMCSCACHE.TestOut.pCache], rdi
-    mov     [rdi + VMCSCACHE.TestOut.pCtx], rsi
-    mov     rax, cr8
-    mov     [rdi + VMCSCACHE.TestOut.cr8], rax
- %endif
-
-    mov     ecx, [rdi + VMCSCACHE.Read.cValidEntries]
-    cmp     ecx, 0  ; can't happen
-    je      .no_cached_reads
-    jmp     .cached_read
-
-ALIGN(16)
-.cached_read:
-    dec     rcx
-    mov     eax, [rdi + VMCSCACHE.Read.aField + rcx*4]
-    vmread  qword [rdi + VMCSCACHE.Read.aFieldVal + rcx*8], rax
-    cmp     rcx, 0
-    jnz     .cached_read
-.no_cached_reads:
-
-    ; Save CR2 for EPT
-    mov     rax, cr2
-    mov     [rdi + VMCSCACHE.cr2], rax
- %ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    mov     dword [rdi + VMCSCACHE.uPos], 8
- %endif
-%endif
-
-    ; Restore segment registers
-    MYPOPSEGS rax
-
-    mov     eax, VINF_SUCCESS
-
-%ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    mov     dword [rdi + VMCSCACHE.uPos], 9
-%endif
-.vmstart64_end:
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
- %ifdef DEBUG
-    mov     rdx, [rsp]                             ; HCPhysVMCS
-    mov     [rdi + VMCSCACHE.TestOut.HCPhysVMCS], rdx
- %endif
-%endif
-
-    ; Write back the data and disable the VMCS
-    vmclear qword [rsp]  ;Pushed pVMCS
-    add     rsp, 8
-
-.vmstart64_vmxoff_end:
-    ; Disable VMX root mode
-    vmxoff
-.vmstart64_vmxon_failed:
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
- %ifdef DEBUG
-    cmp     eax, VINF_SUCCESS
-    jne     .skip_flags_save
-
-    pushf
-    pop     rdx
-    mov     [rdi + VMCSCACHE.TestOut.eflags], rdx
-  %ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    mov     dword [rdi + VMCSCACHE.uPos], 12
-  %endif
-.skip_flags_save:
- %endif
-%endif
-    pop     rbp
-    ret
-
-
-.vmstart64_invalid_vmxon_ptr:
-    pop     rsi         ; pCtx (needed in rsi by the macros below)
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    pop     rdi         ; pCache
- %ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    mov     dword [rdi + VMCSCACHE.uPos], 10
- %endif
-
- %ifdef DEBUG
-    mov     [rdi + VMCSCACHE.TestOut.pCache], rdi
-    mov     [rdi + VMCSCACHE.TestOut.pCtx], rsi
- %endif
-%endif
-
-    ; Restore segment registers
-    MYPOPSEGS rax
-
-    ; Restore all general purpose host registers.
-    mov     eax, VERR_VMX_INVALID_VMXON_PTR
-    jmp     .vmstart64_end
-
-.vmstart64_start_failed:
-    pop     rsi         ; pCtx (needed in rsi by the macros below)
-
-%ifdef VMX_USE_CACHED_VMCS_ACCESSES
-    pop     rdi         ; pCache
-
- %ifdef DEBUG
-    mov     [rdi + VMCSCACHE.TestOut.pCache], rdi
-    mov     [rdi + VMCSCACHE.TestOut.pCtx], rsi
- %endif
- %ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    mov     dword [rdi + VMCSCACHE.uPos], 11
- %endif
-%endif
-
-    ; Restore segment registers
-    MYPOPSEGS rax
-
-    ; Restore all general purpose host registers.
-    mov     eax, VERR_VMX_UNABLE_TO_START_VM
-    jmp     .vmstart64_end
-ENDPROC VMXGCStartVM64
-
-
-;/**
-; * Prepares for and executes VMRUN (64 bits guests)
-; *
-; * @returns VBox status code
-; * @param   HCPhysVMCB     Physical address of host VMCB       (rsp+8)
-; * @param   HCPhysVMCB     Physical address of guest VMCB      (rsp+16)
-; * @param   pCtx           Guest context                       (rsi)
-; */
-BEGINPROC SVMGCVMRun64
-    push    rbp
-    mov     rbp, rsp
-    pushf
-
-    ;/* Manual save and restore:
-    ; * - General purpose registers except RIP, RSP, RAX
-    ; *
-    ; * Trashed:
-    ; * - CR2 (we don't care)
-    ; * - LDTR (reset to 0)
-    ; * - DRx (presumably not changed at all)
-    ; * - DR7 (reset to 0x400)
-    ; */
-
-    ;/* Save the Guest CPU context pointer. */
-    push    rsi                     ; push for saving the state at the end
-
-    ; save host fs, gs, sysenter msr etc
-    mov     rax, [rbp + 8 + 8]              ; pVMCBHostPhys (64 bits physical address)
-    push    rax                             ; save for the vmload after vmrun
-    vmsave
-
-    ; setup eax for VMLOAD
-    mov     rax, [rbp + 8 + 8 + RTHCPHYS_CB]   ; pVMCBPhys (64 bits physical address)
-
-    ;/* Restore Guest's general purpose registers. */
-    ;/* RAX is loaded from the VMCB by VMRUN */
-    mov     rbx, qword [rsi + CPUMCTX.ebx]
-    mov     rcx, qword [rsi + CPUMCTX.ecx]
-    mov     rdx, qword [rsi + CPUMCTX.edx]
-    mov     rdi, qword [rsi + CPUMCTX.edi]
-    mov     rbp, qword [rsi + CPUMCTX.ebp]
-    mov     r8,  qword [rsi + CPUMCTX.r8]
-    mov     r9,  qword [rsi + CPUMCTX.r9]
-    mov     r10, qword [rsi + CPUMCTX.r10]
-    mov     r11, qword [rsi + CPUMCTX.r11]
-    mov     r12, qword [rsi + CPUMCTX.r12]
-    mov     r13, qword [rsi + CPUMCTX.r13]
-    mov     r14, qword [rsi + CPUMCTX.r14]
-    mov     r15, qword [rsi + CPUMCTX.r15]
-    mov     rsi, qword [rsi + CPUMCTX.esi]
-
-    ; Clear the global interrupt flag & execute sti to make sure external interrupts cause a world switch
-    clgi
-    sti
-
-    ; load guest fs, gs, sysenter msr etc
-    vmload
-    ; run the VM
-    vmrun
-
-    ;/* RAX is in the VMCB already; we can use it here. */
-
-    ; save guest fs, gs, sysenter msr etc
-    vmsave
-
-    ; load host fs, gs, sysenter msr etc
-    pop     rax                     ; pushed above
-    vmload
-
-    ; Set the global interrupt flag again, but execute cli to make sure IF=0.
-    cli
-    stgi
-
-    pop     rax                     ; pCtx
-
-    mov     qword [rax + CPUMCTX.ebx], rbx
-    mov     qword [rax + CPUMCTX.ecx], rcx
-    mov     qword [rax + CPUMCTX.edx], rdx
-    mov     qword [rax + CPUMCTX.esi], rsi
-    mov     qword [rax + CPUMCTX.edi], rdi
-    mov     qword [rax + CPUMCTX.ebp], rbp
-    mov     qword [rax + CPUMCTX.r8],  r8
-    mov     qword [rax + CPUMCTX.r9],  r9
-    mov     qword [rax + CPUMCTX.r10], r10
-    mov     qword [rax + CPUMCTX.r11], r11
-    mov     qword [rax + CPUMCTX.r12], r12
-    mov     qword [rax + CPUMCTX.r13], r13
-    mov     qword [rax + CPUMCTX.r14], r14
-    mov     qword [rax + CPUMCTX.r15], r15
-
-    mov     eax, VINF_SUCCESS
-
-    popf
-    pop     rbp
-    ret
-ENDPROC SVMGCVMRun64
-
-;/**
-; * Saves the guest FPU context
-; *
-; * @returns VBox status code
-; * @param   pCtx       Guest context [rsi]
-; */
-BEGINPROC HWACCMSaveGuestFPU64
-    mov     rax, cr0
-    mov     rcx, rax                    ; save old CR0
-    and     rax, ~(X86_CR0_TS | X86_CR0_EM)
-    mov     cr0, rax
-
-    fxsave  [rsi + CPUMCTX.fpu]
-
-    mov     cr0, rcx                    ; and restore old CR0 again
-
-    mov     eax, VINF_SUCCESS
-    ret
-ENDPROC HWACCMSaveGuestFPU64
-
-;/**
-; * Saves the guest debug context (DR0-3, DR6)
-; *
-; * @returns VBox status code
-; * @param   pCtx       Guest context [rsi]
-; */
-BEGINPROC HWACCMSaveGuestDebug64
-    mov rax, dr0
-    mov qword [rsi + CPUMCTX.dr + 0*8], rax
-    mov rax, dr1
-    mov qword [rsi + CPUMCTX.dr + 1*8], rax
-    mov rax, dr2
-    mov qword [rsi + CPUMCTX.dr + 2*8], rax
-    mov rax, dr3
-    mov qword [rsi + CPUMCTX.dr + 3*8], rax
-    mov rax, dr6
-    mov qword [rsi + CPUMCTX.dr + 6*8], rax
-    mov eax, VINF_SUCCESS
-    ret
-ENDPROC HWACCMSaveGuestDebug64
-
-;/**
-; * Dummy callback handler
-; *
-; * @returns VBox status code
-; * @param   param1     Parameter 1 [rsp+8]
-; * @param   param2     Parameter 2 [rsp+12]
-; * @param   param3     Parameter 3 [rsp+16]
-; * @param   param4     Parameter 4 [rsp+20]
-; * @param   param5     Parameter 5 [rsp+24]
-; * @param   pCtx       Guest context [rsi]
-; */
-BEGINPROC HWACCMTestSwitcher64
-    mov eax, [rsp+8]
-    ret
-ENDPROC HWACCMTestSwitcher64
Index: trunk/src/VBox/VMM/VMMRC/VMMRC.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMRC/VMMRC.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMRC/VMMRC.cpp	(revision 43387)
@@ -120,5 +120,5 @@
          * Testcase executes a privileged instruction to force a world switch. (in both SVM & VMX)
          */
-        case VMMGC_DO_TESTCASE_HWACCM_NOP:
+        case VMMGC_DO_TESTCASE_HM_NOP:
             ASMRdMsr_Low(MSR_IA32_SYSENTER_CS);
             return 0;
Index: trunk/src/VBox/VMM/VMMRZ/PGMRZDynMap.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMRZ/PGMRZDynMap.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/VMMRZ/PGMRZDynMap.cpp	(revision 43387)
@@ -1842,5 +1842,5 @@
  * Starts or migrates the autoset of a virtual CPU.
  *
- * This is used by HWACCMR0Enter.  When we've longjumped out of the HWACCM
+ * This is used by HMR0Enter.  When we've longjumped out of the HM
  * execution loop with the set open, we'll migrate it when re-entering.  While
  * under normal circumstances, we'll start it so VMXR0LoadGuestState can access
Index: trunk/src/VBox/VMM/include/EMHandleRCTmpl.h
===================================================================
--- trunk/src/VBox/VMM/include/EMHandleRCTmpl.h	(revision 43379)
+++ trunk/src/VBox/VMM/include/EMHandleRCTmpl.h	(revision 43387)
@@ -20,5 +20,5 @@
 
 /**
- * Process a subset of the raw-mode and hwaccm return codes.
+ * Process a subset of the raw-mode and hm return codes.
  *
  * Since we have to share this with raw-mode single stepping, this inline
@@ -35,5 +35,5 @@
 #ifdef EMHANDLERC_WITH_PATM
 int emR3RawHandleRC(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc)
-#elif defined(EMHANDLERC_WITH_HWACCM)
+#elif defined(EMHANDLERC_WITH_HM)
 int emR3HwaccmHandleRC(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc)
 #endif
@@ -219,14 +219,14 @@
             break;
 
-#ifdef EMHANDLERC_WITH_HWACCM
+#ifdef EMHANDLERC_WITH_HM
         /*
          * (MM)IO intensive code block detected; fall back to the recompiler for better performance
          */
         case VINF_EM_RAW_EMULATE_IO_BLOCK:
-            rc = HWACCMR3EmulateIoBlock(pVM, pCtx);
-            break;
-
-        case VINF_EM_HWACCM_PATCH_TPR_INSTR:
-            rc = HWACCMR3PatchTprInstr(pVM, pVCpu, pCtx);
+            rc = HMR3EmulateIoBlock(pVM, pCtx);
+            break;
+
+        case VINF_EM_HM_PATCH_TPR_INSTR:
+            rc = HMR3PatchTprInstr(pVM, pVCpu, pCtx);
             break;
 #endif
@@ -334,5 +334,5 @@
             break;
 
-#ifdef EMHANDLERC_WITH_HWACCM
+#ifdef EMHANDLERC_WITH_HM
         /*
          * Up a level, after HwAccM have done some release logging.
@@ -347,5 +347,5 @@
         case VERR_VMX_UNABLE_TO_START_VM:
         case VERR_VMX_UNABLE_TO_RESUME_VM:
-            HWACCMR3CheckError(pVM, rc);
+            HMR3CheckError(pVM, rc);
             break;
 
Index: trunk/src/VBox/VMM/include/HMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/HMInternal.h	(revision 43387)
+++ trunk/src/VBox/VMM/include/HMInternal.h	(revision 43387)
@@ -0,0 +1,906 @@
+/* $Id$ */
+/** @file
+ * HM - Internal header file.
+ */
+
+/*
+ * 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;
+ * 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.
+ */
+
+#ifndef ___HMInternal_h
+#define ___HMInternal_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <VBox/vmm/em.h>
+#include <VBox/vmm/stam.h>
+#include <VBox/dis.h>
+#include <VBox/vmm/hm.h>
+#include <VBox/vmm/hm_vmx.h>
+#include <VBox/vmm/pgm.h>
+#include <VBox/vmm/cpum.h>
+#include <iprt/memobj.h>
+#include <iprt/cpuset.h>
+#include <iprt/mp.h>
+#include <iprt/avl.h>
+
+#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) || defined (VBOX_WITH_64_BITS_GUESTS)
+/* Enable 64 bits guest support. */
+# define VBOX_ENABLE_64_BITS_GUESTS
+#endif
+
+#define VMX_USE_CACHED_VMCS_ACCESSES
+#define HM_VMX_EMULATE_REALMODE
+
+/* The MSR auto load/store does not work for KERNEL_GS_BASE MSR, thus we
+ * handle this MSR manually. See @bugref{6208}. This is clearly visible while
+ * booting Solaris 11 (11.1 b19) VMs with 2 Cpus.
+ *
+ * Note: don't forget to update the assembly files while modifying this!
+ */
+# define VBOX_WITH_AUTO_MSR_LOAD_RESTORE
+
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup grp_hm_int       Internal
+ * @ingroup grp_hm
+ * @internal
+ * @{
+ */
+
+
+/** Maximum number of exit reason statistics counters. */
+#define MAX_EXITREASON_STAT        0x100
+#define MASK_EXITREASON_STAT       0xff
+#define MASK_INJECT_IRQ_STAT       0xff
+
+/** @name Changed flags
+ * These flags are used to keep track of which important registers that
+ * have been changed since last they were reset.
+ * @{
+ */
+#define HM_CHANGED_GUEST_FPU                RT_BIT(0)
+#define HM_CHANGED_GUEST_CR0                RT_BIT(1)
+#define HM_CHANGED_GUEST_CR3                RT_BIT(2)
+#define HM_CHANGED_GUEST_CR4                RT_BIT(3)
+#define HM_CHANGED_GUEST_GDTR               RT_BIT(4)
+#define HM_CHANGED_GUEST_IDTR               RT_BIT(5)
+#define HM_CHANGED_GUEST_LDTR               RT_BIT(6)
+#define HM_CHANGED_GUEST_TR                 RT_BIT(7)
+#define HM_CHANGED_GUEST_MSR                RT_BIT(8)
+#define HM_CHANGED_GUEST_SEGMENT_REGS       RT_BIT(9)
+#define HM_CHANGED_GUEST_DEBUG              RT_BIT(10)
+#define HM_CHANGED_HOST_CONTEXT             RT_BIT(11)
+
+#define HM_CHANGED_ALL                  (   HM_CHANGED_GUEST_SEGMENT_REGS \
+                                            |   HM_CHANGED_GUEST_CR0          \
+                                            |   HM_CHANGED_GUEST_CR3          \
+                                            |   HM_CHANGED_GUEST_CR4          \
+                                            |   HM_CHANGED_GUEST_GDTR         \
+                                            |   HM_CHANGED_GUEST_IDTR         \
+                                            |   HM_CHANGED_GUEST_LDTR         \
+                                            |   HM_CHANGED_GUEST_TR           \
+                                            |   HM_CHANGED_GUEST_MSR          \
+                                            |   HM_CHANGED_GUEST_FPU          \
+                                            |   HM_CHANGED_GUEST_DEBUG        \
+                                            |   HM_CHANGED_HOST_CONTEXT)
+
+#define HM_CHANGED_ALL_GUEST            (   HM_CHANGED_GUEST_SEGMENT_REGS \
+                                            |   HM_CHANGED_GUEST_CR0          \
+                                            |   HM_CHANGED_GUEST_CR3          \
+                                            |   HM_CHANGED_GUEST_CR4          \
+                                            |   HM_CHANGED_GUEST_GDTR         \
+                                            |   HM_CHANGED_GUEST_IDTR         \
+                                            |   HM_CHANGED_GUEST_LDTR         \
+                                            |   HM_CHANGED_GUEST_TR           \
+                                            |   HM_CHANGED_GUEST_MSR          \
+                                            |   HM_CHANGED_GUEST_DEBUG        \
+                                            |   HM_CHANGED_GUEST_FPU)
+
+/** @} */
+
+/** Maximum number of page flushes we are willing to remember before considering a full TLB flush. */
+#define HM_MAX_TLB_SHOOTDOWN_PAGES      8
+
+/** Size for the EPT identity page table (1024 4 MB pages to cover the entire address space). */
+#define HM_EPT_IDENTITY_PG_TABLE_SIZE   PAGE_SIZE
+/** Size of the TSS structure + 2 pages for the IO bitmap + end byte. */
+#define HM_VTX_TSS_SIZE                 (sizeof(VBOXTSS) + 2*PAGE_SIZE + 1)
+/** Total guest mapped memory needed. */
+#define HM_VTX_TOTAL_DEVHEAP_MEM        (HM_EPT_IDENTITY_PG_TABLE_SIZE + HM_VTX_TSS_SIZE)
+
+/** Enable for TPR guest patching. */
+#define VBOX_HM_WITH_GUEST_PATCHING
+
+/** HM SSM version
+ */
+#ifdef VBOX_HM_WITH_GUEST_PATCHING
+# define HM_SSM_VERSION                 5
+# define HM_SSM_VERSION_NO_PATCHING     4
+#else
+# define HM_SSM_VERSION                 4
+# define HM_SSM_VERSION_NO_PATCHING     4
+#endif
+#define HM_SSM_VERSION_2_0_X            3
+
+/**
+ * Global per-cpu information. (host)
+ */
+typedef struct HMGLOBLCPUINFO
+{
+    /** The CPU ID. */
+    RTCPUID             idCpu;
+    /** The memory object   */
+    RTR0MEMOBJ          hMemObj;
+    /** Current ASID (AMD-V) / VPID (Intel). */
+    uint32_t            uCurrentASID;
+    /** TLB flush count. */
+    uint32_t            cTLBFlushes;
+    /** Whether to flush each new ASID/VPID before use. */
+    bool                fFlushASIDBeforeUse;
+    /** Configured for VT-x or AMD-V. */
+    bool                fConfigured;
+    /** Set if the VBOX_HWVIRTEX_IGNORE_SVM_IN_USE hack is active. */
+    bool                fIgnoreAMDVInUseError;
+    /** In use by our code. (for power suspend) */
+    volatile bool       fInUse;
+} HMGLOBLCPUINFO;
+/** Pointer to the per-cpu global information. */
+typedef HMGLOBLCPUINFO *PHMGLOBLCPUINFO;
+
+typedef enum
+{
+    HMPENDINGIO_INVALID = 0,
+    HMPENDINGIO_PORT_READ,
+    HMPENDINGIO_PORT_WRITE,
+    HMPENDINGIO_STRING_READ,
+    HMPENDINGIO_STRING_WRITE,
+    /** The usual 32-bit paranoia. */
+    HMPENDINGIO_32BIT_HACK   = 0x7fffffff
+} HMPENDINGIO;
+
+
+typedef enum
+{
+    HMTPRINSTR_INVALID,
+    HMTPRINSTR_READ,
+    HMTPRINSTR_READ_SHR4,
+    HMTPRINSTR_WRITE_REG,
+    HMTPRINSTR_WRITE_IMM,
+    HMTPRINSTR_JUMP_REPLACEMENT,
+    /** The usual 32-bit paranoia. */
+    HMTPRINSTR_32BIT_HACK   = 0x7fffffff
+} HMTPRINSTR;
+
+typedef struct
+{
+    /** The key is the address of patched instruction. (32 bits GC ptr) */
+    AVLOU32NODECORE         Core;
+    /** Original opcode. */
+    uint8_t                 aOpcode[16];
+    /** Instruction size. */
+    uint32_t                cbOp;
+    /** Replacement opcode. */
+    uint8_t                 aNewOpcode[16];
+    /** Replacement instruction size. */
+    uint32_t                cbNewOp;
+    /** Instruction type. */
+    HMTPRINSTR          enmType;
+    /** Source operand. */
+    uint32_t                uSrcOperand;
+    /** Destination operand. */
+    uint32_t                uDstOperand;
+    /** Number of times the instruction caused a fault. */
+    uint32_t                cFaults;
+    /** Patch address of the jump replacement. */
+    RTGCPTR32               pJumpTarget;
+} HMTPRPATCH;
+/** Pointer to HMTPRPATCH. */
+typedef HMTPRPATCH *PHMTPRPATCH;
+
+/**
+ * Switcher function, HC to RC.
+ *
+ * @param   pVM             Pointer to the VM.
+ * @param   uOffsetVMCPU    VMCPU offset from pVM
+ * @returns Return code indicating the action to take.
+ */
+typedef DECLCALLBACK (int) FNHMSWITCHERHC(PVM pVM, uint32_t uOffsetVMCPU);
+/** Pointer to switcher function. */
+typedef FNHMSWITCHERHC *PFNHMSWITCHERHC;
+
+/**
+ * HM VM Instance data.
+ * Changes to this must checked against the padding of the hm union in VM!
+ */
+typedef struct HM
+{
+    /** Set when we've initialized VMX or SVM. */
+    bool                        fInitialized;
+
+    /** Set when hardware acceleration is allowed. */
+    bool                        fAllowed;
+
+    /** Set if nested paging is enabled. */
+    bool                        fNestedPaging;
+
+    /** Set if nested paging is allowed. */
+    bool                        fAllowNestedPaging;
+
+    /** Set if large pages are enabled (requires nested paging). */
+    bool                        fLargePages;
+
+    /** Set if we can support 64-bit guests or not. */
+    bool                        fAllow64BitGuests;
+
+    /** Set if an IO-APIC is configured for this VM. */
+    bool                        fHasIoApic;
+
+    /** Set when TPR patching is allowed. */
+    bool                        fTRPPatchingAllowed;
+
+    /** Set when we initialize VT-x or AMD-V once for all CPUs. */
+    bool                        fGlobalInit;
+
+    /** Set when TPR patching is active. */
+    bool                        fTPRPatchingActive;
+    bool                        u8Alignment[6];
+
+    /** And mask for copying register contents. */
+    uint64_t                    u64RegisterMask;
+
+    /** Maximum ASID allowed. */
+    uint32_t                    uMaxASID;
+
+    /** The maximum number of resumes loops allowed in ring-0 (safety precaution).
+     * This number is set much higher when RTThreadPreemptIsPending is reliable. */
+    uint32_t                    cMaxResumeLoops;
+
+    /** Guest allocated memory for patching purposes. */
+    RTGCPTR                     pGuestPatchMem;
+    /** Current free pointer inside the patch block. */
+    RTGCPTR                     pFreeGuestPatchMem;
+    /** Size of the guest patch memory block. */
+    uint32_t                    cbGuestPatchMem;
+    uint32_t                    uPadding1;
+
+#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+    /** 32 to 64 bits switcher entrypoint. */
+    R0PTRTYPE(PFNHMSWITCHERHC) pfnHost32ToGuest64R0;
+
+    /* AMD-V 64 bits vmrun handler */
+    RTRCPTR                     pfnSVMGCVMRun64;
+
+    /* VT-x 64 bits vmlaunch handler */
+    RTRCPTR                     pfnVMXGCStartVM64;
+
+    /* RC handler to setup the 64 bits FPU state. */
+    RTRCPTR                     pfnSaveGuestFPU64;
+
+    /* RC handler to setup the 64 bits debug state. */
+    RTRCPTR                     pfnSaveGuestDebug64;
+
+    /* Test handler */
+    RTRCPTR                     pfnTest64;
+
+    RTRCPTR                     uAlignment[2];
+/*#elif defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+    uint32_t                    u32Alignment[1]; */
+#endif
+
+    struct
+    {
+        /** Set by the ring-0 side of HM to indicate VMX is supported by the
+         *  CPU. */
+        bool                        fSupported;
+
+        /** Set when we've enabled VMX. */
+        bool                        fEnabled;
+
+        /** Set if VPID is supported. */
+        bool                        fVPID;
+
+        /** Set if VT-x VPID is allowed. */
+        bool                        fAllowVPID;
+
+        /** Set if unrestricted guest execution is allowed (real and protected mode without paging). */
+        bool                        fUnrestrictedGuest;
+
+        /** Whether we're using the preemption timer or not. */
+        bool                        fUsePreemptTimer;
+        /** The shift mask employed by the VMX-Preemption timer. */
+        uint8_t                     cPreemptTimerShift;
+
+        bool                        uAlignment[1];
+
+        /** Virtual address of the TSS page used for real mode emulation. */
+        R3PTRTYPE(PVBOXTSS)         pRealModeTSS;
+
+        /** Virtual address of the identity page table used for real mode and protected mode without paging emulation in EPT mode. */
+        R3PTRTYPE(PX86PD)           pNonPagingModeEPTPageTable;
+
+        /** R0 memory object for the APIC physical page (serves for filtering accesses). */
+        RTR0MEMOBJ                  pMemObjAPIC;
+        /** Physical address of the APIC physical page (serves for filtering accesses). */
+        RTHCPHYS                    pAPICPhys;
+        /** Virtual address of the APIC physical page (serves for filtering accesses). */
+        R0PTRTYPE(uint8_t *)        pAPIC;
+
+        /** R0 memory object for the MSR entry load page (guest MSRs). */
+        RTR0MEMOBJ                  pMemObjMSREntryLoad;
+        /** Physical address of the MSR entry load page (guest MSRs). */
+        RTHCPHYS                    pMSREntryLoadPhys;
+        /** Virtual address of the MSR entry load page (guest MSRs). */
+        R0PTRTYPE(uint8_t *)        pMSREntryLoad;
+
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+        RTR0MEMOBJ                  pMemObjScratch;
+        RTHCPHYS                    pScratchPhys;
+        R0PTRTYPE(uint8_t *)        pScratch;
+#endif
+        /** R0 memory object for the MSR exit store page (guest MSRs). */
+        RTR0MEMOBJ                  pMemObjMSRExitStore;
+        /** Physical address of the MSR exit store page (guest MSRs). */
+        RTHCPHYS                    pMSRExitStorePhys;
+        /** Virtual address of the MSR exit store page (guest MSRs). */
+        R0PTRTYPE(uint8_t *)        pMSRExitStore;
+
+        /** R0 memory object for the MSR exit load page (host MSRs). */
+        RTR0MEMOBJ                  pMemObjMSRExitLoad;
+        /** Physical address of the MSR exit load page (host MSRs). */
+        RTHCPHYS                    pMSRExitLoadPhys;
+        /** Virtual address of the MSR exit load page (host MSRs). */
+        R0PTRTYPE(uint8_t *)        pMSRExitLoad;
+
+        /** Ring 0 handlers for VT-x. */
+        DECLR0CALLBACKMEMBER(void, pfnSetupTaggedTLB, (PVM pVM, PVMCPU pVCpu));
+
+#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS)
+        uint32_t                    u32Alignment;
+#endif
+        /** Host CR4 value (set by ring-0 VMX init) */
+        uint64_t                    hostCR4;
+
+        /** Host EFER value (set by ring-0 VMX init) */
+        uint64_t                    hostEFER;
+
+        /** VMX MSR values */
+        struct
+        {
+            uint64_t                feature_ctrl;
+            uint64_t                vmx_basic_info;
+            VMX_CAPABILITY          vmx_pin_ctls;
+            VMX_CAPABILITY          vmx_proc_ctls;
+            VMX_CAPABILITY          vmx_proc_ctls2;
+            VMX_CAPABILITY          vmx_exit;
+            VMX_CAPABILITY          vmx_entry;
+            uint64_t                vmx_misc;
+            uint64_t                vmx_cr0_fixed0;
+            uint64_t                vmx_cr0_fixed1;
+            uint64_t                vmx_cr4_fixed0;
+            uint64_t                vmx_cr4_fixed1;
+            uint64_t                vmx_vmcs_enum;
+            uint64_t                vmx_eptcaps;
+        } msr;
+
+        /** Flush types for invept & invvpid; they depend on capabilities. */
+        VMX_FLUSH_EPT               enmFlushEPT;
+        VMX_FLUSH_VPID              enmFlushVPID;
+    } vmx;
+
+    struct
+    {
+        /** Set by the ring-0 side of HM to indicate SVM is supported by the
+         *  CPU. */
+        bool                        fSupported;
+        /** Set when we've enabled SVM. */
+        bool                        fEnabled;
+        /** Set if erratum 170 affects the AMD cpu. */
+        bool                        fAlwaysFlushTLB;
+        /** Set when the hack to ignore VERR_SVM_IN_USE is active. */
+        bool                        fIgnoreInUseError;
+
+        /** R0 memory object for the IO bitmap (12kb). */
+        RTR0MEMOBJ                  pMemObjIOBitmap;
+        /** Physical address of the IO bitmap (12kb). */
+        RTHCPHYS                    pIOBitmapPhys;
+        /** Virtual address of the IO bitmap. */
+        R0PTRTYPE(void *)           pIOBitmap;
+
+        /* HWCR msr (for diagnostics) */
+        uint64_t                    msrHWCR;
+
+        /** SVM revision. */
+        uint32_t                    u32Rev;
+
+        /** SVM feature bits from cpuid 0x8000000a */
+        uint32_t                    u32Features;
+    } svm;
+
+    /**
+     * AVL tree with all patches (active or disabled) sorted by guest instruction address
+     */
+    AVLOU32TREE                     PatchTree;
+    uint32_t                        cPatches;
+    HMTPRPATCH                  aPatches[64];
+
+    struct
+    {
+        uint32_t                    u32AMDFeatureECX;
+        uint32_t                    u32AMDFeatureEDX;
+    } cpuid;
+
+    /** Saved error from detection */
+    int32_t                 lLastError;
+
+    /** HMR0Init was run */
+    bool                    fHMR0Init;
+    bool                    u8Alignment1[7];
+
+    STAMCOUNTER             StatTPRPatchSuccess;
+    STAMCOUNTER             StatTPRPatchFailure;
+    STAMCOUNTER             StatTPRReplaceSuccess;
+    STAMCOUNTER             StatTPRReplaceFailure;
+} HM;
+/** Pointer to HM VM instance data. */
+typedef HM *PHM;
+
+/* Maximum number of cached entries. */
+#define VMCSCACHE_MAX_ENTRY                             128
+
+/* Structure for storing read and write VMCS actions. */
+typedef struct VMCSCACHE
+{
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    /* Magic marker for searching in crash dumps. */
+    uint8_t         aMagic[16];
+    uint64_t        uMagic;
+    uint64_t        u64TimeEntry;
+    uint64_t        u64TimeSwitch;
+    uint64_t        cResume;
+    uint64_t        interPD;
+    uint64_t        pSwitcher;
+    uint32_t        uPos;
+    uint32_t        idCpu;
+#endif
+    /* CR2 is saved here for EPT syncing. */
+    uint64_t        cr2;
+    struct
+    {
+        uint32_t    cValidEntries;
+        uint32_t    uAlignment;
+        uint32_t    aField[VMCSCACHE_MAX_ENTRY];
+        uint64_t    aFieldVal[VMCSCACHE_MAX_ENTRY];
+    } Write;
+    struct
+    {
+        uint32_t    cValidEntries;
+        uint32_t    uAlignment;
+        uint32_t    aField[VMCSCACHE_MAX_ENTRY];
+        uint64_t    aFieldVal[VMCSCACHE_MAX_ENTRY];
+    } Read;
+#ifdef DEBUG
+    struct
+    {
+        RTHCPHYS    HCPhysCpuPage;
+        RTHCPHYS    HCPhysVMCS;
+        RTGCPTR     pCache;
+        RTGCPTR     pCtx;
+    } TestIn;
+    struct
+    {
+        RTHCPHYS    HCPhysVMCS;
+        RTGCPTR     pCache;
+        RTGCPTR     pCtx;
+        uint64_t    eflags;
+        uint64_t    cr8;
+    } TestOut;
+    struct
+    {
+        uint64_t    param1;
+        uint64_t    param2;
+        uint64_t    param3;
+        uint64_t    param4;
+    } ScratchPad;
+#endif
+} VMCSCACHE;
+/** Pointer to VMCSCACHE. */
+typedef VMCSCACHE *PVMCSCACHE;
+
+/** VMX StartVM function. */
+typedef DECLCALLBACK(int) FNHMVMXSTARTVM(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu);
+/** Pointer to a VMX StartVM function. */
+typedef R0PTRTYPE(FNHMVMXSTARTVM *) PFNHMVMXSTARTVM;
+
+/** SVM VMRun function. */
+typedef DECLCALLBACK(int) FNHMSVMVMRUN(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu);
+/** Pointer to a SVM VMRun function. */
+typedef R0PTRTYPE(FNHMSVMVMRUN *) PFNHMSVMVMRUN;
+
+/**
+ * HM VMCPU Instance data.
+ */
+typedef struct HMCPU
+{
+    /** Old style FPU reporting trap mask override performed (optimization) */
+    bool                        fFPUOldStyleOverride;
+
+    /** Set if we don't have to flush the TLB on VM entry. */
+    bool                        fResumeVM;
+
+    /** Set if we need to flush the TLB during the world switch. */
+    bool                        fForceTLBFlush;
+
+    /** Set when we're using VT-x or AMD-V at that moment. */
+    bool                        fActive;
+
+    /** Set when the TLB has been checked until we return from the world switch. */
+    volatile bool               fCheckedTLBFlush;
+    uint8_t                     bAlignment[3];
+
+    /** World switch exit counter. */
+    volatile uint32_t           cWorldSwitchExits;
+
+    /** HM_CHANGED_* flags. */
+    uint32_t                    fContextUseFlags;
+
+    /** Id of the last cpu we were executing code on (NIL_RTCPUID for the first time) */
+    RTCPUID                     idLastCpu;
+
+    /** TLB flush count */
+    uint32_t                    cTLBFlushes;
+
+    /** Current ASID in use by the VM */
+    uint32_t                    uCurrentASID;
+
+    uint32_t                    u32Alignment;
+
+    /* Host's TSC_AUX MSR (used when RDTSCP doesn't cause VM-exits). */
+    uint64_t                    u64HostTSCAux;
+
+    struct
+    {
+        /** Physical address of the VM control structure (VMCS). */
+        RTHCPHYS                    HCPhysVMCS;
+        /** R0 memory object for the VM control structure (VMCS). */
+        RTR0MEMOBJ                  hMemObjVMCS;
+        /** Virtual address of the VM control structure (VMCS). */
+        R0PTRTYPE(void *)           pvVMCS;
+
+        /** Ring 0 handlers for VT-x. */
+        PFNHMVMXSTARTVM         pfnStartVM;
+
+#if HC_ARCH_BITS == 32
+        uint32_t                    u32Alignment;
+#endif
+
+        /** Current VMX_VMCS_CTRL_PROC_EXEC_CONTROLS. */
+        uint64_t                    proc_ctls;
+
+        /** Current VMX_VMCS_CTRL_PROC_EXEC2_CONTROLS. */
+        uint64_t                    proc_ctls2;
+
+        /** Physical address of the virtual APIC page for TPR caching. */
+        RTHCPHYS                    HCPhysVAPIC;
+        /** R0 memory object for the virtual APIC page for TPR caching. */
+        RTR0MEMOBJ                  hMemObjVAPIC;
+        /** Virtual address of the virtual APIC page for TPR caching. */
+        R0PTRTYPE(uint8_t *)        pbVAPIC;
+
+        /** Current CR0 mask. */
+        uint64_t                    cr0_mask;
+        /** Current CR4 mask. */
+        uint64_t                    cr4_mask;
+
+        /** Current EPTP. */
+        RTHCPHYS                    GCPhysEPTP;
+
+        /** Physical address of the MSR bitmap (1 page). */
+        RTHCPHYS                    pMSRBitmapPhys;
+        /** R0 memory object for the MSR bitmap (1 page). */
+        RTR0MEMOBJ                  pMemObjMSRBitmap;
+        /** Virtual address of the MSR bitmap (1 page). */
+        R0PTRTYPE(uint8_t *)        pMSRBitmap;
+
+#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
+        /** Physical address of the guest MSR load area (1 page). */
+        RTHCPHYS                    pGuestMSRPhys;
+        /** R0 memory object for the guest MSR load area (1 page). */
+        RTR0MEMOBJ                  pMemObjGuestMSR;
+        /** Virtual address of the guest MSR load area (1 page). */
+        R0PTRTYPE(uint8_t *)        pGuestMSR;
+
+        /** Physical address of the MSR load area (1 page). */
+        RTHCPHYS                    pHostMSRPhys;
+        /** R0 memory object for the MSR load area (1 page). */
+        RTR0MEMOBJ                  pMemObjHostMSR;
+        /** Virtual address of the MSR load area (1 page). */
+        R0PTRTYPE(uint8_t *)        pHostMSR;
+
+        /* Number of automatically loaded/restored guest MSRs during the world switch. */
+        uint32_t                    cCachedMSRs;
+        uint32_t                    uAlignment;
+#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
+
+        /* Last use TSC offset value. (cached) */
+        uint64_t                    u64TSCOffset;
+
+        /** VMCS cache. */
+        VMCSCACHE                   VMCSCache;
+
+        /** Real-mode emulation state. */
+        struct
+        {
+            X86EFLAGS                   eflags;
+            uint32_t                    fValid;
+        } RealMode;
+
+        struct
+        {
+            uint64_t                u64VMCSPhys;
+            uint32_t                ulVMCSRevision;
+            uint32_t                ulInstrError;
+            uint32_t                ulExitReason;
+            RTCPUID                 idEnteredCpu;
+            RTCPUID                 idCurrentCpu;
+            uint32_t                padding;
+        } lasterror;
+
+        /** The last seen guest paging mode (by VT-x). */
+        PGMMODE                     enmLastSeenGuestMode;
+        /** Current guest paging mode (as seen by HMR3PagingModeChanged). */
+        PGMMODE                     enmCurrGuestMode;
+        /** Previous guest paging mode (as seen by HMR3PagingModeChanged). */
+        PGMMODE                     enmPrevGuestMode;
+    } vmx;
+
+    struct
+    {
+        /** R0 memory object for the host VM control block (VMCB). */
+        RTR0MEMOBJ                  pMemObjVMCBHost;
+        /** Physical address of the host VM control block (VMCB). */
+        RTHCPHYS                    pVMCBHostPhys;
+        /** Virtual address of the host VM control block (VMCB). */
+        R0PTRTYPE(void *)           pVMCBHost;
+
+        /** R0 memory object for the VM control block (VMCB). */
+        RTR0MEMOBJ                  pMemObjVMCB;
+        /** Physical address of the VM control block (VMCB). */
+        RTHCPHYS                    pVMCBPhys;
+        /** Virtual address of the VM control block (VMCB). */
+        R0PTRTYPE(void *)           pVMCB;
+
+        /** Ring 0 handlers for VT-x. */
+        PFNHMSVMVMRUN           pfnVMRun;
+
+        /** R0 memory object for the MSR bitmap (8kb). */
+        RTR0MEMOBJ                  pMemObjMSRBitmap;
+        /** Physical address of the MSR bitmap (8kb). */
+        RTHCPHYS                    pMSRBitmapPhys;
+        /** Virtual address of the MSR bitmap. */
+        R0PTRTYPE(void *)           pMSRBitmap;
+    } svm;
+
+    /** Event injection state. */
+    struct
+    {
+        uint32_t                    fPending;
+        uint32_t                    errCode;
+        uint64_t                    intInfo;
+    } Event;
+
+    /** IO Block emulation state. */
+    struct
+    {
+        bool                    fEnabled;
+        uint8_t                 u8Align[7];
+
+        /** RIP at the start of the io code we wish to emulate in the recompiler. */
+        RTGCPTR                 GCPtrFunctionEip;
+
+        uint64_t                cr0;
+    } EmulateIoBlock;
+
+    struct
+    {
+        /* Pending IO operation type. */
+        HMPENDINGIO         enmType;
+        uint32_t                uPadding;
+        RTGCPTR                 GCPtrRip;
+        RTGCPTR                 GCPtrRipNext;
+        union
+        {
+            struct
+            {
+                unsigned        uPort;
+                unsigned        uAndVal;
+                unsigned        cbSize;
+            } Port;
+            uint64_t            aRaw[2];
+        } s;
+    } PendingIO;
+
+    /** Currently shadow paging mode. */
+    PGMMODE                 enmShadowMode;
+
+    /** The CPU ID of the CPU currently owning the VMCS. Set in
+     * HMR0Enter and cleared in HMR0Leave. */
+    RTCPUID                 idEnteredCpu;
+
+    /** To keep track of pending TLB shootdown pages. (SMP guest only) */
+    struct
+    {
+        RTGCPTR             aPages[HM_MAX_TLB_SHOOTDOWN_PAGES];
+        unsigned            cPages;
+    } TlbShootdown;
+
+    /** For saving stack space, the disassembler state is allocated here instead of
+     * on the stack. */
+    DISCPUSTATE             DisState;
+
+    uint32_t                padding2[1];
+
+    STAMPROFILEADV          StatEntry;
+    STAMPROFILEADV          StatExit1;
+    STAMPROFILEADV          StatExit2;
+#if 1 /* temporary for tracking down darwin issues. */
+    STAMPROFILEADV          StatExit2Sub1;
+    STAMPROFILEADV          StatExit2Sub2;
+    STAMPROFILEADV          StatExit2Sub3;
+#endif
+    STAMPROFILEADV          StatInGC;
+
+#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+    STAMPROFILEADV          StatWorldSwitch3264;
+#endif
+    STAMPROFILEADV          StatPoke;
+    STAMPROFILEADV          StatSpinPoke;
+    STAMPROFILEADV          StatSpinPokeFailed;
+
+    STAMCOUNTER             StatIntInject;
+
+    STAMCOUNTER             StatExitShadowNM;
+    STAMCOUNTER             StatExitGuestNM;
+    STAMCOUNTER             StatExitShadowPF;
+    STAMCOUNTER             StatExitShadowPFEM;
+    STAMCOUNTER             StatExitGuestPF;
+    STAMCOUNTER             StatExitGuestUD;
+    STAMCOUNTER             StatExitGuestSS;
+    STAMCOUNTER             StatExitGuestNP;
+    STAMCOUNTER             StatExitGuestGP;
+    STAMCOUNTER             StatExitGuestDE;
+    STAMCOUNTER             StatExitGuestDB;
+    STAMCOUNTER             StatExitGuestMF;
+    STAMCOUNTER             StatExitGuestBP;
+    STAMCOUNTER             StatExitGuestXF;
+    STAMCOUNTER             StatExitGuestXcpUnk;
+    STAMCOUNTER             StatExitInvlpg;
+    STAMCOUNTER             StatExitInvd;
+    STAMCOUNTER             StatExitCpuid;
+    STAMCOUNTER             StatExitRdtsc;
+    STAMCOUNTER             StatExitRdtscp;
+    STAMCOUNTER             StatExitRdpmc;
+    STAMCOUNTER             StatExitCli;
+    STAMCOUNTER             StatExitSti;
+    STAMCOUNTER             StatExitPushf;
+    STAMCOUNTER             StatExitPopf;
+    STAMCOUNTER             StatExitIret;
+    STAMCOUNTER             StatExitInt;
+    STAMCOUNTER             StatExitCRxWrite[16];
+    STAMCOUNTER             StatExitCRxRead[16];
+    STAMCOUNTER             StatExitDRxWrite;
+    STAMCOUNTER             StatExitDRxRead;
+    STAMCOUNTER             StatExitRdmsr;
+    STAMCOUNTER             StatExitWrmsr;
+    STAMCOUNTER             StatExitCLTS;
+    STAMCOUNTER             StatExitHlt;
+    STAMCOUNTER             StatExitMwait;
+    STAMCOUNTER             StatExitMonitor;
+    STAMCOUNTER             StatExitLMSW;
+    STAMCOUNTER             StatExitIOWrite;
+    STAMCOUNTER             StatExitIORead;
+    STAMCOUNTER             StatExitIOStringWrite;
+    STAMCOUNTER             StatExitIOStringRead;
+    STAMCOUNTER             StatExitIrqWindow;
+    STAMCOUNTER             StatExitMaxResume;
+    STAMCOUNTER             StatExitPreemptPending;
+    STAMCOUNTER             StatExitMTF;
+    STAMCOUNTER             StatIntReinject;
+    STAMCOUNTER             StatPendingHostIrq;
+
+    STAMCOUNTER             StatFlushPage;
+    STAMCOUNTER             StatFlushPageManual;
+    STAMCOUNTER             StatFlushPhysPageManual;
+    STAMCOUNTER             StatFlushTLB;
+    STAMCOUNTER             StatFlushTLBManual;
+    STAMCOUNTER             StatFlushPageInvlpg;
+    STAMCOUNTER             StatFlushTLBWorldSwitch;
+    STAMCOUNTER             StatNoFlushTLBWorldSwitch;
+    STAMCOUNTER             StatFlushTLBCRxChange;
+    STAMCOUNTER             StatFlushASID;
+    STAMCOUNTER             StatFlushTLBInvlpga;
+    STAMCOUNTER             StatTlbShootdown;
+    STAMCOUNTER             StatTlbShootdownFlush;
+
+    STAMCOUNTER             StatSwitchGuestIrq;
+    STAMCOUNTER             StatSwitchToR3;
+
+    STAMCOUNTER             StatTSCOffset;
+    STAMCOUNTER             StatTSCIntercept;
+    STAMCOUNTER             StatTSCInterceptOverFlow;
+
+    STAMCOUNTER             StatExitReasonNPF;
+    STAMCOUNTER             StatDRxArmed;
+    STAMCOUNTER             StatDRxContextSwitch;
+    STAMCOUNTER             StatDRxIOCheck;
+
+    STAMCOUNTER             StatLoadMinimal;
+    STAMCOUNTER             StatLoadFull;
+
+#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
+    STAMCOUNTER             StatFpu64SwitchBack;
+    STAMCOUNTER             StatDebug64SwitchBack;
+#endif
+
+#ifdef VBOX_WITH_STATISTICS
+    R3PTRTYPE(PSTAMCOUNTER) paStatExitReason;
+    R0PTRTYPE(PSTAMCOUNTER) paStatExitReasonR0;
+    R3PTRTYPE(PSTAMCOUNTER) paStatInjectedIrqs;
+    R0PTRTYPE(PSTAMCOUNTER) paStatInjectedIrqsR0;
+#endif
+} HMCPU;
+/** Pointer to HM VM instance data. */
+typedef HMCPU *PHMCPU;
+
+
+#ifdef IN_RING0
+
+VMMR0DECL(PHMGLOBLCPUINFO) HMR0GetCurrentCpu(void);
+VMMR0DECL(PHMGLOBLCPUINFO) HMR0GetCurrentCpuEx(RTCPUID idCpu);
+
+
+#ifdef VBOX_STRICT
+VMMR0DECL(void) HMDumpRegs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR0DECL(void) HMR0DumpDescriptor(PCX86DESCHC pDesc, RTSEL Sel, const char *pszMsg);
+#else
+# define HMDumpRegs(a, b ,c)            do { } while (0)
+# define HMR0DumpDescriptor(a, b, c)    do { } while (0)
+#endif
+
+# ifdef VBOX_WITH_KERNEL_USING_XMM
+DECLASM(int)   hmR0VMXStartVMWrapXMM(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu, PFNHMVMXSTARTVM pfnStartVM);
+DECLASM(int)   hmR0SVMRunWrapXMM(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu, PFNHMSVMVMRUN pfnVMRun);
+# endif
+
+# ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
+/**
+ * Gets 64-bit GDTR and IDTR on darwin.
+ * @param  pGdtr        Where to store the 64-bit GDTR.
+ * @param  pIdtr        Where to store the 64-bit IDTR.
+ */
+DECLASM(void) hmR0Get64bitGDTRandIDTR(PX86XDTR64 pGdtr, PX86XDTR64 pIdtr);
+
+/**
+ * Gets 64-bit CR3 on darwin.
+ * @returns CR3
+ */
+DECLASM(uint64_t) hmR0Get64bitCR3(void);
+# endif
+
+#endif /* IN_RING0 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
Index: trunk/src/VBox/VMM/include/HMInternal.mac
===================================================================
--- trunk/src/VBox/VMM/include/HMInternal.mac	(revision 43387)
+++ trunk/src/VBox/VMM/include/HMInternal.mac	(revision 43387)
@@ -0,0 +1,61 @@
+;$Id$
+;; @file
+; HM - Internal header file.
+;
+;
+; Copyright (C) 2006-2007 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.
+;
+
+%define VMX_USE_CACHED_VMCS_ACCESSES
+%define VBOX_WITH_AUTO_MSR_LOAD_RESTORE
+
+;Maximum number of cached entries.
+%define VMCSCACHE_MAX_ENTRY                             128
+
+; Structure for storing read and write VMCS actions.
+struc VMCSCACHE
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    .aMagic                   resb    16
+    .uMagic                   resq    1
+    .u64TimeEntry             resq    1
+    .u64TimeSwitch            resq    1
+    .cResume                  resq    1
+    .interPD                  resq    1
+    .pSwitcher                resq    1
+    .uPos                     resd    1
+    .idCpu                    resd    1
+%endif
+    .cr2                      resq    1
+    .Write.cValidEntries      resd    1
+    .Write.uAlignment         resd    1
+    .Write.aField             resd    VMCSCACHE_MAX_ENTRY
+    .Write.aFieldVal          resq    VMCSCACHE_MAX_ENTRY
+    .Read.cValidEntries       resd    1
+    .Read.uAlignment          resd    1
+    .Read.aField              resd    VMCSCACHE_MAX_ENTRY
+    .Read.aFieldVal           resq    VMCSCACHE_MAX_ENTRY
+%ifdef DEBUG
+    .TestIn.HCPhysCpuPage     resq    1
+    .TestIn.HCPhysVMCS        resq    1
+    .TestIn.pCache            resq    1
+    .TestIn.pCtx              resq    1
+    .TestOut.HCPhysVMCS       resq    1
+    .TestOut.pCache           resq    1
+    .TestOut.pCtx             resq    1
+    .TestOut.eflags           resq    1
+    .TestOut.cr8              resq    1
+    .ScratchPad.param1        resq    1
+    .ScratchPad.param2        resq    1
+    .ScratchPad.param3        resq    1
+    .ScratchPad.param4        resq    1
+%endif
+endstruc
+
Index: trunk/src/VBox/VMM/include/HWACCMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/HWACCMInternal.h	(revision 43379)
+++ 	(revision )
@@ -1,906 +1,0 @@
-/* $Id$ */
-/** @file
- * HM - Internal header file.
- */
-
-/*
- * 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;
- * 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.
- */
-
-#ifndef ___HWACCMInternal_h
-#define ___HWACCMInternal_h
-
-#include <VBox/cdefs.h>
-#include <VBox/types.h>
-#include <VBox/vmm/em.h>
-#include <VBox/vmm/stam.h>
-#include <VBox/dis.h>
-#include <VBox/vmm/hwaccm.h>
-#include <VBox/vmm/hwacc_vmx.h>
-#include <VBox/vmm/pgm.h>
-#include <VBox/vmm/cpum.h>
-#include <iprt/memobj.h>
-#include <iprt/cpuset.h>
-#include <iprt/mp.h>
-#include <iprt/avl.h>
-
-#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) || defined (VBOX_WITH_64_BITS_GUESTS)
-/* Enable 64 bits guest support. */
-# define VBOX_ENABLE_64_BITS_GUESTS
-#endif
-
-#define VMX_USE_CACHED_VMCS_ACCESSES
-#define HWACCM_VMX_EMULATE_REALMODE
-
-/* The MSR auto load/store does not work for KERNEL_GS_BASE MSR, thus we
- * handle this MSR manually. See @bugref{6208}. This is clearly visible while
- * booting Solaris 11 (11.1 b19) VMs with 2 Cpus.
- *
- * Note: don't forget to update the assembly files while modifying this!
- */
-# define VBOX_WITH_AUTO_MSR_LOAD_RESTORE
-
-RT_C_DECLS_BEGIN
-
-
-/** @defgroup grp_hwaccm_int       Internal
- * @ingroup grp_hwaccm
- * @internal
- * @{
- */
-
-
-/** Maximum number of exit reason statistics counters. */
-#define MAX_EXITREASON_STAT        0x100
-#define MASK_EXITREASON_STAT       0xff
-#define MASK_INJECT_IRQ_STAT       0xff
-
-/** @name Changed flags
- * These flags are used to keep track of which important registers that
- * have been changed since last they were reset.
- * @{
- */
-#define HWACCM_CHANGED_GUEST_FPU                RT_BIT(0)
-#define HWACCM_CHANGED_GUEST_CR0                RT_BIT(1)
-#define HWACCM_CHANGED_GUEST_CR3                RT_BIT(2)
-#define HWACCM_CHANGED_GUEST_CR4                RT_BIT(3)
-#define HWACCM_CHANGED_GUEST_GDTR               RT_BIT(4)
-#define HWACCM_CHANGED_GUEST_IDTR               RT_BIT(5)
-#define HWACCM_CHANGED_GUEST_LDTR               RT_BIT(6)
-#define HWACCM_CHANGED_GUEST_TR                 RT_BIT(7)
-#define HWACCM_CHANGED_GUEST_MSR                RT_BIT(8)
-#define HWACCM_CHANGED_GUEST_SEGMENT_REGS       RT_BIT(9)
-#define HWACCM_CHANGED_GUEST_DEBUG              RT_BIT(10)
-#define HWACCM_CHANGED_HOST_CONTEXT             RT_BIT(11)
-
-#define HWACCM_CHANGED_ALL                  (   HWACCM_CHANGED_GUEST_SEGMENT_REGS \
-                                            |   HWACCM_CHANGED_GUEST_CR0          \
-                                            |   HWACCM_CHANGED_GUEST_CR3          \
-                                            |   HWACCM_CHANGED_GUEST_CR4          \
-                                            |   HWACCM_CHANGED_GUEST_GDTR         \
-                                            |   HWACCM_CHANGED_GUEST_IDTR         \
-                                            |   HWACCM_CHANGED_GUEST_LDTR         \
-                                            |   HWACCM_CHANGED_GUEST_TR           \
-                                            |   HWACCM_CHANGED_GUEST_MSR          \
-                                            |   HWACCM_CHANGED_GUEST_FPU          \
-                                            |   HWACCM_CHANGED_GUEST_DEBUG        \
-                                            |   HWACCM_CHANGED_HOST_CONTEXT)
-
-#define HWACCM_CHANGED_ALL_GUEST            (   HWACCM_CHANGED_GUEST_SEGMENT_REGS \
-                                            |   HWACCM_CHANGED_GUEST_CR0          \
-                                            |   HWACCM_CHANGED_GUEST_CR3          \
-                                            |   HWACCM_CHANGED_GUEST_CR4          \
-                                            |   HWACCM_CHANGED_GUEST_GDTR         \
-                                            |   HWACCM_CHANGED_GUEST_IDTR         \
-                                            |   HWACCM_CHANGED_GUEST_LDTR         \
-                                            |   HWACCM_CHANGED_GUEST_TR           \
-                                            |   HWACCM_CHANGED_GUEST_MSR          \
-                                            |   HWACCM_CHANGED_GUEST_DEBUG        \
-                                            |   HWACCM_CHANGED_GUEST_FPU)
-
-/** @} */
-
-/** Maximum number of page flushes we are willing to remember before considering a full TLB flush. */
-#define HWACCM_MAX_TLB_SHOOTDOWN_PAGES      8
-
-/** Size for the EPT identity page table (1024 4 MB pages to cover the entire address space). */
-#define HWACCM_EPT_IDENTITY_PG_TABLE_SIZE   PAGE_SIZE
-/** Size of the TSS structure + 2 pages for the IO bitmap + end byte. */
-#define HWACCM_VTX_TSS_SIZE                 (sizeof(VBOXTSS) + 2*PAGE_SIZE + 1)
-/** Total guest mapped memory needed. */
-#define HWACCM_VTX_TOTAL_DEVHEAP_MEM        (HWACCM_EPT_IDENTITY_PG_TABLE_SIZE + HWACCM_VTX_TSS_SIZE)
-
-/** Enable for TPR guest patching. */
-#define VBOX_HWACCM_WITH_GUEST_PATCHING
-
-/** HWACCM SSM version
- */
-#ifdef VBOX_HWACCM_WITH_GUEST_PATCHING
-# define HWACCM_SSM_VERSION                 5
-# define HWACCM_SSM_VERSION_NO_PATCHING     4
-#else
-# define HWACCM_SSM_VERSION                 4
-# define HWACCM_SSM_VERSION_NO_PATCHING     4
-#endif
-#define HWACCM_SSM_VERSION_2_0_X            3
-
-/**
- * Global per-cpu information. (host)
- */
-typedef struct HMGLOBLCPUINFO
-{
-    /** The CPU ID. */
-    RTCPUID             idCpu;
-    /** The memory object   */
-    RTR0MEMOBJ          hMemObj;
-    /** Current ASID (AMD-V) / VPID (Intel). */
-    uint32_t            uCurrentASID;
-    /** TLB flush count. */
-    uint32_t            cTLBFlushes;
-    /** Whether to flush each new ASID/VPID before use. */
-    bool                fFlushASIDBeforeUse;
-    /** Configured for VT-x or AMD-V. */
-    bool                fConfigured;
-    /** Set if the VBOX_HWVIRTEX_IGNORE_SVM_IN_USE hack is active. */
-    bool                fIgnoreAMDVInUseError;
-    /** In use by our code. (for power suspend) */
-    volatile bool       fInUse;
-} HMGLOBLCPUINFO;
-/** Pointer to the per-cpu global information. */
-typedef HMGLOBLCPUINFO *PHMGLOBLCPUINFO;
-
-typedef enum
-{
-    HWACCMPENDINGIO_INVALID = 0,
-    HWACCMPENDINGIO_PORT_READ,
-    HWACCMPENDINGIO_PORT_WRITE,
-    HWACCMPENDINGIO_STRING_READ,
-    HWACCMPENDINGIO_STRING_WRITE,
-    /** The usual 32-bit paranoia. */
-    HWACCMPENDINGIO_32BIT_HACK   = 0x7fffffff
-} HWACCMPENDINGIO;
-
-
-typedef enum
-{
-    HWACCMTPRINSTR_INVALID,
-    HWACCMTPRINSTR_READ,
-    HWACCMTPRINSTR_READ_SHR4,
-    HWACCMTPRINSTR_WRITE_REG,
-    HWACCMTPRINSTR_WRITE_IMM,
-    HWACCMTPRINSTR_JUMP_REPLACEMENT,
-    /** The usual 32-bit paranoia. */
-    HWACCMTPRINSTR_32BIT_HACK   = 0x7fffffff
-} HWACCMTPRINSTR;
-
-typedef struct
-{
-    /** The key is the address of patched instruction. (32 bits GC ptr) */
-    AVLOU32NODECORE         Core;
-    /** Original opcode. */
-    uint8_t                 aOpcode[16];
-    /** Instruction size. */
-    uint32_t                cbOp;
-    /** Replacement opcode. */
-    uint8_t                 aNewOpcode[16];
-    /** Replacement instruction size. */
-    uint32_t                cbNewOp;
-    /** Instruction type. */
-    HWACCMTPRINSTR          enmType;
-    /** Source operand. */
-    uint32_t                uSrcOperand;
-    /** Destination operand. */
-    uint32_t                uDstOperand;
-    /** Number of times the instruction caused a fault. */
-    uint32_t                cFaults;
-    /** Patch address of the jump replacement. */
-    RTGCPTR32               pJumpTarget;
-} HWACCMTPRPATCH;
-/** Pointer to HWACCMTPRPATCH. */
-typedef HWACCMTPRPATCH *PHWACCMTPRPATCH;
-
-/**
- * Switcher function, HC to RC.
- *
- * @param   pVM             Pointer to the VM.
- * @param   uOffsetVMCPU    VMCPU offset from pVM
- * @returns Return code indicating the action to take.
- */
-typedef DECLCALLBACK (int) FNHWACCMSWITCHERHC(PVM pVM, uint32_t uOffsetVMCPU);
-/** Pointer to switcher function. */
-typedef FNHWACCMSWITCHERHC *PFNHWACCMSWITCHERHC;
-
-/**
- * HWACCM VM Instance data.
- * Changes to this must checked against the padding of the hwaccm union in VM!
- */
-typedef struct HWACCM
-{
-    /** Set when we've initialized VMX or SVM. */
-    bool                        fInitialized;
-
-    /** Set when hardware acceleration is allowed. */
-    bool                        fAllowed;
-
-    /** Set if nested paging is enabled. */
-    bool                        fNestedPaging;
-
-    /** Set if nested paging is allowed. */
-    bool                        fAllowNestedPaging;
-
-    /** Set if large pages are enabled (requires nested paging). */
-    bool                        fLargePages;
-
-    /** Set if we can support 64-bit guests or not. */
-    bool                        fAllow64BitGuests;
-
-    /** Set if an IO-APIC is configured for this VM. */
-    bool                        fHasIoApic;
-
-    /** Set when TPR patching is allowed. */
-    bool                        fTRPPatchingAllowed;
-
-    /** Set when we initialize VT-x or AMD-V once for all CPUs. */
-    bool                        fGlobalInit;
-
-    /** Set when TPR patching is active. */
-    bool                        fTPRPatchingActive;
-    bool                        u8Alignment[6];
-
-    /** And mask for copying register contents. */
-    uint64_t                    u64RegisterMask;
-
-    /** Maximum ASID allowed. */
-    uint32_t                    uMaxASID;
-
-    /** The maximum number of resumes loops allowed in ring-0 (safety precaution).
-     * This number is set much higher when RTThreadPreemptIsPending is reliable. */
-    uint32_t                    cMaxResumeLoops;
-
-    /** Guest allocated memory for patching purposes. */
-    RTGCPTR                     pGuestPatchMem;
-    /** Current free pointer inside the patch block. */
-    RTGCPTR                     pFreeGuestPatchMem;
-    /** Size of the guest patch memory block. */
-    uint32_t                    cbGuestPatchMem;
-    uint32_t                    uPadding1;
-
-#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
-    /** 32 to 64 bits switcher entrypoint. */
-    R0PTRTYPE(PFNHWACCMSWITCHERHC) pfnHost32ToGuest64R0;
-
-    /* AMD-V 64 bits vmrun handler */
-    RTRCPTR                     pfnSVMGCVMRun64;
-
-    /* VT-x 64 bits vmlaunch handler */
-    RTRCPTR                     pfnVMXGCStartVM64;
-
-    /* RC handler to setup the 64 bits FPU state. */
-    RTRCPTR                     pfnSaveGuestFPU64;
-
-    /* RC handler to setup the 64 bits debug state. */
-    RTRCPTR                     pfnSaveGuestDebug64;
-
-    /* Test handler */
-    RTRCPTR                     pfnTest64;
-
-    RTRCPTR                     uAlignment[2];
-/*#elif defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
-    uint32_t                    u32Alignment[1]; */
-#endif
-
-    struct
-    {
-        /** Set by the ring-0 side of HWACCM to indicate VMX is supported by the
-         *  CPU. */
-        bool                        fSupported;
-
-        /** Set when we've enabled VMX. */
-        bool                        fEnabled;
-
-        /** Set if VPID is supported. */
-        bool                        fVPID;
-
-        /** Set if VT-x VPID is allowed. */
-        bool                        fAllowVPID;
-
-        /** Set if unrestricted guest execution is allowed (real and protected mode without paging). */
-        bool                        fUnrestrictedGuest;
-
-        /** Whether we're using the preemption timer or not. */
-        bool                        fUsePreemptTimer;
-        /** The shift mask employed by the VMX-Preemption timer. */
-        uint8_t                     cPreemptTimerShift;
-
-        bool                        uAlignment[1];
-
-        /** Virtual address of the TSS page used for real mode emulation. */
-        R3PTRTYPE(PVBOXTSS)         pRealModeTSS;
-
-        /** Virtual address of the identity page table used for real mode and protected mode without paging emulation in EPT mode. */
-        R3PTRTYPE(PX86PD)           pNonPagingModeEPTPageTable;
-
-        /** R0 memory object for the APIC physical page (serves for filtering accesses). */
-        RTR0MEMOBJ                  pMemObjAPIC;
-        /** Physical address of the APIC physical page (serves for filtering accesses). */
-        RTHCPHYS                    pAPICPhys;
-        /** Virtual address of the APIC physical page (serves for filtering accesses). */
-        R0PTRTYPE(uint8_t *)        pAPIC;
-
-        /** R0 memory object for the MSR entry load page (guest MSRs). */
-        RTR0MEMOBJ                  pMemObjMSREntryLoad;
-        /** Physical address of the MSR entry load page (guest MSRs). */
-        RTHCPHYS                    pMSREntryLoadPhys;
-        /** Virtual address of the MSR entry load page (guest MSRs). */
-        R0PTRTYPE(uint8_t *)        pMSREntryLoad;
-
-#ifdef VBOX_WITH_CRASHDUMP_MAGIC
-        RTR0MEMOBJ                  pMemObjScratch;
-        RTHCPHYS                    pScratchPhys;
-        R0PTRTYPE(uint8_t *)        pScratch;
-#endif
-        /** R0 memory object for the MSR exit store page (guest MSRs). */
-        RTR0MEMOBJ                  pMemObjMSRExitStore;
-        /** Physical address of the MSR exit store page (guest MSRs). */
-        RTHCPHYS                    pMSRExitStorePhys;
-        /** Virtual address of the MSR exit store page (guest MSRs). */
-        R0PTRTYPE(uint8_t *)        pMSRExitStore;
-
-        /** R0 memory object for the MSR exit load page (host MSRs). */
-        RTR0MEMOBJ                  pMemObjMSRExitLoad;
-        /** Physical address of the MSR exit load page (host MSRs). */
-        RTHCPHYS                    pMSRExitLoadPhys;
-        /** Virtual address of the MSR exit load page (host MSRs). */
-        R0PTRTYPE(uint8_t *)        pMSRExitLoad;
-
-        /** Ring 0 handlers for VT-x. */
-        DECLR0CALLBACKMEMBER(void, pfnSetupTaggedTLB, (PVM pVM, PVMCPU pVCpu));
-
-#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS)
-        uint32_t                    u32Alignment;
-#endif
-        /** Host CR4 value (set by ring-0 VMX init) */
-        uint64_t                    hostCR4;
-
-        /** Host EFER value (set by ring-0 VMX init) */
-        uint64_t                    hostEFER;
-
-        /** VMX MSR values */
-        struct
-        {
-            uint64_t                feature_ctrl;
-            uint64_t                vmx_basic_info;
-            VMX_CAPABILITY          vmx_pin_ctls;
-            VMX_CAPABILITY          vmx_proc_ctls;
-            VMX_CAPABILITY          vmx_proc_ctls2;
-            VMX_CAPABILITY          vmx_exit;
-            VMX_CAPABILITY          vmx_entry;
-            uint64_t                vmx_misc;
-            uint64_t                vmx_cr0_fixed0;
-            uint64_t                vmx_cr0_fixed1;
-            uint64_t                vmx_cr4_fixed0;
-            uint64_t                vmx_cr4_fixed1;
-            uint64_t                vmx_vmcs_enum;
-            uint64_t                vmx_eptcaps;
-        } msr;
-
-        /** Flush types for invept & invvpid; they depend on capabilities. */
-        VMX_FLUSH_EPT               enmFlushEPT;
-        VMX_FLUSH_VPID              enmFlushVPID;
-    } vmx;
-
-    struct
-    {
-        /** Set by the ring-0 side of HWACCM to indicate SVM is supported by the
-         *  CPU. */
-        bool                        fSupported;
-        /** Set when we've enabled SVM. */
-        bool                        fEnabled;
-        /** Set if erratum 170 affects the AMD cpu. */
-        bool                        fAlwaysFlushTLB;
-        /** Set when the hack to ignore VERR_SVM_IN_USE is active. */
-        bool                        fIgnoreInUseError;
-
-        /** R0 memory object for the IO bitmap (12kb). */
-        RTR0MEMOBJ                  pMemObjIOBitmap;
-        /** Physical address of the IO bitmap (12kb). */
-        RTHCPHYS                    pIOBitmapPhys;
-        /** Virtual address of the IO bitmap. */
-        R0PTRTYPE(void *)           pIOBitmap;
-
-        /* HWCR msr (for diagnostics) */
-        uint64_t                    msrHWCR;
-
-        /** SVM revision. */
-        uint32_t                    u32Rev;
-
-        /** SVM feature bits from cpuid 0x8000000a */
-        uint32_t                    u32Features;
-    } svm;
-
-    /**
-     * AVL tree with all patches (active or disabled) sorted by guest instruction address
-     */
-    AVLOU32TREE                     PatchTree;
-    uint32_t                        cPatches;
-    HWACCMTPRPATCH                  aPatches[64];
-
-    struct
-    {
-        uint32_t                    u32AMDFeatureECX;
-        uint32_t                    u32AMDFeatureEDX;
-    } cpuid;
-
-    /** Saved error from detection */
-    int32_t                 lLastError;
-
-    /** HWACCMR0Init was run */
-    bool                    fHWACCMR0Init;
-    bool                    u8Alignment1[7];
-
-    STAMCOUNTER             StatTPRPatchSuccess;
-    STAMCOUNTER             StatTPRPatchFailure;
-    STAMCOUNTER             StatTPRReplaceSuccess;
-    STAMCOUNTER             StatTPRReplaceFailure;
-} HWACCM;
-/** Pointer to HWACCM VM instance data. */
-typedef HWACCM *PHWACCM;
-
-/* Maximum number of cached entries. */
-#define VMCSCACHE_MAX_ENTRY                             128
-
-/* Structure for storing read and write VMCS actions. */
-typedef struct VMCSCACHE
-{
-#ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    /* Magic marker for searching in crash dumps. */
-    uint8_t         aMagic[16];
-    uint64_t        uMagic;
-    uint64_t        u64TimeEntry;
-    uint64_t        u64TimeSwitch;
-    uint64_t        cResume;
-    uint64_t        interPD;
-    uint64_t        pSwitcher;
-    uint32_t        uPos;
-    uint32_t        idCpu;
-#endif
-    /* CR2 is saved here for EPT syncing. */
-    uint64_t        cr2;
-    struct
-    {
-        uint32_t    cValidEntries;
-        uint32_t    uAlignment;
-        uint32_t    aField[VMCSCACHE_MAX_ENTRY];
-        uint64_t    aFieldVal[VMCSCACHE_MAX_ENTRY];
-    } Write;
-    struct
-    {
-        uint32_t    cValidEntries;
-        uint32_t    uAlignment;
-        uint32_t    aField[VMCSCACHE_MAX_ENTRY];
-        uint64_t    aFieldVal[VMCSCACHE_MAX_ENTRY];
-    } Read;
-#ifdef DEBUG
-    struct
-    {
-        RTHCPHYS    HCPhysCpuPage;
-        RTHCPHYS    HCPhysVMCS;
-        RTGCPTR     pCache;
-        RTGCPTR     pCtx;
-    } TestIn;
-    struct
-    {
-        RTHCPHYS    HCPhysVMCS;
-        RTGCPTR     pCache;
-        RTGCPTR     pCtx;
-        uint64_t    eflags;
-        uint64_t    cr8;
-    } TestOut;
-    struct
-    {
-        uint64_t    param1;
-        uint64_t    param2;
-        uint64_t    param3;
-        uint64_t    param4;
-    } ScratchPad;
-#endif
-} VMCSCACHE;
-/** Pointer to VMCSCACHE. */
-typedef VMCSCACHE *PVMCSCACHE;
-
-/** VMX StartVM function. */
-typedef DECLCALLBACK(int) FNHWACCMVMXSTARTVM(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu);
-/** Pointer to a VMX StartVM function. */
-typedef R0PTRTYPE(FNHWACCMVMXSTARTVM *) PFNHWACCMVMXSTARTVM;
-
-/** SVM VMRun function. */
-typedef DECLCALLBACK(int) FNHWACCMSVMVMRUN(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu);
-/** Pointer to a SVM VMRun function. */
-typedef R0PTRTYPE(FNHWACCMSVMVMRUN *) PFNHWACCMSVMVMRUN;
-
-/**
- * HWACCM VMCPU Instance data.
- */
-typedef struct HWACCMCPU
-{
-    /** Old style FPU reporting trap mask override performed (optimization) */
-    bool                        fFPUOldStyleOverride;
-
-    /** Set if we don't have to flush the TLB on VM entry. */
-    bool                        fResumeVM;
-
-    /** Set if we need to flush the TLB during the world switch. */
-    bool                        fForceTLBFlush;
-
-    /** Set when we're using VT-x or AMD-V at that moment. */
-    bool                        fActive;
-
-    /** Set when the TLB has been checked until we return from the world switch. */
-    volatile bool               fCheckedTLBFlush;
-    uint8_t                     bAlignment[3];
-
-    /** World switch exit counter. */
-    volatile uint32_t           cWorldSwitchExits;
-
-    /** HWACCM_CHANGED_* flags. */
-    uint32_t                    fContextUseFlags;
-
-    /** Id of the last cpu we were executing code on (NIL_RTCPUID for the first time) */
-    RTCPUID                     idLastCpu;
-
-    /** TLB flush count */
-    uint32_t                    cTLBFlushes;
-
-    /** Current ASID in use by the VM */
-    uint32_t                    uCurrentASID;
-
-    uint32_t                    u32Alignment;
-
-    /* Host's TSC_AUX MSR (used when RDTSCP doesn't cause VM-exits). */
-    uint64_t                    u64HostTSCAux;
-
-    struct
-    {
-        /** Physical address of the VM control structure (VMCS). */
-        RTHCPHYS                    HCPhysVMCS;
-        /** R0 memory object for the VM control structure (VMCS). */
-        RTR0MEMOBJ                  hMemObjVMCS;
-        /** Virtual address of the VM control structure (VMCS). */
-        R0PTRTYPE(void *)           pvVMCS;
-
-        /** Ring 0 handlers for VT-x. */
-        PFNHWACCMVMXSTARTVM         pfnStartVM;
-
-#if HC_ARCH_BITS == 32
-        uint32_t                    u32Alignment;
-#endif
-
-        /** Current VMX_VMCS_CTRL_PROC_EXEC_CONTROLS. */
-        uint64_t                    proc_ctls;
-
-        /** Current VMX_VMCS_CTRL_PROC_EXEC2_CONTROLS. */
-        uint64_t                    proc_ctls2;
-
-        /** Physical address of the virtual APIC page for TPR caching. */
-        RTHCPHYS                    HCPhysVAPIC;
-        /** R0 memory object for the virtual APIC page for TPR caching. */
-        RTR0MEMOBJ                  hMemObjVAPIC;
-        /** Virtual address of the virtual APIC page for TPR caching. */
-        R0PTRTYPE(uint8_t *)        pbVAPIC;
-
-        /** Current CR0 mask. */
-        uint64_t                    cr0_mask;
-        /** Current CR4 mask. */
-        uint64_t                    cr4_mask;
-
-        /** Current EPTP. */
-        RTHCPHYS                    GCPhysEPTP;
-
-        /** Physical address of the MSR bitmap (1 page). */
-        RTHCPHYS                    pMSRBitmapPhys;
-        /** R0 memory object for the MSR bitmap (1 page). */
-        RTR0MEMOBJ                  pMemObjMSRBitmap;
-        /** Virtual address of the MSR bitmap (1 page). */
-        R0PTRTYPE(uint8_t *)        pMSRBitmap;
-
-#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
-        /** Physical address of the guest MSR load area (1 page). */
-        RTHCPHYS                    pGuestMSRPhys;
-        /** R0 memory object for the guest MSR load area (1 page). */
-        RTR0MEMOBJ                  pMemObjGuestMSR;
-        /** Virtual address of the guest MSR load area (1 page). */
-        R0PTRTYPE(uint8_t *)        pGuestMSR;
-
-        /** Physical address of the MSR load area (1 page). */
-        RTHCPHYS                    pHostMSRPhys;
-        /** R0 memory object for the MSR load area (1 page). */
-        RTR0MEMOBJ                  pMemObjHostMSR;
-        /** Virtual address of the MSR load area (1 page). */
-        R0PTRTYPE(uint8_t *)        pHostMSR;
-
-        /* Number of automatically loaded/restored guest MSRs during the world switch. */
-        uint32_t                    cCachedMSRs;
-        uint32_t                    uAlignment;
-#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
-
-        /* Last use TSC offset value. (cached) */
-        uint64_t                    u64TSCOffset;
-
-        /** VMCS cache. */
-        VMCSCACHE                   VMCSCache;
-
-        /** Real-mode emulation state. */
-        struct
-        {
-            X86EFLAGS                   eflags;
-            uint32_t                    fValid;
-        } RealMode;
-
-        struct
-        {
-            uint64_t                u64VMCSPhys;
-            uint32_t                ulVMCSRevision;
-            uint32_t                ulInstrError;
-            uint32_t                ulExitReason;
-            RTCPUID                 idEnteredCpu;
-            RTCPUID                 idCurrentCpu;
-            uint32_t                padding;
-        } lasterror;
-
-        /** The last seen guest paging mode (by VT-x). */
-        PGMMODE                     enmLastSeenGuestMode;
-        /** Current guest paging mode (as seen by HWACCMR3PagingModeChanged). */
-        PGMMODE                     enmCurrGuestMode;
-        /** Previous guest paging mode (as seen by HWACCMR3PagingModeChanged). */
-        PGMMODE                     enmPrevGuestMode;
-    } vmx;
-
-    struct
-    {
-        /** R0 memory object for the host VM control block (VMCB). */
-        RTR0MEMOBJ                  pMemObjVMCBHost;
-        /** Physical address of the host VM control block (VMCB). */
-        RTHCPHYS                    pVMCBHostPhys;
-        /** Virtual address of the host VM control block (VMCB). */
-        R0PTRTYPE(void *)           pVMCBHost;
-
-        /** R0 memory object for the VM control block (VMCB). */
-        RTR0MEMOBJ                  pMemObjVMCB;
-        /** Physical address of the VM control block (VMCB). */
-        RTHCPHYS                    pVMCBPhys;
-        /** Virtual address of the VM control block (VMCB). */
-        R0PTRTYPE(void *)           pVMCB;
-
-        /** Ring 0 handlers for VT-x. */
-        PFNHWACCMSVMVMRUN           pfnVMRun;
-
-        /** R0 memory object for the MSR bitmap (8kb). */
-        RTR0MEMOBJ                  pMemObjMSRBitmap;
-        /** Physical address of the MSR bitmap (8kb). */
-        RTHCPHYS                    pMSRBitmapPhys;
-        /** Virtual address of the MSR bitmap. */
-        R0PTRTYPE(void *)           pMSRBitmap;
-    } svm;
-
-    /** Event injection state. */
-    struct
-    {
-        uint32_t                    fPending;
-        uint32_t                    errCode;
-        uint64_t                    intInfo;
-    } Event;
-
-    /** IO Block emulation state. */
-    struct
-    {
-        bool                    fEnabled;
-        uint8_t                 u8Align[7];
-
-        /** RIP at the start of the io code we wish to emulate in the recompiler. */
-        RTGCPTR                 GCPtrFunctionEip;
-
-        uint64_t                cr0;
-    } EmulateIoBlock;
-
-    struct
-    {
-        /* Pending IO operation type. */
-        HWACCMPENDINGIO         enmType;
-        uint32_t                uPadding;
-        RTGCPTR                 GCPtrRip;
-        RTGCPTR                 GCPtrRipNext;
-        union
-        {
-            struct
-            {
-                unsigned        uPort;
-                unsigned        uAndVal;
-                unsigned        cbSize;
-            } Port;
-            uint64_t            aRaw[2];
-        } s;
-    } PendingIO;
-
-    /** Currently shadow paging mode. */
-    PGMMODE                 enmShadowMode;
-
-    /** The CPU ID of the CPU currently owning the VMCS. Set in
-     * HWACCMR0Enter and cleared in HWACCMR0Leave. */
-    RTCPUID                 idEnteredCpu;
-
-    /** To keep track of pending TLB shootdown pages. (SMP guest only) */
-    struct
-    {
-        RTGCPTR             aPages[HWACCM_MAX_TLB_SHOOTDOWN_PAGES];
-        unsigned            cPages;
-    } TlbShootdown;
-
-    /** For saving stack space, the disassembler state is allocated here instead of
-     * on the stack. */
-    DISCPUSTATE             DisState;
-
-    uint32_t                padding2[1];
-
-    STAMPROFILEADV          StatEntry;
-    STAMPROFILEADV          StatExit1;
-    STAMPROFILEADV          StatExit2;
-#if 1 /* temporary for tracking down darwin issues. */
-    STAMPROFILEADV          StatExit2Sub1;
-    STAMPROFILEADV          StatExit2Sub2;
-    STAMPROFILEADV          StatExit2Sub3;
-#endif
-    STAMPROFILEADV          StatInGC;
-
-#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
-    STAMPROFILEADV          StatWorldSwitch3264;
-#endif
-    STAMPROFILEADV          StatPoke;
-    STAMPROFILEADV          StatSpinPoke;
-    STAMPROFILEADV          StatSpinPokeFailed;
-
-    STAMCOUNTER             StatIntInject;
-
-    STAMCOUNTER             StatExitShadowNM;
-    STAMCOUNTER             StatExitGuestNM;
-    STAMCOUNTER             StatExitShadowPF;
-    STAMCOUNTER             StatExitShadowPFEM;
-    STAMCOUNTER             StatExitGuestPF;
-    STAMCOUNTER             StatExitGuestUD;
-    STAMCOUNTER             StatExitGuestSS;
-    STAMCOUNTER             StatExitGuestNP;
-    STAMCOUNTER             StatExitGuestGP;
-    STAMCOUNTER             StatExitGuestDE;
-    STAMCOUNTER             StatExitGuestDB;
-    STAMCOUNTER             StatExitGuestMF;
-    STAMCOUNTER             StatExitGuestBP;
-    STAMCOUNTER             StatExitGuestXF;
-    STAMCOUNTER             StatExitGuestXcpUnk;
-    STAMCOUNTER             StatExitInvlpg;
-    STAMCOUNTER             StatExitInvd;
-    STAMCOUNTER             StatExitCpuid;
-    STAMCOUNTER             StatExitRdtsc;
-    STAMCOUNTER             StatExitRdtscp;
-    STAMCOUNTER             StatExitRdpmc;
-    STAMCOUNTER             StatExitCli;
-    STAMCOUNTER             StatExitSti;
-    STAMCOUNTER             StatExitPushf;
-    STAMCOUNTER             StatExitPopf;
-    STAMCOUNTER             StatExitIret;
-    STAMCOUNTER             StatExitInt;
-    STAMCOUNTER             StatExitCRxWrite[16];
-    STAMCOUNTER             StatExitCRxRead[16];
-    STAMCOUNTER             StatExitDRxWrite;
-    STAMCOUNTER             StatExitDRxRead;
-    STAMCOUNTER             StatExitRdmsr;
-    STAMCOUNTER             StatExitWrmsr;
-    STAMCOUNTER             StatExitCLTS;
-    STAMCOUNTER             StatExitHlt;
-    STAMCOUNTER             StatExitMwait;
-    STAMCOUNTER             StatExitMonitor;
-    STAMCOUNTER             StatExitLMSW;
-    STAMCOUNTER             StatExitIOWrite;
-    STAMCOUNTER             StatExitIORead;
-    STAMCOUNTER             StatExitIOStringWrite;
-    STAMCOUNTER             StatExitIOStringRead;
-    STAMCOUNTER             StatExitIrqWindow;
-    STAMCOUNTER             StatExitMaxResume;
-    STAMCOUNTER             StatExitPreemptPending;
-    STAMCOUNTER             StatExitMTF;
-    STAMCOUNTER             StatIntReinject;
-    STAMCOUNTER             StatPendingHostIrq;
-
-    STAMCOUNTER             StatFlushPage;
-    STAMCOUNTER             StatFlushPageManual;
-    STAMCOUNTER             StatFlushPhysPageManual;
-    STAMCOUNTER             StatFlushTLB;
-    STAMCOUNTER             StatFlushTLBManual;
-    STAMCOUNTER             StatFlushPageInvlpg;
-    STAMCOUNTER             StatFlushTLBWorldSwitch;
-    STAMCOUNTER             StatNoFlushTLBWorldSwitch;
-    STAMCOUNTER             StatFlushTLBCRxChange;
-    STAMCOUNTER             StatFlushASID;
-    STAMCOUNTER             StatFlushTLBInvlpga;
-    STAMCOUNTER             StatTlbShootdown;
-    STAMCOUNTER             StatTlbShootdownFlush;
-
-    STAMCOUNTER             StatSwitchGuestIrq;
-    STAMCOUNTER             StatSwitchToR3;
-
-    STAMCOUNTER             StatTSCOffset;
-    STAMCOUNTER             StatTSCIntercept;
-    STAMCOUNTER             StatTSCInterceptOverFlow;
-
-    STAMCOUNTER             StatExitReasonNPF;
-    STAMCOUNTER             StatDRxArmed;
-    STAMCOUNTER             StatDRxContextSwitch;
-    STAMCOUNTER             StatDRxIOCheck;
-
-    STAMCOUNTER             StatLoadMinimal;
-    STAMCOUNTER             StatLoadFull;
-
-#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
-    STAMCOUNTER             StatFpu64SwitchBack;
-    STAMCOUNTER             StatDebug64SwitchBack;
-#endif
-
-#ifdef VBOX_WITH_STATISTICS
-    R3PTRTYPE(PSTAMCOUNTER) paStatExitReason;
-    R0PTRTYPE(PSTAMCOUNTER) paStatExitReasonR0;
-    R3PTRTYPE(PSTAMCOUNTER) paStatInjectedIrqs;
-    R0PTRTYPE(PSTAMCOUNTER) paStatInjectedIrqsR0;
-#endif
-} HWACCMCPU;
-/** Pointer to HWACCM VM instance data. */
-typedef HWACCMCPU *PHWACCMCPU;
-
-
-#ifdef IN_RING0
-
-VMMR0DECL(PHMGLOBLCPUINFO) HWACCMR0GetCurrentCpu(void);
-VMMR0DECL(PHMGLOBLCPUINFO) HWACCMR0GetCurrentCpuEx(RTCPUID idCpu);
-
-
-#ifdef VBOX_STRICT
-VMMR0DECL(void) HWACCMDumpRegs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
-VMMR0DECL(void) HWACCMR0DumpDescriptor(PCX86DESCHC pDesc, RTSEL Sel, const char *pszMsg);
-#else
-# define HWACCMDumpRegs(a, b ,c)            do { } while (0)
-# define HWACCMR0DumpDescriptor(a, b, c)    do { } while (0)
-#endif
-
-# ifdef VBOX_WITH_KERNEL_USING_XMM
-DECLASM(int)   hwaccmR0VMXStartVMWrapXMM(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu, PFNHWACCMVMXSTARTVM pfnStartVM);
-DECLASM(int)   hwaccmR0SVMRunWrapXMM(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu, PFNHWACCMSVMVMRUN pfnVMRun);
-# endif
-
-# ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
-/**
- * Gets 64-bit GDTR and IDTR on darwin.
- * @param  pGdtr        Where to store the 64-bit GDTR.
- * @param  pIdtr        Where to store the 64-bit IDTR.
- */
-DECLASM(void) hwaccmR0Get64bitGDTRandIDTR(PX86XDTR64 pGdtr, PX86XDTR64 pIdtr);
-
-/**
- * Gets 64-bit CR3 on darwin.
- * @returns CR3
- */
-DECLASM(uint64_t) hwaccmR0Get64bitCR3(void);
-# endif
-
-#endif /* IN_RING0 */
-
-/** @} */
-
-RT_C_DECLS_END
-
-#endif
-
Index: trunk/src/VBox/VMM/include/HWACCMInternal.mac
===================================================================
--- trunk/src/VBox/VMM/include/HWACCMInternal.mac	(revision 43379)
+++ 	(revision )
@@ -1,61 +1,0 @@
-;$Id$
-;; @file
-; HWACCM - Internal header file.
-;
-;
-; Copyright (C) 2006-2007 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.
-;
-
-%define VMX_USE_CACHED_VMCS_ACCESSES
-%define VBOX_WITH_AUTO_MSR_LOAD_RESTORE
-
-;Maximum number of cached entries.
-%define VMCSCACHE_MAX_ENTRY                             128
-
-; Structure for storing read and write VMCS actions.
-struc VMCSCACHE
-%ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    .aMagic                   resb    16
-    .uMagic                   resq    1
-    .u64TimeEntry             resq    1
-    .u64TimeSwitch            resq    1
-    .cResume                  resq    1
-    .interPD                  resq    1
-    .pSwitcher                resq    1
-    .uPos                     resd    1
-    .idCpu                    resd    1
-%endif
-    .cr2                      resq    1
-    .Write.cValidEntries      resd    1
-    .Write.uAlignment         resd    1
-    .Write.aField             resd    VMCSCACHE_MAX_ENTRY
-    .Write.aFieldVal          resq    VMCSCACHE_MAX_ENTRY
-    .Read.cValidEntries       resd    1
-    .Read.uAlignment          resd    1
-    .Read.aField              resd    VMCSCACHE_MAX_ENTRY
-    .Read.aFieldVal           resq    VMCSCACHE_MAX_ENTRY
-%ifdef DEBUG
-    .TestIn.HCPhysCpuPage     resq    1
-    .TestIn.HCPhysVMCS        resq    1
-    .TestIn.pCache            resq    1
-    .TestIn.pCtx              resq    1
-    .TestOut.HCPhysVMCS       resq    1
-    .TestOut.pCache           resq    1
-    .TestOut.pCtx             resq    1
-    .TestOut.eflags           resq    1
-    .TestOut.cr8              resq    1
-    .ScratchPad.param1        resq    1
-    .ScratchPad.param2        resq    1
-    .ScratchPad.param3        resq    1
-    .ScratchPad.param4        resq    1
-%endif
-endstruc
-
Index: trunk/src/VBox/VMM/include/PGMInline.h
===================================================================
--- trunk/src/VBox/VMM/include/PGMInline.h	(revision 43379)
+++ trunk/src/VBox/VMM/include/PGMInline.h	(revision 43387)
@@ -32,5 +32,5 @@
 #include <VBox/log.h>
 #include <VBox/vmm/gmm.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
 #include <iprt/asm.h>
 #include <iprt/assert.h>
Index: trunk/src/VBox/VMM/include/PGMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/PGMInternal.h	(revision 43379)
+++ trunk/src/VBox/VMM/include/PGMInternal.h	(revision 43387)
@@ -33,6 +33,6 @@
 #include <VBox/log.h>
 #include <VBox/vmm/gmm.h>
-#include <VBox/vmm/hwaccm.h>
-#include <VBox/vmm/hwacc_vmx.h>
+#include <VBox/vmm/hm.h>
+#include <VBox/vmm/hm_vmx.h>
 #include "internal/pgm.h"
 #include <iprt/asm.h>
@@ -348,7 +348,7 @@
 # define PGM_INVL_PG(pVCpu, GCVirt)             ASMInvalidatePage((void *)(uintptr_t)(GCVirt))
 #elif defined(IN_RING0)
-# define PGM_INVL_PG(pVCpu, GCVirt)             HWACCMInvalidatePage(pVCpu, (RTGCPTR)(GCVirt))
+# define PGM_INVL_PG(pVCpu, GCVirt)             HMInvalidatePage(pVCpu, (RTGCPTR)(GCVirt))
 #else
-# define PGM_INVL_PG(pVCpu, GCVirt)             HWACCMInvalidatePage(pVCpu, (RTGCPTR)(GCVirt))
+# define PGM_INVL_PG(pVCpu, GCVirt)             HMInvalidatePage(pVCpu, (RTGCPTR)(GCVirt))
 #endif
 
@@ -362,7 +362,7 @@
 # define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt)      ASMInvalidatePage((void *)(uintptr_t)(GCVirt))
 #elif defined(IN_RING0)
-# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt)      HWACCMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
+# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt)      HMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
 #else
-# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt)      HWACCMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
+# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt)      HMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
 #endif
 
@@ -376,7 +376,7 @@
 # define PGM_INVL_BIG_PG(pVCpu, GCVirt)         ASMReloadCR3()
 #elif defined(IN_RING0)
-# define PGM_INVL_BIG_PG(pVCpu, GCVirt)         HWACCMFlushTLB(pVCpu)
+# define PGM_INVL_BIG_PG(pVCpu, GCVirt)         HMFlushTLB(pVCpu)
 #else
-# define PGM_INVL_BIG_PG(pVCpu, GCVirt)         HWACCMFlushTLB(pVCpu)
+# define PGM_INVL_BIG_PG(pVCpu, GCVirt)         HMFlushTLB(pVCpu)
 #endif
 
@@ -389,7 +389,7 @@
 # define PGM_INVL_VCPU_TLBS(pVCpu)             ASMReloadCR3()
 #elif defined(IN_RING0)
-# define PGM_INVL_VCPU_TLBS(pVCpu)             HWACCMFlushTLB(pVCpu)
+# define PGM_INVL_VCPU_TLBS(pVCpu)             HMFlushTLB(pVCpu)
 #else
-# define PGM_INVL_VCPU_TLBS(pVCpu)             HWACCMFlushTLB(pVCpu)
+# define PGM_INVL_VCPU_TLBS(pVCpu)             HMFlushTLB(pVCpu)
 #endif
 
@@ -402,7 +402,7 @@
 # define PGM_INVL_ALL_VCPU_TLBS(pVM)            ASMReloadCR3()
 #elif defined(IN_RING0)
-# define PGM_INVL_ALL_VCPU_TLBS(pVM)            HWACCMFlushTLBOnAllVCpus(pVM)
+# define PGM_INVL_ALL_VCPU_TLBS(pVM)            HMFlushTLBOnAllVCpus(pVM)
 #else
-# define PGM_INVL_ALL_VCPU_TLBS(pVM)            HWACCMFlushTLBOnAllVCpus(pVM)
+# define PGM_INVL_ALL_VCPU_TLBS(pVM)            HMFlushTLBOnAllVCpus(pVM)
 #endif
 
@@ -3024,5 +3024,5 @@
     bool                            fLessThan52PhysicalAddressBits;
     /** Set when nested paging is active.
-     * This is meant to save calls to HWACCMIsNestedPagingActive and let the
+     * This is meant to save calls to HMIsNestedPagingActive and let the
      * compilers optimize the code better.  Whether we use nested paging or
      * not is something we find out during VMM initialization and we won't
Index: trunk/src/VBox/VMM/include/VMMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/VMMInternal.h	(revision 43379)
+++ trunk/src/VBox/VMM/include/VMMInternal.h	(revision 43387)
@@ -507,5 +507,5 @@
     VMMGC_DO_TESTCASE_INTERRUPT_MASKING,
     /** Switching testing and profiling stub. */
-    VMMGC_DO_TESTCASE_HWACCM_NOP,
+    VMMGC_DO_TESTCASE_HM_NOP,
 
     /** The usual 32-bit hack. */
Index: trunk/src/VBox/VMM/testcase/Makefile.kmk
===================================================================
--- trunk/src/VBox/VMM/testcase/Makefile.kmk	(revision 43379)
+++ trunk/src/VBox/VMM/testcase/Makefile.kmk	(revision 43387)
@@ -36,5 +36,5 @@
  PROGRAMS  += tstGlobalConfig tstInstrEmul
  ifdef VBOX_WITH_RAW_MODE
-  PROGRAMS  += tstVMM tstVMM-HwAccm
+  PROGRAMS  += tstVMM tstVMM-HM
   ifneq ($(KBUILD_TARGET),win)
    PROGRAMS += tstVMMFork
@@ -256,7 +256,7 @@
  tstVMM_LIBS            = $(LIB_VMM) $(LIB_REM) $(LIB_RUNTIME)
 
- tstVMM-HwAccm_TEMPLATE = VBOXR3EXE
- tstVMM-HwAccm_SOURCES  = tstVMM-HwAccm.cpp
- tstVMM-HwAccm_LIBS     = $(LIB_VMM) $(LIB_REM) $(LIB_RUNTIME)
+ tstVMM-HM_TEMPLATE     = VBOXR3EXE
+ tstVMM-HM_SOURCES      = tstVMM-HM.cpp
+ tstVMM-HM_LIBS         = $(LIB_VMM) $(LIB_REM) $(LIB_RUNTIME)
 
  tstVMMFork_TEMPLATE    = VBOXR3EXE
@@ -396,5 +396,5 @@
 		$(VBOX_PATH_VMM_SRC)/include/CPUMInternal.mac \
 		$(VBOX_PATH_VMM_SRC)/include/TRPMInternal.mac \
-		$(VBOX_PATH_VMM_SRC)/include/HWACCMInternal.mac \
+		$(VBOX_PATH_VMM_SRC)/include/HMInternal.mac \
 		$(VBOX_PATH_VMM_SRC)/include/VMMInternal.mac \
 		$(VBOX_PATH_VMM_SRC)/testcase/Makefile.kmk \
@@ -423,5 +423,5 @@
 		$(DEPTH)/include/iprt/x86.mac \
 		$(VBOX_PATH_VMM_SRC)/include/CPUMInternal.mac \
-		$(VBOX_PATH_VMM_SRC)/include/HWACCMInternal.mac \
+		$(VBOX_PATH_VMM_SRC)/include/HMInternal.mac \
 		$(VBOX_PATH_VMM_SRC)/include/VMMInternal.mac \
 		$(VBOX_PATH_VMM_SRC)/include/VMMSwitcher.mac \
Index: trunk/src/VBox/VMM/testcase/tstAsmStructs.cpp
===================================================================
--- trunk/src/VBox/VMM/testcase/tstAsmStructs.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/testcase/tstAsmStructs.cpp	(revision 43387)
@@ -23,5 +23,5 @@
 #include <VBox/vmm/trpm.h>
 #include "TRPMInternal.h"
-#include "HWACCMInternal.h"
+#include "HMInternal.h"
 #include "VMMSwitcher.h"
 #include "VMMInternal.h"
Index: trunk/src/VBox/VMM/testcase/tstAsmStructsAsm.asm
===================================================================
--- trunk/src/VBox/VMM/testcase/tstAsmStructsAsm.asm	(revision 43379)
+++ trunk/src/VBox/VMM/testcase/tstAsmStructsAsm.asm	(revision 43387)
@@ -24,5 +24,5 @@
 
 %include "CPUMInternal.mac"
-%include "HWACCMInternal.mac"
+%include "HMInternal.mac"
 %include "TRPMInternal.mac"
 %include "VMMInternal.mac"
Index: trunk/src/VBox/VMM/testcase/tstVMM-HM.cpp
===================================================================
--- trunk/src/VBox/VMM/testcase/tstVMM-HM.cpp	(revision 43387)
+++ trunk/src/VBox/VMM/testcase/tstVMM-HM.cpp	(revision 43387)
@@ -0,0 +1,115 @@
+/* $Id$ */
+/** @file
+ * VMM Testcase.
+ */
+
+/*
+ * Copyright (C) 2006-2007 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.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <VBox/vmm/vm.h>
+#include <VBox/vmm/vmm.h>
+#include <VBox/vmm/cpum.h>
+#include <VBox/err.h>
+#include <VBox/log.h>
+#include <iprt/assert.h>
+#include <iprt/initterm.h>
+#include <iprt/semaphore.h>
+#include <iprt/stream.h>
+
+
+/*******************************************************************************
+*   Defined Constants And Macros                                               *
+*******************************************************************************/
+#define TESTCASE    "tstVMM-HwAccm"
+
+VMMR3DECL(int) VMMDoHwAccmTest(PVM pVM);
+
+
+static DECLCALLBACK(int) CFGMConstructor(PVM pVM, void *pvUser)
+{
+    NOREF(pvUser);
+
+    /*
+     * Get root node first.
+     * This is the only node in the tree.
+     */
+    PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
+    int rc = CFGMR3InsertInteger(pRoot, "RamSize", 32*1024*1024);
+    AssertRC(rc);
+
+    /* rc = CFGMR3InsertInteger(pRoot, "EnableNestedPaging", false);
+    AssertRC(rc); */
+
+    PCFGMNODE pHWVirtExt;
+    rc = CFGMR3InsertNode(pRoot, "HWVirtExt", &pHWVirtExt);
+    AssertRC(rc);
+    rc = CFGMR3InsertInteger(pHWVirtExt, "Enabled", 1);
+    AssertRC(rc);
+
+    return VINF_SUCCESS;
+}
+
+int main(int argc, char **argv)
+{
+    int     rcRet = 0;                  /* error count. */
+
+    RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
+
+    /*
+     * Doesn't work and I'm sick of rebooting the machine to try figure out
+     * what the heck is going wrong. (Linux sucks at this)
+     */
+    RTPrintf(TESTCASE ": This testcase hits a bunch of breakpoint assertions which\n"
+             TESTCASE ": causes kernel panics on linux regardless of what\n"
+             TESTCASE ": RTAssertDoBreakpoint returns. Only checked AMD-V on linux.\n");
+    /** @todo Make tstVMM-HwAccm to cause kernel panics. */
+    return 1;
+
+    /*
+     * Create empty VM.
+     */
+    RTPrintf(TESTCASE ": Initializing...\n");
+    PVM pVM;
+    int rc = VMR3Create(1, NULL, NULL, NULL, CFGMConstructor, NULL, &pVM);
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Do testing.
+         */
+        RTPrintf(TESTCASE ": Testing...\n");
+        rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)VMMDoHwAccmTest, 1, pVM);
+        AssertRC(rc);
+
+        STAMR3Dump(pVM, "*");
+
+        /*
+         * Cleanup.
+         */
+        rc = VMR3Destroy(pVM);
+        if (RT_FAILURE(rc))
+        {
+            RTPrintf(TESTCASE ": error: failed to destroy vm! rc=%d\n", rc);
+            rcRet++;
+        }
+    }
+    else
+    {
+        RTPrintf(TESTCASE ": fatal error: failed to create vm! rc=%d\n", rc);
+        rcRet++;
+    }
+
+    return rcRet;
+}
Index: trunk/src/VBox/VMM/testcase/tstVMM-HwAccm.cpp
===================================================================
--- trunk/src/VBox/VMM/testcase/tstVMM-HwAccm.cpp	(revision 43379)
+++ 	(revision )
@@ -1,115 +1,0 @@
-/* $Id$ */
-/** @file
- * VMM Testcase.
- */
-
-/*
- * Copyright (C) 2006-2007 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.
- */
-
-
-/*******************************************************************************
-*   Header Files                                                               *
-*******************************************************************************/
-#include <VBox/vmm/vm.h>
-#include <VBox/vmm/vmm.h>
-#include <VBox/vmm/cpum.h>
-#include <VBox/err.h>
-#include <VBox/log.h>
-#include <iprt/assert.h>
-#include <iprt/initterm.h>
-#include <iprt/semaphore.h>
-#include <iprt/stream.h>
-
-
-/*******************************************************************************
-*   Defined Constants And Macros                                               *
-*******************************************************************************/
-#define TESTCASE    "tstVMM-HwAccm"
-
-VMMR3DECL(int) VMMDoHwAccmTest(PVM pVM);
-
-
-static DECLCALLBACK(int) CFGMConstructor(PVM pVM, void *pvUser)
-{
-    NOREF(pvUser);
-
-    /*
-     * Get root node first.
-     * This is the only node in the tree.
-     */
-    PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
-    int rc = CFGMR3InsertInteger(pRoot, "RamSize", 32*1024*1024);
-    AssertRC(rc);
-
-    /* rc = CFGMR3InsertInteger(pRoot, "EnableNestedPaging", false);
-    AssertRC(rc); */
-
-    PCFGMNODE pHWVirtExt;
-    rc = CFGMR3InsertNode(pRoot, "HWVirtExt", &pHWVirtExt);
-    AssertRC(rc);
-    rc = CFGMR3InsertInteger(pHWVirtExt, "Enabled", 1);
-    AssertRC(rc);
-
-    return VINF_SUCCESS;
-}
-
-int main(int argc, char **argv)
-{
-    int     rcRet = 0;                  /* error count. */
-
-    RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
-
-    /*
-     * Doesn't work and I'm sick of rebooting the machine to try figure out
-     * what the heck is going wrong. (Linux sucks at this)
-     */
-    RTPrintf(TESTCASE ": This testcase hits a bunch of breakpoint assertions which\n"
-             TESTCASE ": causes kernel panics on linux regardless of what\n"
-             TESTCASE ": RTAssertDoBreakpoint returns. Only checked AMD-V on linux.\n");
-    /** @todo Make tstVMM-HwAccm to cause kernel panics. */
-    return 1;
-
-    /*
-     * Create empty VM.
-     */
-    RTPrintf(TESTCASE ": Initializing...\n");
-    PVM pVM;
-    int rc = VMR3Create(1, NULL, NULL, NULL, CFGMConstructor, NULL, &pVM);
-    if (RT_SUCCESS(rc))
-    {
-        /*
-         * Do testing.
-         */
-        RTPrintf(TESTCASE ": Testing...\n");
-        rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)VMMDoHwAccmTest, 1, pVM);
-        AssertRC(rc);
-
-        STAMR3Dump(pVM, "*");
-
-        /*
-         * Cleanup.
-         */
-        rc = VMR3Destroy(pVM);
-        if (RT_FAILURE(rc))
-        {
-            RTPrintf(TESTCASE ": error: failed to destroy vm! rc=%d\n", rc);
-            rcRet++;
-        }
-    }
-    else
-    {
-        RTPrintf(TESTCASE ": fatal error: failed to create vm! rc=%d\n", rc);
-        rcRet++;
-    }
-
-    return rcRet;
-}
Index: trunk/src/VBox/VMM/testcase/tstVMStruct.h
===================================================================
--- trunk/src/VBox/VMM/testcase/tstVMStruct.h	(revision 43379)
+++ trunk/src/VBox/VMM/testcase/tstVMStruct.h	(revision 43387)
@@ -1329,5 +1329,5 @@
     GEN_CHECK_OFF(VM, fPATMEnabled);
     GEN_CHECK_OFF(VM, fCSAMEnabled);
-    GEN_CHECK_OFF(VM, fHWACCMEnabled);
+    GEN_CHECK_OFF(VM, fHMEnabled);
     GEN_CHECK_OFF(VM, fHwVirtExtForced);
     GEN_CHECK_OFF(VM, fFaultTolerantMaster);
@@ -1356,5 +1356,5 @@
     GEN_CHECK_OFF(VM, vmm);
     GEN_CHECK_OFF(VM, pgm);
-    GEN_CHECK_OFF(VM, hwaccm);
+    GEN_CHECK_OFF(VM, hm);
     GEN_CHECK_OFF(VM, trpm);
     GEN_CHECK_OFF(VM, selm);
@@ -1390,5 +1390,5 @@
     GEN_CHECK_OFF(VMCPU, aStatAdHoc);
     GEN_CHECK_OFF(VMCPU, cpum);
-    GEN_CHECK_OFF(VMCPU, hwaccm);
+    GEN_CHECK_OFF(VMCPU, hm);
     GEN_CHECK_OFF(VMCPU, em);
     GEN_CHECK_OFF(VMCPU, iem);
Index: trunk/src/VBox/VMM/testcase/tstVMStructDTrace.cpp
===================================================================
--- trunk/src/VBox/VMM/testcase/tstVMStructDTrace.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/testcase/tstVMStructDTrace.cpp	(revision 43387)
@@ -42,5 +42,5 @@
 #include "IOMInternal.h"
 #include "REMInternal.h"
-#include "HWACCMInternal.h"
+#include "HMInternal.h"
 #include "PATMInternal.h"
 #include "VMMInternal.h"
Index: trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp
===================================================================
--- trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/testcase/tstVMStructRC.cpp	(revision 43387)
@@ -70,5 +70,5 @@
 #include "IOMInternal.h"
 #include "REMInternal.h"
-#include "HWACCMInternal.h"
+#include "HMInternal.h"
 #include "PATMInternal.h"
 #include "VMMInternal.h"
Index: trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp
===================================================================
--- trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 43379)
+++ trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 43387)
@@ -41,5 +41,5 @@
 #include "REMInternal.h"
 #include "SSMInternal.h"
-#include "HWACCMInternal.h"
+#include "HMInternal.h"
 #include "PATMInternal.h"
 #include "VMMInternal.h"
@@ -207,6 +207,6 @@
     PRINT_OFFSET(VM, pgm.s.CritSectX);
     CHECK_PADDING_VM(64, pgm);
-    PRINT_OFFSET(VM, hwaccm);
-    CHECK_PADDING_VM(64, hwaccm);
+    PRINT_OFFSET(VM, hm);
+    CHECK_PADDING_VM(64, hm);
     CHECK_PADDING_VM(64, trpm);
     CHECK_PADDING_VM(64, selm);
@@ -227,5 +227,5 @@
     PRINT_OFFSET(VMCPU, cpum);
     CHECK_PADDING_VMCPU(64, cpum);
-    CHECK_PADDING_VMCPU(64, hwaccm);
+    CHECK_PADDING_VMCPU(64, hm);
     CHECK_PADDING_VMCPU(64, em);
     CHECK_PADDING_VMCPU(64, iem);
@@ -394,13 +394,13 @@
     CHECK_MEMBER_ALIGNMENT(MMHYPERHEAP, Lock, sizeof(uintptr_t));
 
-    /* hwaccm - 32-bit gcc won't align uint64_t naturally, so check. */
-    CHECK_MEMBER_ALIGNMENT(HWACCM, u64RegisterMask, 8);
-    CHECK_MEMBER_ALIGNMENT(HWACCM, vmx.hostCR4, 8);
-    CHECK_MEMBER_ALIGNMENT(HWACCM, vmx.msr.feature_ctrl, 8);
-    CHECK_MEMBER_ALIGNMENT(HWACCM, StatTPRPatchSuccess, 8);
-    CHECK_MEMBER_ALIGNMENT(HWACCMCPU, StatEntry, 8);
-    CHECK_MEMBER_ALIGNMENT(HWACCMCPU, vmx.HCPhysVMCS, sizeof(RTHCPHYS));
-    CHECK_MEMBER_ALIGNMENT(HWACCMCPU, vmx.proc_ctls, 8);
-    CHECK_MEMBER_ALIGNMENT(HWACCMCPU, Event.intInfo, 8);
+    /* hm - 32-bit gcc won't align uint64_t naturally, so check. */
+    CHECK_MEMBER_ALIGNMENT(HM, u64RegisterMask, 8);
+    CHECK_MEMBER_ALIGNMENT(HM, vmx.hostCR4, 8);
+    CHECK_MEMBER_ALIGNMENT(HM, vmx.msr.feature_ctrl, 8);
+    CHECK_MEMBER_ALIGNMENT(HM, StatTPRPatchSuccess, 8);
+    CHECK_MEMBER_ALIGNMENT(HMCPU, StatEntry, 8);
+    CHECK_MEMBER_ALIGNMENT(HMCPU, vmx.HCPhysVMCS, sizeof(RTHCPHYS));
+    CHECK_MEMBER_ALIGNMENT(HMCPU, vmx.proc_ctls, 8);
+    CHECK_MEMBER_ALIGNMENT(HMCPU, Event.intInfo, 8);
 
     /* Make sure the set is large enough and has the correct size. */
