Index: /trunk/include/VBox/pdmdev.h
===================================================================
--- /trunk/include/VBox/pdmdev.h	(revision 24124)
+++ /trunk/include/VBox/pdmdev.h	(revision 24125)
@@ -1043,4 +1043,14 @@
                                                 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
 
+    /**
+     * Deliver a signal to CPU's local interrupt pins (LINT0/LINT1). Used for
+     * virtual wire mode when interrupts from the PIC are passed through LAPIC.
+     *
+     * @returns status code.
+     * @param   pDevIns         Device instance of the APIC.
+     * @param   u8Pin           Local pin number (0 or 1 for current CPUs).
+     */
+    DECLR3CALLBACKMEMBER(int,  pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
+
     /** The name of the RC GetInterrupt entry point. */
     const char         *pszGetInterruptRC;
@@ -1061,4 +1071,6 @@
     /** The name of the RC BusDeliver entry point. */
     const char         *pszBusDeliverRC;
+    /** The name of the RC LocalInterrupt entry point. */
+    const char         *pszLocalInterruptRC;
 
     /** The name of the R0 GetInterrupt entry point. */
@@ -1080,4 +1092,6 @@
     /** The name of the R0 BusDeliver entry point. */
     const char         *pszBusDeliverR0;
+    /** The name of the R0 LocalInterrupt entry point. */
+    const char         *pszLocalInterruptR0;
 
 } PDMAPICREG;
@@ -1119,4 +1133,6 @@
     /** SMI. */
     PDMAPICIRQ_SMI,
+    /** ExtINT (HW interrupt via PIC). */
+    PDMAPICIRQ_EXTINT,
     /** The usual 32-bit paranoia. */
     PDMAPICIRQ_32BIT_HACK = 0x7fffffff
@@ -1145,7 +1161,8 @@
      *
      * @param   pDevIns         Device instance of the APIC.
+     * @param   enmType         IRQ type.
      * @param   idCpu           Virtual CPU to clear flag upon.
      */
-    DECLRCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, VMCPUID idCpu));
+    DECLRCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
 
     /**
@@ -1214,7 +1231,8 @@
      *
      * @param   pDevIns         Device instance of the APIC.
+     * @param   enmType         IRQ type.
      * @param   idCpu           Virtual CPU to clear flag upon.
      */
-    DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, VMCPUID idCpu));
+    DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
 
     /**
@@ -1282,7 +1300,8 @@
      *
      * @param   pDevIns         Device instance of the APIC.
+     * @param   enmType         IRQ type.
      * @param   idCpu           Virtual CPU to clear flag upon.
      */
