Index: /trunk/include/VBox/vmm/vm.h
===================================================================
--- /trunk/include/VBox/vmm/vm.h	(revision 80190)
+++ /trunk/include/VBox/vmm/vm.h	(revision 80191)
@@ -990,5 +990,9 @@
  * Asserts that the current thread IS emulation thread \#0 (EMT0).
  */
-#define VM_ASSERT_EMT0(pVM)                 VMCPU_ASSERT_EMT(&(pVM)->aCpus[0])
+#if defined(VBOX_BUGREF_9217_PART_I) && defined(IN_RING3)
+# define VM_ASSERT_EMT0(a_pVM)              VMCPU_ASSERT_EMT((a_pVM)->apCpusR3[0])
+#else
+# define VM_ASSERT_EMT0(a_pVM)              VMCPU_ASSERT_EMT(&(a_pVM)->aCpus[0])
+#endif
 
 /** @def VM_ASSERT_EMT0_RETURN
@@ -1425,26 +1429,16 @@
     } cfgm;
 
-#ifdef VBOX_BUGREF_9217
     /** Padding for aligning the structure size on a page boundrary. */
-# ifdef VBOX_WITH_REM
-    uint8_t         abAlignment2[3030 - sizeof(PVMCPUR3) * VMM_MAX_CPU_COUNT];
-# else
-    uint8_t         abAlignment2[3286 - sizeof(PVMCPUR3) * VMM_MAX_CPU_COUNT];
-# endif
-#else
-    /** Padding for aligning the cpu array on a page boundary. */
-# ifdef VBOX_WITH_REM
-    uint8_t         abAlignment2[3030];
-# else
-    uint8_t         abAlignment2[3286];
-# endif
+#ifdef VBOX_WITH_REM
+    uint8_t         abAlignment2[2520];
+#else
+    uint8_t         abAlignment2[2520 + 256];
 #endif
 
     /* ---- end small stuff ---- */
 
-#ifdef VBOX_BUGREF_9217
     /** Array of VMCPU pointers. */
-    PVMCPUR3        apCpus[VMM_MAX_CPU_COUNT];
-#else
+    PVMCPUR3        apCpusR3[VMM_MAX_CPU_COUNT];
+#if !defined(VBOX_BUGREF_9217) && !defined(VBOX_BUGREF_9217_PART_I)
     /** VMCPU array for the configured number of virtual CPUs.
      * Must be aligned on a page boundary for TLB hit reasons as well as
Index: /trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp	(revision 80191)
@@ -958,6 +958,6 @@
                                     pGVM->aCpus[i].pVMR0 = pGVM;
                                     pGVM->aCpus[i].pVMR3 = pVMR3;
-                                    pGVM->apCpus[i] = RTR0MemObjAddressR3(pGVM->aCpus[i].gvmm.s.VMCpuMapObj);
-                                    AssertPtr((void *)pGVM->apCpus[i]);
+                                    pGVM->apCpusR3[i] = RTR0MemObjAddressR3(pGVM->aCpus[i].gvmm.s.VMCpuMapObj);
+                                    AssertPtr((void *)pGVM->apCpusR3[i]);
                                 }
 
@@ -1094,4 +1094,5 @@
                                         pVM->aCpus[i].idHostCpu       = NIL_RTCPUID;
                                         pVM->aCpus[i].hNativeThreadR0 = NIL_RTNATIVETHREAD;
+                                        pVM->apCpusR3[i] = pVMR3 + RT_UOFFSETOF_DYN(VM, aCpus[i]);
                                     }
 
Index: /trunk/src/VBox/VMM/VMMR3/APIC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DEV_APIC
 #include <VBox/log.h>
@@ -331,5 +332,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     PCAPICCPU    pApicCpu    = VMCPU_TO_APICCPU(pVCpu);
@@ -447,5 +448,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
@@ -646,5 +647,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
@@ -955,5 +956,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         PCAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
 
@@ -1035,5 +1036,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
+        PVMCPU   pVCpu    = pVM->apCpusR3[idCpu];
         PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
 
@@ -1171,5 +1172,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU   pVCpuDest = &pVM->aCpus[idCpu];
+        PVMCPU   pVCpuDest = pVM->apCpusR3[idCpu];
         PAPICCPU pApicCpu  = VMCPU_TO_APICCPU(pVCpuDest);
 
@@ -1219,5 +1220,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
+        PVMCPU   pVCpu    = pVM->apCpusR3[idCpu];
         PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
 
@@ -1289,5 +1290,5 @@
         for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
         {
-            PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
+            PVMCPU   pVCpu    = pVM->apCpusR3[idCpu];
             PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
 
@@ -1480,5 +1481,5 @@
      * Register the MMIO range.
      */
-    PAPICCPU pApicCpu0 = VMCPU_TO_APICCPU(&pVM->aCpus[0]);
+    PAPICCPU pApicCpu0 = VMCPU_TO_APICCPU(pVM->apCpusR3[0]);
     RTGCPHYS GCPhysApicBase = MSR_IA32_APICBASE_GET_ADDR(pApicCpu0->uApicBaseMsr);
 
@@ -1502,5 +1503,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
+        PVMCPU   pVCpu    = pVM->apCpusR3[idCpu];
         PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
         RTStrPrintf(&pApicCpu->szTimerDesc[0], sizeof(pApicCpu->szTimerDesc), "APIC Timer %u", pVCpu->idCpu);
@@ -1550,5 +1551,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU   pVCpu     = &pVM->aCpus[idCpu];
+        PVMCPU   pVCpu     = pVM->apCpusR3[idCpu];
         PAPICCPU pApicCpu  = VMCPU_TO_APICCPU(pVCpu);
 
Index: /trunk/src/VBox/VMM/VMMR3/CFGM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CFGM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/CFGM.cpp	(revision 80191)
@@ -56,4 +56,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_CFGM
 #include <VBox/vmm/cfgm.h>
Index: /trunk/src/VBox/VMM/VMMR3/CPUM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 80191)
@@ -106,4 +106,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_CPUM
 #include <VBox/vmm/cpum.h>
@@ -984,6 +985,9 @@
             if (fExtFeaturesEDX & X86_CPUID_AMD_FEATURE_EDX_FFXSR)
             {
-                for (VMCPUID i = 0; i < pVM->cCpus; i++)
-                    pVM->aCpus[i].cpum.s.fUseFlags |= CPUM_USE_FFXSR_LEAKY;
+                for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+                {
+                    PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+                    pVCpu->cpum.s.fUseFlags |= CPUM_USE_FFXSR_LEAKY;
+                }
                 Log(("CPUM: Host CPU has leaky fxsave/fxrstor behaviour\n"));
             }
@@ -1003,5 +1007,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
         if (pVCpu->cpum.s.Guest.hwvirt.svm.pVmcbR3)
         {
@@ -1041,5 +1045,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
         pVCpu->cpum.s.Guest.hwvirt.enmHwvirt = CPUMHWVIRT_SVM;
 
@@ -1126,5 +1130,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU   pVCpu = &pVM->aCpus[i];
+        PVMCPU   pVCpu = pVM->apCpusR3[i];
         PCPUMCTX pCtx  = &pVCpu->cpum.s.Guest;
 
@@ -1202,5 +1206,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU   pVCpu = &pVM->aCpus[i];
+        PVMCPU   pVCpu = pVM->apCpusR3[i];
         PCPUMCTX pCtx  = &pVCpu->cpum.s.Guest;
         pCtx->hwvirt.enmHwvirt = CPUMHWVIRT_VMX;
@@ -2089,29 +2093,9 @@
     AssertCompileSizeAlignment(CPUMHOSTCTX, 64);
     AssertCompileMemberAlignment(VM, cpum, 64);
-    AssertCompileMemberAlignment(VM, aCpus, 64);
     AssertCompileMemberAlignment(VMCPU, cpum.s, 64);
-    AssertCompileMemberSizeAlignment(VM, aCpus[0].cpum.s, 64);
 #ifdef VBOX_STRICT
     int rc2 = cpumR3MsrStrictInitChecks();
     AssertRCReturn(rc2, rc2);
 #endif
-
-    /*
-     * Initialize offsets.
-     */
-
-    /* Calculate the offset from CPUM to CPUMCPU for the first CPU. */
-    pVM->cpum.s.offCPUMCPU0 = RT_UOFFSETOF(VM, aCpus[0].cpum) - RT_UOFFSETOF(VM, cpum);
-    Assert((uintptr_t)&pVM->cpum + pVM->cpum.s.offCPUMCPU0 == (uintptr_t)&pVM->aCpus[0].cpum);
-
-
-    /* Calculate the offset from CPUMCPU to CPUM. */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
-
-        pVCpu->cpum.s.offCPUM = RT_UOFFSETOF_DYN(VM, aCpus[i].cpum) - RT_UOFFSETOF(VM, cpum);
-        Assert((uintptr_t)&pVCpu->cpum - pVCpu->cpum.s.offCPUM == (uintptr_t)&pVM->cpum);
-    }
 
     /*
@@ -2188,5 +2172,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
 
         pVCpu->cpum.s.Guest.pXStateR3 = (PX86XSAVEAREA)pbXStates;
@@ -2256,5 +2240,5 @@
         rc = cpumR3AllocSvmHwVirtState(pVM);
     else
-        Assert(pVM->aCpus[0].cpum.s.Guest.hwvirt.enmHwvirt == CPUMHWVIRT_NONE);
+        Assert(pVM->apCpusR3[0]->cpum.s.Guest.hwvirt.enmHwvirt == CPUMHWVIRT_NONE);
     if (RT_FAILURE(rc))
         return rc;
@@ -2292,12 +2276,10 @@
 {
 #ifdef VBOX_WITH_CRASHDUMP_MAGIC
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU   pVCpu = &pVM->aCpus[i];
-        PCPUMCTX pCtx  = CPUMQueryGuestCtxPtr(pVCpu);
-
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         memset(pVCpu->cpum.s.aMagic, 0, sizeof(pVCpu->cpum.s.aMagic));
-        pVCpu->cpum.s.uMagic     = 0;
-        pCtx->dr[5]              = 0;
+        pVCpu->cpum.s.uMagic      = 0;
+        pvCpu->cpum.s.Guest.dr[5] = 0;
     }
 #endif
@@ -2478,15 +2460,15 @@
 VMMR3DECL(void) CPUMR3Reset(PVM pVM)
 {
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        CPUMR3ResetCpu(pVM, &pVM->aCpus[i]);
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        CPUMR3ResetCpu(pVM, pVCpu);
 
 #ifdef VBOX_WITH_CRASHDUMP_MAGIC
-        PCPUMCTX pCtx = &pVM->aCpus[i].cpum.s.Guest;
 
         /* Magic marker for searching in crash dumps. */
-        strcpy((char *)pVM->aCpus[i].cpum.s.aMagic, "CPUMCPU Magic");
-        pVM->aCpus[i].cpum.s.uMagic     = UINT64_C(0xDEADBEEFDEADBEEF);
-        pCtx->dr[5]                     = UINT64_C(0xDEADBEEFDEADBEEF);
+        strcpy((char *)pVCpu->.cpum.s.aMagic, "CPUMCPU Magic");
+        pVCpu->cpum.s.uMagic       = UINT64_C(0xDEADBEEFDEADBEEF);
+        pVCpu->cpum.s.Guest->dr[5] = UINT64_C(0xDEADBEEFDEADBEEF);
 #endif
     }
@@ -2525,10 +2507,10 @@
      */
     SSMR3PutU32(pSSM, pVM->cCpus);
-    SSMR3PutU32(pSSM, sizeof(pVM->aCpus[0].cpum.s.GuestMsrs.msr));
+    SSMR3PutU32(pSSM, sizeof(pVM->apCpusR3[0]->cpum.s.GuestMsrs.msr));
     CPUMCTX DummyHyperCtx;
     RT_ZERO(DummyHyperCtx);
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[iCpu];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
 
         SSMR3PutStructEx(pSSM, &DummyHyperCtx,           sizeof(DummyHyperCtx),           0, g_aCpumCtxFields, NULL);
@@ -2710,5 +2692,5 @@
         if (uVersion < CPUM_SAVED_STATE_VERSION_XSAVE)
         {
-            for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
+            for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
             {
                 X86FXSTATE Ign;
@@ -2744,7 +2726,7 @@
          * Do the per-CPU restoring.
          */
-        for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-        {
-            PVMCPU   pVCpu = &pVM->aCpus[iCpu];
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            PVMCPU   pVCpu   = pVM->apCpusR3[idCpu];
             PCPUMCTX pGstCtx = &pVCpu->cpum.s.Guest;
 
@@ -2945,7 +2927,7 @@
         if (uVersion <= CPUM_SAVED_STATE_VERSION_MEM)
         {
-            for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
+            for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
             {
-                PVMCPU      pVCpu  = &pVM->aCpus[iCpu];
+                PVMCPU      pVCpu  = pVM->apCpusR3[idCpu];
                 bool const  fValid = true /*!VM_IS_RAW_MODE_ENABLED(pVM)*/
                                   || (   uVersion > CPUM_SAVED_STATE_VERSION_VER3_2
@@ -2985,13 +2967,16 @@
         if (   uVersion >  CPUM_SAVED_STATE_VERSION_VER3_2
             && uVersion <= CPUM_SAVED_STATE_VERSION_MEM)
-            for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-                pVM->aCpus[iCpu].cpum.s.fChanged &= CPUM_CHANGED_HIDDEN_SEL_REGS_INVALID;
+            for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+            {
+                PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+                pVCpu->cpum.s.fChanged &= CPUM_CHANGED_HIDDEN_SEL_REGS_INVALID;
+            }
 
         /*
          * A quick sanity check.
          */
-        for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-        {
-            PVMCPU pVCpu = &pVM->aCpus[iCpu];
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            PVMCPU pVCpu = pVM->apCpusR3[idCpu];
             AssertLogRelReturn(!(pVCpu->cpum.s.Guest.es.fFlags & ~CPUMSELREG_FLAGS_VALID_MASK), VERR_SSM_UNEXPECTED_DATA);
             AssertLogRelReturn(!(pVCpu->cpum.s.Guest.cs.fFlags & ~CPUMSELREG_FLAGS_VALID_MASK), VERR_SSM_UNEXPECTED_DATA);
@@ -3025,5 +3010,5 @@
 
             /* Use the VMX MSR features from the saved state while exploding guest features. */
-            GuestMsrs.hwvirt.vmx = pVM->aCpus[0].cpum.s.Guest.hwvirt.vmx.Msrs;
+            GuestMsrs.hwvirt.vmx = pVM->apCpusR3[0]->cpum.s.Guest.hwvirt.vmx.Msrs;
         }
 
@@ -3065,5 +3050,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
 
         /* Notify PGM of the NXE states in case they've changed. */
@@ -3534,5 +3519,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     pHlp->pfnPrintf(pHlp, "Guest CPUM (VCPU %d) state: %s\n", pVCpu->idCpu, pszComment);
@@ -3976,5 +3961,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     /*
@@ -4102,5 +4087,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     char szInstruction[256];
@@ -4122,5 +4107,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     CPUMDUMPTYPE enmType;
@@ -4154,5 +4139,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
     PCPUMHOSTCTX pCtx = &pVCpu->cpum.s.Host;
 
@@ -4484,7 +4469,8 @@
              */
             bool const fSupportsLongMode = VMR3IsLongModeAllowed(pVM);
-            for (VMCPUID i = 0; i < pVM->cCpus; i++)
+            for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
             {
-                PVMCPU pVCpu = &pVM->aCpus[i];
+                PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+
                 /* While loading a saved-state we fix it up in, cpumR3LoadDone(). */
                 if (fSupportsLongMode)
Index: /trunk/src/VBox/VMM/VMMR3/CPUMDbg.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUMDbg.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/CPUMDbg.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/cpum.h>
@@ -1250,7 +1251,7 @@
 int cpumR3DbgInit(PVM pVM)
 {
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-    {
-        int rc = DBGFR3RegRegisterCpu(pVM, &pVM->aCpus[iCpu], g_aCpumRegGstDescs, true /*fGuestRegs*/);
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        int rc = DBGFR3RegRegisterCpu(pVM, pVM->apCpusR3[idCpu], g_aCpumRegGstDescs, true /*fGuestRegs*/);
         AssertLogRelRCReturn(rc, rc);
     }
Index: /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_CPUM
 #include <VBox/vmm/cpum.h>
@@ -2415,7 +2416,8 @@
      * Configure XSAVE offsets according to the CPUID info and set the feature flags.
      */
-    memset(&pVM->aCpus[0].cpum.s.Guest.aoffXState[0], 0xff, sizeof(pVM->aCpus[0].cpum.s.Guest.aoffXState));
-    pVM->aCpus[0].cpum.s.Guest.aoffXState[XSAVE_C_X87_BIT] = 0;
-    pVM->aCpus[0].cpum.s.Guest.aoffXState[XSAVE_C_SSE_BIT] = 0;
+    PVMCPU pVCpu0 = pVM->apCpusR3[0];
+    memset(&pVCpu0->cpum.s.Guest.aoffXState[0], 0xff, sizeof(pVCpu0->cpum.s.Guest.aoffXState));
+    pVCpu0->cpum.s.Guest.aoffXState[XSAVE_C_X87_BIT] = 0;
+    pVCpu0->cpum.s.Guest.aoffXState[XSAVE_C_SSE_BIT] = 0;
     for (uint32_t iComponent = XSAVE_C_SSE_BIT + 1; iComponent < 63; iComponent++)
         if (pCpum->fXStateGuestMask & RT_BIT_64(iComponent))
@@ -2432,11 +2434,13 @@
                                    pCpum->GuestFeatures.cbMaxExtendedState),
                                   VERR_CPUM_IPE_1);
-            pVM->aCpus[0].cpum.s.Guest.aoffXState[iComponent] = pSubLeaf->uEbx;
+            pVCpu0->cpum.s.Guest.aoffXState[iComponent] = pSubLeaf->uEbx;
         }
 
     /* Copy the CPU #0  data to the other CPUs. */
-    for (VMCPUID iCpu = 1; iCpu < pVM->cCpus; iCpu++)
-        memcpy(&pVM->aCpus[iCpu].cpum.s.Guest.aoffXState[0], &pVM->aCpus[0].cpum.s.Guest.aoffXState[0],
-               sizeof(pVM->aCpus[iCpu].cpum.s.Guest.aoffXState));
+    for (VMCPUID idCpu = 1; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        memcpy(&pVCpu->cpum.s.Guest.aoffXState[0], &pVCpu0->cpum.s.Guest.aoffXState[0], sizeof(pVCpu0->cpum.s.Guest.aoffXState));
+    }
 
     return VINF_SUCCESS;
@@ -4408,6 +4412,9 @@
      * on construction and manage everything from here on.
      */
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-        pVM->aCpus[iCpu].cpum.s.fCpuIdApicFeatureVisible = true;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        pVCpu->cpum.s.fCpuIdApicFeatureVisible = true;
+    }
 
     /*
@@ -4545,5 +4552,5 @@
             for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
             {
-                PVMCPU pVCpu = &pVM->aCpus[idCpu];
+                PVMCPU pVCpu = pVM->apCpusR3[idCpu];
                 memcpy(&pVCpu->cpum.s.Guest.hwvirt.vmx.Msrs, pVmxMsrs, sizeof(*pVmxMsrs));
             }
@@ -4941,7 +4948,7 @@
 
     /** @todo can probably kill this as this API is now init time only... */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         pVCpu->cpum.s.fChanged |= CPUM_CHANGED_CPUID;
     }
@@ -5100,7 +5107,7 @@
     }
 
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         pVCpu->cpum.s.fChanged |= CPUM_CHANGED_CPUID;
     }
Index: /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_CPUM
 #include <VBox/vmm/cpum.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGF.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGF.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGF.cpp	(revision 80191)
@@ -70,4 +70,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
@@ -507,5 +508,5 @@
 {
     /** @todo SMP support! */
-    PVMCPU pVCpu = &pVM->aCpus[0];
+    PVMCPU pVCpu = pVM->apCpusR3[0];
 
     switch (EMGetState(pVCpu))
@@ -2108,5 +2109,5 @@
         return VERR_NOT_SUP_BY_NEM;
 
-    VMCPU_FF_SET(&pVM->aCpus[idCpu], VMCPU_FF_INTERRUPT_NMI);
+    VMCPU_FF_SET(pVM->apCpusR3[idCpu], VMCPU_FF_INTERRUPT_NMI);
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/VMM/VMMR3/DBGFAddr.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFAddr.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFAddr.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp	(revision 80191)
@@ -38,4 +38,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGFBp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFBp.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFBp.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
@@ -101,5 +102,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         pVCpu->dbgf.s.iActiveBp = ~0U;
     }
Index: /trunk/src/VBox/VMM/VMMR3/DBGFCoreWrite.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFCoreWrite.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFCoreWrite.cpp	(revision 80191)
@@ -49,4 +49,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <iprt/param.h>
@@ -517,7 +518,7 @@
     }
 
-    for (uint32_t iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[iCpu];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         RT_BZERO(pDbgfCoreCpu, sizeof(*pDbgfCoreCpu));
         dbgfR3GetCoreCpu(pVCpu, pDbgfCoreCpu);
@@ -526,5 +527,5 @@
         if (RT_FAILURE(rc))
         {
-            LogRel((DBGFLOG_NAME ": Elf64WriteNoteHdr failed for vCPU[%u] rc=%Rrc\n", iCpu, rc));
+            LogRel((DBGFLOG_NAME ": Elf64WriteNoteHdr failed for vCPU[%u] rc=%Rrc\n", idCpu, rc));
             RTMemFree(pDbgfCoreCpu);
             return rc;
Index: /trunk/src/VBox/VMM/VMMR3/DBGFCpu.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFCpu.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFCpu.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #define VMCPU_INCL_CPUM_GST_CTX /* For CPUM_IMPORT_EXTRN_RET(). */
Index: /trunk/src/VBox/VMM/VMMR3/DBGFDisas.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFDisas.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFDisas.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGFInfo.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFInfo.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFInfo.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF_INFO
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGFLog.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFLog.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFLog.cpp	(revision 80191)
@@ -20,4 +20,6 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
+#define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/vmapi.h>
 #include <VBox/vmm/vmm.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGFMem.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFMem.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFMem.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
@@ -560,5 +561,5 @@
     if (fFlags & (DBGFPGDMP_FLAGS_CURRENT_CR3 | DBGFPGDMP_FLAGS_CURRENT_MODE))
     {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         if (fFlags & DBGFPGDMP_FLAGS_SHADOW)
         {
Index: /trunk/src/VBox/VMM/VMMR3/DBGFOS.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFOS.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFOS.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGFR3BugCheck.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFR3BugCheck.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFR3BugCheck.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGFR3Flow.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFR3Flow.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFR3Flow.cpp	(revision 80191)
@@ -27,4 +27,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
@@ -43,10 +44,4 @@
 #include <iprt/sort.h>
 #include <iprt/strcache.h>
-
-
-/*********************************************************************************************************************************
-*   Defined Constants And Macros                                                                                                 *
-*********************************************************************************************************************************/
-
 
 
Index: /trunk/src/VBox/VMM/VMMR3/DBGFR3ModInMem.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFR3ModInMem.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFR3ModInMem.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGFR3PlugIn.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFR3PlugIn.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFR3PlugIn.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGFR3Trace.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFR3Trace.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFR3Trace.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgftrace.h>
@@ -304,8 +305,8 @@
                     if (!fNo)
                         while (iCpu-- > 0)
-                            pVM->aCpus[iCpu].fTraceGroups = UINT32_MAX;
+                            pVM->apCpusR3[iCpu]->fTraceGroups = UINT32_MAX;
                     else
                         while (iCpu-- > 0)
-                            pVM->aCpus[iCpu].fTraceGroups = 0;
+                            pVM->apCpusR3[iCpu]->fTraceGroups = 0;
                     PDMR3TracingConfig(pVM, NULL, 0, !fNo, uPass > 0);
                 }
@@ -326,8 +327,8 @@
                             if (!fNo)
                                 while (iCpu-- > 0)
-                                    pVM->aCpus[iCpu].fTraceGroups |= g_aVmmTpGroups[i].fMask;
+                                    pVM->apCpusR3[iCpu]->fTraceGroups |= g_aVmmTpGroups[i].fMask;
                             else
                                 while (iCpu-- > 0)
-                                    pVM->aCpus[iCpu].fTraceGroups &= ~g_aVmmTpGroups[i].fMask;
+                                    pVM->apCpusR3[iCpu]->fTraceGroups &= ~g_aVmmTpGroups[i].fMask;
                         }
                         break;
@@ -374,5 +375,5 @@
 
     int             rc           = VINF_SUCCESS;
-    uint32_t const  fTraceGroups = pVM->aCpus[0].fTraceGroups;
+    uint32_t const  fTraceGroups = pVM->apCpusR3[0]->fTraceGroups;
     if (   fTraceGroups == UINT32_MAX
         && PDMR3TracingAreAll(pVM, true /*fEnabled*/))
Index: /trunk/src/VBox/VMM/VMMR3/DBGFR3Type.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFR3Type.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFR3Type.cpp	(revision 80191)
@@ -34,4 +34,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/DBGFStack.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFStack.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFStack.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_DBGF
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/EM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/EM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/EM.cpp	(revision 80191)
@@ -36,4 +36,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_EM
 #define VMCPU_INCL_CPUM_GST_CTX /* for CPUM_IMPORT_GUEST_STATE_RET */
@@ -182,13 +183,13 @@
     AssertLogRelRCReturn(rc, rc);
 
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        pVM->aCpus[i].em.s.fExitOptimizationEnabled                  = fExitOptimizationEnabled;
-        pVM->aCpus[i].em.s.fExitOptimizationEnabledR0                = fExitOptimizationEnabledR0;
-        pVM->aCpus[i].em.s.fExitOptimizationEnabledR0PreemptDisabled = fExitOptimizationEnabledR0PreemptDisabled;
-
-        pVM->aCpus[i].em.s.cHistoryExecMaxInstructions               = cHistoryExecMaxInstructions;
-        pVM->aCpus[i].em.s.cHistoryProbeMinInstructions              = cHistoryProbeMinInstructions;
-        pVM->aCpus[i].em.s.cHistoryProbeMaxInstructionsWithoutExit   = cHistoryProbeMaxInstructionsWithoutExit;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        pVCpu->em.s.fExitOptimizationEnabled                  = fExitOptimizationEnabled;
+        pVCpu->em.s.fExitOptimizationEnabledR0                = fExitOptimizationEnabledR0;
+        pVCpu->em.s.fExitOptimizationEnabledR0PreemptDisabled = fExitOptimizationEnabledR0PreemptDisabled;
+        pVCpu->em.s.cHistoryExecMaxInstructions               = cHistoryExecMaxInstructions;
+        pVCpu->em.s.cHistoryProbeMinInstructions              = cHistoryProbeMinInstructions;
+        pVCpu->em.s.cHistoryProbeMaxInstructionsWithoutExit   = cHistoryProbeMaxInstructionsWithoutExit;
     }
 
@@ -212,9 +213,9 @@
         return rc;
 
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
-
-        pVCpu->em.s.enmState            = i == 0 ? EMSTATE_NONE : EMSTATE_WAIT_SIPI;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+
+        pVCpu->em.s.enmState            = idCpu == 0 ? EMSTATE_NONE : EMSTATE_WAIT_SIPI;
         pVCpu->em.s.enmPrevState        = EMSTATE_NONE;
         pVCpu->em.s.u64TimeSliceStart   = 0; /* paranoia */
@@ -222,17 +223,17 @@
 
 # define EM_REG_COUNTER(a, b, c) \
-        rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, c, b, i); \
+        rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, c, b, idCpu); \
         AssertRC(rc);
 
 # define EM_REG_COUNTER_USED(a, b, c) \
