Index: /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
===================================================================
--- /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 60463)
+++ /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 60464)
@@ -780,5 +780,16 @@
     GEN_CHECK_OFF(APICCPU, uHintedTimerInitialCount);
     GEN_CHECK_OFF(APICCPU, uHintedTimerShift);
-    GEN_CHECK_OFF(APICCPU, StatMmioReadGC);
+    GEN_CHECK_OFF(APICCPU, StatMmioReadR0);
+    GEN_CHECK_OFF(APICCPU, StatMmioReadR3);
+    GEN_CHECK_OFF(APICCPU, StatMmioReadRC);
+    GEN_CHECK_OFF(APICCPU, StatMmioWriteR0);
+    GEN_CHECK_OFF(APICCPU, StatMmioWriteR3);
+    GEN_CHECK_OFF(APICCPU, StatMmioWriteRC);
+    GEN_CHECK_OFF(APICCPU, StatMsrReadR0);
+    GEN_CHECK_OFF(APICCPU, StatMsrReadR3);
+    GEN_CHECK_OFF(APICCPU, StatMsrReadRC);
+    GEN_CHECK_OFF(APICCPU, StatMsrWriteR0);
+    GEN_CHECK_OFF(APICCPU, StatMsrWriteR3);
+    GEN_CHECK_OFF(APICCPU, StatMsrWriteRC);
 #else
     /* PC/DevAPIC.cpp */
Index: /trunk/src/VBox/VMM/VMMAll/APICAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 60463)
+++ /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 60464)
@@ -852,4 +852,6 @@
     PXAPICPAGE pXApicPage = VMCPU_TO_XAPICPAGE(pVCpu);
     pXApicPage->icr_hi.all.u32IcrHi = uIcrHi & XAPIC_ICR_HI_DEST;
+    Log4(("APIC%u: apicSetIcrHi: uIcrHi=%#RX32\n", pVCpu->idCpu, pXApicPage->icr_hi.all.u32IcrHi));
+
     return VINF_SUCCESS;
 }
@@ -871,4 +873,5 @@
     PXAPICPAGE pXApicPage  = VMCPU_TO_XAPICPAGE(pVCpu);
     pXApicPage->icr_lo.all.u32IcrLo = uIcrLo & XAPIC_ICR_LO_WR;
+    Log4(("APIC%u: apicSetIcrLo: uIcrLo=%#RX32\n", pVCpu->idCpu, pXApicPage->icr_lo.all.u32IcrLo));
 
     apicSendIpi(pVCpu, rcRZ);
@@ -909,11 +912,14 @@
  * @returns Strict VBox status code.
  * @param   pVCpu           The cross context virtual CPU structure.
- * @param   uValue          The ESR value.
- */
-static VBOXSTRICTRC apicSetEsr(PVMCPU pVCpu, uint32_t uValue)
-{
-    VMCPU_ASSERT_EMT(pVCpu);
+ * @param   uEsr            The ESR value.
+ */
+static VBOXSTRICTRC apicSetEsr(PVMCPU pVCpu, uint32_t uEsr)
+{
+    VMCPU_ASSERT_EMT(pVCpu);
+
+    Log4(("APIC%u: apicSetEr: uEsr=%#RX32\n", pVCpu->idCpu, uEsr));
+
     if (   XAPIC_IN_X2APIC_MODE(pVCpu)
-        && (uValue & ~XAPIC_ESR_WO))
+        && (uEsr & ~XAPIC_ESR_WO))
         return apicMsrAccessError(pVCpu, MSR_IA32_X2APIC_ESR, APICMSRACCESS_WRITE_RSVD_BITS);
 
@@ -1006,4 +1012,6 @@
     VMCPU_ASSERT_EMT(pVCpu);
 
+    Log4(("APIC%u: apicSetEoi: uEoi=%#RX32\n", pVCpu->idCpu, uEoi));
+
     if (   XAPIC_IN_X2APIC_MODE(pVCpu)
         && (uEoi & ~XAPIC_EOI_WO))
@@ -1052,4 +1060,6 @@
     Assert(!XAPIC_IN_X2APIC_MODE(pVCpu));
 
+    Log4(("APIC%u: apicSetLdr: uLdr=%#RX32\n", pVCpu->idCpu, uLdr));
+
     PXAPICPAGE pXApicPage = VMCPU_TO_XAPICPAGE(pVCpu);
     apicWriteRaw32(pXApicPage, XAPIC_OFF_LDR, uLdr & XAPIC_LDR);
@@ -1072,4 +1082,6 @@
     Assert(!XAPIC_IN_X2APIC_MODE(pVCpu));
 
+    Log4(("APIC%u: apicSetDfr: uDfr=%#RX32\n", pVCpu->idCpu, uDfr));
+
     PXAPICPAGE pXApicPage = VMCPU_TO_XAPICPAGE(pVCpu);
     apicWriteRaw32(pXApicPage, XAPIC_OFF_DFR, uDfr & XAPIC_DFR);
@@ -1091,4 +1103,6 @@
         && (uTimerDcr & ~XAPIC_TIMER_DCR))
         return apicMsrAccessError(pVCpu, MSR_IA32_X2APIC_TIMER_DCR, APICMSRACCESS_WRITE_RSVD_BITS);
