Index: trunk/src/VBox/Devices/PC/DevAPIC.cpp
===================================================================
--- trunk/src/VBox/Devices/PC/DevAPIC.cpp	(revision 19474)
+++ trunk/src/VBox/Devices/PC/DevAPIC.cpp	(revision 19475)
@@ -363,4 +363,5 @@
                                                  getCpuFromLapic(dev, s));
 }
+
 #ifdef IN_RING3
 DECLINLINE(void) cpuSendSipi(APICDeviceInfo* dev, APICState *s, int vector)
@@ -371,4 +372,12 @@
                                  getCpuFromLapic(dev, s),
                                  vector);
+}
+
+DECLINLINE(void) cpuSendInitIpi(APICDeviceInfo* dev, APICState *s)
+{
+    Log2(("apic: send init IPI\n"));
+
+    dev->pApicHlpR3->pfnSendInitIpi(dev->pDevInsR3,
+                                    getCpuFromLapic(dev, s));
 }
 #endif
@@ -416,5 +425,5 @@
 #endif /* !VBOX */
 
-static void apic_init_ipi(APICState *s);
+static void apic_init_ipi(APICDeviceInfo* dev, APICState *s);
 static void apic_set_irq(APICDeviceInfo* dev, APICState *s, int vector_num, int trigger_mode);
 static bool apic_update_irq(APICDeviceInfo* dev, APICState *s);
@@ -431,5 +440,5 @@
 PDMBOTHCBDECL(void) apicSetTPR(PPDMDEVINS pDevIns, uint8_t val);
 PDMBOTHCBDECL(uint8_t) apicGetTPR(PPDMDEVINS pDevIns);
-PDMBOTHCBDECL(void) apicBusDeliverCallback(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
+PDMBOTHCBDECL(int)  apicBusDeliverCallback(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
                                            uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
                                            uint8_t u8TriggerMode);
@@ -451,8 +460,8 @@
     APICState *apic_iter;
 #else /* VBOX */
-static void apic_bus_deliver(APICDeviceInfo* dev,
-                             uint32_t deliver_bitmask, uint8_t delivery_mode,
-                             uint8_t vector_num, uint8_t polarity,
-                             uint8_t trigger_mode)
+static int apic_bus_deliver(APICDeviceInfo* dev,
+                            uint32_t deliver_bitmask, uint8_t delivery_mode,
+                            uint8_t vector_num, uint8_t polarity,
+                            uint8_t trigger_mode)
 {
 #endif /* VBOX */
@@ -470,5 +479,5 @@
                 apic_set_irq(dev, apic, vector_num, trigger_mode);
             }
-            return;
+            return VINF_SUCCESS;
         }
         case APIC_DM_FIXED:
@@ -480,5 +489,5 @@
             foreach_apic(dev, deliver_bitmask,
                          cpuSetInterrupt(dev, apic));
-            return;
+            return VINF_SUCCESS;
 
         case APIC_DM_NMI:
@@ -486,11 +495,19 @@
             foreach_apic(dev, deliver_bitmask,
                          cpuSetInterrupt(dev, apic));
-            return;
+            return VINF_SUCCESS;
 
         case APIC_DM_INIT:
             /* normal INIT IPI sent to processors */
 #ifdef VBOX
+#ifdef IN_RING3
             foreach_apic(dev, deliver_bitmask,
-                         apic_init_ipi(apic));
+                         apic_init_ipi(dev, apic));
+            return VINF_SUCCESS;
+#else
+            /* We shall send init IPI only in R3, R0 calls should be
+               rescheduled to R3 */
+            return  VINF_IOM_HC_MMIO_READ_WRITE;
+#endif /* IN_RING3 */
+
 #else
             for (apic_iter = first_local_apic; apic_iter != NULL;
@@ -499,5 +516,4 @@
             }
 #endif
-            return;
 
         case APIC_DM_EXTINT:
@@ -506,5 +522,5 @@
 
         default:
-            return;
+            return VINF_SUCCESS;
     }
 
@@ -512,4 +528,5 @@
     foreach_apic(dev, deliver_bitmask,
                        apic_set_irq (dev, apic, vector_num, trigger_mode));