-    DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, VMCPUID idCpu));
+    DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
 
     /**
Index: /trunk/src/VBox/Devices/PC/DevAPIC.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevAPIC.cpp	(revision 24124)
+++ /trunk/src/VBox/Devices/PC/DevAPIC.cpp	(revision 24125)
@@ -390,4 +390,5 @@
                                            uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
                                            uint8_t u8TriggerMode);
+PDMBOTHCBDECL(int)  apicLocalInterrupt(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level);
 PDMBOTHCBDECL(int)  apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value);
 PDMBOTHCBDECL(int)  apicReadMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value);
@@ -446,8 +447,8 @@
 }
 
-DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* dev, APICState *s)
+DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* dev, APICState *s, PDMAPICIRQ enmType = PDMAPICIRQ_HARDWARE)
 {
     LogFlow(("apic: clear interrupt flag\n"));
-    dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns),
+    dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns), enmType,
                                                  getCpuFromLapic(dev, s));
 }
@@ -961,4 +962,70 @@
     return apic_bus_deliver(dev, apic_get_delivery_bitmask(dev, u8Dest, u8DestMode),
                             u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
+}
+
+/**
+ * Local interrupt delivery, for devices attached to the CPU's LINT0/LINT1 pin.
+ * Normally used for 8259A PIC and NMI.
+ */
+PDMBOTHCBDECL(int) apicLocalInterrupt(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level)
+{
+    APICDeviceInfo  *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
+    APICState       *s = getLapicById(dev, 0);
+
+    Assert(PDMCritSectIsOwner(dev->CTX_SUFF(pCritSect)));
+    LogFlow(("apicLocalInterrupt: pDevIns=%p u8Pin=%x\n", pDevIns, u8Pin));
+
+    /* If LAPIC is disabled, go straight to the CPU. */
+    if (!(s->spurious_vec & APIC_SV_ENABLE))
+    {
+        LogFlow(("apicLocalInterrupt: LAPIC disabled, delivering directly to CPU core.\n"));
+        if (u8Level)
+            cpuSetInterrupt(dev, s, PDMAPICIRQ_EXTINT);
+        else
+            cpuClearInterrupt(dev, s, PDMAPICIRQ_EXTINT);
+
+        return VINF_SUCCESS;
+    }
+
+    /* If LAPIC is enabled, interrupts are subject to LVT programming. */
+    if (u8Pin > 1)
+    {
+        /* There are only two local interrupt pins. */
+        AssertMsgFailed(("Invalid LAPIC pin %d\n", u8Pin));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    /* NB: We currently only deliver local interrupts to the first CPU. In theory they
+     * should be delivered to all CPUs and it is the guest's responsibility to ensure
+     * no more than one CPU has the interrupt unmasked.
+     */
+    uint32_t    u32Lvec;
+
+    u32Lvec = s->lvt[APIC_LVT_LINT0 + u8Pin];   /* Fetch corresponding LVT entry. */
+    /* Drop int if entry is masked. May not be correct for level-triggered interrupts. */
+    if (!(u32Lvec & APIC_LVT_MASKED))
+    {   uint8_t     u8Delivery;
+        PDMAPICIRQ  enmType;
+
+        u8Delivery = (u32Lvec >> 8) & 7;
+        switch (u8Delivery) 
+        {
+        case APIC_DM_EXTINT:
+            Assert(u8Pin == 0); /* PIC should be wired to LINT0. */
+            enmType = PDMAPICIRQ_EXTINT;
+            break;
+        case APIC_DM_NMI:
+            Assert(u8Pin == 0); /* NMI should be wired to LINT1. */
+            enmType = PDMAPICIRQ_NMI;
+            break;
+        case APIC_DM_SMI:
+            enmType = PDMAPICIRQ_SMI;
+            break;
+
+        }
+        LogFlow(("apicLocalInterrupt: setting local interrupt type %d\n", enmType));
+        cpuSetInterrupt(dev, s, enmType);
+    }
+    return VINF_SUCCESS;
 }
 
@@ -2744,4 +2811,5 @@
     ApicReg.pfnReadMSRR3            = apicReadMSR;
     ApicReg.pfnBusDeliverR3         = apicBusDeliverCallback;
+    ApicReg.pfnLocalInterruptR3     = apicLocalInterrupt;
     if (fGCEnabled) {
         ApicReg.pszGetInterruptRC   = "apicGetInterrupt";
@@ -2754,4 +2822,5 @@
         ApicReg.pszReadMSRRC        = "apicReadMSR";
         ApicReg.pszBusDeliverRC     = "apicBusDeliverCallback";
+        ApicReg.pszLocalInterruptRC = "apicLocalInterrupt";
     } else {
         ApicReg.pszGetInterruptRC   = NULL;
@@ -2764,4 +2833,5 @@
         ApicReg.pszReadMSRRC        = NULL;
         ApicReg.pszBusDeliverRC     = NULL;
+        ApicReg.pszLocalInterruptRC = NULL;
     }
     if (fR0Enabled) {
@@ -2775,4 +2845,5 @@
         ApicReg.pszReadMSRR0        = "apicReadMSR";
         ApicReg.pszBusDeliverR0     = "apicBusDeliverCallback";
+        ApicReg.pszLocalInterruptR0 = "apicLocalInterrupt";
     } else {
         ApicReg.pszGetInterruptR0   = NULL;
@@ -2785,4 +2856,5 @@
         ApicReg.pszReadMSRR0        = NULL;
         ApicReg.pszBusDeliverR0     = NULL;
+        ApicReg.pszLocalInterruptR0 = NULL;
     }
 
Index: /trunk/src/VBox/VMM/PDM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDM.cpp	(revision 24124)
+++ /trunk/src/VBox/VMM/PDM.cpp	(revision 24125)
@@ -424,4 +424,5 @@
         pVM->pdm.s.Apic.pfnGetTPRRC         += offDelta;
         pVM->pdm.s.Apic.pfnBusDeliverRC     += offDelta;
+        pVM->pdm.s.Apic.pfnLocalInterruptRC += offDelta;
         pVM->pdm.s.Apic.pfnWriteMSRRC       += offDelta;
         pVM->pdm.s.Apic.pfnReadMSRRC        += offDelta;
Index: /trunk/src/VBox/VMM/PDMDevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDMDevHlp.cpp	(revision 24124)
+++ /trunk/src/VBox/VMM/PDMDevHlp.cpp	(revision 24125)
@@ -1618,11 +1618,11 @@
     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
     LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseR3=%p, .pfnGetBaseR3=%p, "
-             ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnWriteMSR3=%p, .pfnReadMSR3=%p, .pfnBusDeliverR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, "
-             ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszWriteMSRRC=%p:{%s}, .pszReadMSRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}} ppApicHlpR3=%p\n",
+             ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnWriteMSR3=%p, .pfnReadMSR3=%p, .pfnBusDeliverR3=%p, .pfnLocalInterruptR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, "
+             ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszWriteMSRRC=%p:{%s}, .pszReadMSRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}, .pszLocalInterruptRC=%p:{%s}} ppApicHlpR3=%p\n",
              pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseR3,
