Index: /trunk/include/VBox/vmm/apic.h
===================================================================
--- /trunk/include/VBox/vmm/apic.h	(revision 60397)
+++ /trunk/include/VBox/vmm/apic.h	(revision 60398)
@@ -927,5 +927,4 @@
  * @{
  */
-VMMR3_INT_DECL(int)         APICR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
 VMMR3_INT_DECL(void)        APICR3InitIpi(PVMCPU pVCpu);
 VMMR3_INT_DECL(void)        APICR3Reset(PVMCPU pVCpu);
Index: /trunk/src/VBox/VMM/Makefile.kmk
===================================================================
--- /trunk/src/VBox/VMM/Makefile.kmk	(revision 60397)
+++ /trunk/src/VBox/VMM/Makefile.kmk	(revision 60398)
@@ -649,6 +649,5 @@
  ifdef VBOX_WITH_NEW_APIC
   VMMR0_SOURCES += \
- 	VMMAll/APICAll.cpp \
- 	VMMR0/APICR0.cpp
+ 	VMMAll/APICAll.cpp
  endif
  VMMR0_SOURCES.amd64 = \
Index: unk/src/VBox/VMM/VMMR0/APICR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/APICR0.cpp	(revision 60397)
+++ 	(revision )
@@ -1,185 +1,0 @@
-/* $Id$ */
-/** @file
- * Advanced Programmable Interrupt Controller (APIC) - Host Context Ring-0.
- */
-
-/*
- * Copyright (C) 2016 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_DEV_APIC
-#include "APICInternal.h"
-#include <iprt/mem.h>
-#include <iprt/memobj.h>
-#include <iprt/process.h>
-#include <VBox/vmm/vm.h>
-
-
-/**
- * Does ring-0 per-VM APIC initialization.
- *
- * @returns VBox status code.
- * @param   pVM     The cross context VM structure.
- */
-VMMR0_INT_DECL(int) APICR0InitVM(PVM pVM)
-{
-    /* Paranoia. */
-    PAPIC pApic = VM_TO_APIC(pVM);
-    Assert(pApic->hMapObjApicPibR0 == NIL_RTR0MEMOBJ);
-    Assert(pApic->hMapObjApicPibR0 == NIL_RTR0MEMOBJ);
-
-    /* Init. non-zero members. */
-    pApic->HCPhysApicPib = NIL_RTHCPHYS;
-
-    /*
-     * Allocate and map the pending-interrupt bitmap (PIB).
-     *
-     * We allocate all the VCPUs' PIBs contiguously in order to save space
-     * as physically contiguous allocations are rounded to a multiple of page size.
-     */
-    size_t const cbApicPib = RT_ALIGN_Z(pVM->cCpus * sizeof(APICPIB), PAGE_SIZE);
-    int rc = RTR0MemObjAllocCont(&pApic->hMemObjApicPibR0, cbApicPib, false /* fExecutable */);
-/** @todo r=bird: You can do all this from ring-3 via
- * SUPR3ContAlloc/SUPR3LowAlloc. I would though, suggest using SUPR3PageAllocEx
- * on AMD64 systems (RC is in PAE mode on AMD64 systems, so that should work
- * regardless of HM or RC, I think), since it's generally faster and more
- * reliable to get memory without physical address restraints.
- */
-    if (RT_SUCCESS(rc))
-    {
-        pApic->cbApicPib      = cbApicPib;
-        pApic->pvApicPibR0    = RTR0MemObjAddress(pApic->hMemObjApicPibR0);
-        pApic->HCPhysApicPib  = RTR0MemObjGetPagePhysAddr(pApic->hMemObjApicPibR0, 0 /* iPage */);
-        ASMMemZero32(pApic->pvApicPibR0, cbApicPib);
-
-        rc = RTR0MemObjMapUser(&pApic->hMapObjApicPibR0, pApic->hMemObjApicPibR0, (RTR3PTR)-1, 0 /* uAlignment */,
-                               RTMEM_PROT_READ | RTMEM_PROT_WRITE, RTR0ProcHandleSelf());
-        if (RT_SUCCESS(rc))
-            pApic->pvApicPibR3 = RTR0MemObjAddressR3(pApic->hMapObjApicPibR0);
-        else
-        {
-            LogRel(("APICR0InitVM: Failed to map pending-interrupt bitmap of %u bytes. rc=%Rrc\n", cbApicPib, rc));
-            return rc;
-        }
-    }
-    else
-    {
-        LogRel(("APICR0InitVM: Failed to allocate pending-interrupt bitmap of %u bytes. rc=%Rrc\n", cbApicPib, rc));
-        return rc;
-    }
-
-    /*
-     * Allocate and map the virtual-APIC pages.
-     */
-    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-    {
-        PVMCPU       pVCpu      = &pVM->aCpus[idCpu];
-        PAPICCPU     pApicCpu   = VMCPU_TO_APICCPU(pVCpu);
-        size_t const cbApicPage = PAGE_SIZE;
-
-        /* Paranoia. */
-        Assert(pApicCpu->hMapObjApicPageR0 == NIL_RTR0MEMOBJ);
-        Assert(pApicCpu->hMapObjApicPageR0 == NIL_RTR0MEMOBJ);
-
-        /* Init. non-zero members. */
-        pApicCpu->HCPhysApicPage = NIL_RTHCPHYS;
-
-        rc = RTR0MemObjAllocCont(&pApicCpu->hMemObjApicPageR0, cbApicPage, false /* fExecutable */);
-        if (RT_SUCCESS(rc))
-        {
-            pApicCpu->cbApicPage     = cbApicPage;
-            pApicCpu->pvApicPageR0   = RTR0MemObjAddress(pApicCpu->hMemObjApicPageR0);
-            pApicCpu->HCPhysApicPage = RTR0MemObjGetPagePhysAddr(pApicCpu->hMemObjApicPageR0, 0 /* iPage */);
-            ASMMemZero32(pApicCpu->pvApicPageR0, cbApicPage);
-
-            rc = RTR0MemObjMapUser(&pApicCpu->hMapObjApicPageR0, pApicCpu->hMemObjApicPageR0, (RTR3PTR)-1, 0 /* uAlignment */,
-                                   RTMEM_PROT_READ | RTMEM_PROT_WRITE, RTR0ProcHandleSelf());
-            if (RT_SUCCESS(rc))
-            {
-                pApicCpu->pvApicPageR3 = RTR0MemObjAddressR3(pApicCpu->hMapObjApicPageR0);
-
-                /*
-                 * Associate the per-VCPU PIB pointers to the per-VM PIB allocation.
-                 */
-                const size_t offApicPib = idCpu * sizeof(APICPIB);
-                pApicCpu->HCPhysApicPib = pApic->HCPhysApicPib + offApicPib;
-                pApicCpu->pvApicPibR0   = (RTR0PTR)((const uint8_t *)pApic->pvApicPibR0 + offApicPib);
-                pApicCpu->pvApicPibR3   = (RTR3PTR)((const uint8_t *)pApic->pvApicPibR3 + offApicPib);
-            }
-            else
-            {
-                LogRel(("APICR0InitVM: VCPU[%u]: Failed to map APIC page of %u bytes. rc=%Rrc\n", idCpu, cbApicPib, rc));
-                return rc;
-            }
-        }
-        else
-        {
-            LogRel(("APICR0InitVM: VCPU[%u]: Failed to allocate APIC page of %u bytes. rc=%Rrc\n", idCpu, cbApicPib, rc));
-            return rc;
-        }
-    }
-
-    LogFlow(("APICR0InitVM: Completed successfully\n"));
-    return VINF_SUCCESS;
-}
-
-
-/**
- * Does ring-0 per-VM APIC termination.
- *
- * @returns VBox status code.
- * @param   pVM     The cross context VM structure.
- */
-VMMR0_INT_DECL(int) APICR0TermVM(PVM pVM)
-{
-    PAPIC pApic = VM_TO_APIC(pVM);
-    if (pApic->hMapObjApicPibR0 != NIL_RTR0MEMOBJ)
-    {
-        RTR0MemObjFree(pApic->hMapObjApicPibR0, true /* fFreeMappings */);
-        pApic->hMapObjApicPibR0 = NIL_RTR0MEMOBJ;
-        pApic->pvApicPibR3 = NULL;
-    }
-    if (pApic->hMemObjApicPibR0 != NIL_RTR0MEMOBJ)
-    {
-        RTR0MemObjFree(pApic->hMemObjApicPibR0, true /* fFreeMappings */);
-        pApic->hMemObjApicPibR0 = NIL_RTR0MEMOBJ;
-        pApic->pvApicPibR0 = NULL;
-        pApic->HCPhysApicPib = NIL_RTHCPHYS;
-    }
-
-    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-    {
-        PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
-        PAPICCPU pApicCpu = &pVCpu->apic.s;
-
-        if (pApicCpu->hMapObjApicPageR0 != NIL_RTR0MEMOBJ)
-        {
-            RTR0MemObjFree(pApicCpu->hMapObjApicPageR0, true /* fFreeMappings */);
-            pApicCpu->hMapObjApicPageR0 = NIL_RTR0MEMOBJ;
-            pApicCpu->pvApicPageR3 = NULL;
-        }
-        if (pApicCpu->hMemObjApicPageR0 != NIL_RTR0MEMOBJ)
-        {
-            RTR0MemObjFree(pApicCpu->hMemObjApicPageR0, true /* fFreeMappings */);
-            pApicCpu->hMemObjApicPageR0 = NIL_RTR0MEMOBJ;
-            pApicCpu->pvApicPageR0 = NULL;
-            pApicCpu->HCPhysApicPage = NIL_RTHCPHYS;
-        }
-    }
-
-    LogFlow(("APICR0TermVM: Completed successfully\n"));
-    return VINF_SUCCESS;
-}
-
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 60397)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 60398)
@@ -469,19 +469,10 @@
                         if (RT_SUCCESS(rc))
                         {
-#ifdef VBOX_WITH_NEW_APIC
-                            rc = APICR0InitVM(pVM);
-#endif
+                            VMM_CHECK_SMAP_CHECK2(pVM, rc = VERR_VMM_RING0_ASSERTION);
                             if (RT_SUCCESS(rc))
                             {
-                                VMM_CHECK_SMAP_CHECK2(pVM, rc = VERR_VMM_RING0_ASSERTION);
-                                if (RT_SUCCESS(rc))
-                                {
-                                    GVMMR0DoneInitVM(pVM);
-                                    VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
-                                    return rc;
-                                }
-#ifdef VBOX_WITH_NEW_APIC
-                            APICR0TermVM(pVM);
-#endif
+                                GVMMR0DoneInitVM(pVM);
+                                VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
+                                return rc;
                             }
 
@@ -528,7 +519,4 @@
     if (GVMMR0DoingTermVM(pVM, pGVM))
     {
-#ifdef VBOX_WITH_NEW_APIC
-        APICR0TermVM(pVM);
-#endif
         GIMR0TermVM(pVM);
 
Index: /trunk/src/VBox/VMM/VMMR3/APIC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 60397)
+++ /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 60398)
@@ -445,106 +445,4 @@
 
 /**
- * Called when a init phase has completed.
- *
- * @returns VBox status code.
- * @param   pVM                 The cross context VM structure.
- * @param   enmWhat             Which init phase.
- */
-VMMR3_INT_DECL(int) APICR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
-{
-    switch (enmWhat)
-    {
-        case VMINITCOMPLETED_RING0:
-        {
-            /*
-             * Map the virtual-PIB into RC.
-             * The virtual-PIB should've already been mapped into R0 and R3, see APICR0InitVM().
-             */
-            PAPIC   pApic = VM_TO_APIC(pVM);
-            RTGCPTR GCPtrApicPib;
-            if (   RT_VALID_PTR(pApic->pvApicPibR3)
-                && pApic->HCPhysApicPib != NIL_RTHCPHYS)
-            {
-                int rc = MMR3HyperMapHCPhys(pVM, (void *)pApic->pvApicPibR3, NIL_RTR0PTR, pApic->HCPhysApicPib,
-                                            (size_t)pApic->cbApicPib, "APIC PIB", &GCPtrApicPib);
-                if (RT_FAILURE(rc))
-                {
-                    LogRel(("APIC: Failed to map HC APIC PIB of %u bytes at %#RHp to RC, rc=%Rrc\n", pApic->cbApicPib,
-                            pApic->HCPhysApicPib, rc));
-                    return rc;
-                }
-            }
-            else
-            {
-                LogRel(("APIC: Failed to find R3 mapping for virtual-PIB\n"));
-                return VERR_MAP_FAILED;
-            }
-
-            /*
-             * Map the virtual-APIC pages into RC and initialize per-VCPU APIC state.
-             * The virtual-APIC pages should by now have been mapped into R0 and R3 by APICR0InitVM().
-             */
-            for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-            {
-                PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
-                PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
-
-                if (   RT_VALID_PTR(pApicCpu->pvApicPageR3)
-                    && pApicCpu->HCPhysApicPage != NIL_RTHCPHYS)
-                {
-                    RTGCPTR GCPtrApicPage;
-                    int rc = MMR3HyperMapHCPhys(pVM, (void *)pApicCpu->pvApicPageR3, NIL_RTR0PTR, pApicCpu->HCPhysApicPage,
-                                                (size_t)pApicCpu->cbApicPage, "APIC", &GCPtrApicPage);
-                    if (RT_SUCCESS(rc))
-                    {
-                        pApicCpu->pvApicPageRC = GCPtrApicPage;
-
-                        /*
-                         * Associate the per-VCPU PIB RC pointer to the per-VM PIB RC mapping.
-                         */
-                        size_t const offApicPib = idCpu * sizeof(APICPIB);
-                        pApicCpu->pvApicPibRC   = GCPtrApicPib + offApicPib;
-
-                        /*
-                         * Initialize the remaining state now that we have R3 mappings.
-                         */
-                        APICR3Reset(pVCpu);
-                    }
-                    else
-                    {
-                        LogRel(("APIC%u: Failed to map HC virtual-APIC page of %u bytes at %#RHp to RC, rc=%Rrc\n",
-                                pVCpu->idCpu, pApicCpu->cbApicPage, pApicCpu->HCPhysApicPage, rc));
-                        return rc;
-                    }
-                }
-                else
-                {
-                    LogRel(("APIC%u: Failed to find R3 mapping for virtual-APIC page\n", pVCpu->idCpu));
-                    return VERR_MAP_FAILED;
-                }
-            }
-            return VINF_SUCCESS;
-        }
-
-        case VMINITCOMPLETED_HM:
-        {
-            CPUMCPUIDLEAF CpuLeaf;
-            int rc = CPUMR3CpuIdGetLeaf(pVM, &CpuLeaf, 1, 0);
-            AssertRCReturn(rc, rc);
-
-            PAPIC pApic = VM_TO_APIC(pVM);
-            pApic->fSupportsTscDeadline = RT_BOOL(CpuLeaf.uEcx & X86_CPUID_FEATURE_ECX_TSCDEADL);
-            pApic->fPostedIntrsEnabled  = HMR3IsPostedIntrsEnabled(pVM->pUVM);
-            pApic->fVirtApicRegsEnabled = HMR3IsVirtApicRegsEnabled(pVM->pUVM);
-            return VINF_SUCCESS;
-        }
-
-        default:
-            return VINF_SUCCESS;
-    }
-}
-
-
-/**
  * Receives an INIT IPI.
  *
@@ -1095,10 +993,5 @@
 
     pApic->pApicDevRC     = PDMINS_2_DATA_RCPTR(pDevIns);
-
-    /*
-     * We can get invoked via PGMR3FinalizeMappings() which happens before initializing R0.
-     * This we may not have allocated and mapped the R0, R3 data yet. Hence the NULL checks.
-     */
-    if (pApic->pvApicPibR3)
+    if (pApic->pvApicPibRC)
         pApic->pvApicPibRC = MMHyperR3ToRC(pVM, (void *)pApic->pvApicPibR3);
 