-        rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, c, b, i); \
+        rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, c, b, idCpu); \
         AssertRC(rc);
 
 # define EM_REG_PROFILE(a, b, c) \
-        rc = STAMR3RegisterF(pVM, a, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, c, b, i); \
+        rc = STAMR3RegisterF(pVM, a, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, c, b, idCpu); \
         AssertRC(rc);
 
 # define EM_REG_PROFILE_ADV(a, b, c) \
-        rc = STAMR3RegisterF(pVM, a, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, c, b, i); \
+        rc = STAMR3RegisterF(pVM, a, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, c, b, idCpu); \
         AssertRC(rc);
 
@@ -250,70 +251,70 @@
 
 # if 1 /* rawmode only? */
-        EM_REG_COUNTER_USED(&pStats->StatIoRestarted,            "/EM/CPU%d/R3/PrivInst/IoRestarted",        "I/O instructions restarted in ring-3.");
-        EM_REG_COUNTER_USED(&pStats->StatIoIem,                  "/EM/CPU%d/R3/PrivInst/IoIem",              "I/O instructions end to IEM in ring-3.");
-        EM_REG_COUNTER_USED(&pStats->StatCli,                    "/EM/CPU%d/R3/PrivInst/Cli",                "Number of cli instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatSti,                    "/EM/CPU%d/R3/PrivInst/Sti",                "Number of sli instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatHlt,                    "/EM/CPU%d/R3/PrivInst/Hlt",                "Number of hlt instructions not handled in GC because of PATM.");
-        EM_REG_COUNTER_USED(&pStats->StatInvlpg,                 "/EM/CPU%d/R3/PrivInst/Invlpg",             "Number of invlpg instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMisc,                   "/EM/CPU%d/R3/PrivInst/Misc",               "Number of misc. instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[0],          "/EM/CPU%d/R3/PrivInst/Mov CR0, X",         "Number of mov CR0 write instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[1],          "/EM/CPU%d/R3/PrivInst/Mov CR1, X",         "Number of mov CR1 write instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[2],          "/EM/CPU%d/R3/PrivInst/Mov CR2, X",         "Number of mov CR2 write instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[3],          "/EM/CPU%d/R3/PrivInst/Mov CR3, X",         "Number of mov CR3 write instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[4],          "/EM/CPU%d/R3/PrivInst/Mov CR4, X",         "Number of mov CR4 write instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovReadCR[0],           "/EM/CPU%d/R3/PrivInst/Mov X, CR0",         "Number of mov CR0 read instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovReadCR[1],           "/EM/CPU%d/R3/PrivInst/Mov X, CR1",         "Number of mov CR1 read instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovReadCR[2],           "/EM/CPU%d/R3/PrivInst/Mov X, CR2",         "Number of mov CR2 read instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovReadCR[3],           "/EM/CPU%d/R3/PrivInst/Mov X, CR3",         "Number of mov CR3 read instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovReadCR[4],           "/EM/CPU%d/R3/PrivInst/Mov X, CR4",         "Number of mov CR4 read instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovDRx,                 "/EM/CPU%d/R3/PrivInst/MovDRx",             "Number of mov DRx instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatIret,                   "/EM/CPU%d/R3/PrivInst/Iret",               "Number of iret instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovLgdt,                "/EM/CPU%d/R3/PrivInst/Lgdt",               "Number of lgdt instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovLidt,                "/EM/CPU%d/R3/PrivInst/Lidt",               "Number of lidt instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatMovLldt,                "/EM/CPU%d/R3/PrivInst/Lldt",               "Number of lldt instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatSysEnter,               "/EM/CPU%d/R3/PrivInst/Sysenter",           "Number of sysenter instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatSysExit,                "/EM/CPU%d/R3/PrivInst/Sysexit",            "Number of sysexit instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatSysCall,                "/EM/CPU%d/R3/PrivInst/Syscall",            "Number of syscall instructions.");
-        EM_REG_COUNTER_USED(&pStats->StatSysRet,                 "/EM/CPU%d/R3/PrivInst/Sysret",             "Number of sysret instructions.");
-        EM_REG_COUNTER(&pVCpu->em.s.StatTotalClis,               "/EM/CPU%d/Cli/Total",                      "Total number of cli instructions executed.");
+        EM_REG_COUNTER_USED(&pStats->StatIoRestarted,       "/EM/CPU%u/R3/PrivInst/IoRestarted",        "I/O instructions restarted in ring-3.");
+        EM_REG_COUNTER_USED(&pStats->StatIoIem,             "/EM/CPU%u/R3/PrivInst/IoIem",              "I/O instructions end to IEM in ring-3.");
+        EM_REG_COUNTER_USED(&pStats->StatCli,               "/EM/CPU%u/R3/PrivInst/Cli",                "Number of cli instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatSti,               "/EM/CPU%u/R3/PrivInst/Sti",                "Number of sli instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatHlt,               "/EM/CPU%u/R3/PrivInst/Hlt",                "Number of hlt instructions not handled in GC because of PATM.");
+        EM_REG_COUNTER_USED(&pStats->StatInvlpg,            "/EM/CPU%u/R3/PrivInst/Invlpg",             "Number of invlpg instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMisc,              "/EM/CPU%u/R3/PrivInst/Misc",               "Number of misc. instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[0],     "/EM/CPU%u/R3/PrivInst/Mov CR0, X",         "Number of mov CR0 write instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[1],     "/EM/CPU%u/R3/PrivInst/Mov CR1, X",         "Number of mov CR1 write instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[2],     "/EM/CPU%u/R3/PrivInst/Mov CR2, X",         "Number of mov CR2 write instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[3],     "/EM/CPU%u/R3/PrivInst/Mov CR3, X",         "Number of mov CR3 write instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovWriteCR[4],     "/EM/CPU%u/R3/PrivInst/Mov CR4, X",         "Number of mov CR4 write instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovReadCR[0],      "/EM/CPU%u/R3/PrivInst/Mov X, CR0",         "Number of mov CR0 read instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovReadCR[1],      "/EM/CPU%u/R3/PrivInst/Mov X, CR1",         "Number of mov CR1 read instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovReadCR[2],      "/EM/CPU%u/R3/PrivInst/Mov X, CR2",         "Number of mov CR2 read instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovReadCR[3],      "/EM/CPU%u/R3/PrivInst/Mov X, CR3",         "Number of mov CR3 read instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovReadCR[4],      "/EM/CPU%u/R3/PrivInst/Mov X, CR4",         "Number of mov CR4 read instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovDRx,            "/EM/CPU%u/R3/PrivInst/MovDRx",             "Number of mov DRx instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatIret,              "/EM/CPU%u/R3/PrivInst/Iret",               "Number of iret instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovLgdt,           "/EM/CPU%u/R3/PrivInst/Lgdt",               "Number of lgdt instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovLidt,           "/EM/CPU%u/R3/PrivInst/Lidt",               "Number of lidt instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatMovLldt,           "/EM/CPU%u/R3/PrivInst/Lldt",               "Number of lldt instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatSysEnter,          "/EM/CPU%u/R3/PrivInst/Sysenter",           "Number of sysenter instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatSysExit,           "/EM/CPU%u/R3/PrivInst/Sysexit",            "Number of sysexit instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatSysCall,           "/EM/CPU%u/R3/PrivInst/Syscall",            "Number of syscall instructions.");
+        EM_REG_COUNTER_USED(&pStats->StatSysRet,            "/EM/CPU%u/R3/PrivInst/Sysret",             "Number of sysret instructions.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatTotalClis,          "/EM/CPU%u/Cli/Total",                      "Total number of cli instructions executed.");
 #endif
         pVCpu->em.s.pCliStatTree = 0;
 
         /* these should be considered for release statistics. */
-        EM_REG_COUNTER(&pVCpu->em.s.StatIOEmu,              "/PROF/CPU%d/EM/Emulation/IO",      "Profiling of emR3RawExecuteIOInstruction.");
-        EM_REG_COUNTER(&pVCpu->em.s.StatPrivEmu,            "/PROF/CPU%d/EM/Emulation/Priv",    "Profiling of emR3RawPrivileged.");
-        EM_REG_PROFILE(&pVCpu->em.s.StatHMEntry,            "/PROF/CPU%d/EM/HMEnter",           "Profiling Hardware Accelerated Mode entry overhead.");
-        EM_REG_PROFILE(&pVCpu->em.s.StatHMExec,             "/PROF/CPU%d/EM/HMExec",            "Profiling Hardware Accelerated Mode execution.");
-        EM_REG_COUNTER(&pVCpu->em.s.StatHMExecuteCalled,    "/PROF/CPU%d/EM/HMExecuteCalled",   "Number of times enmR3HMExecute is called.");
-        EM_REG_PROFILE(&pVCpu->em.s.StatIEMEmu,             "/PROF/CPU%d/EM/IEMEmuSingle",      "Profiling single instruction IEM execution.");
-        EM_REG_PROFILE(&pVCpu->em.s.StatIEMThenREM,         "/PROF/CPU%d/EM/IEMThenRem",        "Profiling IEM-then-REM instruction execution (by IEM).");
-        EM_REG_PROFILE(&pVCpu->em.s.StatNEMEntry,           "/PROF/CPU%d/EM/NEMEnter",          "Profiling NEM entry overhead.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatIOEmu,              "/PROF/CPU%u/EM/Emulation/IO",      "Profiling of emR3RawExecuteIOInstruction.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatPrivEmu,            "/PROF/CPU%u/EM/Emulation/Priv",    "Profiling of emR3RawPrivileged.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatHMEntry,            "/PROF/CPU%u/EM/HMEnter",           "Profiling Hardware Accelerated Mode entry overhead.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatHMExec,             "/PROF/CPU%u/EM/HMExec",            "Profiling Hardware Accelerated Mode execution.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatHMExecuteCalled,    "/PROF/CPU%u/EM/HMExecuteCalled",   "Number of times enmR3HMExecute is called.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatIEMEmu,             "/PROF/CPU%u/EM/IEMEmuSingle",      "Profiling single instruction IEM execution.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatIEMThenREM,         "/PROF/CPU%u/EM/IEMThenRem",        "Profiling IEM-then-REM instruction execution (by IEM).");
+        EM_REG_PROFILE(&pVCpu->em.s.StatNEMEntry,           "/PROF/CPU%u/EM/NEMEnter",          "Profiling NEM entry overhead.");
 #endif /* VBOX_WITH_STATISTICS */
-        EM_REG_PROFILE(&pVCpu->em.s.StatNEMExec,            "/PROF/CPU%d/EM/NEMExec",           "Profiling NEM execution.");
-        EM_REG_COUNTER(&pVCpu->em.s.StatNEMExecuteCalled,   "/PROF/CPU%d/EM/NEMExecuteCalled",  "Number of times enmR3NEMExecute is called.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatNEMExec,            "/PROF/CPU%u/EM/NEMExec",           "Profiling NEM execution.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatNEMExecuteCalled,   "/PROF/CPU%u/EM/NEMExecuteCalled",  "Number of times enmR3NEMExecute is called.");
 #ifdef VBOX_WITH_STATISTICS
-        EM_REG_PROFILE(&pVCpu->em.s.StatREMEmu,             "/PROF/CPU%d/EM/REMEmuSingle",      "Profiling single instruction REM execution.");
-        EM_REG_PROFILE(&pVCpu->em.s.StatREMExec,            "/PROF/CPU%d/EM/REMExec",           "Profiling REM execution.");
-        EM_REG_PROFILE(&pVCpu->em.s.StatREMSync,            "/PROF/CPU%d/EM/REMSync",           "Profiling REM context syncing.");
-        EM_REG_PROFILE(&pVCpu->em.s.StatRAWEntry,           "/PROF/CPU%d/EM/RAWEnter",          "Profiling Raw Mode entry overhead.");
-        EM_REG_PROFILE(&pVCpu->em.s.StatRAWExec,            "/PROF/CPU%d/EM/RAWExec",           "Profiling Raw Mode execution.");
-        EM_REG_PROFILE(&pVCpu->em.s.StatRAWTail,            "/PROF/CPU%d/EM/RAWTail",           "Profiling Raw Mode tail overhead.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatREMEmu,             "/PROF/CPU%u/EM/REMEmuSingle",      "Profiling single instruction REM execution.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatREMExec,            "/PROF/CPU%u/EM/REMExec",           "Profiling REM execution.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatREMSync,            "/PROF/CPU%u/EM/REMSync",           "Profiling REM context syncing.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatRAWEntry,           "/PROF/CPU%u/EM/RAWEnter",          "Profiling Raw Mode entry overhead.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatRAWExec,            "/PROF/CPU%u/EM/RAWExec",           "Profiling Raw Mode execution.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatRAWTail,            "/PROF/CPU%u/EM/RAWTail",           "Profiling Raw Mode tail overhead.");
 #endif /* VBOX_WITH_STATISTICS */
 
-        EM_REG_COUNTER(&pVCpu->em.s.StatForcedActions,      "/PROF/CPU%d/EM/ForcedActions",     "Profiling forced action execution.");
-        EM_REG_COUNTER(&pVCpu->em.s.StatHalted,             "/PROF/CPU%d/EM/Halted",            "Profiling halted state (VMR3WaitHalted).");
-        EM_REG_PROFILE_ADV(&pVCpu->em.s.StatCapped,         "/PROF/CPU%d/EM/Capped",            "Profiling capped state (sleep).");
-        EM_REG_COUNTER(&pVCpu->em.s.StatREMTotal,           "/PROF/CPU%d/EM/REMTotal",          "Profiling emR3RemExecute (excluding FFs).");
-        EM_REG_COUNTER(&pVCpu->em.s.StatRAWTotal,           "/PROF/CPU%d/EM/RAWTotal",          "Profiling emR3RawExecute (excluding FFs).");
-
-        EM_REG_PROFILE_ADV(&pVCpu->em.s.StatTotal,          "/PROF/CPU%d/EM/Total",             "Profiling EMR3ExecuteVM.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatForcedActions,      "/PROF/CPU%u/EM/ForcedActions",     "Profiling forced action execution.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatHalted,             "/PROF/CPU%u/EM/Halted",            "Profiling halted state (VMR3WaitHalted).");
+        EM_REG_PROFILE_ADV(&pVCpu->em.s.StatCapped,         "/PROF/CPU%u/EM/Capped",            "Profiling capped state (sleep).");
+        EM_REG_COUNTER(&pVCpu->em.s.StatREMTotal,           "/PROF/CPU%u/EM/REMTotal",          "Profiling emR3RemExecute (excluding FFs).");
+        EM_REG_COUNTER(&pVCpu->em.s.StatRAWTotal,           "/PROF/CPU%u/EM/RAWTotal",          "Profiling emR3RawExecute (excluding FFs).");
+
+        EM_REG_PROFILE_ADV(&pVCpu->em.s.StatTotal,          "/PROF/CPU%u/EM/Total",             "Profiling EMR3ExecuteVM.");
 
         rc = STAMR3RegisterF(pVM, &pVCpu->em.s.iNextExit, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
-                             "Number of recorded exits.", "/PROF/CPU%u/EM/RecordedExits", i);
+                             "Number of recorded exits.", "/PROF/CPU%u/EM/RecordedExits", idCpu);
         AssertRC(rc);
 
         /* History record statistics */
         rc = STAMR3RegisterF(pVM, &pVCpu->em.s.cExitRecordUsed, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
-                             "Number of used hash table entries.", "/EM/CPU%u/ExitHashing/Used", i);
+                             "Number of used hash table entries.", "/EM/CPU%u/ExitHashing/Used", idCpu);
         AssertRC(rc);
 
@@ -321,25 +322,25 @@
         {
             rc = STAMR3RegisterF(pVM, &pVCpu->em.s.aStatHistoryRecHits[iStep], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
-                                 "Number of hits at this step.",             "/EM/CPU%u/ExitHashing/Step%02u-Hits", i, iStep);
+                                 "Number of hits at this step.",             "/EM/CPU%u/ExitHashing/Step%02u-Hits", idCpu, iStep);
             AssertRC(rc);
             rc = STAMR3RegisterF(pVM, &pVCpu->em.s.aStatHistoryRecTypeChanged[iStep], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
-                                 "Number of type changes at this step.",     "/EM/CPU%u/ExitHashing/Step%02u-TypeChanges", i, iStep);
+                                 "Number of type changes at this step.",     "/EM/CPU%u/ExitHashing/Step%02u-TypeChanges", idCpu, iStep);
             AssertRC(rc);
             rc = STAMR3RegisterF(pVM, &pVCpu->em.s.aStatHistoryRecTypeChanged[iStep], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
-                                 "Number of replacments at this step.",     "/EM/CPU%u/ExitHashing/Step%02u-Replacments", i, iStep);
+                                 "Number of replacments at this step.",     "/EM/CPU%u/ExitHashing/Step%02u-Replacments", idCpu, iStep);
             AssertRC(rc);
             rc = STAMR3RegisterF(pVM, &pVCpu->em.s.aStatHistoryRecNew[iStep], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
-                                 "Number of new inserts at this step.",     "/EM/CPU%u/ExitHashing/Step%02u-NewInserts", i, iStep);
+                                 "Number of new inserts at this step.",     "/EM/CPU%u/ExitHashing/Step%02u-NewInserts", idCpu, iStep);
             AssertRC(rc);
         }
 
-        EM_REG_PROFILE(&pVCpu->em.s.StatHistoryExec,              "/EM/CPU%d/ExitOpt/Exec",              "Profiling normal EMHistoryExec operation.");
-        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryExecSavedExits,    "/EM/CPU%d/ExitOpt/ExecSavedExit",     "Net number of saved exits.");
-        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryExecInstructions,  "/EM/CPU%d/ExitOpt/ExecInstructions",  "Number of instructions executed during normal operation.");
-        EM_REG_PROFILE(&pVCpu->em.s.StatHistoryProbe,             "/EM/CPU%d/ExitOpt/Probe",             "Profiling EMHistoryExec when probing.");
-        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryProbeInstructions, "/EM/CPU%d/ExitOpt/ProbeInstructions", "Number of instructions executed during probing.");
-        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryProbedNormal,      "/EM/CPU%d/ExitOpt/ProbedNormal",      "Number of EMEXITACTION_NORMAL_PROBED results.");
-        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryProbedExecWithMax, "/EM/CPU%d/ExitOpt/ProbedExecWithMax", "Number of EMEXITACTION_EXEC_WITH_MAX results.");
-        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryProbedToRing3,     "/EM/CPU%d/ExitOpt/ProbedToRing3",     "Number of ring-3 probe continuations.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatHistoryExec,              "/EM/CPU%u/ExitOpt/Exec",              "Profiling normal EMHistoryExec operation.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryExecSavedExits,    "/EM/CPU%u/ExitOpt/ExecSavedExit",     "Net number of saved exits.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryExecInstructions,  "/EM/CPU%u/ExitOpt/ExecInstructions",  "Number of instructions executed during normal operation.");
+        EM_REG_PROFILE(&pVCpu->em.s.StatHistoryProbe,             "/EM/CPU%u/ExitOpt/Probe",             "Profiling EMHistoryExec when probing.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryProbeInstructions, "/EM/CPU%u/ExitOpt/ProbeInstructions", "Number of instructions executed during probing.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryProbedNormal,      "/EM/CPU%u/ExitOpt/ProbedNormal",      "Number of EMEXITACTION_NORMAL_PROBED results.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryProbedExecWithMax, "/EM/CPU%u/ExitOpt/ProbedExecWithMax", "Number of EMEXITACTION_EXEC_WITH_MAX results.");
+        EM_REG_COUNTER(&pVCpu->em.s.StatHistoryProbedToRing3,     "/EM/CPU%u/ExitOpt/ProbedToRing3",     "Number of ring-3 probe continuations.");
     }
 
@@ -360,6 +361,6 @@
     if (enmWhat == VMINITCOMPLETED_RING0)
         LogRel(("EM: Exit history optimizations: enabled=%RTbool enabled-r0=%RTbool enabled-r0-no-preemption=%RTbool\n",
-                pVM->aCpus[0].em.s.fExitOptimizationEnabled, pVM->aCpus[0].em.s.fExitOptimizationEnabledR0,
-                pVM->aCpus[0].em.s.fExitOptimizationEnabledR0PreemptDisabled));
+                pVM->apCpusR3[0]->em.s.fExitOptimizationEnabled, pVM->apCpusR3[0]->em.s.fExitOptimizationEnabledR0,
+                pVM->apCpusR3[0]->em.s.fExitOptimizationEnabledR0PreemptDisabled));
     return VINF_SUCCESS;
 }
@@ -411,6 +412,6 @@
 {
     Log(("EMR3Reset: \n"));
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        EMR3ResetCpu(&pVM->aCpus[i]);
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        EMR3ResetCpu(pVM->apCpusR3[idCpu]);
 }
 