+    return VINF_SUCCESS;
 #else  /* VBOX */
     for (apic_iter = first_local_apic; apic_iter != NULL;
@@ -672,5 +689,5 @@
 {
     APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
-    int rv = VINF_SUCCESS;
+    int rc = VINF_SUCCESS;
 
     if (dev->enmVersion < PDMAPICVERSION_X2APIC)
@@ -718,5 +735,5 @@
             apic->icr[0] = (uint32_t)u64Value;
             apic->icr[1] = (uint32_t)(u64Value >> 32);
-            rv = apic_deliver(dev, apic, (apic->icr[1] >> 24) & 0xff, (apic->icr[0] >> 11) & 1,
+            rc = apic_deliver(dev, apic, (apic->icr[1] >> 24) & 0xff, (apic->icr[0] >> 11) & 1,
                              (apic->icr[0] >>  8) & 7, (apic->icr[0] & 0xff),
                              (apic->icr[0] >> 14) & 1, (apic->icr[0] >> 15) & 1);
@@ -750,10 +767,10 @@
             /* Self IPI, see x2APIC book 2.4.5 */
             int vector = u64Value & 0xff;
-            apic_bus_deliver(dev,
-                             1 << getLapicById(dev, idCpu)->id /* Self */,
-                             0 /* Delivery mode - fixed */,
-                             vector,
-                             0 /* Polarity - conform to the bus */,
-                             0 /* Trigger mode - edge */);
+            rc = apic_bus_deliver(dev,
+                                  1 << getLapicById(dev, idCpu)->id /* Self */,
+                                  0 /* Delivery mode - fixed */,
+                                  vector,
+                                  0 /* Polarity - conform to the bus */,
+                                  0 /* Trigger mode - edge */);
             break;
         }
@@ -764,5 +781,5 @@
     }
 
-    return rv;
+    return rc;
 }
 PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value)
@@ -854,5 +871,5 @@
  * for connecting the two devices.
  */
-PDMBOTHCBDECL(void) apicBusDeliverCallback(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
+PDMBOTHCBDECL(int) apicBusDeliverCallback(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
                                            uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
                                            uint8_t u8TriggerMode)
@@ -861,6 +878,6 @@
     LogFlow(("apicBusDeliverCallback: pDevIns=%p u8Dest=%#x u8DestMode=%#x u8DeliveryMode=%#x iVector=%#x u8Polarity=%#x u8TriggerMode=%#x\n",
              pDevIns, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
-    apic_bus_deliver(dev, apic_get_delivery_bitmask(dev, u8Dest, u8DestMode),
-                     u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
+    return apic_bus_deliver(dev, apic_get_delivery_bitmask(dev, u8Dest, u8DestMode),
+                            u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
 }
 
@@ -1053,5 +1070,6 @@
 }
 
-static void apic_init_ipi(APICState *s)
+#ifdef IN_RING3
+static void apic_init_ipi(APICDeviceInfo* dev, APICState *s)
 {
     int i;
@@ -1075,10 +1093,8 @@
 
 #ifdef VBOX
-    /** @todo reset CPU, activate wait for sipi mode for application processors */
-    /** Must be dealt with in ring 3 */
-#endif
-}
-
-#ifdef IN_RING3
+    cpuSendInitIpi(dev, s);
+#endif
+}
+
 /* send a SIPI message to the CPU to start it */
 static void apic_startup(APICDeviceInfo* dev, APICState *s, int vector_num)
@@ -1098,5 +1114,5 @@
 #endif
 }
-#endif
+#endif /* IN_RING3 */
 
 static int  apic_deliver(APICDeviceInfo* dev, APICState *s,
@@ -1142,17 +1158,11 @@
                 int level = (s->icr[0] >> 14) & 1;
                 if (level == 0 && trig_mode == 1) {
-#ifdef VBOX
                     foreach_apic(dev, deliver_bitmask,
                                        apic->arb_id = apic->id);
+#ifndef VBOX
+                    return;
+#else
                     return VINF_SUCCESS;
-#else /* !VBOX */
-                    for (apic_iter = first_local_apic; apic_iter != NULL;
-                         apic_iter = apic_iter->next_apic) {
-                        if (deliver_bitmask & (1 << apic_iter->id)) {
-                            apic_iter->arb_id = apic_iter->id;
-                        }
-                    }
-                    return;
-#endif /* !VBOX */
+#endif
                 }
             }
@@ -1171,10 +1181,9 @@
 #else
 # ifdef IN_RING3
-            
             foreach_apic(dev, deliver_bitmask,
                          apic_startup(dev, apic, vector_num));
             return VINF_SUCCESS;
 # else
-            /* We shall send SIPI only in R3, R0 calls should be 
+            /* We shall send SIPI only in R3, R0 calls should be
                rescheduled to R3 */
             return  VINF_IOM_HC_MMIO_WRITE;
@@ -1187,7 +1196,6 @@
                      trigger_mode);
 #else /* VBOX */
