Index: /trunk/src/VBox/VMM/VMMAll/APICAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 60604)
+++ /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 60605)
@@ -1481,8 +1481,7 @@
  * @thread  Any.
  */
-static void apicHintTimerFreq(PAPICCPU pApicCpu, uint32_t uInitialCount, uint8_t uTimerShift)
+void apicHintTimerFreq(PAPICCPU pApicCpu, uint32_t uInitialCount, uint8_t uTimerShift)
 {
     Assert(pApicCpu);
-    Assert(TMTimerIsLockOwner(pApicCpu->CTX_SUFF(pTimer)));
 
     if (   pApicCpu->uHintedTimerInitialCount != uInitialCount
Index: /trunk/src/VBox/VMM/VMMR3/APIC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 60604)
+++ /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 60605)
@@ -632,4 +632,43 @@
 
 /**
+ * Worker for loading per-VM APIC data.
+ *
+ * @returns VBox status code.
+ * @param   pVM     The cross context VM structure.
+ * @param   pSSM    The SSM handle.
+ */
+static int apicR3LoadVMData(PVM pVM, PSSMHANDLE pSSM)
+{
+    PAPIC pApic = VM_TO_APIC(pVM);
+
+    /* Load and verify number of CPUs. */
+    uint32_t cCpus;
+    int rc = SSMR3GetU32(pSSM, &cCpus);
+    AssertRCReturn(rc, rc);
+    if (cCpus != pVM->cCpus)
+        return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - cCpus: saved=%u config=%u"), cCpus, pVM->cCpus);
+
+    /* Load and verify I/O APIC presence. */
+    bool fIoApicPresent;
+    rc = SSMR3GetBool(pSSM, &fIoApicPresent);
+    AssertRCReturn(rc, rc);
+    if (fIoApicPresent != pApic->fIoApicPresent)
+        return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - fIoApicPresent: saved=%RTbool config=%RTbool"),
+                                fIoApicPresent, pApic->fIoApicPresent);
+
+    /* Load and verify configured APIC mode. */
+    uint32_t uLegacyApicMode;
+    rc = SSMR3GetU32(pSSM, &uLegacyApicMode);
+    AssertRCReturn(rc, rc);
+    APICMODE const enmApicMode = apicR3ConvertFromLegacyApicMode((PDMAPICMODE)uLegacyApicMode);
+    if (enmApicMode != pApic->enmOriginalMode)
+        return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - uApicMode: saved=%#x(%#x) config=%#x(%#x)"),
+                                uLegacyApicMode, enmApicMode, apicR3ConvertToLegacyApicMode(pApic->enmOriginalMode),
+                                pApic->enmOriginalMode);
+    return VINF_SUCCESS;
+}
+
+
+/**
  * @copydoc FNSSMDEVLIVEEXEC
  */
@@ -671,18 +710,16 @@
         /* Save the APIC page. */
         if (XAPIC_IN_X2APIC_MODE(pVCpu))
-            SSMR3PutStruct(pSSM, (const void *)pApicCpu->pvApicPageR3, g_aX2ApicPageFields);
+            SSMR3PutStruct(pSSM, (const void *)pApicCpu->pvApicPageR3, &g_aX2ApicPageFields[0]);
         else
-            SSMR3PutStruct(pSSM, (const void *)pApicCpu->pvApicPageR3, g_aXApicPageFields);
+            SSMR3PutStruct(pSSM, (const void *)pApicCpu->pvApicPageR3, &g_aXApicPageFields[0]);
 
         /* Save the PIBs: In theory, we could push them to vIRR and avoid saving them here, but
            with posted-interrupts we can't at this point as HM is paralyzed, so just save PIBs always. */
-        SSMR3PutStruct(pSSM, (const void *)pApicCpu->pvApicPibR3,   g_aApicPibFields);
-        SSMR3PutStruct(pSSM, (const void *)&pApicCpu->ApicPibLevel, g_aApicPibFields);
+        SSMR3PutStruct(pSSM, (const void *)pApicCpu->pvApicPibR3,   &g_aApicPibFields[0]);
+        SSMR3PutStruct(pSSM, (const void *)&pApicCpu->ApicPibLevel, &g_aApicPibFields[0]);
 
         /* Save the timer. */
         TMR3TimerSave(pApicCpu->pTimerR3, pSSM);
         SSMR3PutU64(pSSM, pApicCpu->u64TimerInitial);
-
-        /** @todo anything else? */
     }
 
@@ -703,4 +740,5 @@
     /* Weed out invalid versions. */
     if (    uVersion != APIC_SAVED_STATE_VERSION
+        &&  uVersion != APIC_SAVED_STATE_VERSION_VBOX_50
         &&  uVersion != APIC_SAVED_STATE_VERSION_VBOX_30
         &&  uVersion != APIC_SAVED_STATE_VERSION_ANCIENT)