@@ -445,7 +446,7 @@
 static DECLCALLBACK(int) emR3Save(PVM pVM, PSSMHANDLE pSSM)
 {
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
 
         SSMR3PutBool(pSSM, false /*fForceRAW*/);
@@ -493,7 +494,7 @@
      * Load the saved state.
      */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
 
         bool fForceRAWIgnored;
Index: /trunk/src/VBox/VMM/VMMR3/EMHM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/EMHM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/EMHM.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_EM
 #define VMCPU_INCL_CPUM_GST_CTX
Index: /trunk/src/VBox/VMM/VMMR3/EMR3Dbg.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/EMR3Dbg.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/EMR3Dbg.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_EM
 #include <VBox/vmm/em.h>
@@ -199,5 +200,5 @@
     PVMCPU   pVCpu    = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
     bool     fReverse = true;
     uint32_t cLeft    = RT_ELEMENTS(pVCpu->em.s.aExitHistory);
Index: /trunk/src/VBox/VMM/VMMR3/EMR3Nem.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/EMR3Nem.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/EMR3Nem.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_EM
 #define VMCPU_INCL_CPUM_GST_CTX
Index: /trunk/src/VBox/VMM/VMMR3/GIM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GIM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/GIM.cpp	(revision 80191)
@@ -50,4 +50,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_GIM
 #include <VBox/vmm/gim.h>
@@ -92,5 +93,5 @@
      */
     AssertCompile(sizeof(pVM->gim.s) <= sizeof(pVM->gim.padding));
-    AssertCompile(sizeof(pVM->aCpus[0].gim.s) <= sizeof(pVM->aCpus[0].gim.padding));
+    AssertCompile(sizeof(pVM->apCpusR3[0]->gim.s) <= sizeof(pVM->apCpusR3[0]->gim.padding));
 
     /*
@@ -228,7 +229,8 @@
     /* Save per-CPU data. */
     SSMR3PutU32(pSSM, pVM->cCpus);
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        rc = SSMR3PutXYZ(pSSM, pVM->aCpus[i].gim.s.XYZ);
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        rc = SSMR3PutXYZ(pSSM, pVCpu->gim.s.XYZ);
     }
 #endif
@@ -276,7 +278,8 @@
 #if 0
     /* Load per-CPU data. */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        rc = SSMR3PutXYZ(pSSM, pVM->aCpus[i].gim.s.XYZ);
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        rc = SSMR3PutXYZ(pSSM, pVCpu->gim.s.XYZ);
     }
 #endif
Index: /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_GIM
 #include <VBox/vmm/apic.h>
@@ -465,7 +466,7 @@
     if (pHv->uMiscFeat & GIM_HV_MISC_FEAT_GUEST_CRASH_MSRS)
         pHv->uCrashCtlMsr = MSR_GIM_HV_CRASH_CTL_NOTIFY;
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PGIMHVCPU pHvCpu = &pVM->aCpus[i].gim.s.u.HvCpu;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PGIMHVCPU pHvCpu = &pVM->apCpusR3[idCpu]->gim.s.u.HvCpu;
         for (uint8_t idxSintMsr = 0; idxSintMsr < RT_ELEMENTS(pHvCpu->auSintMsrs); idxSintMsr++)
             pHvCpu->auSintMsrs[idxSintMsr] = MSR_GIM_HV_SINT_MASKED;
@@ -492,5 +493,5 @@
         for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
         {
-            PVMCPU       pVCpu     = &pVM->aCpus[idCpu];
+            PVMCPU       pVCpu     = pVM->apCpusR3[idCpu];
             PGIMHVCPU    pHvCpu    = &pVCpu->gim.s.u.HvCpu;
 
@@ -519,5 +520,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU    pVCpu  = &pVM->aCpus[idCpu];
+        PVMCPU    pVCpu  = pVM->apCpusR3[idCpu];
         PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu;
 
@@ -598,5 +599,5 @@
         for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
         {
-            PGIMHVCPU pHvCpu = &pVM->aCpus[idCpu].gim.s.u.HvCpu;
+            PGIMHVCPU pHvCpu = &pVM->apCpusR3[idCpu]->gim.s.u.HvCpu;
             for (uint8_t idxStimer = 0; idxStimer < RT_ELEMENTS(pHvCpu->aStimers); idxStimer++)
             {
@@ -670,7 +671,7 @@
     pHv->uDbgSendBufferMsr    = 0;
     pHv->uDbgRecvBufferMsr    = 0;
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PGIMHVCPU pHvCpu = &pVM->aCpus[i].gim.s.u.HvCpu;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PGIMHVCPU pHvCpu = &pVM->apCpusR3[idCpu]->gim.s.u.HvCpu;
         pHvCpu->uSControlMsr = 0;
         pHvCpu->uSimpMsr  = 0;
@@ -853,7 +854,7 @@
     SSMR3PutU16(pSSM, pHv->uUdpGuestSrcPort);
 
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PGIMHVCPU pHvCpu = &pVM->aCpus[i].gim.s.u.HvCpu;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PGIMHVCPU pHvCpu = &pVM->apCpusR3[idCpu]->gim.s.u.HvCpu;
         SSMR3PutU64(pSSM, pHvCpu->uSimpMsr);
         for (size_t idxSintMsr = 0; idxSintMsr < RT_ELEMENTS(pHvCpu->auSintMsrs); idxSintMsr++)
@@ -990,7 +991,7 @@
         }
 
-        for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        {
-            PGIMHVCPU pHvCpu = &pVM->aCpus[i].gim.s.u.HvCpu;
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            PGIMHVCPU pHvCpu = &pVM->apCpusR3[idCpu]->gim.s.u.HvCpu;
             SSMR3GetU64(pSSM, &pHvCpu->uSimpMsr);
             if (uHvSavedStateVersion <= GIM_HV_SAVED_STATE_VERSION_PRE_SYNIC)
@@ -1028,9 +1029,9 @@
          */
         if (pVM->gim.s.u.Hv.u64GuestOsIdMsr)
-            for (VMCPUID i = 0; i < pVM->cCpus; i++)
-                EMSetHypercallInstructionsEnabled(&pVM->aCpus[i], true);
+            for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+                EMSetHypercallInstructionsEnabled(pVM->apCpusR3[idCpu], true);
         else
-            for (VMCPUID i = 0; i < pVM->cCpus; i++)
-                EMSetHypercallInstructionsEnabled(&pVM->aCpus[i], false);
+            for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+                EMSetHypercallInstructionsEnabled(pVM->apCpusR3[idCpu], false);
     }
     return VINF_SUCCESS;
@@ -1110,5 +1111,5 @@
     Assert(pHvStimer->idCpu < pVM->cCpus);
 
-    PVMCPU    pVCpu  = &pVM->aCpus[pHvStimer->idCpu];
+    PVMCPU    pVCpu  = pVM->apCpusR3[pHvStimer->idCpu];
     PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu;
     Assert(pHvStimer->idxStimer < RT_ELEMENTS(pHvCpu->aStatStimerFired));
@@ -1475,6 +1476,6 @@
              * Notify VMM that hypercalls are now enabled for all VCPUs.
              */
-            for (VMCPUID i = 0; i < pVM->cCpus; i++)
-                VMMHypercallsEnable(&pVM->aCpus[i]);
+            for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+                VMMHypercallsEnable(pVM->apCpusR3[idCpu]);
 
             LogRel(("GIM: HyperV: Enabled hypercall page at %#RGp\n", GCPhysHypercallPage));
Index: /trunk/src/VBox/VMM/VMMR3/GIMKvm.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GIMKvm.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/GIMKvm.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_GIM
 #include <VBox/vmm/gim.h>
@@ -160,6 +161,6 @@
      * Note! We always need to trap VMCALL/VMMCALL hypercall using #UDs for raw-mode VMs.
      */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        EMSetHypercallInstructionsEnabled(&pVM->aCpus[i], true);
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        EMSetHypercallInstructionsEnabled(pVM->apCpusR3[idCpu], true);
 
     size_t cbHypercall = 0;
@@ -240,7 +241,7 @@
     PGIMKVM pKvm = &pVM->gim.s.u.Kvm;
     pKvm->u64WallClockMsr = 0;
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-    {
-        PGIMKVMCPU pKvmCpu = &pVM->aCpus[iCpu].gim.s.u.KvmCpu;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PGIMKVMCPU pKvmCpu = &pVM->apCpusR3[idCpu]->gim.s.u.KvmCpu;
         pKvmCpu->u64SystemTimeMsr = 0;
         pKvmCpu->u32SystemTimeVersion = 0;
@@ -272,7 +273,7 @@
      * Save per-VCPU data.
      */
-    for (uint32_t i = 0; i < pVM->cCpus; i++)
-    {
-        PCGIMKVMCPU pKvmCpu = &pVM->aCpus[i].gim.s.u.KvmCpu;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PCGIMKVMCPU pKvmCpu = &pVM->apCpusR3[idCpu]->gim.s.u.KvmCpu;
         SSMR3PutU64(pSSM, pKvmCpu->u64SystemTimeMsr);
         SSMR3PutU64(pSSM, pKvmCpu->uTsc);
@@ -320,7 +321,7 @@
      * Load per-VCPU data.
      */
-    for (uint32_t i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU     pVCpu   = &pVM->aCpus[i];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU     pVCpu   = pVM->apCpusR3[idCpu];
         PGIMKVMCPU pKvmCpu = &pVCpu->gim.s.u.KvmCpu;
 
Index: /trunk/src/VBox/VMM/VMMR3/GIMMinimal.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GIMMinimal.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/GIMMinimal.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_GIM
 #include <VBox/vmm/gim.h>
Index: /trunk/src/VBox/VMM/VMMR3/GMM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GMM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/GMM.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_GMM
 #include <VBox/vmm/gmm.h>
Index: /trunk/src/VBox/VMM/VMMR3/HM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/HM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/HM.cpp	(revision 80191)
@@ -37,4 +37,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_HM
 #define VMCPU_INCL_CPUM_GST_CTX
@@ -450,6 +451,9 @@
     rc = CFGMR3QueryBoolDef(pCfgHm, "LovelyMesaDrvWorkaround", &f, false);
     AssertLogRelRCReturn(rc, rc);
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        pVM->aCpus[i].hm.s.fTrapXcptGpForLovelyMesaDrv = f;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        pVCpu->hm.s.fTrapXcptGpForLovelyMesaDrv = f;
+    }
 
     /*
@@ -604,7 +608,7 @@
         return VINF_SUCCESS;
 
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         pVCpu->hm.s.fActive = false;
         pVCpu->hm.s.fGIMTrapXcptUD = GIMShouldTrapXcptUD(pVCpu);    /* Is safe to call now since GIMR3Init() has completed. */
@@ -622,202 +626,160 @@
      * Statistics.
      */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu  = pVM->apCpusR3[idCpu];
+        PHMCPU pHmCpu = &pVCpu->hm.s;
         int    rc;
 
+# define HM_REG_STAT(a_pVar, a_enmType, s_enmVisibility, a_enmUnit, a_szNmFmt, a_szDesc) do { \
+                rc = STAMR3RegisterF(pVM, a_pVar, a_enmType, s_enmVisibility, a_enmUnit, a_szDesc, a_szNmFmt, idCpu); \
+                AssertRC(rc); \
+            } while (0)
+# define HM_REG_PROFILE(a_pVar, a_szNmFmt, a_szDesc) \
+            HM_REG_STAT(a_pVar, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, a_szNmFmt, a_szDesc)
+
 #ifdef VBOX_WITH_STATISTICS
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatPoke, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "Profiling of RTMpPokeCpu.",
-                             "/PROF/CPU%d/HM/Poke", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatSpinPoke, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "Profiling of poke wait.",
-                             "/PROF/CPU%d/HM/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/CPU%d/HM/PokeWaitFailed", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatEntry, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "Profiling of entry until entering GC.",
-                             "/PROF/CPU%d/HM/Entry", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatPreExit, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "Profiling of pre-exit processing after returning from GC.",
-                             "/PROF/CPU%d/HM/SwitchFromGC_1", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitHandling, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "Profiling of exit handling (longjmps not included!)",
-                             "/PROF/CPU%d/HM/SwitchFromGC_2", i);
-        AssertRC(rc);
-
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitIO, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "I/O.",
-                             "/PROF/CPU%d/HM/SwitchFromGC_2/IO", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitMovCRx, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "MOV CRx.",
-                             "/PROF/CPU%d/HM/SwitchFromGC_2/MovCRx", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitXcptNmi, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "Exceptions, NMIs.",
-                             "/PROF/CPU%d/HM/SwitchFromGC_2/XcptNmi", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitVmentry, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "VMLAUNCH/VMRESUME on Intel or VMRUN on AMD.",
-                             "/PROF/CPU%d/HM/SwitchFromGC_2/Vmentry", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatImportGuestState, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "Profiling of importing guest state from hardware after VM-exit.",
-                             "/PROF/CPU%d/HM/ImportGuestState", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExportGuestState, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "Profiling of exporting guest state to hardware before VM-entry.",
-                             "/PROF/CPU%d/HM/ExportGuestState", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatLoadGuestFpuState, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "Profiling of CPUMR0LoadGuestFPU.",
-                             "/PROF/CPU%d/HM/LoadGuestFpuState", i);
-        AssertRC(rc);
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatInGC, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
-                             "Profiling of execution of guest-code in hardware.",
-                             "/PROF/CPU%d/HM/InGC", i);
-        AssertRC(rc);
-
+
+        HM_REG_PROFILE(&pHmCpu->StatPoke,                   "/PROF/CPU%u/HM/Poke", "Profiling of RTMpPokeCpu.");
+        HM_REG_PROFILE(&pHmCpu->StatSpinPoke,               "/PROF/CPU%u/HM/PokeWait", "Profiling of poke wait.");
+        HM_REG_PROFILE(&pHmCpu->StatSpinPokeFailed,         "/PROF/CPU%u/HM/PokeWaitFailed", "Profiling of poke wait when RTMpPokeCpu fails.");
+        HM_REG_PROFILE(&pHmCpu->StatEntry,                  "/PROF/CPU%u/HM/Entry", "Profiling of entry until entering GC.");
+        HM_REG_PROFILE(&pHmCpu->StatPreExit,                "/PROF/CPU%u/HM/SwitchFromGC_1", "Profiling of pre-exit processing after returning from GC.");
+        HM_REG_PROFILE(&pHmCpu->StatExitHandling,           "/PROF/CPU%u/HM/SwitchFromGC_2", "Profiling of exit handling (longjmps not included!)");
+        HM_REG_PROFILE(&pHmCpu->StatExitIO,                 "/PROF/CPU%u/HM/SwitchFromGC_2/IO", "I/O.");
+        HM_REG_PROFILE(&pHmCpu->StatExitMovCRx,             "/PROF/CPU%u/HM/SwitchFromGC_2/MovCRx", "MOV CRx.");
+        HM_REG_PROFILE(&pHmCpu->StatExitXcptNmi,            "/PROF/CPU%u/HM/SwitchFromGC_2/XcptNmi", "Exceptions, NMIs.");
+        HM_REG_PROFILE(&pHmCpu->StatExitVmentry,            "/PROF/CPU%u/HM/SwitchFromGC_2/Vmentry", "VMLAUNCH/VMRESUME on Intel or VMRUN on AMD.");
+        HM_REG_PROFILE(&pHmCpu->StatImportGuestState,       "/PROF/CPU%u/HM/ImportGuestState",  "Profiling of importing guest state from hardware after VM-exit.");
+        HM_REG_PROFILE(&pHmCpu->StatExportGuestState,       "/PROF/CPU%u/HM/ExportGuestState",  "Profiling of exporting guest state to hardware before VM-entry.");
+        HM_REG_PROFILE(&pHmCpu->StatLoadGuestFpuState,      "/PROF/CPU%u/HM/LoadGuestFpuState", "Profiling of CPUMR0LoadGuestFPU.");
+        HM_REG_PROFILE(&pHmCpu->StatInGC,                   "/PROF/CPU%u/HM/InGC", "Profiling of execution of guest-code in hardware.");
 # ifdef HM_PROFILE_EXIT_DISPATCH
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatExitDispatch, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_USED,
-                             STAMUNIT_TICKS_PER_CALL, "Profiling the dispatching of exit handlers.",
-                             "/PROF/CPU%d/HM/ExitDispatch", i);
-        AssertRC(rc);
+        HM_REG_STAT(&pHmCpu->StatExitDispatch, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL,
+                    "/PROF/CPU%u/HM/ExitDispatch", "Profiling the dispatching of exit handlers.");
 # endif
-
 #endif