-    apic_bus_deliver(dev, deliver_bitmask, delivery_mode, vector_num, polarity,
-                     trigger_mode);
-    return VINF_SUCCESS;
+    return apic_bus_deliver(dev, deliver_bitmask, delivery_mode, vector_num,
+                            polarity, trigger_mode);
 #endif /* VBOX */
 }
@@ -1456,5 +1464,5 @@
 static int apic_mem_writel(APICDeviceInfo* dev, APICState *s, target_phys_addr_t addr, uint32_t val)
 {
-    int rv = VINF_SUCCESS;
+    int rc = VINF_SUCCESS;
 #endif /* VBOX */
     int index;
@@ -1520,5 +1528,5 @@
     case 0x30:
         s->icr[0] = val;
-        rv = apic_deliver(dev, s, (s->icr[1] >> 24) & 0xff, 
+        rc = apic_deliver(dev, s, (s->icr[1] >> 24) & 0xff,
                           (s->icr[0] >> 11) & 1,
                           (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
@@ -1570,5 +1578,5 @@
     }
 #ifdef VBOX
-    return rv;
+    return rc;
 #endif
 }
@@ -1783,5 +1791,5 @@
                                  delivery_mode, vector, polarity, trig_mode);
 #else /* VBOX */
-                s->CTX_SUFF(pIoApicHlp)->pfnApicBusDeliver(s->CTX_SUFF(pDevIns),
+                int rc = s->CTX_SUFF(pIoApicHlp)->pfnApicBusDeliver(s->CTX_SUFF(pDevIns),
                                                            dest,
                                                            dest_mode,
@@ -1790,4 +1798,7 @@
                                                            polarity,
                                                            trig_mode);
+                /* We must be sure that attempts to reschedule in R3 
+                   never get here */
+                Assert(rc == VINF_SUCCESS);
 #endif /* VBOX */
             }
@@ -2155,5 +2166,5 @@
     TMTimerStop(s->CTX_SUFF(pTimer));
 
-    apic_init_ipi(s);
+    apic_init_ipi(dev, s);
     /* malc, I've removed the initing duplicated in apic_init_ipi(). This
      * arb_id was left over.. */
Index: trunk/src/VBox/VMM/PDMDevMiscHlp.cpp
===================================================================
--- trunk/src/VBox/VMM/PDMDevMiscHlp.cpp	(revision 19474)
+++ trunk/src/VBox/VMM/PDMDevMiscHlp.cpp	(revision 19475)
@@ -221,5 +221,4 @@
 }
 
-
 /** @copydoc PDMAPICHLPR3::pfnGetCpuId */
 static DECLCALLBACK(VMCPUID) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns)
@@ -239,4 +238,11 @@
 }
 
+/** @copydoc PDMAPICHLPR3::pfnSendInitIpi */
+static DECLCALLBACK(void) pdmR3ApicHlp_SendInitIpi(PPDMDEVINS pDevIns, VMCPUID idCpu)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
+    VMMR3SendInitIpi(pDevIns->Internal.s.pVMR3, idCpu);
+}
 
 /** @copydoc PDMAPICHLPR3::pfnGetRCHelpers */
@@ -283,4 +289,5 @@
     pdmR3ApicHlp_GetCpuId,
     pdmR3ApicHlp_SendSipi,
+    pdmR3ApicHlp_SendInitIpi,
     pdmR3ApicHlp_GetRCHelpers,
     pdmR3ApicHlp_GetR0Helpers,
@@ -298,5 +305,5 @@
 
 /** @copydoc PDMIOAPICHLPR3::pfnApicBusDeliver */