@@ -1109,10 +1002,191 @@
         pApicCpu->pTimerRC     = TMTimerRCPtr(pApicCpu->pTimerR3);
 
+        if (pApicCpu->pvApicPageRC)
+            pApicCpu->pvApicPageRC = MMHyperR3ToRC(pVM, (void *)pApicCpu->pvApicPageR3);
+        if (pApicCpu->pvApicPibRC)
+            pApicCpu->pvApicPibRC  = MMHyperR3ToRC(pVM, (void *)pApicCpu->pvApicPibR3);
+    }
+}
+
+
+/**
+ * Terminates the APIC state.
+ *
+ * @param   pVM     The cross context VM structure.
+ */
+static void apicR3TermState(PVM pVM)
+{
+    PAPIC pApic = VM_TO_APIC(pVM);
+    if (pApic->pvApicPibR3)
+    {
+        size_t const cPages = pApic->cbApicPib >> PAGE_SHIFT;
+        if (cPages == 1)
+            SUPR3PageFreeEx((void *)pApic->pvApicPibR3, cPages);
+        else
+            SUPR3ContFree((void *)pApic->pvApicPibR3, cPages);
+        pApic->pvApicPibR3 = NULL;
+    }
+
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU   pVCpu      = &pVM->aCpus[idCpu];
+        PAPICCPU pApicCpu   = VMCPU_TO_APICCPU(pVCpu);
         if (pApicCpu->pvApicPageR3)
-            pApicCpu->pvApicPageRC = MMHyperR3ToRC(pVM, (void *)pApicCpu->pvApicPageR3);
-
-        if (pApicCpu->pvApicPibR3)
-            pApicCpu->pvApicPibRC  = MMHyperR3ToRC(pVM, (void *)pApicCpu->pvApicPibR3);
-    }
+        {
+            SUPR3PageFreeEx((void *)pApicCpu->pvApicPageR3, 1 /* cPages */);
+            pApicCpu->pvApicPageR3 = NULL;
+        }
+    }
+}
+
+
+/**
+ * Initializes the APIC state.
+ *
+ * @returns VBox status code.
+ * @param   pVM     The cross context VM structure.
+ */
+static int apicR3InitState(PVM pVM)
+{
+    PAPIC pApic = VM_TO_APIC(pVM);
+    bool const fNeedGCMapping = !HMIsEnabled(pVM);
+
+    /*
+     * Allocate and map the pending-interrupt bitmap (PIB).
+     *
+     * We allocate all the VCPUs' PIBs contiguously in order to save space as
+     * physically contiguous allocations are rounded to a multiple of page size.
+     */
+    pApic->cbApicPib    = RT_ALIGN_Z(pVM->cCpus * sizeof(APICPIB), PAGE_SIZE);
+    size_t const cPages = pApic->cbApicPib >> PAGE_SHIFT;
+    Assert(!pApic->pvApicPibR3);
+    if (cPages == 1)
+    {
+        SUPPAGE SupApicPib;
+        RT_ZERO(SupApicPib);
+        SupApicPib.Phys = NIL_RTHCPHYS;
+        int rc = SUPR3PageAllocEx(cPages, 0 /* fFlags */, (void **)&pApic->pvApicPibR3, &pApic->pvApicPibR0, &SupApicPib);
+        if (RT_SUCCESS(rc))
+        {
+            pApic->HCPhysApicPib = SupApicPib.Phys;
+            Assert(pApic->HCPhysApicPib != NIL_RTHCPHYS);
+            Assert(pApic->pvApicPibR3);
+        }
+        else
+        {
+            LogRel(("APIC: Failed to allocate %u bytes for the pending-interrupt bitmap, rc=%Rrc\n", pApic->cbApicPib, rc));
+            return rc;
+        }
+    }
+    else
+        pApic->pvApicPibR3 = SUPR3ContAlloc(cPages, &pApic->pvApicPibR0, &pApic->HCPhysApicPib);
+
+    if (pApic->pvApicPibR3)
+    {
+        /* Map the pending-interrupt bitmap (PIB) into GC.  */
+        if (fNeedGCMapping)
+        {
+            int rc = MMR3HyperMapHCPhys(pVM, (void *)pApic->pvApicPibR3, NIL_RTR0PTR, pApic->HCPhysApicPib, pApic->cbApicPib,
+                                        "APIC PIB", (PRTGCPTR)&pApic->pvApicPibRC);
+            if (RT_FAILURE(rc))
+            {
+                LogRel(("APIC: Failed to map %u bytes for the pending-interrupt bitmap to GC, rc=%Rrc\n", pApic->cbApicPib, rc));
+                apicR3TermState(pVM);
+                return rc;
+            }
+        }
+
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
+            PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
+
+            /* Allocate and map the virtual-APIC page. */
+            SUPPAGE SupApicPage;
+            RT_ZERO(SupApicPage);
+            SupApicPage.Phys = NIL_RTHCPHYS;
+
+            pApicCpu->cbApicPage = sizeof(XAPICPAGE);
+            AssertCompile(sizeof(XAPICPAGE) == PAGE_SIZE);
+
+            Assert(!pApicCpu->pvApicPageR3);
+            int rc = SUPR3PageAllocEx(1 /* cPages */, 0 /* fFlags */, (void **)&pApicCpu->pvApicPageR3, &pApicCpu->pvApicPageR0,
+                                      &SupApicPage);
+            if (RT_SUCCESS(rc))
+            {
+                pApicCpu->HCPhysApicPage = SupApicPage.Phys;
+                Assert(pApicCpu->HCPhysApicPage != NIL_RTHCPHYS);
+
+                /* Map the virtual-APIC page into GC. */
+                if (fNeedGCMapping)
+                {
+                    rc = MMR3HyperMapHCPhys(pVM, (void *)pApicCpu->pvApicPageR3, NIL_RTR0PTR, pApicCpu->HCPhysApicPage,
+                                            pApicCpu->cbApicPage, "APIC", (PRTGCPTR)&pApicCpu->pvApicPageRC);
+                    if (RT_FAILURE(rc))
+                    {
+                        LogRel(("APIC%u: Failed to map %u bytes for the virtual-APIC page to GC, rc=%Rrc", idCpu,
+                                pApicCpu->cbApicPage, rc));
+                        apicR3TermState(pVM);
+                        return rc;
+                    }
+                }
+
+                /* Associate the per-VCPU PIB pointers to the per-VM PIB mapping. */
+                size_t const offApicPib    = idCpu * sizeof(APICPIB);
+                pApicCpu->pvApicPibR0      = (RTR0PTR)((const uint8_t *)pApic->pvApicPibR0 + offApicPib);
+                pApicCpu->pvApicPibR3      = (RTR3PTR)((const uint8_t *)pApic->pvApicPibR3 + offApicPib);
+                if (fNeedGCMapping)
+                    pApicCpu->pvApicPibRC += offApicPib;
+
+                /* Initialize the virtual-APIC state. */
+                memset((void *)pApicCpu->pvApicPageR3, 0, pApicCpu->cbApicPage);
+                APICR3Reset(pVCpu);
+            }
+            else
+            {
+                LogRel(("APIC%u: Failed to allocate %u bytes for the virtual-APIC page\n", pApicCpu->cbApicPage));
+                apicR3TermState(pVM);
+                return VERR_NO_MEMORY;
+            }
+        }
+
+        return VINF_SUCCESS;
+    }
+
+    LogRel(("APIC: Failed to allocate %u bytes of contiguous low-memory for the pending-interrupt bitmap\n", pApic->cbApicPib));
+    return VERR_NO_MEMORY;
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnDestruct}
+ */
+static DECLCALLBACK(int) apicR3Destruct(PPDMDEVINS pDevIns)
+{
+    PVM pVM = PDMDevHlpGetVM(pDevIns);
+    apicR3TermState(pVM);
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnInitComplete}
+ */
+static DECLCALLBACK(int) apicR3InitComplete(PPDMDEVINS pDevIns)
+{
+    PVM   pVM   = PDMDevHlpGetVM(pDevIns);
+    PAPIC pApic = VM_TO_APIC(pVM);
+
+    CPUMCPUIDLEAF CpuLeaf;
+    int rc = CPUMR3CpuIdGetLeaf(pVM, &CpuLeaf, 1, 0);
+    AssertRCReturn(rc, rc);
+    pApic->fSupportsTscDeadline = RT_BOOL(CpuLeaf.uEcx & X86_CPUID_FEATURE_ECX_TSCDEADL);
+
+    pApic->fPostedIntrsEnabled  = HMR3IsPostedIntrsEnabled(pVM->pUVM);
+    pApic->fVirtApicRegsEnabled = HMR3IsVirtApicRegsEnabled(pVM->pUVM);
+
+    LogRel(("APIC: fPostedIntrsEnabled=%RTbool fVirtApicRegsEnabled=%RTbool fSupportsTscDeadline=%RTbool\n",
+            pApic->fPostedIntrsEnabled, pApic->fVirtApicRegsEnabled, pApic->fSupportsTscDeadline));
+    return VINF_SUCCESS;
 }
 