-# define HM_REG_COUNTER(a, b, desc) \
-        rc = STAMR3RegisterF(pVM, a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, desc, b, i); \
-        AssertRC(rc);
+# define HM_REG_COUNTER(a, b, desc) HM_REG_STAT(a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, b, desc)
 
 #ifdef VBOX_WITH_STATISTICS
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitAll,                "/HM/CPU%d/Exit/All", "Total exits (including nested-guest exits).");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatNestedExitAll,          "/HM/CPU%d/Exit/NestedGuest/All", "Total nested-guest exits.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitShadowNM,           "/HM/CPU%d/Exit/Trap/Shw/#NM", "Shadow #NM (device not available, no math co-processor) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestNM,            "/HM/CPU%d/Exit/Trap/Gst/#NM", "Guest #NM (device not available, no math co-processor) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitShadowPF,           "/HM/CPU%d/Exit/Trap/Shw/#PF", "Shadow #PF (page fault) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitShadowPFEM,         "/HM/CPU%d/Exit/Trap/Shw/#PF-EM", "#PF (page fault) exception going back to ring-3 for emulating the instruction.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestPF,            "/HM/CPU%d/Exit/Trap/Gst/#PF", "Guest #PF (page fault) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestUD,            "/HM/CPU%d/Exit/Trap/Gst/#UD", "Guest #UD (undefined opcode) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestSS,            "/HM/CPU%d/Exit/Trap/Gst/#SS", "Guest #SS (stack-segment fault) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestNP,            "/HM/CPU%d/Exit/Trap/Gst/#NP", "Guest #NP (segment not present) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestTS,            "/HM/CPU%d/Exit/Trap/Gst/#TS", "Guest #TS (task switch) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestOF,            "/HM/CPU%d/Exit/Trap/Gst/#OF", "Guest #OF (overflow) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestGP,            "/HM/CPU%d/Exit/Trap/Gst/#GP", "Guest #GP (general protection) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestDE,            "/HM/CPU%d/Exit/Trap/Gst/#DE", "Guest #DE (divide error) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestDF,            "/HM/CPU%d/Exit/Trap/Gst/#DF", "Guest #DF (double fault) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestBR,            "/HM/CPU%d/Exit/Trap/Gst/#BR", "Guest #BR (boundary range exceeded) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestAC,            "/HM/CPU%d/Exit/Trap/Gst/#AC", "Guest #AC (alignment check) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestDB,            "/HM/CPU%d/Exit/Trap/Gst/#DB", "Guest #DB (debug) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestMF,            "/HM/CPU%d/Exit/Trap/Gst/#MF", "Guest #MF (x87 FPU error, math fault) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestBP,            "/HM/CPU%d/Exit/Trap/Gst/#BP", "Guest #BP (breakpoint) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestXF,            "/HM/CPU%d/Exit/Trap/Gst/#XF", "Guest #XF (extended math fault, SIMD FPU) exception.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitGuestXcpUnk,        "/HM/CPU%d/Exit/Trap/Gst/Other", "Other guest exceptions.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitRdmsr,              "/HM/CPU%d/Exit/Instr/Rdmsr", "MSR read.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitWrmsr,              "/HM/CPU%d/Exit/Instr/Wrmsr", "MSR write.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitDRxWrite,           "/HM/CPU%d/Exit/Instr/DR-Write", "Debug register write.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitDRxRead,            "/HM/CPU%d/Exit/Instr/DR-Read", "Debug register read.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCR0Read,            "/HM/CPU%d/Exit/Instr/CR-Read/CR0", "CR0 read.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCR2Read,            "/HM/CPU%d/Exit/Instr/CR-Read/CR2", "CR2 read.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCR3Read,            "/HM/CPU%d/Exit/Instr/CR-Read/CR3", "CR3 read.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCR4Read,            "/HM/CPU%d/Exit/Instr/CR-Read/CR4", "CR4 read.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCR8Read,            "/HM/CPU%d/Exit/Instr/CR-Read/CR8", "CR8 read.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCR0Write,           "/HM/CPU%d/Exit/Instr/CR-Write/CR0", "CR0 write.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCR2Write,           "/HM/CPU%d/Exit/Instr/CR-Write/CR2", "CR2 write.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCR3Write,           "/HM/CPU%d/Exit/Instr/CR-Write/CR3", "CR3 write.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCR4Write,           "/HM/CPU%d/Exit/Instr/CR-Write/CR4", "CR4 write.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitCR8Write,           "/HM/CPU%d/Exit/Instr/CR-Write/CR8", "CR8 write.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitClts,               "/HM/CPU%d/Exit/Instr/CLTS", "CLTS instruction.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitLmsw,               "/HM/CPU%d/Exit/Instr/LMSW", "LMSW instruction.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitXdtrAccess,         "/HM/CPU%d/Exit/Instr/XdtrAccess", "GDTR, IDTR, LDTR access.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitIOWrite,            "/HM/CPU%d/Exit/Instr/IO/Write", "I/O write.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitIORead,             "/HM/CPU%d/Exit/Instr/IO/Read", "I/O read.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitIOStringWrite,      "/HM/CPU%d/Exit/Instr/IO/WriteString", "String I/O write.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitIOStringRead,       "/HM/CPU%d/Exit/Instr/IO/ReadString", "String I/O read.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitIntWindow,          "/HM/CPU%d/Exit/IntWindow", "Interrupt-window exit. Guest is ready to receive interrupts.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitExtInt,             "/HM/CPU%d/Exit/ExtInt", "Physical maskable interrupt (host).");
+        HM_REG_COUNTER(&pHmCpu->StatExitAll,                "/HM/CPU%u/Exit/All", "Total exits (including nested-guest exits).");
+        HM_REG_COUNTER(&pHmCpu->StatNestedExitAll,          "/HM/CPU%u/Exit/NestedGuest/All", "Total nested-guest exits.");
+        HM_REG_COUNTER(&pHmCpu->StatExitShadowNM,           "/HM/CPU%u/Exit/Trap/Shw/#NM", "Shadow #NM (device not available, no math co-processor) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestNM,            "/HM/CPU%u/Exit/Trap/Gst/#NM", "Guest #NM (device not available, no math co-processor) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitShadowPF,           "/HM/CPU%u/Exit/Trap/Shw/#PF", "Shadow #PF (page fault) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitShadowPFEM,         "/HM/CPU%u/Exit/Trap/Shw/#PF-EM", "#PF (page fault) exception going back to ring-3 for emulating the instruction.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestPF,            "/HM/CPU%u/Exit/Trap/Gst/#PF", "Guest #PF (page fault) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestUD,            "/HM/CPU%u/Exit/Trap/Gst/#UD", "Guest #UD (undefined opcode) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestSS,            "/HM/CPU%u/Exit/Trap/Gst/#SS", "Guest #SS (stack-segment fault) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestNP,            "/HM/CPU%u/Exit/Trap/Gst/#NP", "Guest #NP (segment not present) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestTS,            "/HM/CPU%u/Exit/Trap/Gst/#TS", "Guest #TS (task switch) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestOF,            "/HM/CPU%u/Exit/Trap/Gst/#OF", "Guest #OF (overflow) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestGP,            "/HM/CPU%u/Exit/Trap/Gst/#GP", "Guest #GP (general protection) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestDE,            "/HM/CPU%u/Exit/Trap/Gst/#DE", "Guest #DE (divide error) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestDF,            "/HM/CPU%u/Exit/Trap/Gst/#DF", "Guest #DF (double fault) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestBR,            "/HM/CPU%u/Exit/Trap/Gst/#BR", "Guest #BR (boundary range exceeded) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestAC,            "/HM/CPU%u/Exit/Trap/Gst/#AC", "Guest #AC (alignment check) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestDB,            "/HM/CPU%u/Exit/Trap/Gst/#DB", "Guest #DB (debug) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestMF,            "/HM/CPU%u/Exit/Trap/Gst/#MF", "Guest #MF (x87 FPU error, math fault) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestBP,            "/HM/CPU%u/Exit/Trap/Gst/#BP", "Guest #BP (breakpoint) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestXF,            "/HM/CPU%u/Exit/Trap/Gst/#XF", "Guest #XF (extended math fault, SIMD FPU) exception.");
+        HM_REG_COUNTER(&pHmCpu->StatExitGuestXcpUnk,        "/HM/CPU%u/Exit/Trap/Gst/Other", "Other guest exceptions.");
+        HM_REG_COUNTER(&pHmCpu->StatExitRdmsr,              "/HM/CPU%u/Exit/Instr/Rdmsr", "MSR read.");
+        HM_REG_COUNTER(&pHmCpu->StatExitWrmsr,              "/HM/CPU%u/Exit/Instr/Wrmsr", "MSR write.");
+        HM_REG_COUNTER(&pHmCpu->StatExitDRxWrite,           "/HM/CPU%u/Exit/Instr/DR-Write", "Debug register write.");
+        HM_REG_COUNTER(&pHmCpu->StatExitDRxRead,            "/HM/CPU%u/Exit/Instr/DR-Read", "Debug register read.");
+        HM_REG_COUNTER(&pHmCpu->StatExitCR0Read,            "/HM/CPU%u/Exit/Instr/CR-Read/CR0", "CR0 read.");
+        HM_REG_COUNTER(&pHmCpu->StatExitCR2Read,            "/HM/CPU%u/Exit/Instr/CR-Read/CR2", "CR2 read.");
+        HM_REG_COUNTER(&pHmCpu->StatExitCR3Read,            "/HM/CPU%u/Exit/Instr/CR-Read/CR3", "CR3 read.");
+        HM_REG_COUNTER(&pHmCpu->StatExitCR4Read,            "/HM/CPU%u/Exit/Instr/CR-Read/CR4", "CR4 read.");
+        HM_REG_COUNTER(&pHmCpu->StatExitCR8Read,            "/HM/CPU%u/Exit/Instr/CR-Read/CR8", "CR8 read.");
+        HM_REG_COUNTER(&pHmCpu->StatExitCR0Write,           "/HM/CPU%u/Exit/Instr/CR-Write/CR0", "CR0 write.");
+        HM_REG_COUNTER(&pHmCpu->StatExitCR2Write,           "/HM/CPU%u/Exit/Instr/CR-Write/CR2", "CR2 write.");
+        HM_REG_COUNTER(&pHmCpu->StatExitCR3Write,           "/HM/CPU%u/Exit/Instr/CR-Write/CR3", "CR3 write.");
+        HM_REG_COUNTER(&pHmCpu->StatExitCR4Write,           "/HM/CPU%u/Exit/Instr/CR-Write/CR4", "CR4 write.");
+        HM_REG_COUNTER(&pHmCpu->StatExitCR8Write,           "/HM/CPU%u/Exit/Instr/CR-Write/CR8", "CR8 write.");
+        HM_REG_COUNTER(&pHmCpu->StatExitClts,               "/HM/CPU%u/Exit/Instr/CLTS", "CLTS instruction.");
+        HM_REG_COUNTER(&pHmCpu->StatExitLmsw,               "/HM/CPU%u/Exit/Instr/LMSW", "LMSW instruction.");
+        HM_REG_COUNTER(&pHmCpu->StatExitXdtrAccess,         "/HM/CPU%u/Exit/Instr/XdtrAccess", "GDTR, IDTR, LDTR access.");
+        HM_REG_COUNTER(&pHmCpu->StatExitIOWrite,            "/HM/CPU%u/Exit/Instr/IO/Write", "I/O write.");
+        HM_REG_COUNTER(&pHmCpu->StatExitIORead,             "/HM/CPU%u/Exit/Instr/IO/Read", "I/O read.");
+        HM_REG_COUNTER(&pHmCpu->StatExitIOStringWrite,      "/HM/CPU%u/Exit/Instr/IO/WriteString", "String I/O write.");
+        HM_REG_COUNTER(&pHmCpu->StatExitIOStringRead,       "/HM/CPU%u/Exit/Instr/IO/ReadString", "String I/O read.");
+        HM_REG_COUNTER(&pHmCpu->StatExitIntWindow,          "/HM/CPU%u/Exit/IntWindow", "Interrupt-window exit. Guest is ready to receive interrupts.");
+        HM_REG_COUNTER(&pHmCpu->StatExitExtInt,             "/HM/CPU%u/Exit/ExtInt", "Physical maskable interrupt (host).");
 #endif
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitHostNmiInGC,        "/HM/CPU%d/Exit/HostNmiInGC", "Host NMI received while in guest context.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitHostNmiInGCIpi,     "/HM/CPU%d/Exit/HostNmiInGCIpi", "Host NMI received while in guest context dispatched using IPIs.");
+        HM_REG_COUNTER(&pHmCpu->StatExitHostNmiInGC,        "/HM/CPU%u/Exit/HostNmiInGC", "Host NMI received while in guest context.");
+        HM_REG_COUNTER(&pHmCpu->StatExitHostNmiInGCIpi,     "/HM/CPU%u/Exit/HostNmiInGCIpi", "Host NMI received while in guest context dispatched using IPIs.");
 #ifdef VBOX_WITH_STATISTICS
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitPreemptTimer,       "/HM/CPU%d/Exit/PreemptTimer", "VMX-preemption timer expired.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitTprBelowThreshold,  "/HM/CPU%d/Exit/TprBelowThreshold", "TPR lowered below threshold by the guest.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitTaskSwitch,         "/HM/CPU%d/Exit/TaskSwitch", "Task switch caused through task gate in IDT.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExitApicAccess,         "/HM/CPU%d/Exit/ApicAccess", "APIC access. Guest attempted to access memory at a physical address on the APIC-access page.");
-
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchTprMaskedIrq,     "/HM/CPU%d/Switch/TprMaskedIrq", "PDMGetInterrupt() signals TPR masks pending Irq.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchGuestIrq,         "/HM/CPU%d/Switch/IrqPending", "PDMGetInterrupt() cleared behind our back!?!.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchPendingHostIrq,   "/HM/CPU%d/Switch/PendingHostIrq", "Exit to ring-3 due to pending host interrupt before executing guest code.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchHmToR3FF,         "/HM/CPU%d/Switch/HmToR3FF", "Exit to ring-3 due to pending timers, EMT rendezvous, critical section etc.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchVmReq,            "/HM/CPU%d/Switch/VmReq", "Exit to ring-3 due to pending VM requests.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchPgmPoolFlush,     "/HM/CPU%d/Switch/PgmPoolFlush", "Exit to ring-3 due to pending PGM pool flush.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchDma,              "/HM/CPU%d/Switch/PendingDma", "Exit to ring-3 due to pending DMA requests.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchExitToR3,         "/HM/CPU%d/Switch/ExitToR3", "Exit to ring-3 (total).");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchLongJmpToR3,      "/HM/CPU%d/Switch/LongJmpToR3", "Longjump to ring-3.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchMaxResumeLoops,   "/HM/CPU%d/Switch/MaxResumeLoops", "Maximum VMRESUME inner-loop counter reached.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchHltToR3,          "/HM/CPU%d/Switch/HltToR3", "HLT causing us to go to ring-3.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchApicAccessToR3,   "/HM/CPU%d/Switch/ApicAccessToR3", "APIC access causing us to go to ring-3.");
+        HM_REG_COUNTER(&pHmCpu->StatExitPreemptTimer,       "/HM/CPU%u/Exit/PreemptTimer", "VMX-preemption timer expired.");
+        HM_REG_COUNTER(&pHmCpu->StatExitTprBelowThreshold,  "/HM/CPU%u/Exit/TprBelowThreshold", "TPR lowered below threshold by the guest.");
+        HM_REG_COUNTER(&pHmCpu->StatExitTaskSwitch,         "/HM/CPU%u/Exit/TaskSwitch", "Task switch caused through task gate in IDT.");
+        HM_REG_COUNTER(&pHmCpu->StatExitApicAccess,         "/HM/CPU%u/Exit/ApicAccess", "APIC access. Guest attempted to access memory at a physical address on the APIC-access page.");
+
+        HM_REG_COUNTER(&pHmCpu->StatSwitchTprMaskedIrq,     "/HM/CPU%u/Switch/TprMaskedIrq", "PDMGetInterrupt() signals TPR masks pending Irq.");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchGuestIrq,         "/HM/CPU%u/Switch/IrqPending", "PDMGetInterrupt() cleared behind our back!?!.");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchPendingHostIrq,   "/HM/CPU%u/Switch/PendingHostIrq", "Exit to ring-3 due to pending host interrupt before executing guest code.");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchHmToR3FF,         "/HM/CPU%u/Switch/HmToR3FF", "Exit to ring-3 due to pending timers, EMT rendezvous, critical section etc.");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchVmReq,            "/HM/CPU%u/Switch/VmReq", "Exit to ring-3 due to pending VM requests.");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchPgmPoolFlush,     "/HM/CPU%u/Switch/PgmPoolFlush", "Exit to ring-3 due to pending PGM pool flush.");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchDma,              "/HM/CPU%u/Switch/PendingDma", "Exit to ring-3 due to pending DMA requests.");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchExitToR3,         "/HM/CPU%u/Switch/ExitToR3", "Exit to ring-3 (total).");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchLongJmpToR3,      "/HM/CPU%u/Switch/LongJmpToR3", "Longjump to ring-3.");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchMaxResumeLoops,   "/HM/CPU%u/Switch/MaxResumeLoops", "Maximum VMRESUME inner-loop counter reached.");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchHltToR3,          "/HM/CPU%u/Switch/HltToR3", "HLT causing us to go to ring-3.");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchApicAccessToR3,   "/HM/CPU%u/Switch/ApicAccessToR3", "APIC access causing us to go to ring-3.");
 #endif
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchPreempt,          "/HM/CPU%d/Switch/Preempting", "EMT has been preempted while in HM context.");
+        HM_REG_COUNTER(&pHmCpu->StatSwitchPreempt,          "/HM/CPU%u/Switch/Preempting", "EMT has been preempted while in HM context.");
 #ifdef VBOX_WITH_STATISTICS
-        HM_REG_COUNTER(&pVCpu->hm.s.StatSwitchNstGstVmexit,     "/HM/CPU%d/Switch/NstGstVmexit", "Nested-guest VM-exit occurred.");
-
-        HM_REG_COUNTER(&pVCpu->hm.s.StatInjectInterrupt,        "/HM/CPU%d/EventInject/Interrupt", "Injected an external interrupt into the guest.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatInjectXcpt,             "/HM/CPU%d/EventInject/Trap", "Injected an exception into the guest.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatInjectReflect,          "/HM/CPU%d/EventInject/Reflect", "Reflecting an exception caused due to event injection.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatInjectConvertDF,        "/HM/CPU%d/EventInject/ReflectDF", "Injected a converted #DF caused due to event injection.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatInjectInterpret,        "/HM/CPU%d/EventInject/Interpret", "Falling back to interpreter for handling exception caused due to event injection.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatInjectReflectNPF,       "/HM/CPU%d/EventInject/ReflectNPF", "Reflecting event that caused an EPT violation / nested #PF.");
-
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushPage,              "/HM/CPU%d/Flush/Page", "Invalidating a guest page on all guest CPUs.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushPageManual,        "/HM/CPU%d/Flush/Page/Virt", "Invalidating a guest page using guest-virtual address.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushPhysPageManual,    "/HM/CPU%d/Flush/Page/Phys", "Invalidating a guest page using guest-physical address.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushTlb,               "/HM/CPU%d/Flush/TLB", "Forcing a full guest-TLB flush (ring-0).");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushTlbManual,         "/HM/CPU%d/Flush/TLB/Manual", "Request a full guest-TLB flush.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushTlbNstGst,         "/HM/CPU%d/Flush/TLB/NestedGuest", "Request a nested-guest-TLB flush.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushTlbWorldSwitch,    "/HM/CPU%d/Flush/TLB/CpuSwitch", "Forcing a full guest-TLB flush due to host-CPU reschedule or ASID-limit hit by another guest-VCPU.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatNoFlushTlbWorldSwitch,  "/HM/CPU%d/Flush/TLB/Skipped", "No TLB flushing required.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushEntire,            "/HM/CPU%d/Flush/TLB/Entire", "Flush the entire TLB (host + guest).");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushAsid,              "/HM/CPU%d/Flush/TLB/ASID", "Flushed guest-TLB entries for the current VPID.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushNestedPaging,      "/HM/CPU%d/Flush/TLB/NestedPaging", "Flushed guest-TLB entries for the current EPT.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushTlbInvlpgVirt,     "/HM/CPU%d/Flush/TLB/InvlpgVirt", "Invalidated a guest-TLB entry for a guest-virtual address.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatFlushTlbInvlpgPhys,     "/HM/CPU%d/Flush/TLB/InvlpgPhys", "Currently not possible, flushes entire guest-TLB.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatTlbShootdown,           "/HM/CPU%d/Flush/Shootdown/Page", "Inter-VCPU request to flush queued guest page.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatTlbShootdownFlush,      "/HM/CPU%d/Flush/Shootdown/TLB", "Inter-VCPU request to flush entire guest-TLB.");
-
-        HM_REG_COUNTER(&pVCpu->hm.s.StatTscParavirt,            "/HM/CPU%d/TSC/Paravirt", "Paravirtualized TSC in effect.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatTscOffset,              "/HM/CPU%d/TSC/Offset", "TSC offsetting is in effect.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatTscIntercept,           "/HM/CPU%d/TSC/Intercept", "Intercept TSC accesses.");
-
-        HM_REG_COUNTER(&pVCpu->hm.s.StatDRxArmed,               "/HM/CPU%d/Debug/Armed", "Loaded guest-debug state while loading guest-state.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatDRxContextSwitch,       "/HM/CPU%d/Debug/ContextSwitch", "Loaded guest-debug state on MOV DRx.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatDRxIoCheck,             "/HM/CPU%d/Debug/IOCheck", "Checking for I/O breakpoint.");
-
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExportMinimal,          "/HM/CPU%d/Export/Minimal", "VM-entry exporting minimal guest-state.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExportFull,             "/HM/CPU%d/Export/Full", "VM-entry exporting the full guest-state.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatLoadGuestFpu,           "/HM/CPU%d/Export/GuestFpu", "VM-entry loading the guest-FPU state.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatExportHostState,        "/HM/CPU%d/Export/HostState", "VM-entry exporting host-state.");
-
-        HM_REG_COUNTER(&pVCpu->hm.s.StatVmxCheckBadRmSelBase,   "/HM/CPU%d/VMXCheck/RMSelBase", "Could not use VMX due to unsuitable real-mode selector base.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatVmxCheckBadRmSelLimit,  "/HM/CPU%d/VMXCheck/RMSelLimit", "Could not use VMX due to unsuitable real-mode selector limit.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatVmxCheckBadRmSelAttr,   "/HM/CPU%d/VMXCheck/RMSelAttrs", "Could not use VMX due to unsuitable real-mode selector attributes.");
-
-        HM_REG_COUNTER(&pVCpu->hm.s.StatVmxCheckBadV86SelBase,  "/HM/CPU%d/VMXCheck/V86SelBase",  "Could not use VMX due to unsuitable v8086-mode selector base.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatVmxCheckBadV86SelLimit, "/HM/CPU%d/VMXCheck/V86SelLimit", "Could not use VMX due to unsuitable v8086-mode selector limit.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatVmxCheckBadV86SelAttr,  "/HM/CPU%d/VMXCheck/V86SelAttrs", "Could not use VMX due to unsuitable v8086-mode selector attributes.");
-
-        HM_REG_COUNTER(&pVCpu->hm.s.StatVmxCheckRmOk,           "/HM/CPU%d/VMXCheck/VMX_RM", "VMX execution in real (V86) mode OK.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatVmxCheckBadSel,         "/HM/CPU%d/VMXCheck/Selector", "Could not use VMX due to unsuitable selector.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatVmxCheckBadRpl,         "/HM/CPU%d/VMXCheck/RPL", "Could not use VMX due to unsuitable RPL.");
-        HM_REG_COUNTER(&pVCpu->hm.s.StatVmxCheckPmOk,           "/HM/CPU%d/VMXCheck/VMX_PM", "VMX execution in protected mode OK.");
-
-#undef HM_REG_COUNTER
+        HM_REG_COUNTER(&pHmCpu->StatSwitchNstGstVmexit,     "/HM/CPU%u/Switch/NstGstVmexit", "Nested-guest VM-exit occurred.");
+
+        HM_REG_COUNTER(&pHmCpu->StatInjectInterrupt,        "/HM/CPU%u/EventInject/Interrupt", "Injected an external interrupt into the guest.");
+        HM_REG_COUNTER(&pHmCpu->StatInjectXcpt,             "/HM/CPU%u/EventInject/Trap", "Injected an exception into the guest.");
+        HM_REG_COUNTER(&pHmCpu->StatInjectReflect,          "/HM/CPU%u/EventInject/Reflect", "Reflecting an exception caused due to event injection.");
+        HM_REG_COUNTER(&pHmCpu->StatInjectConvertDF,        "/HM/CPU%u/EventInject/ReflectDF", "Injected a converted #DF caused due to event injection.");
+        HM_REG_COUNTER(&pHmCpu->StatInjectInterpret,        "/HM/CPU%u/EventInject/Interpret", "Falling back to interpreter for handling exception caused due to event injection.");
+        HM_REG_COUNTER(&pHmCpu->StatInjectReflectNPF,       "/HM/CPU%u/EventInject/ReflectNPF", "Reflecting event that caused an EPT violation / nested #PF.");
+
+        HM_REG_COUNTER(&pHmCpu->StatFlushPage,              "/HM/CPU%u/Flush/Page", "Invalidating a guest page on all guest CPUs.");
+        HM_REG_COUNTER(&pHmCpu->StatFlushPageManual,        "/HM/CPU%u/Flush/Page/Virt", "Invalidating a guest page using guest-virtual address.");
+        HM_REG_COUNTER(&pHmCpu->StatFlushPhysPageManual,    "/HM/CPU%u/Flush/Page/Phys", "Invalidating a guest page using guest-physical address.");
+        HM_REG_COUNTER(&pHmCpu->StatFlushTlb,               "/HM/CPU%u/Flush/TLB", "Forcing a full guest-TLB flush (ring-0).");
+        HM_REG_COUNTER(&pHmCpu->StatFlushTlbManual,         "/HM/CPU%u/Flush/TLB/Manual", "Request a full guest-TLB flush.");
+        HM_REG_COUNTER(&pHmCpu->StatFlushTlbNstGst,         "/HM/CPU%u/Flush/TLB/NestedGuest", "Request a nested-guest-TLB flush.");
+        HM_REG_COUNTER(&pHmCpu->StatFlushTlbWorldSwitch,    "/HM/CPU%u/Flush/TLB/CpuSwitch", "Forcing a full guest-TLB flush due to host-CPU reschedule or ASID-limit hit by another guest-VCPU.");
+        HM_REG_COUNTER(&pHmCpu->StatNoFlushTlbWorldSwitch,  "/HM/CPU%u/Flush/TLB/Skipped", "No TLB flushing required.");
+        HM_REG_COUNTER(&pHmCpu->StatFlushEntire,            "/HM/CPU%u/Flush/TLB/Entire", "Flush the entire TLB (host + guest).");
+        HM_REG_COUNTER(&pHmCpu->StatFlushAsid,              "/HM/CPU%u/Flush/TLB/ASID", "Flushed guest-TLB entries for the current VPID.");
+        HM_REG_COUNTER(&pHmCpu->StatFlushNestedPaging,      "/HM/CPU%u/Flush/TLB/NestedPaging", "Flushed guest-TLB entries for the current EPT.");
+        HM_REG_COUNTER(&pHmCpu->StatFlushTlbInvlpgVirt,     "/HM/CPU%u/Flush/TLB/InvlpgVirt", "Invalidated a guest-TLB entry for a guest-virtual address.");
+        HM_REG_COUNTER(&pHmCpu->StatFlushTlbInvlpgPhys,     "/HM/CPU%u/Flush/TLB/InvlpgPhys", "Currently not possible, flushes entire guest-TLB.");
+        HM_REG_COUNTER(&pHmCpu->StatTlbShootdown,           "/HM/CPU%u/Flush/Shootdown/Page", "Inter-VCPU request to flush queued guest page.");
+        HM_REG_COUNTER(&pHmCpu->StatTlbShootdownFlush,      "/HM/CPU%u/Flush/Shootdown/TLB", "Inter-VCPU request to flush entire guest-TLB.");
+
+        HM_REG_COUNTER(&pHmCpu->StatTscParavirt,            "/HM/CPU%u/TSC/Paravirt", "Paravirtualized TSC in effect.");
+        HM_REG_COUNTER(&pHmCpu->StatTscOffset,              "/HM/CPU%u/TSC/Offset", "TSC offsetting is in effect.");
+        HM_REG_COUNTER(&pHmCpu->StatTscIntercept,           "/HM/CPU%u/TSC/Intercept", "Intercept TSC accesses.");
+
+        HM_REG_COUNTER(&pHmCpu->StatDRxArmed,               "/HM/CPU%u/Debug/Armed", "Loaded guest-debug state while loading guest-state.");
+        HM_REG_COUNTER(&pHmCpu->StatDRxContextSwitch,       "/HM/CPU%u/Debug/ContextSwitch", "Loaded guest-debug state on MOV DRx.");
+        HM_REG_COUNTER(&pHmCpu->StatDRxIoCheck,             "/HM/CPU%u/Debug/IOCheck", "Checking for I/O breakpoint.");
+
+        HM_REG_COUNTER(&pHmCpu->StatExportMinimal,          "/HM/CPU%u/Export/Minimal", "VM-entry exporting minimal guest-state.");
+        HM_REG_COUNTER(&pHmCpu->StatExportFull,             "/HM/CPU%u/Export/Full", "VM-entry exporting the full guest-state.");
+        HM_REG_COUNTER(&pHmCpu->StatLoadGuestFpu,           "/HM/CPU%u/Export/GuestFpu", "VM-entry loading the guest-FPU state.");
+        HM_REG_COUNTER(&pHmCpu->StatExportHostState,        "/HM/CPU%u/Export/HostState", "VM-entry exporting host-state.");
+
+        HM_REG_COUNTER(&pHmCpu->StatVmxCheckBadRmSelBase,   "/HM/CPU%u/VMXCheck/RMSelBase", "Could not use VMX due to unsuitable real-mode selector base.");
+        HM_REG_COUNTER(&pHmCpu->StatVmxCheckBadRmSelLimit,  "/HM/CPU%u/VMXCheck/RMSelLimit", "Could not use VMX due to unsuitable real-mode selector limit.");
+        HM_REG_COUNTER(&pHmCpu->StatVmxCheckBadRmSelAttr,   "/HM/CPU%u/VMXCheck/RMSelAttrs", "Could not use VMX due to unsuitable real-mode selector attributes.");
+
+        HM_REG_COUNTER(&pHmCpu->StatVmxCheckBadV86SelBase,  "/HM/CPU%u/VMXCheck/V86SelBase",  "Could not use VMX due to unsuitable v8086-mode selector base.");
+        HM_REG_COUNTER(&pHmCpu->StatVmxCheckBadV86SelLimit, "/HM/CPU%u/VMXCheck/V86SelLimit", "Could not use VMX due to unsuitable v8086-mode selector limit.");
+        HM_REG_COUNTER(&pHmCpu->StatVmxCheckBadV86SelAttr,  "/HM/CPU%u/VMXCheck/V86SelAttrs", "Could not use VMX due to unsuitable v8086-mode selector attributes.");
+
+        HM_REG_COUNTER(&pHmCpu->StatVmxCheckRmOk,           "/HM/CPU%u/VMXCheck/VMX_RM", "VMX execution in real (V86) mode OK.");
+        HM_REG_COUNTER(&pHmCpu->StatVmxCheckBadSel,         "/HM/CPU%u/VMXCheck/Selector", "Could not use VMX due to unsuitable selector.");
+        HM_REG_COUNTER(&pHmCpu->StatVmxCheckBadRpl,         "/HM/CPU%u/VMXCheck/RPL", "Could not use VMX due to unsuitable RPL.");
+        HM_REG_COUNTER(&pHmCpu->StatVmxCheckPmOk,           "/HM/CPU%u/VMXCheck/VMX_PM", "VMX execution in protected mode OK.");
 
         bool const fCpuSupportsVmx = ASMIsIntelCpu() || ASMIsViaCentaurCpu() || ASMIsShanghaiCpu();
@@ -826,7 +788,7 @@
          * Guest Exit reason stats.
          */
-        pVCpu->hm.s.paStatExitReason = NULL;
-        rc = MMHyperAlloc(pVM, MAX_EXITREASON_STAT * sizeof(*pVCpu->hm.s.paStatExitReason), 0 /* uAlignment */, MM_TAG_HM,
-                          (void **)&pVCpu->hm.s.paStatExitReason);
+        pHmCpu->paStatExitReason = NULL;
+        rc = MMHyperAlloc(pVM, MAX_EXITREASON_STAT * sizeof(*pHmCpu->paStatExitReason), 0 /* uAlignment */, MM_TAG_HM,
+                          (void **)&pHmCpu->paStatExitReason);
         AssertRCReturn(rc, rc);
 