+
+    Log4(("APIC%u: apicSetTimerDcr: uTimerDcr=%#RX32\n", pVCpu->idCpu, uTimerDcr));
 
     PXAPICPAGE pXApicPage = VMCPU_TO_XAPICPAGE(pVCpu);
@@ -1174,4 +1188,6 @@
         && pXApicPage->lvt_timer.u.u2TimerMode == XAPIC_TIMER_MODE_TSC_DEADLINE)
         return VINF_SUCCESS;
+
+    Log4(("APIC%u: apicSetTimerIcr: uInitialCount=%#RX32\n", pVCpu->idCpu, uInitialCount));
 
     /*
@@ -1267,4 +1283,5 @@
 
     Log4(("APIC%u: apicSetLvtEntry: offLvt=%#RX16 uLvt=%#RX32\n", pVCpu->idCpu, offLvt, uLvt));
+
     apicWriteRaw32(pXApicPage, offLvt, uLvt);
     return VINF_SUCCESS;
@@ -1569,5 +1586,5 @@
         return VINF_CPUM_R3_MSR_READ;
 
-    STAM_COUNTER_INC(&VMCPU_TO_APICCPU(pVCpu)->StatMsrRead);
+    STAM_COUNTER_INC(&pVCpu->apic.s.CTX_SUFF(StatMsrRead));
 
     VBOXSTRICTRC rcStrict = VINF_SUCCESS;
@@ -1671,5 +1688,5 @@
         return VINF_CPUM_R3_MSR_WRITE;
 
-    STAM_COUNTER_INC(&VMCPU_TO_APICCPU(pVCpu)->StatMsrWrite);
+    STAM_COUNTER_INC(&pVCpu->apic.s.CTX_SUFF(StatMsrWrite));
 
     /*
@@ -1846,4 +1863,5 @@
                 APICR3Reset(pVCpu);
                 uBaseMsr &= ~(MSR_APICBASE_XAPIC_ENABLE_BIT | MSR_APICBASE_X2APIC_ENABLE_BIT);
+                Log4(("APIC%u: Switched mode to disabled\n", pVCpu->idCpu));
 #else
                 return VINF_CPUM_R3_MSR_WRITE;
@@ -1860,4 +1878,5 @@
                 }
                 uBaseMsr |= MSR_APICBASE_XAPIC_ENABLE_BIT;
+                Log4(("APIC%u: Switched mode to xApic\n", pVCpu->idCpu));
                 break;
             }
@@ -1884,4 +1903,5 @@
                 pX2ApicPage->ldr.u32LogicalApicId = ((pX2ApicPage->id.u32ApicId & UINT32_C(0xffff0)) << 16)
                                                   | (UINT32_C(1) << pX2ApicPage->id.u32ApicId & UINT32_C(0xf));
+                Log4(("APIC%u: Switched mode to x2Apic\n", pVCpu->idCpu));
                 break;
             }
@@ -2108,5 +2128,5 @@
             if (uTpr > 0 && uVector <= uTpr)
             {
-                Log4(("APIC%u: APICGetInterrupt: Returns spurious vector %#x\n", pVCpu->idCpu,
+                Log4(("APIC%u: APICGetInterrupt: Spurious interrupt. uVector=%#x\n", pVCpu->idCpu,
                       pXApicPage->svr.u.u8SpuriousVector));
                 return pXApicPage->svr.u.u8SpuriousVector;
@@ -2122,5 +2142,5 @@
                 apicSignalNextPendingIntr(pVCpu);
 
-                Log4(("APIC%u: APICGetInterrupt: Returns vector %#x\n", pVCpu->idCpu, uVector));
+                Log4(("APIC%u: APICGetInterrupt: Valid Interrupt. uVector=%#x\n", pVCpu->idCpu, uVector));
                 return uVector;
             }
@@ -2146,8 +2166,5 @@
     uint32_t uValue   = 0;
 
-#ifdef VBOX_WITH_STATISTICS
-    PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
-    STAM_COUNTER_INC(&CTXSUFF(pApicCpu->StatMmioRead));
-#endif
+    STAM_COUNTER_INC(&pVCpu->apic.s.CTX_SUFF(StatMmioRead));
 
     Log4(("APIC%u: ApicReadMmio: offReg=%#RX16\n", pVCpu->idCpu, offReg));
@@ -2173,8 +2190,5 @@
     uint32_t uValue   = *(uint32_t *)pv;
 
-#ifdef VBOX_WITH_STATISTICS
-    PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
-    STAM_COUNTER_INC(&CTXSUFF(pApicCpu->StatMmioWrite));
-#endif
+    STAM_COUNTER_INC(&pVCpu->apic.s.CTX_SUFF(StatMmioWrite));
 
     LogRel(("APIC%u: APICWriteMmio: offReg=%#RX16 uValue=%#RX32\n", pVCpu->idCpu, offReg, uValue));
@@ -2334,4 +2348,7 @@
 
         case APICMODE_XAPIC:
+            CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_APIC);
+            break;
+
         case APICMODE_X2APIC:
             CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_APIC);
Index: /trunk/src/VBox/VMM/VMMR3/APIC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 60463)
+++ /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 60464)
@@ -891,4 +891,5 @@
     Assert(TMTimerIsLockOwner(pTimer));
     Assert(pVCpu);
+    LogFlow(("APIC%u: apicR3TimerCallback\n", pVCpu->idCpu));
 
     PXAPICPAGE     pXApicPage = VMCPU_TO_XAPICPAGE(pVCpu);
@@ -897,4 +898,5 @@
     {
         uint8_t uVector = XAPIC_LVT_GET_VECTOR(uLvtTimer);
+        Log4(("APIC%u: apicR3TimerCallback: Raising timer interrupt. uVector=%#x\n", pVCpu->idCpu, uVector));
         APICPostInterrupt(pVCpu, uVector, XAPICTRIGGERMODE_EDGE);
     }
@@ -1190,4 +1192,40 @@
     LogRel(("APIC: fPostedIntrsEnabled=%RTbool fVirtApicRegsEnabled=%RTbool fSupportsTscDeadline=%RTbool\n",
             pApic->fPostedIntrsEnabled, pApic->fVirtApicRegsEnabled, pApic->fSupportsTscDeadline));
+
+#ifdef VBOX_WITH_STATISTICS
+    /*
+     * Statistics.
+     */
+    /** @todo Figure out why doing this from apicR3Construct() it doesn't work. See @bugref{8245#c48} */
+#define APIC_REG_COUNTER(a_Reg, a_Desc, a_Key) \
+    rc = STAMR3RegisterF(pVM, a_Reg, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, a_Desc, a_Key, idCpu)
+
+    bool const fHasRC = !HMIsEnabled(pVM);
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU   pVCpu     = &pVM->aCpus[idCpu];
+        PAPICCPU pApicCpu  = VMCPU_TO_APICCPU(pVCpu);
+
+        APIC_REG_COUNTER(&pApicCpu->StatMmioReadR0,  "Number of APIC MMIO reads in R0.",  "/Devices/APIC/%u/R0/MmioRead");
+        APIC_REG_COUNTER(&pApicCpu->StatMmioWriteR0, "Number of APIC MMIO writes in R0.", "/Devices/APIC/%u/R0/MmioWrite");
+        APIC_REG_COUNTER(&pApicCpu->StatMsrReadR0,   "Number of APIC MSR reads in R0.",   "/Devices/APIC/%u/R0/MsrRead");
+        APIC_REG_COUNTER(&pApicCpu->StatMsrWriteR0,  "Number of APIC MSR writes in R0.",  "/Devices/APIC/%u/R0/MsrWrite");
+
+        APIC_REG_COUNTER(&pApicCpu->StatMmioReadR3,  "Number of APIC MMIO reads in R3.",  "/Devices/APIC/%u/R3/MmioReadR3");
+        APIC_REG_COUNTER(&pApicCpu->StatMmioWriteR3, "Number of APIC MMIO writes in R3.", "/Devices/APIC/%u/R3/MmioWriteR3");
+        APIC_REG_COUNTER(&pApicCpu->StatMsrReadR3,   "Number of APIC MSR reads in R3.",   "/Devices/APIC/%u/R3/MsrReadR3");
+        APIC_REG_COUNTER(&pApicCpu->StatMsrWriteR3,  "Number of APIC MSR writes in R3.",  "/Devices/APIC/%u/R3/MsrWriteR3");
+
+        if (fHasRC)
+        {
+            APIC_REG_COUNTER(&pApicCpu->StatMmioReadRC,  "Number of APIC MMIO reads in RC.",  "/Devices/APIC/%u/RC/MmioRead");
+            APIC_REG_COUNTER(&pApicCpu->StatMmioWriteRC, "Number of APIC MMIO writes in RC.", "/Devices/APIC/%u/RC/MmioWrite");
+            APIC_REG_COUNTER(&pApicCpu->StatMsrReadRC,   "Number of APIC MSR reads in RC.",   "/Devices/APIC/%u/RC/MsrRead");
+            APIC_REG_COUNTER(&pApicCpu->StatMsrWriteRC,  "Number of APIC MSR writes in RC.",  "/Devices/APIC/%u/RC/MsrWrite");
+        }
+    }
+# undef APIC_REG_ACCESS_COUNTER
+#endif
+
     return VINF_SUCCESS;
 }