-             pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnWriteMSRR3, pApicReg->pfnReadMSRR3, pApicReg->pfnBusDeliverR3, pApicReg->pszGetInterruptRC,
+             pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnWriteMSRR3, pApicReg->pfnReadMSRR3, pApicReg->pfnBusDeliverR3, pApicReg->pfnLocalInterruptR3, pApicReg->pszGetInterruptRC,
              pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseRC, pApicReg->pszSetBaseRC, pApicReg->pszGetBaseRC, pApicReg->pszGetBaseRC,
              pApicReg->pszSetTPRRC, pApicReg->pszSetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszWriteMSRRC, pApicReg->pszWriteMSRRC, pApicReg->pszReadMSRRC, pApicReg->pszReadMSRRC, pApicReg->pszBusDeliverRC,
-             pApicReg->pszBusDeliverRC, ppApicHlpR3));
+             pApicReg->pszBusDeliverRC, pApicReg->pszLocalInterruptRC, pApicReg->pszLocalInterruptRC, ppApicHlpR3));
 
     /*
@@ -1643,5 +1643,6 @@
         ||  !pApicReg->pfnWriteMSRR3
         ||  !pApicReg->pfnReadMSRR3
-        ||  !pApicReg->pfnBusDeliverR3)
+        ||  !pApicReg->pfnBusDeliverR3
+        ||  !pApicReg->pfnLocalInterruptR3)
     {
         Assert(pApicReg->pfnGetInterruptR3);
@@ -1654,4 +1655,5 @@
         Assert(pApicReg->pfnReadMSRR3);
         Assert(pApicReg->pfnBusDeliverR3);
+        Assert(pApicReg->pfnLocalInterruptR3);
         LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
         return VERR_INVALID_PARAMETER;
@@ -1665,5 +1667,6 @@
             ||  pApicReg->pszWriteMSRRC
             ||  pApicReg->pszReadMSRRC
-            ||  pApicReg->pszBusDeliverRC)
+            ||  pApicReg->pszBusDeliverRC
+            ||  pApicReg->pszLocalInterruptRC)
         &&  (   !VALID_PTR(pApicReg->pszGetInterruptRC)
             ||  !VALID_PTR(pApicReg->pszHasPendingIrqRC)
@@ -1674,5 +1677,6 @@
             ||  !VALID_PTR(pApicReg->pszWriteMSRRC)
             ||  !VALID_PTR(pApicReg->pszReadMSRRC)
-            ||  !VALID_PTR(pApicReg->pszBusDeliverRC))
+            ||  !VALID_PTR(pApicReg->pszBusDeliverRC)
+            ||  !VALID_PTR(pApicReg->pszLocalInterruptRC))
        )
     {
@@ -1686,4 +1690,5 @@
         Assert(VALID_PTR(pApicReg->pszWriteMSRRC));
         Assert(VALID_PTR(pApicReg->pszBusDeliverRC));
+        Assert(VALID_PTR(pApicReg->pszLocalInterruptRC));
         LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
         return VERR_INVALID_PARAMETER;
@@ -1697,5 +1702,6 @@
             ||  pApicReg->pszWriteMSRR0
             ||  pApicReg->pszReadMSRR0
-            ||  pApicReg->pszBusDeliverR0)
+            ||  pApicReg->pszBusDeliverR0
+            ||  pApicReg->pszLocalInterruptR0)
         &&  (   !VALID_PTR(pApicReg->pszGetInterruptR0)
             ||  !VALID_PTR(pApicReg->pszHasPendingIrqR0)
@@ -1706,5 +1712,6 @@
             ||  !VALID_PTR(pApicReg->pszReadMSRR0)
             ||  !VALID_PTR(pApicReg->pszWriteMSRR0)
-            ||  !VALID_PTR(pApicReg->pszBusDeliverR0))
+            ||  !VALID_PTR(pApicReg->pszBusDeliverR0)
+            ||  !VALID_PTR(pApicReg->pszLocalInterruptR0))
        )
     {
@@ -1718,4 +1725,5 @@
         Assert(VALID_PTR(pApicReg->pszWriteMSRR0));
         Assert(VALID_PTR(pApicReg->pszBusDeliverR0));
+        Assert(VALID_PTR(pApicReg->pszLocalInterruptR0));
         LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc (R0 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
         return VERR_INVALID_PARAMETER;
@@ -1786,4 +1794,9 @@
             rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, &pVM->pdm.s.Apic.pfnBusDeliverRC);
             AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszBusDeliverRC, rc));
+        }
+        if (RT_SUCCESS(rc))
+        {
+            rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszLocalInterruptRC, &pVM->pdm.s.Apic.pfnLocalInterruptRC);
+            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszLocalInterruptRC, rc));
         }
         if (RT_FAILURE(rc))
@@ -1806,4 +1819,5 @@
         pVM->pdm.s.Apic.pfnReadMSRRC        = 0;
         pVM->pdm.s.Apic.pfnBusDeliverRC     = 0;
+        pVM->pdm.s.Apic.pfnLocalInterruptRC = 0;
     }
 
@@ -1854,4 +1868,9 @@
             rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, &pVM->pdm.s.Apic.pfnBusDeliverR0);
             AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszBusDeliverR0, rc));
+        }
+        if (RT_SUCCESS(rc))
+        {
+            rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszLocalInterruptR0, &pVM->pdm.s.Apic.pfnLocalInterruptR0);
+            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszLocalInterruptR0, rc));
         }
         if (RT_FAILURE(rc))
@@ -1874,4 +1893,5 @@
         pVM->pdm.s.Apic.pfnReadMSRR0        = 0;
         pVM->pdm.s.Apic.pfnBusDeliverR0     = 0;
+        pVM->pdm.s.Apic.pfnLocalInterruptR0 = 0;
         pVM->pdm.s.Apic.pDevInsR0           = 0;
     }
@@ -1890,4 +1910,5 @@
     pVM->pdm.s.Apic.pfnReadMSRR3        = pApicReg->pfnReadMSRR3;
     pVM->pdm.s.Apic.pfnBusDeliverR3     = pApicReg->pfnBusDeliverR3;
+    pVM->pdm.s.Apic.pfnLocalInterruptR3 = pApicReg->pfnLocalInterruptR3;
     Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
 
Index: /trunk/src/VBox/VMM/PDMDevMiscHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDMDevMiscHlp.cpp	(revision 24124)
+++ /trunk/src/VBox/VMM/PDMDevMiscHlp.cpp	(revision 24125)
@@ -48,4 +48,14 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM pVM = pDevIns->Internal.s.pVMR3;
+
+    if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
+    {
+        LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: Setting local interrupt on LAPIC\n",
+                 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
+        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
+        pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, 0, 1);
+        return;
+    }
+ 
     PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
 
@@ -65,4 +75,14 @@
     PVM pVM = pDevIns->Internal.s.pVMR3;
     PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+
+    if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
+    {
+        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
+        LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
+                 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
+        /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
+        pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, 0, 0);
+        return;
+    }
 
     LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
@@ -167,4 +187,7 @@
             VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
             break;
+        case PDMAPICIRQ_EXTINT:
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+            break;
         default:
             AssertMsgFailed(("enmType=%d\n", enmType));
@@ -177,5 +200,5 @@
 
 /** @copydoc PDMAPICHLPR3::pfnClearInterruptFF */