@@ -838,6 +800,6 @@
                 if (pszExitName)
                 {
-                    rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.paStatExitReason[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED,
-                                         STAMUNIT_OCCURENCES, pszExitName, "/HM/CPU%d/Exit/Reason/%02x", i, j);
+                    rc = STAMR3RegisterF(pVM, &pHmCpu->paStatExitReason[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED,
+                                         STAMUNIT_OCCURENCES, pszExitName, "/HM/CPU%u/Exit/Reason/%02x", idCpu, j);
                     AssertRCReturn(rc, rc);
                 }
@@ -851,19 +813,14 @@
                 if (pszExitName)
                 {
-                    rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.paStatExitReason[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED,
-                                         STAMUNIT_OCCURENCES, pszExitName, "/HM/CPU%d/Exit/Reason/%02x", i, j);
-                    AssertRCReturn(rc, rc);
+                    rc = STAMR3RegisterF(pVM, &pHmCpu->paStatExitReason[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED,
+                                         STAMUNIT_OCCURENCES, pszExitName, "/HM/CPU%u/Exit/Reason/%02x", idCpu, 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);
-        AssertRCReturn(rc, 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 || !HMIsEnabled(pVM));
-# else
-        Assert(pVCpu->hm.s.paStatExitReasonR0 != NIL_RTR0PTR);
-# endif
+        HM_REG_COUNTER(&pHmCpu->StatExitReasonNpf, "/HM/CPU%u/Exit/Reason/#NPF", "Nested page faults");
+
+        pHmCpu->paStatExitReasonR0 = MMHyperR3ToR0(pVM, pHmCpu->paStatExitReason);
+        Assert(pHmCpu->paStatExitReasonR0 != NIL_RTR0PTR);
 
 #if defined(VBOX_WITH_NESTED_HWVIRT_SVM) || defined(VBOX_WITH_NESTED_HWVIRT_VMX)
@@ -871,7 +828,7 @@
          * Nested-guest VM-exit reason stats.
          */
-        pVCpu->hm.s.paStatNestedExitReason = NULL;
-        rc = MMHyperAlloc(pVM, MAX_EXITREASON_STAT * sizeof(*pVCpu->hm.s.paStatNestedExitReason), 0 /* uAlignment */, MM_TAG_HM,
-                          (void **)&pVCpu->hm.s.paStatNestedExitReason);
+        pHmCpu->paStatNestedExitReason = NULL;
+        rc = MMHyperAlloc(pVM, MAX_EXITREASON_STAT * sizeof(*pHmCpu->paStatNestedExitReason), 0 /* uAlignment */, MM_TAG_HM,
+                          (void **)&pHmCpu->paStatNestedExitReason);
         AssertRCReturn(rc, rc);
         if (fCpuSupportsVmx)
@@ -882,6 +839,6 @@
                 if (pszExitName)
                 {
-                    rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.paStatNestedExitReason[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED,
-                                         STAMUNIT_OCCURENCES, pszExitName, "/HM/CPU%d/Exit/NestedGuest/Reason/%02x", i, j);
+                    rc = STAMR3RegisterF(pVM, &pHmCpu->paStatNestedExitReason[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED,
+                                         STAMUNIT_OCCURENCES, pszExitName, "/HM/CPU%u/Exit/NestedGuest/Reason/%02x", idCpu, j);
                     AssertRC(rc);
                 }
@@ -895,19 +852,13 @@
                 if (pszExitName)
                 {
-                    rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.paStatNestedExitReason[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED,
-                                         STAMUNIT_OCCURENCES, pszExitName, "/HM/CPU%d/Exit/NestedGuest/Reason/%02x", i, j);
+                    rc = STAMR3RegisterF(pVM, &pHmCpu->paStatNestedExitReason[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED,
+                                         STAMUNIT_OCCURENCES, pszExitName, "/HM/CPU%u/Exit/NestedGuest/Reason/%02x", idCpu, j);
                     AssertRC(rc);
                 }
             }
         }
-        rc = STAMR3RegisterF(pVM, &pVCpu->hm.s.StatNestedExitReasonNpf, STAMTYPE_COUNTER, STAMVISIBILITY_USED,
-                             STAMUNIT_OCCURENCES, "Nested page fault", "/HM/CPU%d/Exit/NestedGuest/Reason/#NPF", i);
-        AssertRCReturn(rc, rc);
-        pVCpu->hm.s.paStatNestedExitReasonR0 = MMHyperR3ToR0(pVM, pVCpu->hm.s.paStatNestedExitReason);
-# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
-        Assert(pVCpu->hm.s.paStatNestedExitReasonR0 != NIL_RTR0PTR || !HMIsEnabled(pVM));
-# else
-        Assert(pVCpu->hm.s.paStatNestedExitReasonR0 != NIL_RTR0PTR);
-# endif
+        HM_REG_COUNTER(&pHmCpu->StatNestedExitReasonNpf, "/HM/CPU%u/Exit/NestedGuest/Reason/#NPF", "Nested page faults");
+        pHmCpu->paStatNestedExitReasonR0 = MMHyperR3ToR0(pVM, pHmCpu->paStatNestedExitReason);
+        Assert(pHmCpu->paStatNestedExitReasonR0 != NIL_RTR0PTR);
 #endif
 
@@ -915,20 +866,21 @@
          * Injected events stats.
          */
-        rc = MMHyperAlloc(pVM, sizeof(STAMCOUNTER) * 256, 8, MM_TAG_HM, (void **)&pVCpu->hm.s.paStatInjectedIrqs);
+        rc = MMHyperAlloc(pVM, sizeof(STAMCOUNTER) * 256, 8, MM_TAG_HM, (void **)&pHmCpu->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 || !HMIsEnabled(pVM));
-# else
-        Assert(pVCpu->hm.s.paStatInjectedIrqsR0 != NIL_RTR0PTR);
-# endif
+        pHmCpu->paStatInjectedIrqsR0 = MMHyperR3ToR0(pVM, pHmCpu->paStatInjectedIrqs);
+        Assert(pHmCpu->paStatInjectedIrqsR0 != NIL_RTR0PTR);
         for (unsigned j = 0; j < 255; j++)
         {
-            STAMR3RegisterF(pVM, &pVCpu->hm.s.paStatInjectedIrqs[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
-                            "Injected event.",
-                            (j < 0x20) ? "/HM/CPU%d/EventInject/InjectTrap/%02X" : "/HM/CPU%d/EventInject/InjectIRQ/%02X", i, j);
+            rc = STAMR3RegisterF(pVM, &pHmCpu->paStatInjectedIrqs[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED,
+                                 STAMUNIT_OCCURENCES, "Injected events.",
+                                 j < 0x20 ? "/HM/CPU%u/EventInject/InjectTrap/%02X" : "/HM/CPU%u/EventInject/InjectIRQ/%02X",
+                                 idCpu, j);
+            AssertRC(rc);
         }
 
 #endif /* VBOX_WITH_STATISTICS */
+#undef HM_REG_COUNTER
+#undef HM_REG_PROFILE
+#undef HM_REG_STAT
     }
 
@@ -967,7 +919,7 @@
 /** @todo r=bird: HM shouldn't be doing this crap. */
     /* Reinit the paging mode to force the new shadow mode. */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         PGMHCChangeMode(pVM, pVCpu, PGMMODE_REAL);
     }
@@ -1094,7 +1046,7 @@
     /** @todo Move this out of of CPUMCTX and into some ring-0 only HM structure.
      *        That will require a little bit of work, of course. */
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-    {
-        PVMCPU   pVCpu   = &pVM->aCpus[iCpu];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU   pVCpu   = pVM->apCpusR3[idCpu];
         PCPUMCTX pCpuCtx = &pVCpu->cpum.GstCtx;
         pCpuCtx->fWorldSwitcher &= ~(CPUMCTX_WSF_IBPB_EXIT | CPUMCTX_WSF_IBPB_ENTRY);
@@ -1110,5 +1062,5 @@
         if (pVM->cpum.ro.HostFeatures.fMdsClear && pVM->hm.s.fMdsClearOnVmEntry)
             pCpuCtx->fWorldSwitcher |= CPUMCTX_WSF_MDS_ENTRY;
-        if (iCpu == 0)
+        if (idCpu == 0)
             LogRel(("HM: fWorldSwitcher=%#x (fIbpbOnVmExit=%RTbool fIbpbOnVmEntry=%RTbool fL1dFlushOnVmEntry=%RTbool); fL1dFlushOnSched=%RTbool fMdsClearOnVmEntry=%RTbool\n",
                     pCpuCtx->fWorldSwitcher, pVM->hm.s.fIbpbOnVmExit, pVM->hm.s.fIbpbOnVmEntry, pVM->hm.s.fL1dFlushOnVmEntry,
@@ -1525,9 +1477,9 @@
 
     LogRel(("HM: APIC-access page physaddr         = %#RHp\n",  pVM->hm.s.vmx.HCPhysApicAccess));
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PCVMXVMCSINFO pVmcsInfo = &pVM->aCpus[i].hm.s.vmx.VmcsInfo;
-        LogRel(("HM: VCPU%3d: MSR bitmap physaddr      = %#RHp\n", i, pVmcsInfo->HCPhysMsrBitmap));
-        LogRel(("HM: VCPU%3d: VMCS physaddr            = %#RHp\n", i, pVmcsInfo->HCPhysVmcs));
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PCVMXVMCSINFO pVmcsInfo = &pVM->apCpusR3[idCpu]->hm.s.vmx.VmcsInfo;
+        LogRel(("HM: VCPU%3d: MSR bitmap physaddr      = %#RHp\n", idCpu, pVmcsInfo->HCPhysMsrBitmap));
+        LogRel(("HM: VCPU%3d: VMCS physaddr            = %#RHp\n", idCpu, pVmcsInfo->HCPhysVmcs));
     }
 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
@@ -1535,9 +1487,9 @@
     {
         LogRel(("HM: Nested-guest:\n"));
-        for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        {
-            PCVMXVMCSINFO pVmcsInfoNstGst = &pVM->aCpus[i].hm.s.vmx.VmcsInfoNstGst;
-            LogRel(("HM: VCPU%3d:   MSR bitmap physaddr    = %#RHp\n", i, pVmcsInfoNstGst->HCPhysMsrBitmap));
-            LogRel(("HM: VCPU%3d:   VMCS physaddr          = %#RHp\n", i, pVmcsInfoNstGst->HCPhysVmcs));
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            PCVMXVMCSINFO pVmcsInfoNstGst = &pVM->aCpus[idCpu]->hm.s.vmx.VmcsInfoNstGst;
+            LogRel(("HM: VCPU%3d:   MSR bitmap physaddr    = %#RHp\n", idCpu, pVmcsInfoNstGst->HCPhysMsrBitmap));
+            LogRel(("HM: VCPU%3d:   VMCS physaddr          = %#RHp\n", idCpu, pVmcsInfoNstGst->HCPhysVmcs));
         }
     }
@@ -1636,9 +1588,9 @@
     {
         LogRel(("HM: VMX setup failed with rc=%Rrc!\n", rc));
-        for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        {
-            PVMCPU pVCpu = &pVM->aCpus[i];
-            LogRel(("HM: CPU[%u] Last instruction error  %#x\n", i, pVCpu->hm.s.vmx.LastError.u32InstrError));
-            LogRel(("HM: CPU[%u] HM error                %#x (%u)\n", i, pVCpu->hm.s.u32HMError, pVCpu->hm.s.u32HMError));
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+            LogRel(("HM: CPU[%u] Last instruction error  %#x\n", idCpu, pVCpu->hm.s.vmx.LastError.u32InstrError));
+            LogRel(("HM: CPU[%u] HM error                %#x (%u)\n", idCpu, pVCpu->hm.s.u32HMError, pVCpu->hm.s.u32HMError));
         }
         HMR3CheckError(pVM, rc);
@@ -1887,7 +1839,7 @@
     if (VMR3GetState(pVM) == VMSTATE_LOADING)
     {
-        for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        {
-            PVMCPU pVCpu = &pVM->aCpus[i];
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            PVMCPU pVCpu = pVM->apCpusR3[idCpu];
             pVCpu->hm.s.enmShadowMode = PGMGetShadowMode(pVCpu);
         }
@@ -1925,9 +1877,8 @@
 static int hmR3TermCPU(PVM pVM)
 {
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i]; NOREF(pVCpu);
-
 #ifdef VBOX_WITH_STATISTICS
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu]; NOREF(pVCpu);
         if (pVCpu->hm.s.paStatExitReason)
         {
@@ -1950,7 +1901,9 @@
         }
 # endif
+    }
+#else
+    RT_NOREF(pVM);
 #endif
-    }
-    return 0;
+    return VINF_SUCCESS;
 }
 
@@ -1999,10 +1952,6 @@
         hmR3DisableRawMode(pVM);
 
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[i];
-
-        HMR3ResetCpu(pVCpu);
-    }
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        HMR3ResetCpu(pVM->apCpusR3[idCpu]);
 
     /* Clear all patch information. */
@@ -2941,9 +2890,9 @@
 VMMR3_INT_DECL(void) HMR3CheckError(PVM pVM, int iStatusCode)
 {
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
         /** @todo r=ramshankar: Are all EMTs out of ring-0 at this point!? If not, we
          *  might be getting inaccurate values for non-guru'ing EMTs. */
-        PVMCPU        pVCpu = &pVM->aCpus[i];
+        PVMCPU        pVCpu = pVM->apCpusR3[idCpu];
         PCVMXVMCSINFO pVmcsInfo = hmGetVmxActiveVmcsInfo(pVCpu);
         bool const    fNstGstVmcsActive = pVCpu->hm.s.vmx.fSwitchedToNstGstVmcs;
@@ -2953,10 +2902,10 @@
             {
                 LogRel(("HM: VERR_VMX_INVALID_VMCS_PTR:\n"));
-                LogRel(("HM: CPU[%u] %s VMCS active\n", i, fNstGstVmcsActive ? "Nested-guest" : "Guest"));
-                LogRel(("HM: CPU[%u] Current pointer      %#RHp vs %#RHp\n", i, pVCpu->hm.s.vmx.LastError.HCPhysCurrentVmcs,
+                LogRel(("HM: CPU[%u] %s VMCS active\n", idCpu, fNstGstVmcsActive ? "Nested-guest" : "Guest"));
+                LogRel(("HM: CPU[%u] Current pointer      %#RHp vs %#RHp\n", idCpu, pVCpu->hm.s.vmx.LastError.HCPhysCurrentVmcs,
                                                                                 pVmcsInfo->HCPhysVmcs));
-                LogRel(("HM: CPU[%u] Current VMCS version %#x\n", i, pVCpu->hm.s.vmx.LastError.u32VmcsRev));
-                LogRel(("HM: CPU[%u] Entered Host Cpu     %u\n",  i, pVCpu->hm.s.vmx.LastError.idEnteredCpu));
-                LogRel(("HM: CPU[%u] Current Host Cpu     %u\n",  i, pVCpu->hm.s.vmx.LastError.idCurrentCpu));
+                LogRel(("HM: CPU[%u] Current VMCS version %#x\n", idCpu, pVCpu->hm.s.vmx.LastError.u32VmcsRev));
+                LogRel(("HM: CPU[%u] Entered Host Cpu     %u\n",  idCpu, pVCpu->hm.s.vmx.LastError.idEnteredCpu));
+                LogRel(("HM: CPU[%u] Current Host Cpu     %u\n",  idCpu, pVCpu->hm.s.vmx.LastError.idCurrentCpu));
                 break;
             }
@@ -2965,24 +2914,24 @@
             {
                 LogRel(("HM: VERR_VMX_UNABLE_TO_START_VM:\n"));
-                LogRel(("HM: CPU[%u] %s VMCS active\n", i, fNstGstVmcsActive ? "Nested-guest" : "Guest"));
-                LogRel(("HM: CPU[%u] Instruction error    %#x\n", i, pVCpu->hm.s.vmx.LastError.u32InstrError));
-                LogRel(("HM: CPU[%u] Exit reason          %#x\n", i, pVCpu->hm.s.vmx.LastError.u32ExitReason));
+                LogRel(("HM: CPU[%u] %s VMCS active\n", idCpu, fNstGstVmcsActive ? "Nested-guest" : "Guest"));
+                LogRel(("HM: CPU[%u] Instruction error    %#x\n", idCpu, pVCpu->hm.s.vmx.LastError.u32InstrError));
+                LogRel(("HM: CPU[%u] Exit reason          %#x\n", idCpu, pVCpu->hm.s.vmx.LastError.u32ExitReason));
 
                 if (   pVCpu->hm.s.vmx.LastError.u32InstrError == VMXINSTRERR_VMLAUNCH_NON_CLEAR_VMCS
                     || pVCpu->hm.s.vmx.LastError.u32InstrError == VMXINSTRERR_VMRESUME_NON_LAUNCHED_VMCS)
                 {
-                    LogRel(("HM: CPU[%u] Entered Host Cpu     %u\n",  i, pVCpu->hm.s.vmx.LastError.idEnteredCpu));
-                    LogRel(("HM: CPU[%u] Current Host Cpu     %u\n",  i, pVCpu->hm.s.vmx.LastError.idCurrentCpu));
+                    LogRel(("HM: CPU[%u] Entered Host Cpu     %u\n",  idCpu, pVCpu->hm.s.vmx.LastError.idEnteredCpu));
+                    LogRel(("HM: CPU[%u] Current Host Cpu     %u\n",  idCpu, pVCpu->hm.s.vmx.LastError.idCurrentCpu));
                 }
                 else if (pVCpu->hm.s.vmx.LastError.u32InstrError == VMXINSTRERR_VMENTRY_INVALID_CTLS)
                 {
-                    hmR3CheckErrorLogVmcsCtls(i, pVmcsInfo);
-                    LogRel(("HM: CPU[%u] HCPhysMsrBitmap      %#RHp\n",  i, pVmcsInfo->HCPhysMsrBitmap));
-                    LogRel(("HM: CPU[%u] HCPhysGuestMsrLoad   %#RHp\n",  i, pVmcsInfo->HCPhysGuestMsrLoad));
-                    LogRel(("HM: CPU[%u] HCPhysGuestMsrStore  %#RHp\n",  i, pVmcsInfo->HCPhysGuestMsrStore));
-                    LogRel(("HM: CPU[%u] HCPhysHostMsrLoad    %#RHp\n",  i, pVmcsInfo->HCPhysHostMsrLoad));
-                    LogRel(("HM: CPU[%u] cEntryMsrLoad        %u\n",     i, pVmcsInfo->cEntryMsrLoad));
-                    LogRel(("HM: CPU[%u] cExitMsrStore        %u\n",     i, pVmcsInfo->cExitMsrStore));
-                    LogRel(("HM: CPU[%u] cExitMsrLoad         %u\n",     i, pVmcsInfo->cExitMsrLoad));
+                    hmR3CheckErrorLogVmcsCtls(idCpu, pVmcsInfo);
+                    LogRel(("HM: CPU[%u] HCPhysMsrBitmap      %#RHp\n",  idCpu, pVmcsInfo->HCPhysMsrBitmap));
+                    LogRel(("HM: CPU[%u] HCPhysGuestMsrLoad   %#RHp\n",  idCpu, pVmcsInfo->HCPhysGuestMsrLoad));
+                    LogRel(("HM: CPU[%u] HCPhysGuestMsrStore  %#RHp\n",  idCpu, pVmcsInfo->HCPhysGuestMsrStore));
+                    LogRel(("HM: CPU[%u] HCPhysHostMsrLoad    %#RHp\n",  idCpu, pVmcsInfo->HCPhysHostMsrLoad));
+                    LogRel(("HM: CPU[%u] cEntryMsrLoad        %u\n",     idCpu, pVmcsInfo->cEntryMsrLoad));
+                    LogRel(("HM: CPU[%u] cExitMsrStore        %u\n",     idCpu, pVmcsInfo->cExitMsrStore));
+                    LogRel(("HM: CPU[%u] cExitMsrLoad         %u\n",     idCpu, pVmcsInfo->cExitMsrLoad));
                 }
                 /** @todo Log VM-entry event injection control fields
@@ -2995,5 +2944,5 @@
             {
                 LogRel(("HM: VERR_VMX_INVALID_GUEST_STATE:\n"));
-                hmR3CheckErrorLogVmcsCtls(i, pVmcsInfo);
+                hmR3CheckErrorLogVmcsCtls(idCpu, pVmcsInfo);
                 break;
             }
@@ -3041,10 +2990,11 @@
     Log(("hmR3Save:\n"));
 
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        Assert(!pVM->aCpus[i].hm.s.Event.fPending);
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        Assert(!pVCpu->hm.s.Event.fPending);
         if (pVM->cpum.ro.GuestFeatures.fSvm)
         {
-            PCSVMNESTEDVMCBCACHE pVmcbNstGstCache = &pVM->aCpus[i].hm.s.svm.NstGstVmcbCache;
+            PCSVMNESTEDVMCBCACHE pVmcbNstGstCache = &pVCpu->hm.s.svm.NstGstVmcbCache;
             rc  = SSMR3PutBool(pSSM, pVmcbNstGstCache->fCacheValid);
             rc |= SSMR3PutU16(pSSM,  pVmcbNstGstCache->u16InterceptRdCRx);
@@ -3125,6 +3075,7 @@
      * Load per-VCPU state.
      */
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         if (uVersion >= HM_SAVED_STATE_VERSION_SVM_NESTED_HWVIRT)
         {
@@ -3132,5 +3083,5 @@
             if (pVM->cpum.ro.GuestFeatures.fSvm)
             {
-                PSVMNESTEDVMCBCACHE pVmcbNstGstCache = &pVM->aCpus[i].hm.s.svm.NstGstVmcbCache;
+                PSVMNESTEDVMCBCACHE pVmcbNstGstCache = &pVCpu->hm.s.svm.NstGstVmcbCache;
                 rc  = SSMR3GetBool(pSSM, &pVmcbNstGstCache->fCacheValid);
                 rc |= SSMR3GetU16(pSSM,  &pVmcbNstGstCache->u16InterceptRdCRx);
@@ -3152,7 +3103,7 @@
         {
             /* Pending HM event (obsolete for a long time since TPRM holds the info.) */
-            rc  = SSMR3GetU32(pSSM, &pVM->aCpus[i].hm.s.Event.fPending);
-            rc |= SSMR3GetU32(pSSM, &pVM->aCpus[i].hm.s.Event.u32ErrCode);
-            rc |= SSMR3GetU64(pSSM, &pVM->aCpus[i].hm.s.Event.u64IntInfo);
+            rc  = SSMR3GetU32(pSSM, &pVCpu->hm.s.Event.fPending);
+            rc |= SSMR3GetU32(pSSM, &pVCpu->hm.s.Event.u32ErrCode);
+            rc |= SSMR3GetU64(pSSM, &pVCpu->hm.s.Event.u64IntInfo);
 
             /* VMX fWasInRealMode related data. */
@@ -3228,5 +3179,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     if (HMIsEnabled(pVM))
@@ -3275,5 +3226,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     if (HMIsEnabled(pVM))
@@ -3305,5 +3256,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     bool const fSvmEnabled = HMR3IsSvmEnabled(pVM->pUVM);
Index: /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_EM
 #include <VBox/vmm/iem.h>
@@ -66,5 +67,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
 
         pVCpu->iem.s.CodeTlb.uTlbRevision = pVCpu->iem.s.DataTlb.uTlbRevision = uInitialTlbRevision;
@@ -154,8 +155,8 @@
         else
         {
-            pVCpu->iem.s.enmCpuVendor             = pVM->aCpus[0].iem.s.enmCpuVendor;
-            pVCpu->iem.s.enmHostCpuVendor         = pVM->aCpus[0].iem.s.enmHostCpuVendor;
+            pVCpu->iem.s.enmCpuVendor             = pVM->apCpusR3[0]->iem.s.enmCpuVendor;
+            pVCpu->iem.s.enmHostCpuVendor         = pVM->apCpusR3[0]->iem.s.enmHostCpuVendor;
 #if IEM_CFG_TARGET_CPU == IEMTARGETCPU_DYNAMIC
-            pVCpu->iem.s.uTargetCpu               = pVM->aCpus[0].iem.s.uTargetCpu;
+            pVCpu->iem.s.uTargetCpu               = pVM->apCpusR3[0]->iem.s.uTargetCpu;
 #endif
         }
@@ -175,5 +176,5 @@
     if (pVM->cpum.ro.GuestFeatures.fVmx)
     {
-        PVMCPU pVCpu0 = &pVM->aCpus[0];
+        PVMCPU pVCpu0 = pVM->apCpusR3[0];
         int rc = PGMR3HandlerPhysicalTypeRegister(pVM, PGMPHYSHANDLERKIND_ALL, iemVmxApicAccessPageHandler,
                                                   NULL /* pszModR0 */,
@@ -196,5 +197,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         MMR3HeapFree(pVCpu->iem.s.pStatsR3);
         pVCpu->iem.s.pStatsR3 = NULL;
Index: /trunk/src/VBox/VMM/VMMR3/IOM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/IOM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/IOM.cpp	(revision 80191)
@@ -106,4 +106,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_IOM
 #include <VBox/vmm/iom.h>
@@ -260,8 +261,8 @@
      */
     IOM_LOCK_EXCL(pVM);
-    VMCPUID iCpu = pVM->cCpus;
-    while (iCpu-- > 0)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[iCpu];
+    VMCPUID idCpu = pVM->cCpus;
+    while (idCpu-- > 0)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         pVCpu->iom.s.pRangeLastReadR0  = NIL_RTR0PTR;
         pVCpu->iom.s.pRangeLastWriteR0 = NIL_RTR0PTR;
@@ -319,8 +320,8 @@
      * Reset the raw-mode cache (don't bother relocating it).
      */
-    VMCPUID iCpu = pVM->cCpus;
-    while (iCpu-- > 0)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[iCpu];
+    VMCPUID idCpu = pVM->cCpus;
+    while (idCpu-- > 0)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         pVCpu->iom.s.pRangeLastReadRC  = NIL_RTRCPTR;
         pVCpu->iom.s.pRangeLastWriteRC = NIL_RTRCPTR;
Index: /trunk/src/VBox/VMM/VMMR3/MM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/MM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/MM.cpp	(revision 80191)
@@ -145,4 +145,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_MM
 #include <VBox/vmm/mm.h>
Index: /trunk/src/VBox/VMM/VMMR3/MMHeap.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/MMHeap.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/MMHeap.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_MM_HEAP
 #include <VBox/vmm/mm.h>
Index: /trunk/src/VBox/VMM/VMMR3/MMHyper.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/MMHyper.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/MMHyper.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_MM_HYPER
 #include <VBox/vmm/pgm.h>
@@ -152,5 +153,9 @@
          * Map the VM structure into the hypervisor space.
          */
-        AssertRelease(pVM->cbSelf == RT_UOFFSETOF_DYN(VM, aCpus[pVM->cCpus]));
+#ifdef VBOX_BUGREF_9217
+        AssertRelease(pVM->cbSelf >= sizeof(VMCPU) * pVM->cCpus + sizeof(*pVM));
+#else
+        AssertRelease(pVM->cbSelf >= sizeof(VMCPU));
+#endif
         RTGCPTR GCPtr;
         rc = MMR3HyperMapPages(pVM, pVM, pVM->pVMR0, RT_ALIGN_Z(pVM->cbSelf, PAGE_SIZE) >> PAGE_SHIFT, pVM->paVMPagesR3, "VM",
@@ -160,5 +165,5 @@
             pVM->pVMRC = (RTRCPTR)GCPtr;
             for (VMCPUID i = 0; i < pVM->cCpus; i++)
-                pVM->aCpus[i].pVMRC = pVM->pVMRC;
+                pVM->apCpusR3[i]->pVMRC = pVM->pVMRC;
 
             /* Reserve a page for fencing. */
Index: /trunk/src/VBox/VMM/VMMR3/MMPagePool.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/MMPagePool.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/MMPagePool.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_MM_POOL
 #include <VBox/vmm/mm.h>
Index: /trunk/src/VBox/VMM/VMMR3/MMUkHeap.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/MMUkHeap.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/MMUkHeap.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_MM_HEAP
 #include <VBox/vmm/mm.h>
Index: /trunk/src/VBox/VMM/VMMR3/NEMR3.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/NEMR3.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/NEMR3.cpp	(revision 80191)
@@ -30,4 +30,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_NEM
 #include <VBox/vmm/nem.h>
@@ -65,6 +66,9 @@
      */
     pVM->nem.s.u32Magic = NEM_MAGIC;
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-        pVM->aCpus[iCpu].nem.s.u32Magic = NEMCPU_MAGIC;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        pVCpu->nem.s.u32Magic = NEMCPU_MAGIC;
+    }
 
     /*
@@ -233,6 +237,9 @@
      */
     if (enmWhat == VMINITCOMPLETED_RING3)
-        for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-            pVM->aCpus[iCpu].nem.s.fGIMTrapXcptUD = GIMShouldTrapXcptUD(&pVM->aCpus[iCpu]);
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+            pVCpu->nem.s.fGIMTrapXcptUD = GIMShouldTrapXcptUD(pVCpu);
+        }
 
     /*
@@ -258,6 +265,6 @@
 {
     AssertReturn(pVM->nem.s.u32Magic == NEM_MAGIC, VERR_WRONG_ORDER);
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-        AssertReturn(pVM->aCpus[iCpu].nem.s.u32Magic == NEMCPU_MAGIC, VERR_WRONG_ORDER);
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        AssertReturn(pVM->apCpusR3[idCpu]->nem.s.u32Magic == NEMCPU_MAGIC, VERR_WRONG_ORDER);
 
     /* Do native termination. */
@@ -269,6 +276,9 @@
 
     /* Mark it as terminated. */
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-        pVM->aCpus[iCpu].nem.s.u32Magic = NEMCPU_MAGIC_DEAD;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        pVCpu->nem.s.u32Magic = NEMCPU_MAGIC_DEAD;
+    }
     pVM->nem.s.u32Magic = NEM_MAGIC_DEAD;
     return rc;
Index: /trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp	(revision 80191)
@@ -26,4 +26,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_NEM
 #define VMCPU_INCL_CPUM_GST_CTX
@@ -1192,7 +1193,7 @@
     pVM->nem.s.fA20Enabled = true;
 #if 0
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-    {
-        PNEMCPU pNemCpu = &pVM->aCpus[iCpu].nem.s;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PNEMCPU pNemCpu = &pVM->apCpusR3[idCpu]->nem.s;
     }
 #endif
@@ -1245,35 +1246,35 @@
 
                         /* Register release statistics */
-                        for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
+                        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
                         {
-                            PNEMCPU pNemCpu = &pVM->aCpus[iCpu].nem.s;
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitPortIo,          STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of port I/O exits",               "/NEM/CPU%u/ExitPortIo", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitMemUnmapped,     STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of unmapped memory exits",        "/NEM/CPU%u/ExitMemUnmapped", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitMemIntercept,    STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of intercepted memory exits",     "/NEM/CPU%u/ExitMemIntercept", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitHalt,            STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of HLT exits",                    "/NEM/CPU%u/ExitHalt", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitInterruptWindow, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of HLT exits",                    "/NEM/CPU%u/ExitInterruptWindow", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitCpuId,           STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of CPUID exits",                  "/NEM/CPU%u/ExitCpuId", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitMsr,             STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of MSR access exits",             "/NEM/CPU%u/ExitMsr", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitException,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of exception exits",              "/NEM/CPU%u/ExitException", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitExceptionBp,     STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of #BP exits",                    "/NEM/CPU%u/ExitExceptionBp", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitExceptionDb,     STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of #DB exits",                    "/NEM/CPU%u/ExitExceptionDb", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitExceptionUd,     STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of #UD exits",                    "/NEM/CPU%u/ExitExceptionUd", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitExceptionUdHandled, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of handled #UD exits",         "/NEM/CPU%u/ExitExceptionUdHandled", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatExitUnrecoverable,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of unrecoverable exits",          "/NEM/CPU%u/ExitUnrecoverable", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatGetMsgTimeout,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of get message timeouts/alerts",  "/NEM/CPU%u/GetMsgTimeout", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuSuccess,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of successful CPU stops",         "/NEM/CPU%u/StopCpuSuccess", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuPending,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of pending CPU stops",            "/NEM/CPU%u/StopCpuPending", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuPendingAlerts,STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of pending CPU stop alerts",      "/NEM/CPU%u/StopCpuPendingAlerts", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuPendingOdd,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of odd pending CPU stops (see code)", "/NEM/CPU%u/StopCpuPendingOdd", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatCancelChangedState,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel changed state",         "/NEM/CPU%u/CancelChangedState", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatCancelAlertedThread, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel alerted EMT",           "/NEM/CPU%u/CancelAlertedEMT", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnFFPre,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of pre execution FF breaks",      "/NEM/CPU%u/BreakOnFFPre", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnFFPost,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of post execution FF breaks",     "/NEM/CPU%u/BreakOnFFPost", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnCancel,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel execution breaks",      "/NEM/CPU%u/BreakOnCancel", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnStatus,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of status code breaks",           "/NEM/CPU%u/BreakOnStatus", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatImportOnDemand,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of on-demand state imports",      "/NEM/CPU%u/ImportOnDemand", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatImportOnReturn,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of state imports on loop return", "/NEM/CPU%u/ImportOnReturn", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatImportOnReturnSkipped, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of skipped state imports on loop return", "/NEM/CPU%u/ImportOnReturnSkipped", iCpu);
-                            STAMR3RegisterF(pVM, &pNemCpu->StatQueryCpuTick,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of TSC queries",                  "/NEM/CPU%u/QueryCpuTick", iCpu);
+                            PNEMCPU pNemCpu = &pVM->apCpusR3[idCpu]->nem.s;
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitPortIo,          STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of port I/O exits",               "/NEM/CPU%u/ExitPortIo", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitMemUnmapped,     STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of unmapped memory exits",        "/NEM/CPU%u/ExitMemUnmapped", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitMemIntercept,    STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of intercepted memory exits",     "/NEM/CPU%u/ExitMemIntercept", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitHalt,            STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of HLT exits",                    "/NEM/CPU%u/ExitHalt", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitInterruptWindow, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of HLT exits",                    "/NEM/CPU%u/ExitInterruptWindow", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitCpuId,           STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of CPUID exits",                  "/NEM/CPU%u/ExitCpuId", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitMsr,             STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of MSR access exits",             "/NEM/CPU%u/ExitMsr", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitException,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of exception exits",              "/NEM/CPU%u/ExitException", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitExceptionBp,     STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of #BP exits",                    "/NEM/CPU%u/ExitExceptionBp", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitExceptionDb,     STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of #DB exits",                    "/NEM/CPU%u/ExitExceptionDb", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitExceptionUd,     STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of #UD exits",                    "/NEM/CPU%u/ExitExceptionUd", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitExceptionUdHandled, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of handled #UD exits",         "/NEM/CPU%u/ExitExceptionUdHandled", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatExitUnrecoverable,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of unrecoverable exits",          "/NEM/CPU%u/ExitUnrecoverable", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatGetMsgTimeout,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of get message timeouts/alerts",  "/NEM/CPU%u/GetMsgTimeout", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuSuccess,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of successful CPU stops",         "/NEM/CPU%u/StopCpuSuccess", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuPending,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of pending CPU stops",            "/NEM/CPU%u/StopCpuPending", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuPendingAlerts,STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of pending CPU stop alerts",      "/NEM/CPU%u/StopCpuPendingAlerts", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatStopCpuPendingOdd,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of odd pending CPU stops (see code)", "/NEM/CPU%u/StopCpuPendingOdd", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatCancelChangedState,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel changed state",         "/NEM/CPU%u/CancelChangedState", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatCancelAlertedThread, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel alerted EMT",           "/NEM/CPU%u/CancelAlertedEMT", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnFFPre,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of pre execution FF breaks",      "/NEM/CPU%u/BreakOnFFPre", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnFFPost,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of post execution FF breaks",     "/NEM/CPU%u/BreakOnFFPost", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnCancel,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of cancel execution breaks",      "/NEM/CPU%u/BreakOnCancel", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnStatus,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of status code breaks",           "/NEM/CPU%u/BreakOnStatus", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatImportOnDemand,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of on-demand state imports",      "/NEM/CPU%u/ImportOnDemand", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatImportOnReturn,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of state imports on loop return", "/NEM/CPU%u/ImportOnReturn", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatImportOnReturnSkipped, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of skipped state imports on loop return", "/NEM/CPU%u/ImportOnReturnSkipped", idCpu);
+                            STAMR3RegisterF(pVM, &pNemCpu->StatQueryCpuTick,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of TSC queries",                  "/NEM/CPU%u/QueryCpuTick", idCpu);
                         }
 
@@ -1415,8 +1416,7 @@
      * Setup the EMTs.
      */
-    VMCPUID iCpu;
-    for (iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[iCpu];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
 
         pVCpu->nem.s.hNativeThreadHandle = (RTR3PTR)RTThreadGetNativeHandle(VMR3GetThreadHandle(pVCpu->pUVCpu));
@@ -1428,14 +1428,14 @@
 # endif
         {
-            hrc = WHvCreateVirtualProcessor(hPartition, iCpu, 0 /*fFlags*/);
+            hrc = WHvCreateVirtualProcessor(hPartition, idCpu, 0 /*fFlags*/);
             if (FAILED(hrc))
             {
                 NTSTATUS const rcNtLast  = RTNtLastStatusValue();
                 DWORD const    dwErrLast = RTNtLastErrorValue();
-                while (iCpu-- > 0)
+                while (idCpu-- > 0)
                 {
-                    HRESULT hrc2 = WHvDeleteVirtualProcessor(hPartition, iCpu);
+                    HRESULT hrc2 = WHvDeleteVirtualProcessor(hPartition, idCpu);
                     AssertLogRelMsg(SUCCEEDED(hrc2), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n",
-                                                      hPartition, iCpu, hrc2, RTNtLastStatusValue(),
+                                                      hPartition, idCpu, hrc2, RTNtLastStatusValue(),
                                                       RTNtLastErrorValue()));
                 }
@@ -1451,8 +1451,8 @@
         {
             VID_MAPPED_MESSAGE_SLOT MappedMsgSlot = { NULL, UINT32_MAX, UINT32_MAX };
-            if (g_pfnVidMessageSlotMap(hPartitionDevice, &MappedMsgSlot, iCpu))
+            if (g_pfnVidMessageSlotMap(hPartitionDevice, &MappedMsgSlot, idCpu))
             {
-                AssertLogRelMsg(MappedMsgSlot.iCpu == iCpu && MappedMsgSlot.uParentAdvisory == UINT32_MAX,
-                                ("%#x %#x (iCpu=%#x)\n", MappedMsgSlot.iCpu, MappedMsgSlot.uParentAdvisory, iCpu));
+                AssertLogRelMsg(MappedMsgSlot.iCpu == idCpu && MappedMsgSlot.uParentAdvisory == UINT32_MAX,
+                                ("%#x %#x (iCpu=%#x)\n", MappedMsgSlot.iCpu, MappedMsgSlot.uParentAdvisory, idCpu));
                 pVCpu->nem.s.pvMsgSlotMapping = MappedMsgSlot.pMsgBlock;
             }
@@ -1472,5 +1472,5 @@
      * Do some more ring-0 initialization now that we've got the partition handle.
      */
-    int rc = VMMR3CallR0Emt(pVM, &pVM->aCpus[0], VMMR0_DO_NEM_INIT_VM_PART_2, 0, NULL);
+    int rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_NEM_INIT_VM_PART_2, 0, NULL);
     if (RT_SUCCESS(rc))
     {
@@ -1478,5 +1478,5 @@
 
 #if 1
-        VMMR3CallR0Emt(pVM, &pVM->aCpus[0], VMMR0_DO_NEM_UPDATE_STATISTICS, 0, NULL);
+        VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_NEM_UPDATE_STATISTICS, 0, NULL);
         LogRel(("NEM: Memory balance: %#RX64 out of %#RX64 pages in use\n",
                 pVM->nem.s.R0Stats.cPagesInUse, pVM->nem.s.R0Stats.cPagesAvailable));
@@ -1497,5 +1497,5 @@
          * Poke and probe a little.
          */
-        PVMCPU              pVCpu = &pVM->aCpus[0];
+        PVMCPU              pVCpu = pVM->apCpusR3[0];
         uint32_t            aRegNames[1024];
         HV_REGISTER_VALUE   aRegValues[1024];
@@ -1625,9 +1625,10 @@
     if (hPartition != NULL)
     {
-        VMCPUID iCpu = pVM->nem.s.fCreatedEmts ? pVM->cCpus : 0;
-        LogRel(("NEM: Destroying partition %p with its %u VCpus...\n", hPartition, iCpu));
-        while (iCpu-- > 0)
+        VMCPUID idCpu = pVM->nem.s.fCreatedEmts ? pVM->cCpus : 0;
+        LogRel(("NEM: Destroying partition %p with its %u VCpus...\n", hPartition, idCpu));
+        while (idCpu-- > 0)
         {
-            pVM->aCpus[iCpu].nem.s.pvMsgSlotMapping = NULL;
+            PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+            pVCpu->nem.s.pvMsgSlotMapping = NULL;
 #ifndef NEM_WIN_USE_OUR_OWN_RUN_API
 # ifdef NEM_WIN_WITH_RING0_RUNLOOP
@@ -1635,7 +1636,7 @@
 # endif
             {
-                HRESULT hrc = WHvDeleteVirtualProcessor(hPartition, iCpu);
+                HRESULT hrc = WHvDeleteVirtualProcessor(hPartition, idCpu);
                 AssertLogRelMsg(SUCCEEDED(hrc), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n",
-                                                 hPartition, iCpu, hrc, RTNtLastStatusValue(),
+                                                 hPartition, idCpu, hrc, RTNtLastStatusValue(),
                                                  RTNtLastErrorValue()));
             }
Index: /trunk/src/VBox/VMM/VMMR3/PDM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDM.cpp	(revision 80191)
@@ -276,4 +276,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM
 #define PDMPCIDEV_INCLUDE_PRIVATE  /* Hack to get pdmpcidevint.h included at the right point. */
@@ -893,5 +894,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         SSMR3PutU32(pSSM, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC));
         SSMR3PutU32(pSSM, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC));
@@ -923,5 +924,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         LogFlow(("pdmR3LoadPrep: VCPU %u %s%s\n", idCpu,
                 VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC) ? " VMCPU_FF_INTERRUPT_APIC" : "",
@@ -941,5 +942,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
         VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
@@ -992,5 +993,5 @@
         for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
         {
-            PVMCPU pVCpu = &pVM->aCpus[idCpu];
+            PVMCPU pVCpu = pVM->apCpusR3[idCpu];
 
             /* APIC interrupt */
@@ -1636,5 +1637,5 @@
      */
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-        PDMR3ResetCpu(&pVM->aCpus[idCpu]);
+        PDMR3ResetCpu(pVM->apCpusR3[idCpu]);
     VM_FF_CLEAR(pVM, VM_FF_PDM_DMA);
 
@@ -1702,8 +1703,8 @@
      */
     bool     fOtherCpusActive = false;
-    VMCPUID  iCpu             = pVM->cCpus;
-    while (iCpu-- > 1)
-    {
-        EMSTATE enmState = EMGetState(&pVM->aCpus[iCpu]);
+    VMCPUID  idCpu            = pVM->cCpus;
+    while (idCpu-- > 1)
+    {
+        EMSTATE enmState = EMGetState(pVM->apCpusR3[idCpu]);
         if (   enmState != EMSTATE_WAIT_SIPI
             && enmState != EMSTATE_NONE)
Index: /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletion.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
 #include "PDMInternal.h"
Index: /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
 #include "PDMInternal.h"
Index: /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileFailsafe.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileFailsafe.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileFailsafe.cpp	(revision 80191)
@@ -21,4 +21,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
 #include <iprt/asm.h>
@@ -27,4 +28,6 @@
 
 #include "PDMAsyncCompletionFileInternal.h"
+
+
 
 /**
Index: /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileNormal.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileNormal.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFileNormal.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
 #include <iprt/types.h>
@@ -31,4 +32,8 @@
 #include "PDMAsyncCompletionFileInternal.h"
 
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
 /** The update period for the I/O load statistics in ms. */
 #define PDMACEPFILEMGR_LOAD_UPDATE_PERIOD   1000
Index: /trunk/src/VBox/VMM/VMMR3/PDMBlkCache.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMBlkCache.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMBlkCache.cpp	(revision 80191)
@@ -24,4 +24,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_BLK_CACHE
 #include "PDMInternal.h"
@@ -38,4 +39,8 @@
 #include "PDMBlkCacheInternal.h"
 
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
 #ifdef VBOX_STRICT
 # define PDMACFILECACHE_IS_CRITSECT_OWNER(Cache) \
Index: /trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM//_CRITSECT
 #include "PDMInternal.h"
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_DEVICE
 #define PDMPCIDEV_INCLUDE_PRIVATE  /* Hack to get pdmpcidevint.h included at the right point. */
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_DEVICE
 #include "PDMInternal.h"
@@ -53,5 +54,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM    pVM = pDevIns->Internal.s.pVMR3;
-    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+    PVMCPU pVCpu = pVM->apCpusR3[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
 
     /* IRQ state should be loaded as-is by "LoadExec". Changes can be made from LoadDone. */
@@ -67,5 +68,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM pVM = pDevIns->Internal.s.pVMR3;
-    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+    PVMCPU pVCpu = pVM->apCpusR3[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
 
     /* IRQ state should be loaded as-is by "LoadExec". Changes can be made from LoadDone. */
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_DEVICE
 #include "PDMInternal.h"
Index: /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_DRIVER
 #include "PDMInternal.h"
Index: /trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp	(revision 80191)
@@ -22,4 +22,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_LDR
 #include "PDMInternal.h"
Index: /trunk/src/VBox/VMM/VMMR3/PDMNetShaper.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMNetShaper.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMNetShaper.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_NET_SHAPER
 #include "PDMInternal.h"
Index: /trunk/src/VBox/VMM/VMMR3/PDMQueue.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMQueue.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMQueue.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_QUEUE
 #include "PDMInternal.h"
@@ -214,5 +215,5 @@
      * Validate input.
      */
-    VMCPU_ASSERT_EMT(&pVM->aCpus[0]);
+    VM_ASSERT_EMT0(pVM);
     if (!pfnCallback)
     {
@@ -264,5 +265,5 @@
      * Validate input.
      */
-    VMCPU_ASSERT_EMT(&pVM->aCpus[0]);
+    VM_ASSERT_EMT0(pVM);
     AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
 
@@ -310,5 +311,5 @@
      * Validate input.
      */
-    VMCPU_ASSERT_EMT(&pVM->aCpus[0]);
+    VM_ASSERT_EMT0(pVM);
     AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
 
@@ -354,5 +355,5 @@
      * Validate input.
      */
-    VMCPU_ASSERT_EMT(&pVM->aCpus[0]);
+    VM_ASSERT_EMT0(pVM);
     AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
 
Index: /trunk/src/VBox/VMM/VMMR3/PDMThread.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMThread.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMThread.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 /// @todo \#define LOG_GROUP LOG_GROUP_PDM_THREAD
 #include "PDMInternal.h"
Index: /trunk/src/VBox/VMM/VMMR3/PDMUsb.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMUsb.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PDMUsb.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PDM_DRIVER
 #include "PDMInternal.h"
Index: /trunk/src/VBox/VMM/VMMR3/PGM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PGM.cpp	(revision 80191)
@@ -615,4 +615,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PGM
 #include <VBox/vmm/dbgf.h>
@@ -753,5 +754,5 @@
      */
     AssertCompile(sizeof(pVM->pgm.s) <= sizeof(pVM->pgm.padding));
-    AssertCompile(sizeof(pVM->aCpus[0].pgm.s) <= sizeof(pVM->aCpus[0].pgm.padding));
+    AssertCompile(sizeof(pVM->apCpusR3[0]->pgm.s) <= sizeof(pVM->apCpusR3[0]->pgm.padding));
     AssertCompileMemberAlignment(PGM, CritSectX, sizeof(uintptr_t));
 
@@ -780,5 +781,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
         PPGMCPU pPGM = &pVCpu->pgm.s;
 
@@ -891,8 +892,9 @@
     pv = (uint8_t *)pv + RT_ALIGN_Z(sizeof(PGMSTATS), 64);
 
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-    {
-        pVM->aCpus[iCpu].pgm.s.pStatsR3 = (PGMCPUSTATS *)pv;
-        pVM->aCpus[iCpu].pgm.s.pStatsR0 = MMHyperCCToR0(pVM, pv);
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        pVCpu->pgm.s.pStatsR3 = (PGMCPUSTATS *)pv;
+        pVCpu->pgm.s.pStatsR0 = MMHyperCCToR0(pVM, pv);
 
         pv = (uint8_t *)pv + RT_ALIGN_Z(sizeof(PGMCPUSTATS), 64);
@@ -993,5 +995,5 @@
         for (VMCPUID i = 0; i < pVM->cCpus; i++)
         {
-            PVMCPU pVCpu = &pVM->aCpus[i];
+            PVMCPU pVCpu = pVM->apCpusR3[i];
             rc = PGMHCChangeMode(pVM, pVCpu, PGMMODE_REAL);
             if (RT_FAILURE(rc))
@@ -1068,5 +1070,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
 
         pVCpu->pgm.s.enmShadowMode     = PGMMODE_INVALID;
@@ -1390,5 +1392,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PPGMCPU pPgmCpu = &pVM->aCpus[idCpu].pgm.s;
+        PPGMCPU pPgmCpu = &pVM->apCpusR3[idCpu]->pgm.s;
 
 #define PGM_REG_COUNTER(a, b, c) \
@@ -1403,5 +1405,5 @@
 
 #ifdef VBOX_WITH_STATISTICS
-        PGMCPUSTATS *pCpuStats = pVM->aCpus[idCpu].pgm.s.pStatsR3;
+        PGMCPUSTATS *pCpuStats = pVM->apCpusR3[idCpu]->pgm.s.pStatsR3;
 
 # if 0 /* rarely useful; leave for debugging. */
@@ -1725,7 +1727,7 @@
      */
     uint64_t fMbzPageFrameMask = pVM->pgm.s.GCPhysInvAddrMask & UINT64_C(0x000ffffffffff000);
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-    {
-        PVMCPU pVCpu = &pVM->aCpus[iCpu];
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
 
         /** @todo The manuals are not entirely clear whether the physical
@@ -1846,5 +1848,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU  pVCpu = &pVM->aCpus[i];
+        PVMCPU  pVCpu = pVM->apCpusR3[i];
 
         uintptr_t idxShw = pVCpu->pgm.s.idxShadowModeData;
@@ -1994,5 +1996,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU          pVCpu  = &pVM->aCpus[i];
+        PVMCPU          pVCpu  = pVM->apCpusR3[i];
         uintptr_t const idxGst = pVCpu->pgm.s.idxGuestModeData;
         if (   idxGst < RT_ELEMENTS(g_aPgmGuestModeData)
@@ -2015,5 +2017,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU  pVCpu = &pVM->aCpus[i];
+        PVMCPU  pVCpu = pVM->apCpusR3[i];
 
         int rc = PGMHCChangeMode(pVM, pVCpu, PGMMODE_REAL);
@@ -2034,5 +2036,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
 
         pVCpu->pgm.s.fGst32BitPageSizeExtension = false;
@@ -2152,5 +2154,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
 
@@ -2302,5 +2304,5 @@
 {
     /** @todo SMP support!! */
-    PVMCPU pVCpu = &pVM->aCpus[0];
+    PVMCPU pVCpu = pVM->apCpusR3[0];
 
 /** @todo fix this! Convert the PGMR3DumpHierarchyHC functions to do guest stuff. */
Index: /trunk/src/VBox/VMM/VMMR3/PGMDbg.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMDbg.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PGMDbg.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PGM
 #include <VBox/vmm/pgm.h>
@@ -333,5 +334,5 @@
 
     /** @todo SMP support! */
-    PVMCPU pVCpu = &pVM->aCpus[0];
+    PVMCPU pVCpu = pVM->apCpusR3[0];
 
 /** @todo deal with HMA */
@@ -389,5 +390,5 @@
 
     /** @todo SMP support! */
-    PVMCPU pVCpu = &pVM->aCpus[0];
+    PVMCPU pVCpu = pVM->apCpusR3[0];
 
 /** @todo deal with HMA */
@@ -1848,5 +1849,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     uint32_t fFlags = DBGFPGDMP_FLAGS_HEADER | DBGFPGDMP_FLAGS_PRINT_CR3 | DBGFPGDMP_FLAGS_PAGE_INFO | DBGFPGDMP_FLAGS_SHADOW;
Index: /trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PGM
 #include <VBox/vmm/dbgf.h>
Index: /trunk/src/VBox/VMM/VMMR3/PGMMap.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMMap.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PGMMap.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PGM
 #include <VBox/vmm/dbgf.h>
@@ -206,5 +207,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
         VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
     }
@@ -265,5 +266,5 @@
             for (VMCPUID i = 0; i < pVM->cCpus; i++)
             {
-                PVMCPU pVCpu = &pVM->aCpus[i];
+                PVMCPU pVCpu = pVM->apCpusR3[i];
                 VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
             }
@@ -525,5 +526,5 @@
          */
         Assert(pVM->cCpus == 1);
-        PVMCPU pVCpu = &pVM->aCpus[0];
+        PVMCPU pVCpu = pVM->apCpusR3[0];
 
         /*
@@ -597,5 +598,5 @@
      * In PAE / PAE mode, make sure we don't cross page directories.
      */
-    PVMCPU pVCpu = &pVM->aCpus[0];
+    PVMCPU pVCpu = pVM->apCpusR3[0];
     if (    (   pVCpu->pgm.s.enmGuestMode  == PGMMODE_PAE
              || pVCpu->pgm.s.enmGuestMode  == PGMMODE_PAE_NX)
@@ -681,5 +682,5 @@
     {
         pVM->aCpus[idCpu].pgm.s.fSyncFlags &= ~PGM_SYNC_MONITOR_CR3;
-        VMCPU_FF_SET(&pVM->aCpus[idCpu], VMCPU_FF_PGM_SYNC_CR3);
+        VMCPU_FF_SET(pVM->apCpusR3[idCpu], VMCPU_FF_PGM_SYNC_CR3);
     }
     return VINF_SUCCESS;
@@ -715,5 +716,5 @@
         if (fResyncCR3)
             for (VMCPUID i = 0; i < pVM->cCpus; i++)
-                VMCPU_FF_SET(&pVM->aCpus[i], VMCPU_FF_PGM_SYNC_CR3);
+                VMCPU_FF_SET(pVM->apCpusR3[i], VMCPU_FF_PGM_SYNC_CR3);
     }
     return VINF_SUCCESS;
Index: /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PGM_PHYS
 #include <VBox/vmm/pgm.h>
@@ -1308,5 +1309,5 @@
     /* Flush the recompiler's TLB as well. */
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        CPUMSetChangedFlags(&pVM->aCpus[i], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
+        CPUMSetChangedFlags(pVM->apCpusR3[i], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
 
     AssertLogRelRC(rc);
@@ -1456,5 +1457,5 @@
     PGM_INVL_ALL_VCPU_TLBS(pVM);
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-        CPUMSetChangedFlags(&pVM->aCpus[idCpu], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
+        CPUMSetChangedFlags(pVM->apCpusR3[idCpu], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
 
     pgmUnlock(pVM);
@@ -4866,5 +4867,5 @@
         /** @todo also not really efficient to unmap a chunk that contains PD
          *  or PT pages. */
-        pgmR3PoolClearAllRendezvous(pVM, &pVM->aCpus[0], NULL /* no need to flush the REM TLB as we already did that above */);
+        pgmR3PoolClearAllRendezvous(pVM, pVM->apCpusR3[0], NULL /* no need to flush the REM TLB as we already did that above */);
 
         /*
@@ -4907,5 +4908,5 @@
                 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
                 {
-                    PPGMCPU pPGM = &pVM->aCpus[idCpu].pgm.s;
+                    PPGMCPU pPGM = &pVM->apCpusR3[idCpu]->pgm.s;
 
                     pPGM->pGst32BitPdR3    = NULL;
@@ -4926,5 +4927,5 @@
 
                     /* Flush REM TLBs. */
-                    CPUMSetChangedFlags(&pVM->aCpus[idCpu], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
+                    CPUMSetChangedFlags(pVM->apCpusR3[idCpu], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
                 }
 #ifdef VBOX_WITH_REM
Index: /trunk/src/VBox/VMM/VMMR3/PGMPool.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMPool.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PGMPool.cpp	(revision 80191)
@@ -96,4 +96,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PGM_POOL
 #include <VBox/vmm/pgm.h>
@@ -762,5 +763,5 @@
     /* Clear the PGM_SYNC_CLEAR_PGM_POOL flag on all VCPUs to prevent redundant flushes. */
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-        pVM->aCpus[idCpu].pgm.s.fSyncFlags &= ~PGM_SYNC_CLEAR_PGM_POOL;
+        pVM->apCpusR3[idCpu]->pgm.s.fSyncFlags &= ~PGM_SYNC_CLEAR_PGM_POOL;
 
     /* Flush job finished. */
@@ -773,5 +774,5 @@
     if (fpvFlushRemTlb)
         for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-            CPUMSetChangedFlags(&pVM->aCpus[idCpu], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
+            CPUMSetChangedFlags(pVM->apCpusR3[idCpu], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
 
     STAM_PROFILE_STOP(&pPool->StatClearAll, c);
Index: /trunk/src/VBox/VMM/VMMR3/PGMSavedState.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMSavedState.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PGMSavedState.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PGM
 #include <VBox/vmm/pgm.h>
@@ -2049,5 +2050,5 @@
 
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-        rc = SSMR3PutStruct(pSSM, &pVM->aCpus[idCpu].pgm.s, &s_aPGMCpuFields[0]);
+        rc = SSMR3PutStruct(pSSM, &pVM->apCpusR3[idCpu]->pgm.s, &s_aPGMCpuFields[0]);
 
     /*
@@ -2974,7 +2975,7 @@
         {
             if (uVersion <= PGM_SAVED_STATE_VERSION_PRE_PAE)
-                rc = SSMR3GetStruct(pSSM, &pVM->aCpus[i].pgm.s, &s_aPGMCpuFieldsPrePae[0]);
+                rc = SSMR3GetStruct(pSSM, &pVM->apCpusR3[i]->pgm.s, &s_aPGMCpuFieldsPrePae[0]);
             else
-                rc = SSMR3GetStruct(pSSM, &pVM->aCpus[i].pgm.s, &s_aPGMCpuFields[0]);
+                rc = SSMR3GetStruct(pSSM, &pVM->apCpusR3[i]->pgm.s, &s_aPGMCpuFields[0]);
             AssertLogRelRCReturn(rc, rc);
         }
@@ -2992,7 +2993,8 @@
         pPGM->cbMappingFixed    = pgmOld.cbMappingFixed;
 
-        pVM->aCpus[0].pgm.s.fA20Enabled   = pgmOld.fA20Enabled;
-        pVM->aCpus[0].pgm.s.GCPhysA20Mask = pgmOld.GCPhysA20Mask;
-        pVM->aCpus[0].pgm.s.enmGuestMode  = pgmOld.enmGuestMode;
+        PVMCPU pVCpu0 = pVM->apCpusR3[0];
+        pVCpu0->pgm.s.fA20Enabled   = pgmOld.fA20Enabled;
+        pVCpu0->pgm.s.GCPhysA20Mask = pgmOld.GCPhysA20Mask;
+        pVCpu0->pgm.s.enmGuestMode  = pgmOld.enmGuestMode;
     }
     else
@@ -3008,13 +3010,14 @@
         if (RT_FAILURE(rc))
             return rc;
-        SSMR3GetGCPhys(pSSM,    &pVM->aCpus[0].pgm.s.GCPhysA20Mask);
+        PVMCPU pVCpu0 = pVM->apCpusR3[0];
+        SSMR3GetGCPhys(pSSM,    &pVCpu0->pgm.s.GCPhysA20Mask);
 
         uint32_t u32 = 0;
         SSMR3GetUInt(pSSM,      &u32);
-        pVM->aCpus[0].pgm.s.fA20Enabled = !!u32;
-        SSMR3GetUInt(pSSM,      &pVM->aCpus[0].pgm.s.fSyncFlags);
+        pVCpu0->pgm.s.fA20Enabled = !!u32;
+        SSMR3GetUInt(pSSM,      &pVCpu0->pgm.s.fSyncFlags);
         RTUINT uGuestMode;
         SSMR3GetUInt(pSSM,      &uGuestMode);
-        pVM->aCpus[0].pgm.s.enmGuestMode = (PGMMODE)uGuestMode;
+        pVCpu0->pgm.s.enmGuestMode = (PGMMODE)uGuestMode;
 
         /* check separator. */
@@ -3034,5 +3037,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
         pVCpu->pgm.s.GCPhysA20Mask = ~((RTGCPHYS)!pVCpu->pgm.s.fA20Enabled << 20);
         pgmR3RefreshShadowModeAfterA20Change(pVCpu);
@@ -3171,5 +3174,5 @@
             for (VMCPUID i = 0; i < pVM->cCpus; i++)
             {
-                PVMCPU pVCpu = &pVM->aCpus[i];
+                PVMCPU pVCpu = pVM->apCpusR3[i];
                 VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
                 VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
@@ -3193,5 +3196,5 @@
             for (VMCPUID i = 0; i < pVM->cCpus; i++)
             {
-                PVMCPU pVCpu = &pVM->aCpus[i];
+                PVMCPU pVCpu = pVM->apCpusR3[i];
 
                 rc = PGMHCChangeMode(pVM, pVCpu, pVCpu->pgm.s.enmGuestMode);
@@ -3251,5 +3254,5 @@
             if (pgmMapAreMappingsFloating(pVM))
             {
-                PVMCPU pVCpu = &pVM->aCpus[0];
+                PVMCPU pVCpu = pVM->apCpusR3[0];
                 rc = PGMSyncCR3(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR3(pVCpu),  CPUMGetGuestCR4(pVCpu), true);
                 if (RT_FAILURE(rc))
Index: /trunk/src/VBox/VMM/VMMR3/PGMSharedPage.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMSharedPage.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/PGMSharedPage.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_PGM_SHARED
 #include <VBox/vmm/pgm.h>
Index: /trunk/src/VBox/VMM/VMMR3/SELM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/SELM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/SELM.cpp	(revision 80191)
@@ -60,4 +60,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_SELM
 #include <VBox/vmm/selm.h>
@@ -568,5 +569,5 @@
 {
     /** @todo SMP support! */
-    PVMCPU      pVCpu = &pVM->aCpus[0];
+    PVMCPU      pVCpu = pVM->apCpusR3[0];
 
     VBOXGDTR    GDTR;
@@ -611,5 +612,5 @@
 {
     /** @todo SMP support! */
-    PVMCPU   pVCpu = &pVM->aCpus[0];
+    PVMCPU   pVCpu = pVM->apCpusR3[0];
 
     uint64_t GCPtrLdt;
Index: /trunk/src/VBox/VMM/VMMR3/SSM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/SSM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/SSM.cpp	(revision 80191)
@@ -144,4 +144,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_SSM
 #include <VBox/vmm/ssm.h>
Index: /trunk/src/VBox/VMM/VMMR3/STAM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/STAM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/STAM.cpp	(revision 80191)
@@ -49,4 +49,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_STAM
 #include <VBox/vmm/stam.h>
Index: /trunk/src/VBox/VMM/VMMR3/TM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/TM.cpp	(revision 80191)
@@ -121,4 +121,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_TM
 #ifdef DEBUG_bird
@@ -801,24 +802,25 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.offTSCRawSrc,          STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS, "TSC offset relative the raw source",           "/TM/TSC/offCPU%u", i);
+        PVMCPU pVCpu = pVM->apCpusR3[i];
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.offTSCRawSrc,          STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS, "TSC offset relative the raw source",           "/TM/TSC/offCPU%u", i);
 #ifndef VBOX_WITHOUT_NS_ACCOUNTING
 # if defined(VBOX_WITH_STATISTICS) || defined(VBOX_WITH_NS_ACCOUNTING_STATS)
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsTotal,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,               "Resettable: Total CPU run time.",   "/TM/CPU/%02u", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsExecuting,   STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code.",    "/TM/CPU/%02u/PrfExecuting", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsExecLong,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - long hauls.",    "/TM/CPU/%02u/PrfExecLong", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsExecShort,   STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - short stretches.",    "/TM/CPU/%02u/PrfExecShort", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsExecTiny,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - tiny bits.",    "/TM/CPU/%02u/PrfExecTiny", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsHalted,      STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent halted.",                  "/TM/CPU/%02u/PrfHalted", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.StatNsOther,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent in the VMM or preempted.", "/TM/CPU/%02u/PrfOther", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsTotal,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,               "Resettable: Total CPU run time.",   "/TM/CPU/%02u", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecuting,   STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code.",    "/TM/CPU/%02u/PrfExecuting", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecLong,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - long hauls.",    "/TM/CPU/%02u/PrfExecLong", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecShort,   STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - short stretches.",    "/TM/CPU/%02u/PrfExecShort", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsExecTiny,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent executing guest code - tiny bits.",    "/TM/CPU/%02u/PrfExecTiny", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsHalted,      STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent halted.",                  "/TM/CPU/%02u/PrfHalted", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.StatNsOther,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_OCCURENCE, "Resettable: Time spent in the VMM or preempted.", "/TM/CPU/%02u/PrfOther", i);
 # endif
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.cNsTotal,              STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Total CPU run time.",                          "/TM/CPU/%02u/cNsTotal", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.cNsExecuting,          STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Time spent executing guest code.",             "/TM/CPU/%02u/cNsExecuting", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.cNsHalted,             STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Time spent halted.",                           "/TM/CPU/%02u/cNsHalted", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.cNsOther,              STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Time spent in the VMM or preempted.",          "/TM/CPU/%02u/cNsOther", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.cPeriodsExecuting,     STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Times executed guest code.",                   "/TM/CPU/%02u/cPeriodsExecuting", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.cPeriodsHalted,        STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Times halted.",                                "/TM/CPU/%02u/cPeriodsHalted", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.CpuLoad.cPctExecuting, STAMTYPE_U8,  STAMVISIBILITY_ALWAYS, STAMUNIT_PCT,   "Time spent executing guest code recently.",    "/TM/CPU/%02u/pctExecuting", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.CpuLoad.cPctHalted,    STAMTYPE_U8,  STAMVISIBILITY_ALWAYS, STAMUNIT_PCT,   "Time spent halted recently.",                  "/TM/CPU/%02u/pctHalted", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].tm.s.CpuLoad.cPctOther,     STAMTYPE_U8,  STAMVISIBILITY_ALWAYS, STAMUNIT_PCT,   "Time spent in the VMM or preempted recently.", "/TM/CPU/%02u/pctOther", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.cNsTotal,              STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Total CPU run time.",                          "/TM/CPU/%02u/cNsTotal", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.cNsExecuting,          STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Time spent executing guest code.",             "/TM/CPU/%02u/cNsExecuting", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.cNsHalted,             STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Time spent halted.",                           "/TM/CPU/%02u/cNsHalted", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.cNsOther,              STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_NS,    "Time spent in the VMM or preempted.",          "/TM/CPU/%02u/cNsOther", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.cPeriodsExecuting,     STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Times executed guest code.",                   "/TM/CPU/%02u/cPeriodsExecuting", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.cPeriodsHalted,        STAMTYPE_U64, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Times halted.",                                "/TM/CPU/%02u/cPeriodsHalted", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.CpuLoad.cPctExecuting, STAMTYPE_U8,  STAMVISIBILITY_ALWAYS, STAMUNIT_PCT,   "Time spent executing guest code recently.",    "/TM/CPU/%02u/pctExecuting", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.CpuLoad.cPctHalted,    STAMTYPE_U8,  STAMVISIBILITY_ALWAYS, STAMUNIT_PCT,   "Time spent halted recently.",                  "/TM/CPU/%02u/pctHalted", i);
+        STAMR3RegisterF(pVM, &pVCpu->tm.s.CpuLoad.cPctOther,     STAMTYPE_U8,  STAMVISIBILITY_ALWAYS, STAMUNIT_PCT,   "Time spent in the VMM or preempted recently.", "/TM/CPU/%02u/pctOther", i);
 #endif
     }
@@ -1223,5 +1225,5 @@
 #endif
 
-    PVMCPU pVCpuDst = &pVM->aCpus[pVM->tm.s.idTimerCpu];
+    PVMCPU pVCpuDst = pVM->apCpusR3[pVM->tm.s.idTimerCpu];
     VMCPU_FF_CLEAR(pVCpuDst, VMCPU_FF_TIMER); /** @todo FIXME: this isn't right. */
 
@@ -1234,5 +1236,5 @@
     {
         VM_ASSERT_EMT0(pVM);
-        tmR3CpuTickParavirtDisable(pVM, &pVM->aCpus[0], NULL /* pvData */);
+        tmR3CpuTickParavirtDisable(pVM, pVM->apCpusR3[0], NULL /* pvData */);
     }
     Assert(!GIMIsParavirtTscEnabled(pVM));
@@ -1263,9 +1265,10 @@
             AssertFailedBreakStmt(offTscRawSrc = 0);
     }
-    for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
-    {
-        pVM->aCpus[iCpu].tm.s.offTSCRawSrc   = offTscRawSrc;
-        pVM->aCpus[iCpu].tm.s.u64TSC         = 0;
-        pVM->aCpus[iCpu].tm.s.u64TSCLastSeen = 0;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
+        pVCpu->tm.s.offTSCRawSrc   = offTscRawSrc;
+        pVCpu->tm.s.u64TSC         = 0;
+        pVCpu->tm.s.u64TSCLastSeen = 0;
     }
 
@@ -1308,5 +1311,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
         Assert(!pVCpu->tm.s.fTSCTicking);
     }
@@ -1336,5 +1339,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
         SSMR3PutU64(pSSM, TMCpuTickGet(pVCpu));
     }
@@ -1360,5 +1363,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
         Assert(!pVCpu->tm.s.fTSCTicking);
     }
@@ -1427,5 +1430,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
 
         pVCpu->tm.s.fTSCTicking = false;
@@ -1481,5 +1484,5 @@
      * Make sure timers get rescheduled immediately.
      */
-    PVMCPU pVCpuDst = &pVM->aCpus[pVM->tm.s.idTimerCpu];
+    PVMCPU pVCpuDst = pVM->apCpusR3[pVM->tm.s.idTimerCpu];
     VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
 
@@ -2014,5 +2017,5 @@
         case TMCLOCK_VIRTUAL_SYNC:  return TMVirtualSyncGet(pVM);
         case TMCLOCK_REAL:          return TMRealGet(pVM);
-        case TMCLOCK_TSC:           return TMCpuTickGet(&pVM->aCpus[0] /* just take VCPU 0 */);
+        case TMCLOCK_TSC:           return TMCpuTickGet(pVM->apCpusR3[0] /* just take VCPU 0 */);
         default:
             AssertMsgFailed(("enmClock=%d\n", enmClock));
@@ -2084,5 +2087,5 @@
 {
     PVM     pVM      = (PVM)pvUser;
-    PVMCPU  pVCpuDst = &pVM->aCpus[pVM->tm.s.idTimerCpu];
+    PVMCPU  pVCpuDst = pVM->apCpusR3[pVM->tm.s.idTimerCpu];
     NOREF(pTimer);
 
@@ -2132,5 +2135,5 @@
      */
     Assert(pVM->tm.s.idTimerCpu < pVM->cCpus);
-    PVMCPU pVCpuDst = &pVM->aCpus[pVM->tm.s.idTimerCpu];
+    PVMCPU pVCpuDst = pVM->apCpusR3[pVM->tm.s.idTimerCpu];
     if (VMMGetCpu(pVM) != pVCpuDst)
     {
@@ -3210,5 +3213,5 @@
      * This should be way quicker than an EMT request.
      */
-    PVMCPU      pVCpu        = &pVM->aCpus[idCpu];
+    PVMCPU      pVCpu        = pVM->apCpusR3[idCpu];
     uint32_t    uTimesGen    = ASMAtomicReadU32(&pVCpu->tm.s.uTimesGen);
     uint64_t    cNsTotal     = pVCpu->tm.s.cNsTotal;
@@ -3284,5 +3287,5 @@
         pState = &pVM->tm.s.CpuLoad;
     else
-        pState = &pVM->aCpus[idCpu].tm.s.CpuLoad;
+        pState = &pVM->apCpusR3[idCpu]->tm.s.CpuLoad;
 
     if (pcMsInterval)
@@ -3390,5 +3393,5 @@
     for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
     {
-        PVMCPU      pVCpu = &pVM->aCpus[iCpu];
+        PVMCPU      pVCpu = pVM->apCpusR3[iCpu];
 
         /* Try get a stable data set. */
@@ -3460,5 +3463,5 @@
     for (uint32_t i = 0; i < cCpus; i++)
     {
-        PVMCPU   pVCpu   = &pVM->aCpus[i];
+        PVMCPU   pVCpu   = pVM->apCpusR3[i];
         uint64_t uOldTsc = uRawOldTsc - pVCpu->tm.s.offTSCRawSrc;
         pVCpu->tm.s.offTSCRawSrc = uRawNewTsc - uOldTsc;
@@ -3516,5 +3519,5 @@
     for (uint32_t i = 0; i < cCpus; i++)
     {
-        PVMCPU   pVCpu   = &pVM->aCpus[i];
+        PVMCPU   pVCpu   = pVM->apCpusR3[i];
         uint64_t uOldTsc = uRawOldTsc - pVCpu->tm.s.offTSCRawSrc;
         pVCpu->tm.s.offTSCRawSrc = uRawNewTsc - uOldTsc;
@@ -3701,5 +3704,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU   pVCpu  = &pVM->aCpus[i];
+        PVMCPU   pVCpu  = pVM->apCpusR3[i];
         uint64_t u64TSC = TMCpuTickGet(pVCpu);
 
@@ -3812,5 +3815,5 @@
         {
             case 'a':
-                pState   = &pVM->aCpus[0].tm.s.CpuLoad;
+                pState   = &pVM->apCpusR3[0]->tm.s.CpuLoad;
                 idCpu    = 0;
                 fAllCpus = true;
@@ -3819,5 +3822,5 @@
                 if (ValueUnion.u32 < pVM->cCpus)
                 {
-                    pState = &pVM->aCpus[ValueUnion.u32].tm.s.CpuLoad;
+                    pState = &pVM->apCpusR3[ValueUnion.u32]->tm.s.CpuLoad;
                     idCpu  = ValueUnion.u32;
                 }
@@ -3981,5 +3984,5 @@
         if (idCpu >= pVM->cCpus)
             break;
-        pState   = &pVM->aCpus[idCpu].tm.s.CpuLoad;
+        pState   = &pVM->apCpusR3[idCpu]->tm.s.CpuLoad;
     }
 
Index: /trunk/src/VBox/VMM/VMMR3/TRPM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/TRPM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/TRPM.cpp	(revision 80191)
@@ -74,4 +74,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_TRPM
 #include <VBox/vmm/trpm.h>
@@ -140,5 +141,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[i];
+        PVMCPU pVCpu = pVM->apCpusR3[i];
         pVCpu->trpm.s.uActiveVector = ~0U;
     }
@@ -231,5 +232,5 @@
      */
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        TRPMR3ResetCpu(&pVM->aCpus[i]);
+        TRPMR3ResetCpu(pVM->apCpusR3[i]);
     TRPMR3Relocate(pVM, 0);
 }
@@ -252,5 +253,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PTRPMCPU pTrpmCpu = &pVM->aCpus[i].trpm.s;
+        PTRPMCPU pTrpmCpu = &pVM->apCpusR3[i]->trpm.s;
         SSMR3PutUInt(pSSM,      pTrpmCpu->uActiveVector);
         SSMR3PutUInt(pSSM,      pTrpmCpu->enmActiveType);
@@ -310,5 +311,5 @@
         for (VMCPUID i = 0; i < pVM->cCpus; i++)
         {
-            PTRPMCPU pTrpmCpu = &pVM->aCpus[i].trpm.s;
+            PTRPMCPU pTrpmCpu = &pVM->apCpusR3[i]->trpm.s;
             SSMR3GetUInt(pSSM,      &pTrpmCpu->uActiveVector);
             SSMR3GetUInt(pSSM,      (uint32_t *)&pTrpmCpu->enmActiveType);
@@ -327,5 +328,5 @@
     else
     {
-        PTRPMCPU pTrpmCpu = &pVM->aCpus[0].trpm.s;
+        PTRPMCPU pTrpmCpu = &pVM->apCpusR3[0]->trpm.s;
         SSMR3GetUInt(pSSM,      &pTrpmCpu->uActiveVector);
         SSMR3GetUInt(pSSM,      (uint32_t *)&pTrpmCpu->enmActiveType);
@@ -451,5 +452,5 @@
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
-        pVCpu = &pVM->aCpus[0];
+        pVCpu = pVM->apCpusR3[0];
 
     uint8_t     uVector;
Index: /trunk/src/VBox/VMM/VMMR3/VM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 80191)
@@ -43,4 +43,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_VM
 #include <VBox/vmm/cfgm.h>
@@ -589,5 +590,4 @@
         AssertCompileMemberAlignment(VM, cpum, 64);
         AssertCompileMemberAlignment(VM, tm, 64);
-        AssertCompileMemberAlignment(VM, aCpus, PAGE_SIZE);
 
         Log(("VMR3Create: Created pUVM=%p pVM=%p pVMR0=%p hSelf=%#x cCpus=%RU32\n",
@@ -601,11 +601,12 @@
         for (VMCPUID i = 0; i < pVM->cCpus; i++)
         {
-            pVM->aCpus[i].pUVCpu            = &pUVM->aCpus[i];
-            pVM->aCpus[i].idCpu             = i;
-            pVM->aCpus[i].hNativeThread     = pUVM->aCpus[i].vm.s.NativeThreadEMT;
-            Assert(pVM->aCpus[i].hNativeThread != NIL_RTNATIVETHREAD);
+            PVMCPU pVCpu = pVM->apCpusR3[i];
+            pVCpu->pUVCpu            = &pUVM->aCpus[i];
+            pVCpu->idCpu             = i;
+            pVCpu->hNativeThread     = pUVM->aCpus[i].vm.s.NativeThreadEMT;
+            Assert(pVCpu->hNativeThread != NIL_RTNATIVETHREAD);
             /* hNativeThreadR0 is initialized on EMT registration. */
-            pUVM->aCpus[i].pVCpu            = &pVM->aCpus[i];
-            pUVM->aCpus[i].pVM              = pVM;
+            pUVM->aCpus[i].pVCpu     = pVCpu;
+            pUVM->aCpus[i].pVM       = pVM;
         }
 
Index: /trunk/src/VBox/VMM/VMMR3/VMEmt.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VMEmt.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/VMEmt.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_VM
 #include <VBox/vmm/tm.h>
@@ -167,5 +168,5 @@
             if (VM_FF_IS_SET(pVM, VM_FF_EMT_RENDEZVOUS))
             {
-                rc = VMMR3EmtRendezvousFF(pVM, &pVM->aCpus[idCpu]);
+                rc = VMMR3EmtRendezvousFF(pVM, pVM->apCpusR3[idCpu]);
                 Log(("vmR3EmulationThread: Rendezvous rc=%Rrc, VM state %s -> %s\n", rc, VMR3GetStateName(enmBefore), VMR3GetStateName(pVM->enmVMState)));
             }
@@ -235,5 +236,5 @@
             if (pVM)
             {
-                pVCpu = &pVM->aCpus[idCpu];
+                pVCpu = pVM->apCpusR3[idCpu];
                 if (   pVM->enmVMState == VMSTATE_RUNNING
                     && VMCPUSTATE_IS_STARTED(VMCPU_GET_STATE(pVCpu)))
@@ -1390,5 +1391,5 @@
     VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
-    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+    PVMCPU pVCpu = pVM->apCpusR3[idCpu];
     VMCPU_ASSERT_EMT_RETURN(pVCpu, VERR_VM_THREAD_NOT_EMT);
 
@@ -1417,5 +1418,5 @@
     VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
-    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+    PVMCPU pVCpu = pVM->apCpusR3[idCpu];
 
     /*
Index: /trunk/src/VBox/VMM/VMMR3/VMM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VMM.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/VMM.cpp	(revision 80191)
@@ -98,4 +98,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_VMM
 #include <VBox/vmm/vmm.h>
@@ -334,5 +335,5 @@
     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     {
-        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
 
 #ifdef VBOX_STRICT_VMM_STACK
@@ -375,7 +376,7 @@
     {
         size_t const cbLogger = RTLogCalcSizeForR0(pLogger->cGroups, 0);
-        for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        {
-            PVMCPU pVCpu = &pVM->aCpus[i];
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            PVMCPU pVCpu = pVM->apCpusR3[idCpu];
             rc = MMR3HyperAllocOnceNoRelEx(pVM, cbLogger, PAGE_SIZE, MM_TAG_VMM, MMHYPER_AONR_FLAGS_KERNEL_MAPPING,
                                            (void **)&pVCpu->vmm.s.pR0LoggerR3);
@@ -409,7 +410,7 @@
         size_t const cbLogger = RTLogCalcSizeForR0(pRelLogger->cGroups, 0);
 
-        for (VMCPUID i = 0; i < pVM->cCpus; i++)
-        {
-            PVMCPU pVCpu = &pVM->aCpus[i];
+        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+        {
+            PVMCPU pVCpu = pVM->apCpusR3[idCpu];
             rc = MMR3HyperAllocOnceNoRelEx(pVM, cbLogger, PAGE_SIZE, MM_TAG_VMM, MMHYPER_AONR_FLAGS_KERNEL_MAPPING,
                                            (void **)&pVCpu->vmm.s.pR0RelLoggerR3);
@@ -424,8 +425,8 @@
             pVmmLogger->fFlushingDisabled   = false;
             pVmmLogger->fRegistered         = false;
-            pVmmLogger->idCpu               = i;
+            pVmmLogger->idCpu               = idCpu;
 
             char szR0ThreadName[16];
-            RTStrPrintf(szR0ThreadName, sizeof(szR0ThreadName), "EMT-%u-R0", i);
+            RTStrPrintf(szR0ThreadName, sizeof(szR0ThreadName), "EMT-%u-R0", idCpu);
             rc = RTLogCreateForR0(&pVmmLogger->Logger, pVmmLogger->cbLogger, R0PtrVmmLogger + RT_UOFFSETOF(VMMR0LOGGER, Logger),
                                   pfnLoggerWrapper, pfnLoggerFlush,
@@ -526,21 +527,23 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.CallRing3JmpBufR0.cbUsedMax,  STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,      "Max amount of stack used.", "/VMM/Stack/CPU%u/Max", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.CallRing3JmpBufR0.cbUsedAvg,  STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,      "Average stack usage.",      "/VMM/Stack/CPU%u/Avg", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.CallRing3JmpBufR0.cUsedTotal, STAMTYPE_U64,       STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of stack usages.",   "/VMM/Stack/CPU%u/Uses", i);
+        PVMCPU pVCpu = pVM->apCpusR3[i];
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.CallRing3JmpBufR0.cbUsedMax,  STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,      "Max amount of stack used.", "/VMM/Stack/CPU%u/Max", i);
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.CallRing3JmpBufR0.cbUsedAvg,  STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,      "Average stack usage.",      "/VMM/Stack/CPU%u/Avg", i);
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.CallRing3JmpBufR0.cUsedTotal, STAMTYPE_U64,       STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of stack usages.",   "/VMM/Stack/CPU%u/Uses", i);
     }
 #endif
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.StatR0HaltBlock,          STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "", "/PROF/CPU%u/VM/Halt/R0HaltBlock", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.StatR0HaltBlockOnTime,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "", "/PROF/CPU%u/VM/Halt/R0HaltBlockOnTime", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.StatR0HaltBlockOverslept, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "", "/PROF/CPU%u/VM/Halt/R0HaltBlockOverslept", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.StatR0HaltBlockInsomnia,  STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "", "/PROF/CPU%u/VM/Halt/R0HaltBlockInsomnia", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.StatR0HaltExec,           STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltExec", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.StatR0HaltExecFromSpin,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltExec/FromSpin", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.StatR0HaltExecFromBlock,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltExec/FromBlock", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.cR0Halts,                 STAMTYPE_U32,     STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltHistoryCounter", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.cR0HaltsSucceeded,        STAMTYPE_U32,     STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltHistorySucceeded", i);
-        STAMR3RegisterF(pVM, &pVM->aCpus[i].vmm.s.cR0HaltsToRing3,          STAMTYPE_U32,     STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltHistoryToRing3", i);
+        PVMCPU pVCpu = pVM->apCpusR3[i];
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.StatR0HaltBlock,          STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "", "/PROF/CPU%u/VM/Halt/R0HaltBlock", i);
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.StatR0HaltBlockOnTime,    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "", "/PROF/CPU%u/VM/Halt/R0HaltBlockOnTime", i);
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.StatR0HaltBlockOverslept, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "", "/PROF/CPU%u/VM/Halt/R0HaltBlockOverslept", i);
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.StatR0HaltBlockInsomnia,  STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_NS_PER_CALL, "", "/PROF/CPU%u/VM/Halt/R0HaltBlockInsomnia", i);
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.StatR0HaltExec,           STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltExec", i);
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.StatR0HaltExecFromSpin,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltExec/FromSpin", i);
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.StatR0HaltExecFromBlock,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltExec/FromBlock", i);
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.cR0Halts,                 STAMTYPE_U32,     STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltHistoryCounter", i);
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.cR0HaltsSucceeded,        STAMTYPE_U32,     STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltHistorySucceeded", i);
+        STAMR3RegisterF(pVM, &pVCpu->vmm.s.cR0HaltsToRing3,          STAMTYPE_U32,     STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,  "", "/PROF/CPU%u/VM/Halt/R0HaltHistoryToRing3", i);
     }
 }
@@ -620,5 +623,5 @@
 
     /* Log whether thread-context hooks are used (on Linux this can depend on how the kernel is configured). */
-    if (pVM->aCpus[0].vmm.s.hCtxHook != NIL_RTTHREADCTXHOOK)
+    if (pVM->apCpusR3[0]->vmm.s.hCtxHook != NIL_RTTHREADCTXHOOK)
         LogRel(("VMM: Enabled thread-context hooks\n"));
     else
@@ -639,5 +642,5 @@
      */
     for (VMCPUID idCpu = 0; RT_SUCCESS(rc) && idCpu < pVM->cCpus; idCpu++)
-        rc = VMR3ReqCallWait(pVM, idCpu, (PFNRT)vmmR3InitR0Emt, 2, pVM, &pVM->aCpus[idCpu]);
+        rc = VMR3ReqCallWait(pVM, idCpu, (PFNRT)vmmR3InitR0Emt, 2, pVM, pVM->apCpusR3[idCpu]);
 
     return rc;
@@ -815,5 +818,5 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        PVMCPU       pVCpu = &pVM->aCpus[i];
+        PVMCPU       pVCpu = pVM->apCpusR3[i];
         PVMMR0LOGGER pR0LoggerR3 = pVCpu->vmm.s.pR0LoggerR3;
         if (pR0LoggerR3)
@@ -880,5 +883,5 @@
     AssertReturn(idCpu < pUVM->cCpus, NULL);
     VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, NULL);
-    return &pUVM->pVM->aCpus[idCpu];
+    return pUVM->pVM->apCpusR3[idCpu];
 }
 
@@ -912,5 +915,5 @@
      */
     for (VMCPUID i = 1; i < pVM->cCpus; i++)
-        SSMR3PutBool(pSSM, VMCPUSTATE_IS_STARTED(VMCPU_GET_STATE(&pVM->aCpus[i])));
+        SSMR3PutBool(pSSM, VMCPUSTATE_IS_STARTED(VMCPU_GET_STATE(pVM->apCpusR3[i])));
 
     return SSMR3PutU32(pSSM, UINT32_MAX); /* terminator */
@@ -966,5 +969,5 @@
      * Restore the VMCPU states. VCPU 0 is always started.
      */
-    VMCPU_SET_STATE(&pVM->aCpus[0], VMCPUSTATE_STARTED);
+    VMCPU_SET_STATE(pVM->apCpusR3[0], VMCPUSTATE_STARTED);
     for (VMCPUID i = 1; i < pVM->cCpus; i++)
     {
@@ -973,5 +976,5 @@
         if (RT_FAILURE(rc))
             return rc;
-        VMCPU_SET_STATE(&pVM->aCpus[i], fStarted ? VMCPUSTATE_STARTED : VMCPUSTATE_STOPPED);
+        VMCPU_SET_STATE(pVM->apCpusR3[i], fStarted ? VMCPUSTATE_STARTED : VMCPUSTATE_STOPPED);
     }
 
@@ -997,5 +1000,5 @@
 VMMR3_INT_DECL(void) VMMR3YieldSuspend(PVM pVM)
 {
-    VMCPU_ASSERT_EMT(&pVM->aCpus[0]);
+    VMCPU_ASSERT_EMT(pVM->apCpusR3[0]);
     if (!pVM->vmm.s.cYieldResumeMillies)
     {
@@ -2601,5 +2604,6 @@
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
-        const uint64_t fLocalForcedActions = pVM->aCpus[i].fLocalForcedActions;
+        PVMCPU         pVCpu               = pVM->apCpusR3[i];
+        const uint64_t fLocalForcedActions = pVCpu->fLocalForcedActions;
         pHlp->pfnPrintf(pHlp, "CPU %u FFs: %#RX64", i, fLocalForcedActions);
 
@@ -2633,5 +2637,5 @@
 
         if (fLocalForcedActions & VMCPU_FF_INHIBIT_INTERRUPTS)
-            pHlp->pfnPrintf(pHlp, "    intr inhibit RIP: %RGp\n", EMGetInhibitInterruptsPC(&pVM->aCpus[i]));
+            pHlp->pfnPrintf(pHlp, "    intr inhibit RIP: %RGp\n", EMGetInhibitInterruptsPC(pVCpu));
 
         /* the groups */
Index: /trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_VMM
 #include <VBox/vmm/vmm.h>
Index: /trunk/src/VBox/VMM/VMMR3/VMReq.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VMReq.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/VMMR3/VMReq.cpp	(revision 80191)
@@ -20,4 +20,5 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
+#define VBOX_BUGREF_9217_PART_I
 #define LOG_GROUP LOG_GROUP_VM
 #include <VBox/vmm/mm.h>
@@ -865,5 +866,5 @@
     {
         VMCPUID  idTarget = pReq->idDstCpu;     Assert(idTarget < pUVM->cCpus);
-        PVMCPU   pVCpu = &pUVM->pVM->aCpus[idTarget];
+        PVMCPU   pVCpu = pUVM->pVM->apCpusR3[idTarget];
         unsigned fFlags = ((VMREQ volatile *)pReq)->fFlags;     /* volatile paranoia */
 
@@ -1024,5 +1025,5 @@
             VM_FF_SET(pUVM->pVM, VM_FF_REQUEST);
         else
-            VMCPU_FF_SET(&pUVM->pVM->aCpus[idDstCpu], VMCPU_FF_REQUEST);
+            VMCPU_FF_SET(pUVM->pVM->apCpusR3[idDstCpu], VMCPU_FF_REQUEST);
     }
 }
@@ -1144,5 +1145,5 @@
                 VM_FF_CLEAR(pUVM->pVM, VM_FF_REQUEST);
             else
-                VMCPU_FF_CLEAR(&pUVM->pVM->aCpus[idDstCpu], VMCPU_FF_REQUEST);
+                VMCPU_FF_CLEAR(pUVM->pVM->apCpusR3[idDstCpu], VMCPU_FF_REQUEST);
         }
 
Index: /trunk/src/VBox/VMM/include/CPUMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/CPUMInternal.h	(revision 80190)
+++ /trunk/src/VBox/VMM/include/CPUMInternal.h	(revision 80191)
@@ -337,7 +337,4 @@
 typedef struct CPUM
 {
-    /** Offset from CPUM to CPUMCPU for the first CPU. */
-    uint32_t                offCPUMCPU0;
-
     /** Use flags.
      * These flags indicates which CPU features the host uses.
@@ -357,5 +354,5 @@
      * This is used to verify load order dependencies (PGM). */
     bool                    fPendingRestore;
-    uint8_t                 abPadding0[6];
+    uint8_t                 abPadding0[2];
 
     /** XSAVE/XRTOR components we can expose to the guest mask. */
@@ -367,5 +364,5 @@
     /** The host MXCSR mask (determined at init). */
     uint32_t                fHostMxCsrMask;
-    uint8_t                 abPadding1[20];
+    uint8_t                 abPadding1[20+8];
 
     /** Host CPU feature information.
@@ -432,7 +429,4 @@
     uint32_t                fChanged;
 
-    /** Offset from CPUM to CPUMCPU. */
-    uint32_t                offCPUM;
-
     /** Temporary storage for the return code of the function called in the
      * 32-64 switcher. */
@@ -440,15 +434,15 @@
 
 #ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    /** Used by the world switcher code to store which vectors needs restoring on
+     * the way back. */
+    uint32_t                fApicDisVectors;
     /** The address of the APIC mapping, NULL if no APIC.
      * Call CPUMR0SetLApic to update this before doing a world switch. */
     RTHCPTR                 pvApicBase;
-    /** Used by the world switcher code to store which vectors needs restoring on
-     * the way back. */
-    uint32_t                fApicDisVectors;
     /** Set if the CPU has the X2APIC mode enabled.
      * Call CPUMR0SetLApic to update this before doing a world switch. */
     bool                    fX2Apic;
 #else
-    uint8_t                 abPadding3[(HC_ARCH_BITS == 64 ? 8 : 4) + 4 + 1];
+    uint8_t                 abPadding3[4 + sizeof(RTHCPTR) + 1];
 #endif
 
@@ -461,5 +455,5 @@
 
     /** Align the next member on a 64-byte boundrary. */
-    uint8_t                 abPadding2[64 - 16 - 8 - 4 - 1 - 2];
+    uint8_t                 abPadding2[64 - 16 - 8 - 4 - 1 - 2 + 4];
 
     /** Saved host context.  Only valid while inside RC or HM contexts.
Index: /trunk/src/VBox/VMM/include/CPUMInternal.mac
===================================================================
--- /trunk/src/VBox/VMM/include/CPUMInternal.mac	(revision 80190)
+++ /trunk/src/VBox/VMM/include/CPUMInternal.mac	(revision 80191)
@@ -80,5 +80,4 @@
 struc CPUM
     ;...
-    .offCPUMCPU0                resd    1
     .fHostUseFlags              resd    1
 
@@ -265,13 +264,12 @@
     .fUseFlags            resd    1
     .fChanged             resd    1
-    .offCPUM              resd    1
     .u32RetCode           resd    1
 
 %ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+    .fApicDisVectors      resd    1
     .pvApicBase           RTR0PTR_RES 1
-    .fApicDisVectors      resd    1
     .fX2Apic              resb    1
 %else
-    .abPadding3           resb    (RTR0PTR_CB + 4 + 1)
+    .abPadding3           resb    (4 + RTR0PTR_CB + 1)
 %endif
 
@@ -279,5 +277,5 @@
     .fCpuIdApicFeatureVisible resb 1
 
-    .abPadding2           resb    (64 - 16 - RTR0PTR_CB - 4 - 1 - 2)
+    .abPadding2           resb    (64 - 16 - RTR0PTR_CB - 4 - 1 - 2 + 4)
 
     ;
@@ -370,35 +368,4 @@
 
 
-;;
-; Converts the CPUM pointer to CPUMCPU
-; @param   %1   register name
-%macro CPUMCPU_FROM_CPUM 1
-    add     %1, dword [%1 + CPUM.offCPUMCPU0]
-%endmacro
-
-;;
-; Converts the CPUM pointer to CPUMCPU
-; @param   %1   register name (CPUM)
-; @param   %2   register name (CPUMCPU offset)
-%macro CPUMCPU_FROM_CPUM_WITH_OFFSET 2
-    add     %1, %2
-%endmacro
-
-;;
-; Converts the CPUMCPU pointer to CPUM
-; @param   %1   register name
-%macro CPUM_FROM_CPUMCPU 1
-    sub     %1, dword [%1 + CPUMCPU.offCPUM]
-%endmacro
-
-;;
-; Converts the CPUMCPU pointer to CPUM
-; @param   %1   register name (CPUM)
-; @param   %2   register name (CPUMCPU offset)
-%macro CPUM_FROM_CPUMCPU_WITH_OFFSET 2
-    sub     %1, %2
-%endmacro
-
-
 
 %if 0 ; Currently not used anywhere.
Index: /trunk/src/VBox/VMM/testcase/tstVMStruct.h
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMStruct.h	(revision 80190)
+++ /trunk/src/VBox/VMM/testcase/tstVMStruct.h	(revision 80191)
@@ -27,5 +27,4 @@
 
     GEN_CHECK_SIZE(CPUM);    // has .mac
-    GEN_CHECK_OFF(CPUM, offCPUMCPU0);
     GEN_CHECK_OFF(CPUM, fHostUseFlags);
     GEN_CHECK_OFF(CPUM, CR4);
@@ -49,5 +48,4 @@
     GEN_CHECK_OFF(CPUMCPU, fUseFlags);
     GEN_CHECK_OFF(CPUMCPU, fChanged);
-    GEN_CHECK_OFF(CPUMCPU, offCPUM);
     GEN_CHECK_OFF(CPUMCPU, u32RetCode);
 #ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
Index: /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 80190)
+++ /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 80191)
@@ -232,4 +232,6 @@
     CHECK_PADDING_VM(8, cfgm);
     CHECK_PADDING_VM(8, apic);
+    PRINT_OFFSET(VM, cfgm);
+    PRINT_OFFSET(VM, apCpusR3);
 
     PRINT_OFFSET(VMCPU, cpum);