@@ -1360,4 +1398,5 @@
             pApicCpu->pTimerRC = TMTimerRCPtr(pApicCpu->pTimerR3);
 
+#if 0
             rc = PDMR3CritSectInit(pVM, &pApicCpu->TimerCritSect, RT_SRC_POS, pApicCpu->szTimerDesc);
             if (RT_SUCCESS(rc))
@@ -1365,4 +1404,7 @@
             else
                 return rc;
+#else
+            return VINF_SUCCESS;
+#endif
         }
         else
@@ -1384,28 +1426,4 @@
                               "Recognizes 'basic', 'lvt', 'timer' as arguments, defaulting to 'basic'.", apicR3DbgInfo);
 
-#ifdef VBOX_WITH_STATISTICS
-    /*
-     * Statistics.
-     */
-    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-    {
-        PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
-        PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
-        PDMDevHlpSTAMRegisterF(pDevIns, &pApicCpu->StatMmioReadGC,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
-                               "Number of APIC MMIO reads in GC.",  "/Devices/APIC/%u/MmioReadGC",  idCpu);
-        PDMDevHlpSTAMRegisterF(pDevIns, &pApicCpu->StatMmioReadHC,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
-                               "Number of APIC MMIO reads in HC.",  "/Devices/APIC/%u/MmioReadHC",  idCpu);
-
-        PDMDevHlpSTAMRegisterF(pDevIns, &pApicCpu->StatMmioWriteGC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
-                               "Number of APIC MMIO writes in GC.", "/Devices/APIC/%u/MmioWriteGC", idCpu);
-        PDMDevHlpSTAMRegisterF(pDevIns, &pApicCpu->StatMmioWriteHC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
-                               "Number of APIC MMIO writes in HC.", "/Devices/APIC/%u/MmioWriteHC", idCpu);
-
-        PDMDevHlpSTAMRegisterF(pDevIns, &pApicCpu->StatMsrWrite,    STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
-                               "Number of APIC MSR writes.", "/Devices/APIC/%u/MsrWrite", idCpu);
-        PDMDevHlpSTAMRegisterF(pDevIns, &pApicCpu->StatMsrRead,     STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
-                               "Number of APIC MSR reads.",  "/Devices/APIC/%u/MsrRead",  idCpu);
-    }
-#endif
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/VMM/include/APICInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/APICInternal.h	(revision 60463)
+++ /trunk/src/VBox/VMM/include/APICInternal.h	(revision 60464)
@@ -558,16 +558,31 @@
     /** @name APIC statistics.
      * @{ */
