Index: /trunk/include/VBox/vmm/apic.h
===================================================================
--- /trunk/include/VBox/vmm/apic.h	(revision 60600)
+++ /trunk/include/VBox/vmm/apic.h	(revision 60601)
@@ -901,11 +901,8 @@
 AssertCompileMemberOffset(X2APICPAGE, self_ipi,    X2APIC_OFF_SELF_IPI);
 
-/** The offset (in bits) of the posted-interrupt bitmap's outstanding
- *  notification bit. */
-#define XAPIC_PIB_NOTIFICATION_BIT             UINT32_C(256)
-
 /**
  * APIC Pending Interrupt Bitmap (PIB).
- * The layout is critical as it mimics VT-x's Posted Interrupt Bitmap!
+ * @note This structure is used in saved-state, careful with changing layout or
+ *       size!
  */
 typedef struct APICPIB
@@ -915,5 +912,5 @@
     uint8_t           au8Reserved[28];
 } APICPIB;
-AssertCompileMemberOffset(APICPIB, fOutstandingNotification, XAPIC_PIB_NOTIFICATION_BIT / 8);
+AssertCompileMemberOffset(APICPIB, fOutstandingNotification, 256 / 8);
 AssertCompileSize(APICPIB, 64);
 /** Pointer to a pending interrupt bitmap. */
Index: /trunk/src/VBox/VMM/VMMAll/APICAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 60600)
+++ /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 60601)
@@ -105,12 +105,12 @@
 
 /**
- * Atomically tests and sets the PIB notification bit.
- *
- * @returns true if the bit was already set, false otherwise.
- * @param   pvPib           Opaque pointer to the PIB.
- */
-DECLINLINE(bool) apicSetNotificationBitInPib(volatile void *pvPib)
-{
-    return ASMAtomicBitTestAndSet(pvPib, XAPIC_PIB_NOTIFICATION_BIT);
+ * Atomically sets the PIB notification bit.
+ *
+ * @returns non-zero if the bit was already set, 0 otherwise.
+ * @param   pApicPib        Pointer to the PIB.
+ */
+DECLINLINE(uint32_t) apicSetNotificationBitInPib(PAPICPIB pApicPib)
+{
+    return ASMAtomicXchgU32(&pApicPib->fOutstandingNotification, RT_BIT_32(31));
 }
 
@@ -119,9 +119,10 @@
  * Atomically tests and clears the PIB notification bit.
  *
- * @returns true if the bit was already set, false otherwise.
- */
-DECLINLINE(bool) apicClearNotificationBitInPib(volatile void *pvPib)
-{
-    return ASMAtomicBitTestAndClear(pvPib, XAPIC_PIB_NOTIFICATION_BIT);
+ * @returns non-zero if the bit was already set, 0 otherwise.
+ * @param   pApicPib        Pointer to the PIB.
+ */
+DECLINLINE(uint32_t) apicClearNotificationBitInPib(PAPICPIB pApicPib)
+{
+    return ASMAtomicXchgU32(&pApicPib->fOutstandingNotification, UINT32_C(0));
 }
 
@@ -2442,7 +2443,6 @@
                 else
                 {
-                    Assert(CTX_SUFF(pApicCpu->pvApicPib));
-                    apicSetVectorInPib(CTX_SUFF(pApicCpu->pvApicPib), uVector);
-                    bool const fAlreadySet = apicSetNotificationBitInPib(CTX_SUFF(pApicCpu->pvApicPib));
+                    apicSetVectorInPib(pApicCpu->CTX_SUFF(pvApicPib), uVector);
+                    uint32_t const fAlreadySet = apicSetNotificationBitInPib((PAPICPIB)pApicCpu->CTX_SUFF(pvApicPib));
                     if (!fAlreadySet)
                         APICSetInterruptFF(pVCpu, PDMAPICIRQ_HARDWARE);
@@ -2455,6 +2455,6 @@
                  * delivered asynchronously.
                  */
-                apicSetVectorInPib(&pApicCpu->ApicPibLevel.aVectorBitmap[0], uVector);
-                bool const fAlreadySet = apicSetNotificationBitInPib(&pApicCpu->ApicPibLevel.aVectorBitmap[0]);
+                apicSetVectorInPib(&pApicCpu->ApicPibLevel, uVector);
+                uint32_t const fAlreadySet = apicSetNotificationBitInPib((PAPICPIB)&pApicCpu->ApicPibLevel);
                 if (!fAlreadySet)
                     APICSetInterruptFF(pVCpu, PDMAPICIRQ_HARDWARE);
@@ -2636,5 +2636,5 @@
     for (;;)
     {
-        bool const fAlreadySet = apicClearNotificationBitInPib(CTX_SUFF(pApicCpu->pvApicPib));
+        uint32_t const fAlreadySet = apicClearNotificationBitInPib((PAPICPIB)pApicCpu->CTX_SUFF(pvApicPib));
         if (!fAlreadySet)
             break;
@@ -2663,5 +2663,5 @@
     for (;;)
     {
-        bool const fAlreadySet = apicClearNotificationBitInPib(&pApicCpu->ApicPibLevel);
+        uint32_t const fAlreadySet = apicClearNotificationBitInPib((PAPICPIB)&pApicCpu->ApicPibLevel);
         if (!fAlreadySet)
             break;
Index: /trunk/src/VBox/VMM/VMMR3/APIC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 60600)
+++ /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 60601)
@@ -148,4 +148,14 @@
 };
 
+/** Saved state field descriptors for APICPIB. */
+static const SSMFIELD g_aApicPibFields[] =
+{
+    SSMFIELD_ENTRY(APICPIB,    aVectorBitmap[0]),
+    SSMFIELD_ENTRY(APICPIB,    aVectorBitmap[1]),
+    SSMFIELD_ENTRY(APICPIB,    aVectorBitmap[2]),
+    SSMFIELD_ENTRY(APICPIB,    aVectorBitmap[3]),
+    SSMFIELD_ENTRY(APICPIB,    fOutstandingNotification),
+    SSMFIELD_ENTRY_TERM()
+};
 
 /**
@@ -655,7 +665,24 @@
         PCAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
 
+        /* Save the auxiliary data. */
         SSMR3PutU64(pSSM, pApicCpu->uApicBaseMsr);
-
-        /** @todo  */
+        SSMR3PutU32(pSSM, pApicCpu->uEsrInternal);
+
+        /* Save the APIC page. */
+        if (XAPIC_IN_X2APIC_MODE(pVCpu))
+            SSMR3PutStruct(pSSM, (const void *)pApicCpu->pvApicPageR3, g_aX2ApicPageFields);
+        else
+            SSMR3PutStruct(pSSM, (const void *)pApicCpu->pvApicPageR3, g_aXApicPageFields);
+
+        /* Save the PIBs: We could in theory push them to vIRR and avoid saving them,
+           but in case of posted-interrupts we can't do that at this point, so save in all cases. */
+        SSMR3PutStruct(pSSM, (const void *)pApicCpu->pvApicPibR3,   g_aApicPibFields);
+        SSMR3PutStruct(pSSM, (const void *)&pApicCpu->ApicPibLevel, g_aApicPibFields);
+
+        /* Save the timer. */
+        TMR3TimerSave(pApicCpu->pTimerR3, pSSM);
+        SSMR3PutU64(pSSM, pApicCpu->u64TimerInitial);
+
+        /** @todo anything else? */
     }
 