@@ -711,47 +749,48 @@
     if (uVersion > APIC_SAVED_STATE_VERSION_VBOX_30)
     {
-        /* Verify number of CPUs. */
-        uint32_t cCpus;
-        int rc = SSMR3GetU32(pSSM, &cCpus);
-        AssertRCReturn(rc, rc);
-        if (cCpus != pVM->cCpus)
-            return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - cCpus: saved=%u config=%u"), cCpus, pVM->cCpus);
-
-        /* Verify I/O APIC presence. */
-        bool fIoApicPresent;
-        rc = SSMR3GetBool(pSSM, &fIoApicPresent);
-        AssertRCReturn(rc, rc);
-        if (fIoApicPresent != pApic->fIoApicPresent)
-            return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - fIoApicPresent: saved=%RTbool config=%RTbool"),
-                                    fIoApicPresent, pApic->fIoApicPresent);
-
-        /* Verify configured APIC mode. */
-        uint32_t uLegacyApicMode;
-        rc = SSMR3GetU32(pSSM, &uLegacyApicMode);
-        AssertRCReturn(rc, rc);
-        APICMODE const enmApicMode = apicR3ConvertFromLegacyApicMode((PDMAPICMODE)uLegacyApicMode);
-        if (enmApicMode != pApic->enmOriginalMode)
-            return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - uApicMode: saved=%#x(%#x) config=%#x(%#x)"),
-                                    uLegacyApicMode, enmApicMode, apicR3ConvertToLegacyApicMode(pApic->enmOriginalMode),
-                                    pApic->enmOriginalMode);
+        int rc2 = apicR3LoadVMData(pVM, pSSM);
+        AssertRCReturn(rc2, rc2);
+
+        if (uVersion == APIC_SAVED_STATE_VERSION)
+        { /* Load any new additional per-VM data. */ }
+    }
+
+    if (uPass != SSM_PASS_FINAL)
+        return VINF_SUCCESS;
+
+    int rc = VINF_SUCCESS;
+    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+    {
+        PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
+        PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
 
         if (uVersion == APIC_SAVED_STATE_VERSION)
         {
-            /** @todo load any new additional per-VM data. */
-        }
-    }
-
-    if (uPass != SSM_PASS_FINAL)
-        return VINF_SUCCESS;
-
-    int rc = VINF_SUCCESS;
-    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-    {
-        PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
-        PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
-
-        if (uVersion == APIC_SAVED_STATE_VERSION)
-        {
-            /** @todo load new per-VCPU data. */
+            /* Load the auxiliary data. */
+            SSMR3GetU64(pSSM, (uint64_t *)&pApicCpu->uApicBaseMsr);
+            SSMR3GetU32(pSSM, &pApicCpu->uEsrInternal);
+
+            /* Load the APIC page. */
+            if (XAPIC_IN_X2APIC_MODE(pVCpu))
+                SSMR3GetStruct(pSSM, (void *)pApicCpu->pvApicPageR3, &g_aX2ApicPageFields[0]);
+            else
+                SSMR3GetStruct(pSSM, (void *)pApicCpu->pvApicPageR3, &g_aXApicPageFields[0]);
+
+            /* Load the PIBs. */
+            SSMR3GetStruct(pSSM, (void *)pApicCpu->pvApicPibR3,   &g_aApicPibFields[0]);
+            SSMR3GetStruct(pSSM, (void *)&pApicCpu->ApicPibLevel, &g_aApicPibFields[0]);
+
+            /* Load the timer. */
+            rc = TMR3TimerLoad(pApicCpu->pTimerR3, pSSM);           AssertRCReturn(rc, rc);
+            rc = SSMR3GetU64(pSSM, &pApicCpu->u64TimerInitial);     AssertRCReturn(rc, rc);
+            Assert(pApicCpu->uHintedTimerShift == 0);
+            Assert(pApicCpu->uHintedTimerInitialCount == 0);
+            if (TMTimerIsActive(pApicCpu->pTimerR3))
+            {
+                PCXAPICPAGE    pXApicPage    = VMCPU_TO_CXAPICPAGE(pVCpu);
+                uint32_t const uInitialCount = pXApicPage->timer_icr.u32InitialCount;
+                uint8_t const  uTimerShift   = apicGetTimerShift(pXApicPage);
+                apicHintTimerFreq(pApicCpu, uInitialCount, uTimerShift);
+            }
         }
         else
Index: /trunk/src/VBox/VMM/include/APICInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/APICInternal.h	(revision 60604)
+++ /trunk/src/VBox/VMM/include/APICInternal.h	(revision 60605)
@@ -514,5 +514,5 @@
      * @{ */
     /** The error status register's internal state. */
-    uint32_t volatile           uEsrInternal;
+    uint32_t                    uEsrInternal;
     /** The APIC base MSR.*/
     uint64_t volatile           uApicBaseMsr;
@@ -626,4 +626,5 @@
 const char             *apicGetDestShorthandName(XAPICDESTSHORTHAND enmDestShorthand);
 const char             *apicGetTimerModeName(XAPICTIMERMODE enmTimerMode);
+void                    apicHintTimerFreq(PAPICCPU pApicCpu, uint32_t uInitialCount, uint8_t uTimerShift);
 
 VMMDECL(uint64_t)       APICGetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu);