-    /** Number of MMIO reads in GC. */
-    STAMCOUNTER                 StatMmioReadGC;
-    /** Number of MMIO reads in GC. */
-    STAMCOUNTER                 StatMmioReadHC;
-    /** Number of MMIO writes in GC. */
-    STAMCOUNTER                 StatMmioWriteGC;
-    /** Number of MMIO writes in HC. */
-    STAMCOUNTER                 StatMmioWriteHC;
-    /** Number of MSR writes. */
-    STAMCOUNTER                 StatMsrWrite;
-    /** Number of MSR reads. */
-    STAMCOUNTER                 StatMsrRead;
+    /** Number of MMIO reads in R0. */
+    STAMCOUNTER                 StatMmioReadR0;
+    /** Number of MMIO reads in R3. */
+    STAMCOUNTER                 StatMmioReadR3;
+    /** Number of MMIO reads in RC. */
+    STAMCOUNTER                 StatMmioReadRC;
+
+    /** Number of MMIO writes in R0. */
+    STAMCOUNTER                 StatMmioWriteR0;
+    /** Number of MMIO writes in R3. */
+    STAMCOUNTER                 StatMmioWriteR3;
+    /** Number of MMIO writes in RC. */
+    STAMCOUNTER                 StatMmioWriteRC;
+
+    /** Number of MSR reads in R0. */
+    STAMCOUNTER                 StatMsrReadR0;
+    /** Number of MSR reads in R3. */
+    STAMCOUNTER                 StatMsrReadR3;
+    /** Number of MSR reads in RC. */
+    STAMCOUNTER                 StatMsrReadRC;
+
+    /** Number of MSR writes in R0. */
+    STAMCOUNTER                 StatMsrWriteR0;
+    /** Number of MSR writes in R3. */
+    STAMCOUNTER                 StatMsrWriteR3;
+    /** Number of MSR writes in RC. */
+    STAMCOUNTER                 StatMsrWriteRC;
     /** @} */
 #endif