-static DECLCALLBACK(void) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+static DECLCALLBACK(int) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                         uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
 {
@@ -306,5 +313,6 @@
              pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
     if (pVM->pdm.s.Apic.pfnBusDeliverR3)
-        pVM->pdm.s.Apic.pfnBusDeliverR3(pVM->pdm.s.Apic.pDevInsR3, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
+        return pVM->pdm.s.Apic.pfnBusDeliverR3(pVM->pdm.s.Apic.pDevInsR3, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
+    return VINF_SUCCESS;
 }
 
Index: trunk/src/VBox/VMM/PDMInternal.h
===================================================================
--- trunk/src/VBox/VMM/PDMInternal.h	(revision 19474)
+++ trunk/src/VBox/VMM/PDMInternal.h	(revision 19475)
@@ -417,5 +417,5 @@
     DECLR3CALLBACKMEMBER(int,       pfnReadMSRR3, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value));
     /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
-    DECLR3CALLBACKMEMBER(void,      pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+    DECLR3CALLBACKMEMBER(int,       pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                      uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
 
@@ -439,5 +439,5 @@
     DECLR0CALLBACKMEMBER(uint32_t,  pfnReadMSRR0, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value));
     /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
-    DECLR0CALLBACKMEMBER(void,      pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+    DECLR0CALLBACKMEMBER(int,       pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                      uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
 
@@ -461,5 +461,5 @@
     DECLRCCALLBACKMEMBER(uint32_t,  pfnReadMSRRC, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value));
     /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
-    DECLRCCALLBACKMEMBER(void,      pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+    DECLRCCALLBACKMEMBER(int,       pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                      uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
 } PDMAPIC;
Index: trunk/src/VBox/VMM/VMMAll/VMMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/VMMAll.cpp	(revision 19474)
+++ trunk/src/VBox/VMM/VMMAll/VMMAll.cpp	(revision 19475)
@@ -100,4 +100,14 @@
 }
 
+DECLCALLBACK(int) vmmR3SendInitIpi(PVM pVM, VMCPUID idCpu)
+{
+    PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu);
+    VMCPU_ASSERT_EMT(pVCpu);
+
+    /** @todo: reset CPU and halt till SIPI */
+
+    return VINF_SUCCESS;
+}
+
 /**
  * Sends SIPI to the virtual CPU by setting CS:EIP into vector-dependent state
@@ -115,4 +125,21 @@
     int rc = VMR3ReqCallU(pVM->pUVM, idCpu, &pReq, RT_INDEFINITE_WAIT, 0,
                           (PFNRT)vmmR3SendSipi, 3, pVM, idCpu, uVector);
+    AssertRC(rc);
+    VMR3ReqFree(pReq);
+}
+
+/**
+ * Sends init IPI to the virtual CPU.
+ *
+ * @param   pVM         The VM to operate on.
+ * @param   idCpu       Virtual CPU to perform int IPI on
+ */
+VMMR3DECL(void) VMMR3SendInitIpi(PVM pVM, VMCPUID idCpu)
+{
+    AssertReturnVoid(idCpu < pVM->cCPUs);
+
+    PVMREQ pReq;
+    int rc = VMR3ReqCallU(pVM->pUVM, idCpu, &pReq, RT_INDEFINITE_WAIT, 0,
+                          (PFNRT)vmmR3SendInitIpi, 2, pVM, idCpu);
     AssertRC(rc);
     VMR3ReqFree(pReq);
Index: trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp	(revision 19474)
+++ trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp	(revision 19475)
@@ -98,5 +98,5 @@
  * @{
  */
-static DECLCALLBACK(void) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+static DECLCALLBACK(int) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                         uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);
 static DECLCALLBACK(int) pdmRCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
@@ -490,5 +490,5 @@
 
 /** @copydoc PDMIOAPICHLPRC::pfnApicBusDeliver */
-static DECLCALLBACK(void) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+static DECLCALLBACK(int) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                         uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
 {
@@ -498,5 +498,6 @@
              pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
     if (pVM->pdm.s.Apic.pfnBusDeliverRC)
-        pVM->pdm.s.Apic.pfnBusDeliverRC(pVM->pdm.s.Apic.pDevInsRC, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
+        return pVM->pdm.s.Apic.pfnBusDeliverRC(pVM->pdm.s.Apic.pDevInsRC, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
+    return VINF_SUCCESS;
 }
 
Index: trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 19474)
+++ trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 19475)
@@ -100,5 +100,5 @@
  * @{
  */
-static DECLCALLBACK(void) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                         uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);
 static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
@@ -504,5 +504,5 @@
 
 /** @copydoc PDMIOAPICHLPR0::pfnApicBusDeliver */
-static DECLCALLBACK(void) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                         uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
 {
@@ -513,5 +513,6 @@
     Assert(pVM->pdm.s.Apic.pDevInsR0);
     if (pVM->pdm.s.Apic.pfnBusDeliverR0)
-        pVM->pdm.s.Apic.pfnBusDeliverR0(pVM->pdm.s.Apic.pDevInsR0, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
+        return pVM->pdm.s.Apic.pfnBusDeliverR0(pVM->pdm.s.Apic.pDevInsR0, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
+    return VINF_SUCCESS;
 }
 