-static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu)
+static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
@@ -188,5 +211,17 @@
              pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
 
-    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+    /* Note: NMI/SMI can't be cleared. */
+    switch (enmType)
+    {
+        case PDMAPICIRQ_HARDWARE:
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+            break;
+        case PDMAPICIRQ_EXTINT:
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+            break;
+        default:
+            AssertMsgFailed(("enmType=%d\n", enmType));
+            break;
+    }
     REMR3NotifyInterruptClear(pVM, pVCpu);
 }
Index: /trunk/src/VBox/VMM/PDMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/PDMInternal.h	(revision 24124)
+++ /trunk/src/VBox/VMM/PDMInternal.h	(revision 24125)
@@ -438,4 +438,6 @@
     DECLR3CALLBACKMEMBER(int,       pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                      uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
+    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
+    DECLR3CALLBACKMEMBER(int,       pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
 
     /** Pointer to the APIC device instance - R0 Ptr. */
@@ -460,4 +462,6 @@
     DECLR0CALLBACKMEMBER(int,       pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                      uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
+    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
+    DECLR0CALLBACKMEMBER(int,       pfnLocalInterruptR0,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
 
     /** Pointer to the APIC device instance - RC Ptr. */
@@ -482,4 +486,7 @@
     DECLRCCALLBACKMEMBER(int,       pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
                                                      uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
+    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
+    DECLRCCALLBACKMEMBER(int,       pfnLocalInterruptRC,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
+
 } PDMAPIC;
 
Index: /trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp	(revision 24124)
+++ /trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp	(revision 24125)
@@ -87,5 +87,5 @@
  */
 static DECLCALLBACK(void) pdmRCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
-static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu);
+static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
 static DECLCALLBACK(void) pdmRCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion);
 static DECLCALLBACK(int) pdmRCApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
@@ -441,5 +441,5 @@
 
 /** @copydoc PDMAPICHLPRC::pfnClearInterruptFF */
-static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu)
+static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
@@ -451,5 +451,18 @@
     LogFlow(("pdmRCApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
              pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
-    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+
+    /* Note: NMI/SMI can't be cleared. */
+    switch (enmType)
+    {
+        case PDMAPICIRQ_HARDWARE:
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+            break;
+        case PDMAPICIRQ_EXTINT:
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+            break;
+        default:
+            AssertMsgFailed(("enmType=%d\n", enmType));
+            break;
+    }
 }
 
Index: /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 24124)
+++ /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 24125)
@@ -90,5 +90,5 @@
  */
 static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
-static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu);
+static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
 static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion);
 static DECLCALLBACK(int)  pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
@@ -475,5 +475,5 @@
 
 /** @copydoc PDMAPICHLPR0::pfnClearInterruptFF */
-static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu)
+static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
@@ -485,5 +485,18 @@
     LogFlow(("pdmR0ApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
              pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
-    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+
+    /* Note: NMI/SMI can't be cleared. */
+    switch (enmType)
+    {
+        case PDMAPICIRQ_HARDWARE:
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+            break;
+        case PDMAPICIRQ_EXTINT:
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+            break;
+        default:
+            AssertMsgFailed(("enmType=%d\n", enmType));
+            break;
+    }
 }
 