@@ -1167,5 +1241,5 @@
 
     /*
-     * Initialize part of APIC state.
+     * Initialize the APIC state.
      */
     pApicDev->pDevInsR3 = pDevIns;
@@ -1177,16 +1251,6 @@
     pApic->pApicDevRC   = PDMINS_2_DATA_RCPTR(pDevIns);
 
-    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-    {
-        PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
-        PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
-        RTStrPrintf(&pApicCpu->szTimerDesc[0], sizeof(pApicCpu->szTimerDesc), "APIC Timer %u", pVCpu->idCpu);
-
-        /* Initialize the APIC base MSR as we require it for registering the MMIO range. */
-        apicR3ResetBaseMsr(pVCpu);
-
-        /* Disable the APIC until we're fully initialized in APICR3InitCompleted(), see @bugref{8245#c46}. */
-        apicR3SetEnabled(pVCpu, false);
-    }
+    rc = apicR3InitState(pVM);
+    AssertRCReturn(rc, rc);
 
     /*
@@ -1285,4 +1349,5 @@
         PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
         PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
+        RTStrPrintf(&pApicCpu->szTimerDesc[0], sizeof(pApicCpu->szTimerDesc), "APIC Timer %u", pVCpu->idCpu);
         rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicR3TimerCallback, pVCpu, TMTIMER_FLAGS_NO_CRIT_SECT,
                                     pApicCpu->szTimerDesc, &pApicCpu->pTimerR3);
@@ -1371,5 +1436,5 @@
     apicR3Construct,
     /* pfnDestruct */
-    NULL,
+    apicR3Destruct,
     /* pfnRelocate */
     apicR3Relocate,
@@ -1391,5 +1456,5 @@
     NULL,
     /* pfnInitComplete */
-    NULL,
+    apicR3InitComplete,
     /* pfnPowerOff */
     NULL,
Index: /trunk/src/VBox/VMM/VMMR3/VM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 60397)
+++ /trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 60398)
@@ -1179,8 +1179,4 @@
     if (RT_SUCCESS(rc))
         rc = PGMR3InitCompleted(pVM, enmWhat);
-#ifdef VBOX_WITH_NEW_APIC
-    if (RT_SUCCESS(rc))
-        rc = APICR3InitCompleted(pVM, enmWhat);
-#endif
     if (RT_SUCCESS(rc))
         rc = CPUMR3InitCompleted(pVM, enmWhat);
