Index: /trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp	(revision 43306)
+++ /trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp	(revision 43307)
@@ -91,5 +91,6 @@
     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));
+    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));
@@ -251,7 +252,8 @@
 }
 
-static DECLCALLBACK(int) hmR0DummyEnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
-{
-    NOREF(pCpu); NOREF(pVM); NOREF(pvCpuPage); NOREF(HCPhysCpuPage);
+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;
 }
@@ -467,17 +469,4 @@
                         g_HvmR0.vmx.fSupported = true;
                         VMXDisable();
-
-                        /*
-                         * 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. */
-                        }
                     }
                     else
@@ -512,9 +501,9 @@
             }
 
-            /*
-             * Install the VT-x methods.
-             */
             if (g_HvmR0.vmx.fSupported)
             {
+                /*
+                 * Install the VT-x methods.
+                 */
                 g_HvmR0.pfnEnterSession     = VMXR0Enter;
                 g_HvmR0.pfnLeaveSession     = VMXR0Leave;
@@ -527,4 +516,17 @@
                 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. */
+                }
             }
         }
@@ -864,5 +866,4 @@
     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));
@@ -874,11 +875,14 @@
     /* Do NOT reset cTLBFlushes here, see @bugref{6255}. */
 
-    /* Should never happen */
-    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);
-
-    int rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage);
+    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))
@@ -932,4 +936,11 @@
     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
@@ -941,15 +952,6 @@
         rc = SUPR0EnableVTx(true /* fEnable */);
         if (RT_SUCCESS(rc))
-        {
-            for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo); iCpu++)
-            {
-                g_HvmR0.aCpuInfo[iCpu].fConfigured = true;
-                g_HvmR0.aCpuInfo[iCpu].cTLBFlushes = 0;
-                Assert(g_HvmR0.aCpuInfo[iCpu].hMemObj == NIL_RTR0MEMOBJ);
-            }
-
             /* 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));
@@ -973,20 +975,18 @@
                 ASMMemZeroPage(pvR0);
             }
-            g_HvmR0.aCpuInfo[i].fConfigured = false;
-            g_HvmR0.aCpuInfo[i].cTLBFlushes = 0;
         }
 
-        if (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));
-        }
-        else
-            rc = VINF_SUCCESS;
+        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));
     }
 
@@ -1754,5 +1754,5 @@
     void           *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
     RTHCPHYS        HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
-    return VMXR0EnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage);
+    return VMXR0EnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage, false);
 }
 
Index: /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 43306)
+++ /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 43307)
@@ -76,6 +76,7 @@
  * @param   HCPhysCpuPage   Physical address of the global CPU page.
  */
-VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
+VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage, bool fEnabledByHost)
 {
+    AssertReturn(!fEnabledByHost, VERR_INVALID_PARAMETER);
     AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
     AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
Index: /trunk/src/VBox/VMM/VMMR0/HWSVMR0.h
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWSVMR0.h	(revision 43306)
+++ /trunk/src/VBox/VMM/VMMR0/HWSVMR0.h	(revision 43307)
@@ -58,14 +58,5 @@
 VMMR0DECL(int) SVMR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
 
-/**
- * Sets up and activates AMD-V on the current CPU
- *
- * @returns VBox status code.
- * @param   pCpu            Pointer to the CPU info struct.
- * @param   pVM             Pointer to the VM (can be NULL after a resume!).
- * @param   pvPageCpu       Pointer to the global CPU page.
- * @param   pPageCpuPhys    Physical address of the global CPU page.
- */
-VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS HCPhysCpuPage);
+VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS HCPhysCpuPage, bool fEnabledBySystem);
 
 /**
Index: /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 43306)
+++ /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 43307)
@@ -117,33 +117,38 @@
  * @param   pvCpuPage       Pointer to the global CPU page.
  * @param   HCPhysCpuPage   Physical address of the global CPU page.
+ * @param   fEnabledByHost  Set if SUPR0EnableVTx or similar was used to enable
+ *                          VT-x/AMD-V on the host.
  */
-VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
+VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage, bool fEnabledByHost)
 {
-    AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
-    AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
-
-    if (pVM)
-    {
-        /* 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);
-    }
-
-    /** @todo we should unmap the two pages from the virtual address space in order to prevent accidental corruption.
-     * (which can have very bad consequences!!!)
-     */
-
-    if (ASMGetCR4() & X86_CR4_VMXE)
-        return VERR_VMX_IN_VMX_ROOT_MODE;
-
-    ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE);    /* Make sure the VMX instructions don't cause #UD faults. */
-
-    /*
-     * Enter VM root mode.
-     */
-    int rc = VMXEnable(HCPhysCpuPage);
-    if (RT_FAILURE(rc))
-    {
-        ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
-        return VERR_VMX_VMXON_FAILED;
+    if (!fEnabledByHost)
+    {
+        AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
+        AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
+
+        if (pVM)
+        {
+            /* 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);
+        }
+
+        /** @todo we should unmap the two pages from the virtual address space in order to prevent accidental corruption.
+         * (which can have very bad consequences!!!)
+         */
+
+        if (ASMGetCR4() & X86_CR4_VMXE)
+            return VERR_VMX_IN_VMX_ROOT_MODE;
+
+        ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE);    /* Make sure the VMX instructions don't cause #UD faults. */
+
+        /*
+         * Enter VM root mode.
+         */
+        int rc = VMXEnable(HCPhysCpuPage);
+        if (RT_FAILURE(rc))
+        {
+            ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
+            return VERR_VMX_VMXON_FAILED;
+        }
     }
 
Index: /trunk/src/VBox/VMM/VMMR0/HWVMXR0.h
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWVMXR0.h	(revision 43306)
+++ /trunk/src/VBox/VMM/VMMR0/HWVMXR0.h	(revision 43307)
@@ -122,15 +122,5 @@
 VMMR0DECL(int) VMXR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
 
-
-/**
- * Sets up and activates VT-x on the current CPU.
- *
- * @returns VBox status code.
- * @param   pCpu            Pointer to the CPU info struct.
- * @param   pVM             Pointer to the VM. (can be NULL after a resume)
- * @param   pvPageCpu       Pointer to the global CPU page.
- * @param   pPageCpuPhys    Physical address of the global CPU page.
- */
-VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
+VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys, bool fEnabledBySystem);
 
 /**
