Index: /trunk/include/VBox/vmm/pdmapi.h
===================================================================
--- /trunk/include/VBox/vmm/pdmapi.h	(revision 40906)
+++ /trunk/include/VBox/vmm/pdmapi.h	(revision 40907)
@@ -41,18 +41,18 @@
  */
 
-VMMDECL(int)    PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt);
-VMMDECL(int)    PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level);
-VMMDECL(int)    PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level);
-VMMDECL(int)    PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue);
-VMMDECL(bool)   PDMHasIoApic(PVM pVM);
-VMMDECL(int)    PDMApicHasPendingIrq(PVM pVM, bool *pfPending);
-VMMDECL(int)    PDMApicSetBase(PVM pVM, uint64_t u64Base);
-VMMDECL(int)    PDMApicGetBase(PVM pVM, uint64_t *pu64Base);
-VMMDECL(int)    PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR);
-VMMDECL(int)    PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending);
-VMMDECL(int)    PDMApicWriteMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value);
-VMMDECL(int)    PDMApicReadMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value);
-VMMDECL(int)    PDMVMMDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys);
-VMMDECL(bool)   PDMVMMDevHeapIsEnabled(PVM pVM);
+VMMDECL(int)        PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt);
+VMMDECL(int)        PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc);
+VMM_INT_DECL(int)   PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc);
+VMM_INT_DECL(int)   PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc);
+VMMDECL(bool)       PDMHasIoApic(PVM pVM);
+VMMDECL(int)        PDMApicHasPendingIrq(PVM pVM, bool *pfPending);
+VMMDECL(int)        PDMApicSetBase(PVM pVM, uint64_t u64Base);
+VMMDECL(int)        PDMApicGetBase(PVM pVM, uint64_t *pu64Base);
+VMMDECL(int)        PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR);
+VMMDECL(int)        PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending);
+VMMDECL(int)        PDMApicWriteMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value);
+VMMDECL(int)        PDMApicReadMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value);
+VMMDECL(int)        PDMVMMDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys);
+VMMDECL(bool)       PDMVMMDevHeapIsEnabled(PVM pVM);
 
 
Index: /trunk/include/VBox/vmm/pdmdev.h
===================================================================
--- /trunk/include/VBox/vmm/pdmdev.h	(revision 40906)
+++ /trunk/include/VBox/vmm/pdmdev.h	(revision 40907)
@@ -552,6 +552,7 @@
      * @param   iIrq            IRQ number to set.
      * @param   iLevel          IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
-     */
-    DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
+     */
+    DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
 
     /**
@@ -596,5 +597,5 @@
 
 /** Current PDMPCIBUSREG version number. */
-#define PDM_PCIBUSREG_VERSION                   PDM_VERSION_MAKE(0xfffe, 2, 0)
+#define PDM_PCIBUSREG_VERSION                   PDM_VERSION_MAKE(0xfffe, 3, 0)
 
 /**
@@ -612,7 +613,8 @@
      * @param   iIrq            IRQ number to set.
      * @param   iLevel          IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
      * @thread  EMT only.
      */
-    DECLRCCALLBACKMEMBER(void,  pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+    DECLRCCALLBACKMEMBER(void,  pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
 
     /**
@@ -622,7 +624,8 @@
      * @param   iIrq            IRQ number to set.
      * @param   iLevel          IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
      * @thread  EMT only.
      */
-    DECLRCCALLBACKMEMBER(void,  pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+    DECLRCCALLBACKMEMBER(void,  pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
 
     /**
@@ -630,9 +633,10 @@
      *
      * @param   pDevIns         PCI device instance.
-     * @param   GCAddr          Physical address MSI request was written.
+     * @param   GCPhys          Physical address MSI request was written.
      * @param   uValue          Value written.
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
      * @thread  EMT only.
      */
-    DECLRCCALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
+    DECLRCCALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
 
 
@@ -663,5 +667,5 @@
 
 /** Current PDMPCIHLPRC version number. */
-#define PDM_PCIHLPRC_VERSION                    PDM_VERSION_MAKE(0xfffd, 2, 0)
+#define PDM_PCIHLPRC_VERSION                    PDM_VERSION_MAKE(0xfffd, 3, 0)
 
 
@@ -680,7 +684,8 @@
      * @param   iIrq            IRQ number to set.
      * @param   iLevel          IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
      * @thread  EMT only.
      */
-    DECLR0CALLBACKMEMBER(void,  pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+    DECLR0CALLBACKMEMBER(void,  pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
 
     /**
@@ -690,7 +695,8 @@
      * @param   iIrq            IRQ number to set.
      * @param   iLevel          IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
      * @thread  EMT only.
      */
-    DECLR0CALLBACKMEMBER(void,  pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+    DECLR0CALLBACKMEMBER(void,  pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
 
     /**
@@ -698,9 +704,10 @@
      *
      * @param   pDevIns         PCI device instance.
-     * @param   GCAddr          Physical address MSI request was written.
+     * @param   GCPhys          Physical address MSI request was written.
      * @param   uValue          Value written.
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
      * @thread  EMT only.
      */
-    DECLR0CALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
+    DECLR0CALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
 
 
@@ -731,5 +738,5 @@
 
 /** Current PDMPCIHLPR0 version number. */
-#define PDM_PCIHLPR0_VERSION                    PDM_VERSION_MAKE(0xfffc, 2, 0)
+#define PDM_PCIHLPR0_VERSION                    PDM_VERSION_MAKE(0xfffc, 3, 0)
 
 /**
@@ -747,7 +754,7 @@
      * @param   iIrq            IRQ number to set.
      * @param   iLevel          IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
-     * @thread  EMT only.
-     */
-    DECLR3CALLBACKMEMBER(void,  pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
+     */
+    DECLR3CALLBACKMEMBER(void,  pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
 
     /**
@@ -757,7 +764,7 @@
      * @param   iIrq            IRQ number to set.
      * @param   iLevel          IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
-     * @thread  EMT only.
-     */
-    DECLR3CALLBACKMEMBER(void,  pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
+     */
+    DECLR3CALLBACKMEMBER(void,  pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
 
     /**
@@ -765,9 +772,9 @@
      *
      * @param   pDevIns         PCI device instance.
-     * @param   GCAddr          Physical address MSI request was written.
+     * @param   GCPhys          Physical address MSI request was written.
      * @param   uValue          Value written.
-     * @thread  EMT only.
-     */
-    DECLR3CALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
+     */
+    DECLR3CALLBACKMEMBER(void,  pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
 
     /**
@@ -831,5 +838,5 @@
 
 /** Current PDMPCIHLPR3 version number. */
-#define PDM_PCIHLPR3_VERSION                    PDM_VERSION_MAKE(0xfffb, 2, 0)
+#define PDM_PCIHLPR3_VERSION                    PDM_VERSION_MAKE(0xfffb, 3, 0)
 
 
@@ -848,6 +855,7 @@
      * @param   iIrq            IRQ number to set.
      * @param   iLevel          IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
-     */
-    DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
+     */
+    DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
 
     /**
@@ -856,6 +864,7 @@
      * @returns Pending interrupt number.
      * @param   pDevIns         Device instance of the PIC.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns));
+     * @param   puTagSrc        Where to return the IRQ tag and source.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
 
     /** The name of the RC SetIrq entry point. */
@@ -873,5 +882,5 @@
 
 /** Current PDMPICREG version number. */
-#define PDM_PICREG_VERSION                      PDM_VERSION_MAKE(0xfffa, 1, 0)
+#define PDM_PICREG_VERSION                      PDM_VERSION_MAKE(0xfffa, 2, 0)
 
 /**
@@ -924,5 +933,5 @@
 
 /** Current PDMPICHLPRC version number. */
-#define PDM_PICHLPRC_VERSION                    PDM_VERSION_MAKE(0xfff9, 1, 0)
+#define PDM_PICHLPRC_VERSION                    PDM_VERSION_MAKE(0xfff9, 2, 0)
 
 
@@ -1066,6 +1075,7 @@
      * @returns Pending interrupt number.
      * @param   pDevIns         Device instance of the APIC.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns));
+     * @param   puTagSrc        Where to return the tag source.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
 
     /**
@@ -1156,15 +1166,20 @@
      * @param   u8Polarity      See APIC implementation.
      * @param   u8TriggerMode   See APIC implementation.
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
      */
     DECLR3CALLBACKMEMBER(int,  pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                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.
+                                                uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
+
+    /**
+     * 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).
+     * @param   u8Level         The level.
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
      */
     DECLR3CALLBACKMEMBER(int,  pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
@@ -1217,5 +1232,5 @@
 
 /** Current PDMAPICREG version number. */
-#define PDM_APICREG_VERSION                     PDM_VERSION_MAKE(0xfff6, 1, 0)
+#define PDM_APICREG_VERSION                     PDM_VERSION_MAKE(0xfff6, 2, 0)
 
 
@@ -1527,8 +1542,9 @@
      * @param   iIrq            IRQ number to set.
      * @param   iLevel          IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
-     */
-    DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
-
-    /** The name of the GC SetIrq entry point. */
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
+     */
+    DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
+
+    /** The name of the RC SetIrq entry point. */
     const char         *pszSetIrqRC;
 
@@ -1542,8 +1558,9 @@
      * @param   GCPhys          Request address.
      * @param   uValue          Request value.
-     */
-    DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
-
-    /** The name of the GC SendMsi entry point. */
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
+     */
+    DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
+
+    /** The name of the RC SendMsi entry point. */
     const char         *pszSendMsiRC;
 
@@ -1555,5 +1572,5 @@
 
 /** Current PDMAPICREG version number. */
-#define PDM_IOAPICREG_VERSION                   PDM_VERSION_MAKE(0xfff2, 2, 0)
+#define PDM_IOAPICREG_VERSION                   PDM_VERSION_MAKE(0xfff2, 3, 0)
 
 
@@ -1579,7 +1596,8 @@
      * @param   u8Polarity      See APIC implementation.
      * @param   u8TriggerMode   See APIC implementation.
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
      */
     DECLRCCALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                  uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
+                                                  uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
 
     /**
@@ -1609,5 +1627,5 @@
 
 /** Current PDMIOAPICHLPRC version number. */
-#define PDM_IOAPICHLPRC_VERSION                 PDM_VERSION_MAKE(0xfff1, 1, 0)
+#define PDM_IOAPICHLPRC_VERSION                 PDM_VERSION_MAKE(0xfff1, 2, 0)
 
 
@@ -1633,7 +1651,8 @@
      * @param   u8Polarity      See APIC implementation.
      * @param   u8TriggerMode   See APIC implementation.
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
      */
     DECLR0CALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                  uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
+                                                  uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
 
     /**
@@ -1663,5 +1682,5 @@
 
 /** Current PDMIOAPICHLPR0 version number. */
-#define PDM_IOAPICHLPR0_VERSION                 PDM_VERSION_MAKE(0xfff0, 1, 0)
+#define PDM_IOAPICHLPR0_VERSION                 PDM_VERSION_MAKE(0xfff0, 2, 0)
 
 /**
@@ -1686,7 +1705,8 @@
      * @param   u8Polarity      See APIC implementation.
      * @param   u8TriggerMode   See APIC implementation.
+     * @param   uTagSrc         The IRQ tag and source (for tracing).
      */
     DECLR3CALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                  uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
+                                                  uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
 
     /**
@@ -1738,5 +1758,5 @@
 
 /** Current PDMIOAPICHLPR3 version number. */
-#define PDM_IOAPICHLPR3_VERSION                 PDM_VERSION_MAKE(0xffef, 1, 0)
+#define PDM_IOAPICHLPR3_VERSION                 PDM_VERSION_MAKE(0xffef, 2, 0)
 
 
@@ -3925,7 +3945,9 @@
     /** Tracing indicator. */
     uint32_t                    fTracing;
-#if HC_ARCH_BITS == 64
+    /** The tracing ID of this device.  */
+    uint32_t                    idTracing;
+#if HC_ARCH_BITS == 32
     /** Align the internal data more naturally. */
-    uint32_t                    u32Padding;
+    uint32_t                    au32Padding[HC_ARCH_BITS == 32 ? 13 : 0];
 #endif
 
@@ -3936,5 +3958,5 @@
         PDMDEVINSINT            s;
 #endif
-        uint8_t                 padding[HC_ARCH_BITS == 32 ? 64 + 0 : 112 + 0x28];
+        uint8_t                 padding[HC_ARCH_BITS == 32 ? 72 : 112 + 0x28];
     } Internal;
 
@@ -3945,5 +3967,5 @@
 
 /** Current PDMDEVINS version number. */
-#define PDM_DEVINS_VERSION                      PDM_VERSION_MAKE(0xffe4, 2, 0)
+#define PDM_DEVINS_VERSION                      PDM_VERSION_MAKE(0xffe4, 3, 0)
 
 /** Converts a pointer to the PDMDEVINS::IBase to a pointer to PDMDEVINS. */
Index: /trunk/include/VBox/vmm/pdmdrv.h
===================================================================
--- /trunk/include/VBox/vmm/pdmdrv.h	(revision 40906)
+++ /trunk/include/VBox/vmm/pdmdrv.h	(revision 40907)
@@ -389,7 +389,9 @@
     /** Tracing indicator. */
     uint32_t                    fTracing;
-#if HC_ARCH_BITS == 64
+    /** The tracing ID of this device.  */
+    uint32_t                    idTracing;
+#if HC_ARCH_BITS == 32
     /** Align the internal data more naturally. */
-    uint32_t                    u32Padding;
+    uint32_t                    au32Padding[HC_ARCH_BITS == 32 ? 7 : 0];
 #endif
 
@@ -409,5 +411,5 @@
 
 /** Current DRVREG version number. */
-#define PDM_DRVINS_VERSION                      PDM_VERSION_MAKE(0xf0fe, 1, 0)
+#define PDM_DRVINS_VERSION                      PDM_VERSION_MAKE(0xf0fe, 2, 0)
 
 /** Converts a pointer to the PDMDRVINS::IBase to a pointer to PDMDRVINS. */
Index: /trunk/include/VBox/vmm/pdmusb.h
===================================================================
--- /trunk/include/VBox/vmm/pdmusb.h	(revision 40906)
+++ /trunk/include/VBox/vmm/pdmusb.h	(revision 40907)
@@ -694,5 +694,5 @@
     uint32_t                    u32Version;
     /** USB device instance number. */
-    RTUINT                      iInstance;
+    uint32_t                    iInstance;
     /** The base interface of the device.
      * The device constructor initializes this if it has any device level
@@ -731,6 +731,10 @@
     /** Tracing indicator. */
     uint32_t                    fTracing;
+    /** The tracing ID of this device.  */
+    uint32_t                    idTracing;
+
     /** Padding to make achInstanceData aligned at 32 byte boundary. */
-    uint32_t                    au32Padding[HC_ARCH_BITS == 32 ? 4 : 1];
+    uint32_t                    au32Padding[HC_ARCH_BITS == 32 ? 3 : 4];
+
     /** Device instance data. The size of this area is defined
      * in the PDMUSBREG::cbInstanceData field. */
@@ -739,5 +743,5 @@
 
 /** Current USBINS version number. */
-#define PDM_USBINS_VERSION                      PDM_VERSION_MAKE(0xeefd, 1, 0)
+#define PDM_USBINS_VERSION                      PDM_VERSION_MAKE(0xeefd, 2, 0)
 
 /**
Index: /trunk/src/VBox/Devices/Bus/DevPCI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 40906)
+++ /trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 40907)
@@ -214,6 +214,6 @@
 RT_C_DECLS_BEGIN
 
-PDMBOTHCBDECL(void) pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel);
-PDMBOTHCBDECL(void) pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel);
+PDMBOTHCBDECL(void) pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTag);
+PDMBOTHCBDECL(void) pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTag);
 PDMBOTHCBDECL(int)  pciIOPortAddressWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
 PDMBOTHCBDECL(int)  pciIOPortAddressRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
@@ -601,5 +601,5 @@
 }
 
-static void apic_set_irq(PPCIBUS pBus, uint8_t uDevFn, PCIDevice *pPciDev, int irq_num1, int iLevel, int acpi_irq)
+static void apic_set_irq(PPCIBUS pBus, uint8_t uDevFn, PCIDevice *pPciDev, int irq_num1, int iLevel, int acpi_irq, uint32_t uTagSrc)
 {
     /* This is only allowed to be called with a pointer to the host bus. */
@@ -620,5 +620,5 @@
         Log3(("apic_set_irq: %s: irq_num1=%d level=%d apic_irq=%d apic_level=%d irq_num1=%d\n",
               R3STRING(pPciDev->name), irq_num1, iLevel, apic_irq, apic_level, irq_num));
-        pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), apic_irq, apic_level);
+        pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), apic_irq, apic_level, uTagSrc);
 
         if ((iLevel & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP) {
@@ -628,10 +628,10 @@
             Log3(("apic_set_irq: %s: irq_num1=%d level=%d apic_irq=%d apic_level=%d irq_num1=%d (flop)\n",
                   R3STRING(pPciDev->name), irq_num1, iLevel, apic_irq, apic_level, irq_num));
-            pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), apic_irq, apic_level);
+            pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), apic_irq, apic_level, uTagSrc);
         }
     } else {
         Log3(("apic_set_irq: %s: irq_num1=%d level=%d acpi_irq=%d\n",
               R3STRING(pPciDev->name), irq_num1, iLevel, acpi_irq));
-        pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), acpi_irq, iLevel);
+        pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), acpi_irq, iLevel, uTagSrc);
     }
 }
@@ -650,9 +650,10 @@
  * @param   iIrq            IRQ number to set.
  * @param   iLevel          IRQ level.
+ * @param   uTagSrc         The IRQ tag and source ID (for tracing).
  * @remark  uDevFn and pPciDev->devfn are not the same if the device is behind a bridge.
  *          In that case uDevFn will be the slot of the bridge which is needed to calculate the
  *          PIRQ value.
  */
-static void pciSetIrqInternal(PPCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel)
+static void pciSetIrqInternal(PPCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc)
 {
     PPCIBUS     pBus =     &pGlobals->PciBus;
@@ -682,7 +683,7 @@
                  * PCI device configuration space).
                  */
-                apic_set_irq(pBus, uDevFn, pPciDev, -1, iLevel, pPciDev->config[PCI_INTERRUPT_LINE]);
+                apic_set_irq(pBus, uDevFn, pPciDev, -1, iLevel, pPciDev->config[PCI_INTERRUPT_LINE], uTagSrc);
             else
-                apic_set_irq(pBus, uDevFn, pPciDev, iIrq, iLevel, -1);
+                apic_set_irq(pBus, uDevFn, pPciDev, iIrq, iLevel, -1, uTagSrc);
             return;
         }
@@ -732,11 +733,11 @@
             pic_level |= pGlobals->acpi_irq_level;
 
-        Log3(("pciSetIrq: %s: iLevel=%d iIrq=%d pic_irq=%d pic_level=%d\n",
-              R3STRING(pPciDev->name), iLevel, iIrq, pic_irq, pic_level));
-        pBus->CTX_SUFF(pPciHlp)->pfnIsaSetIrq(pBus->CTX_SUFF(pDevIns), pic_irq, pic_level);
+        Log3(("pciSetIrq: %s: iLevel=%d iIrq=%d pic_irq=%d pic_level=%d uTagSrc=%#x\n",
+              R3STRING(pPciDev->name), iLevel, iIrq, pic_irq, pic_level, uTagSrc));
+        pBus->CTX_SUFF(pPciHlp)->pfnIsaSetIrq(pBus->CTX_SUFF(pDevIns), pic_irq, pic_level, uTagSrc);
 
         /** @todo optimize pci irq flip-flop some rainy day. */
         if ((iLevel & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP)
-            pciSetIrqInternal(pGlobals, uDevFn, pPciDev, iIrq, PDM_IRQ_LEVEL_LOW);
+            pciSetIrqInternal(pGlobals, uDevFn, pPciDev, iIrq, PDM_IRQ_LEVEL_LOW, uTagSrc);
     }
 }
@@ -749,8 +750,9 @@
  * @param   iIrq            IRQ number to set.
  * @param   iLevel          IRQ level.
- */
-PDMBOTHCBDECL(void) pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel)
-{
-    pciSetIrqInternal(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), pPciDev->devfn, pPciDev, iIrq, iLevel);
+ * @param   uTagSrc         The IRQ tag and source ID (for tracing).
+ */
+PDMBOTHCBDECL(void) pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc)
+{
+    pciSetIrqInternal(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), pPciDev->devfn, pPciDev, iIrq, iLevel, uTagSrc);
 }
 
@@ -2246,6 +2248,7 @@
  * @param   iIrq            IRQ number to set.
  * @param   iLevel          IRQ level.
- */
-PDMBOTHCBDECL(void) pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel)
+ * @param   uTagSrc         The IRQ tag and source ID (for tracing).
+ */
+PDMBOTHCBDECL(void) pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc)
 {
     /*
@@ -2273,5 +2276,5 @@
 
     AssertMsg(pBus->iBus == 0, ("This is not the host pci bus iBus=%d\n", pBus->iBus));
-    pciSetIrqInternal(PCIBUS_2_PCIGLOBALS(pBus), uDevFnBridge, pPciDev, iIrqPinBridge, iLevel);
+    pciSetIrqInternal(PCIBUS_2_PCIGLOBALS(pBus), uDevFnBridge, pPciDev, iIrqPinBridge, iLevel, uTagSrc);
 }
 
Index: /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 40906)
+++ /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 40907)
@@ -165,5 +165,6 @@
 
 /* Prototypes */
-static void ich9pciSetIrqInternal(PICH9PCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel);
+static void ich9pciSetIrqInternal(PICH9PCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev,
+                                  int iIrq, int iLevel, uint32_t uTagSrc);
 #ifdef IN_RING3
 static void ich9pcibridgeReset(PPDMDEVINS pDevIns);
@@ -192,10 +193,10 @@
 }
 
-PDMBOTHCBDECL(void) ich9pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel)
-{
-    ich9pciSetIrqInternal(PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS), pPciDev->devfn, pPciDev, iIrq, iLevel);
-}
-
-PDMBOTHCBDECL(void) ich9pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel)
+PDMBOTHCBDECL(void) ich9pciSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc)
+{
+    ich9pciSetIrqInternal(PDMINS_2_DATA(pDevIns, PICH9PCIGLOBALS), pPciDev->devfn, pPciDev, iIrq, iLevel, uTagSrc);
+}
+
+PDMBOTHCBDECL(void) ich9pcibridgeSetIrq(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc)
 {
     /*
@@ -223,5 +224,5 @@
 
     AssertMsgReturnVoid(pBus->iBus == 0, ("This is not the host pci bus iBus=%d\n", pBus->iBus));
-    ich9pciSetIrqInternal(PCIROOTBUS_2_PCIGLOBALS(pBus), uDevFnBridge, pPciDev, iIrqPinBridge, iLevel);
+    ich9pciSetIrqInternal(PCIROOTBUS_2_PCIGLOBALS(pBus), uDevFnBridge, pPciDev, iIrqPinBridge, iLevel, uTagSrc);
 }
 
@@ -504,5 +505,6 @@
 }
 
-static void ich9pciApicSetIrq(PICH9PCIBUS pBus, uint8_t uDevFn, PCIDevice *pPciDev, int irq_num1, int iLevel, int iForcedIrq)
+static void ich9pciApicSetIrq(PICH9PCIBUS pBus, uint8_t uDevFn, PCIDevice *pPciDev, int irq_num1, int iLevel,
+                              uint32_t uTagSrc, int iForcedIrq)
 {
     /* This is only allowed to be called with a pointer to the root bus. */
@@ -522,7 +524,7 @@
         apic_irq = irq_num + 0x10;
         apic_level = pGlobals->uaPciApicIrqLevels[irq_num] != 0;
-        Log3(("ich9pciApicSetIrq: %s: irq_num1=%d level=%d apic_irq=%d apic_level=%d irq_num1=%d\n",
-              R3STRING(pPciDev->name), irq_num1, iLevel, apic_irq, apic_level, irq_num));
-        pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), apic_irq, apic_level);
+        Log3(("ich9pciApicSetIrq: %s: irq_num1=%d level=%d apic_irq=%d apic_level=%d irq_num1=%d uTagSrc=%#x\n",
+              R3STRING(pPciDev->name), irq_num1, iLevel, apic_irq, apic_level, irq_num, uTagSrc));
+        pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), apic_irq, apic_level, uTagSrc);
 
         if ((iLevel & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP)
@@ -535,16 +537,17 @@
             pPciDev->Int.s.uIrqPinState = PDM_IRQ_LEVEL_LOW;
             apic_level = pGlobals->uaPciApicIrqLevels[irq_num] != 0;
-            Log3(("ich9pciApicSetIrq: %s: irq_num1=%d level=%d apic_irq=%d apic_level=%d irq_num1=%d (flop)\n",
-                  R3STRING(pPciDev->name), irq_num1, iLevel, apic_irq, apic_level, irq_num));
-            pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), apic_irq, apic_level);
+            Log3(("ich9pciApicSetIrq: %s: irq_num1=%d level=%d apic_irq=%d apic_level=%d irq_num1=%d uTagSrc=%#x (flop)\n",
+                  R3STRING(pPciDev->name), irq_num1, iLevel, apic_irq, apic_level, irq_num, uTagSrc));
+            pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), apic_irq, apic_level, uTagSrc);
         }
     } else {
-        Log3(("ich9pciApicSetIrq: (forced) %s: irq_num1=%d level=%d acpi_irq=%d\n",
-              R3STRING(pPciDev->name), irq_num1, iLevel, iForcedIrq));
-        pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), iForcedIrq, iLevel);
-    }
-}
-
-static void ich9pciSetIrqInternal(PICH9PCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel)
+        Log3(("ich9pciApicSetIrq: (forced) %s: irq_num1=%d level=%d acpi_irq=%d uTagSrc=%#x\n",
+              R3STRING(pPciDev->name), irq_num1, iLevel, iForcedIrq, uTagSrc));
+        pBus->CTX_SUFF(pPciHlp)->pfnIoApicSetIrq(pBus->CTX_SUFF(pDevIns), iForcedIrq, iLevel, uTagSrc);
+    }
+}
+
+static void ich9pciSetIrqInternal(PICH9PCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev,
+                                  int iIrq, int iLevel, uint32_t uTagSrc)
 {
 
@@ -554,5 +557,5 @@
         {
             PPDMDEVINS pDevIns = pGlobals->aPciBus.CTX_SUFF(pDevIns);
-            MsiNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq, iLevel);
+            MsiNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq, iLevel, uTagSrc);
         }
 
@@ -560,5 +563,5 @@
         {
             PPDMDEVINS pDevIns = pGlobals->aPciBus.CTX_SUFF(pDevIns);
-            MsixNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq, iLevel);
+            MsixNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq, iLevel, uTagSrc);
         }
         return;
@@ -582,7 +585,7 @@
              * PCI device configuration space).
              */
-            ich9pciApicSetIrq(pBus, uDevFn, pPciDev, -1, iLevel, PCIDevGetInterruptLine(pPciDev));
+            ich9pciApicSetIrq(pBus, uDevFn, pPciDev, -1, iLevel, uTagSrc, PCIDevGetInterruptLine(pPciDev));
         else
-            ich9pciApicSetIrq(pBus, uDevFn, pPciDev, iIrq, iLevel, -1);
+            ich9pciApicSetIrq(pBus, uDevFn, pPciDev, iIrq, iLevel, uTagSrc, -1);
     }
 }
Index: /trunk/src/VBox/Devices/Bus/MsiCommon.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/MsiCommon.cpp	(revision 40906)
+++ /trunk/src/VBox/Devices/Bus/MsiCommon.cpp	(revision 40907)
@@ -103,5 +103,6 @@
 
 #ifdef IN_RING3
-void     MsiPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len)
+void     MsiPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev,
+                           uint32_t u32Address, uint32_t val, unsigned len)
 {
     int32_t iOff = u32Address - pDev->Int.s.u8MsiCapOffset;
@@ -169,5 +170,5 @@
                                 {
                                     Log(("msi: notify earlier masked pending vector: %d\n", uVector));
-                                    MsiNotify(pDevIns, pPciHlp, pDev, uVector, PDM_IRQ_LEVEL_HIGH);
+                                    MsiNotify(pDevIns, pPciHlp, pDev, uVector, PDM_IRQ_LEVEL_HIGH, 0 /*uTagSrc*/);
                                 }
                             }
@@ -271,5 +272,5 @@
 }
 
-void MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel)
+void MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel, uint32_t uTagSrc)
 {
     AssertMsg(msiIsEnabled(pDev), ("Must be enabled to use that"));
@@ -304,4 +305,4 @@
 
     Assert(pPciHlp->pfnIoApicSendMsi != NULL);
-    pPciHlp->pfnIoApicSendMsi(pDevIns, GCAddr, u32Value);
-}
+    pPciHlp->pfnIoApicSendMsi(pDevIns, GCAddr, u32Value, uTagSrc);
+}
Index: /trunk/src/VBox/Devices/Bus/MsiCommon.h
===================================================================
--- /trunk/src/VBox/Devices/Bus/MsiCommon.h	(revision 40906)
+++ /trunk/src/VBox/Devices/Bus/MsiCommon.h	(revision 40907)
@@ -37,5 +37,5 @@
 
 /* Device notification (aka interrupt). */
-void     MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel);
+void     MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel, uint32_t uTagSrc);
 
 #ifdef IN_RING3
@@ -54,5 +54,5 @@
 
 /* Device notification (aka interrupt). */
-void     MsixNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel);
+void     MsixNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel, uint32_t uTagSrc);
 
 #ifdef IN_RING3
Index: /trunk/src/VBox/Devices/Bus/MsixCommon.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/MsixCommon.cpp	(revision 40906)
+++ /trunk/src/VBox/Devices/Bus/MsixCommon.cpp	(revision 40907)
@@ -109,5 +109,5 @@
 {
     if (msixIsPending(pDev, iVector) && !msixIsVectorMasked(pDev, iVector))
-        MsixNotify(pDevIns, pPciHlp, pDev, iVector, 1 /* iLevel */);
+        MsixNotify(pDevIns, pPciHlp, pDev, iVector, 1 /* iLevel */, 0 /*uTagSrc*/);
 }
 
@@ -239,5 +239,5 @@
 }
 
-void MsixNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel)
+void MsixNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector, int iLevel, uint32_t uTagSrc)
 {
     AssertMsg(msixIsEnabled(pDev), ("Must be enabled to use that"));
@@ -265,5 +265,5 @@
     uint32_t   u32Value = msixGetMsiData(pDev, iVector);
 
-    pPciHlp->pfnIoApicSendMsi(pDevIns, GCAddr, u32Value);
+    pPciHlp->pfnIoApicSendMsi(pDevIns, GCAddr, u32Value, uTagSrc);
 }
 
Index: /trunk/src/VBox/Devices/PC/DevAPIC.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevAPIC.cpp	(revision 40906)
+++ /trunk/src/VBox/Devices/PC/DevAPIC.cpp	(revision 40907)
@@ -55,4 +55,5 @@
 #include "VBoxDD2.h"
 #include "DevApic.h"
+
 
 /*******************************************************************************
@@ -338,4 +339,8 @@
     /** Timer description timer. */
     R3PTRTYPE(char *)       pszDesc;
+
+    /** The IRQ tags and source IDs for each (tracing purposes). */
+    uint32_t                auTags[256];
+
 # ifdef VBOX_WITH_STATISTICS
 #  if HC_ARCH_BITS == 32
@@ -436,5 +441,5 @@
 
 static void apic_init_ipi(APICDeviceInfo* pDev, APICState *s);
-static void apic_set_irq(APICDeviceInfo* pDev, APICState *s, int vector_num, int trigger_mode);
+static void apic_set_irq(APICDeviceInfo* pDev, APICState *s, int vector_num, int trigger_mode, uint32_t uTagSrc);
 static bool apic_update_irq(APICDeviceInfo* pDev, APICState *s);
 
@@ -530,8 +535,8 @@
                             PCVMCPUSET pDstSet, uint8_t delivery_mode,
                             uint8_t vector_num, uint8_t polarity,
-                            uint8_t trigger_mode)
-{
-    LogFlow(("apic_bus_deliver mask=%R[vmcpuset] mode=%x vector=%x polarity=%x trigger_mode=%x\n",
-             pDstSet, delivery_mode, vector_num, polarity, trigger_mode));
+                            uint8_t trigger_mode, uint32_t uTagSrc)
+{
+    LogFlow(("apic_bus_deliver mask=%R[vmcpuset] mode=%x vector=%x polarity=%x trigger_mode=%x uTagSrc=%#x\n",
+             pDstSet, delivery_mode, vector_num, polarity, trigger_mode, uTagSrc));
 
     switch (delivery_mode)
@@ -543,5 +548,5 @@
             {
                 APICState *pApic = getLapicById(pDev, idDstCpu);
-                apic_set_irq(pDev, pApic, vector_num, trigger_mode);
+                apic_set_irq(pDev, pApic, vector_num, trigger_mode, uTagSrc);
             }
             return VINF_SUCCESS;
@@ -585,5 +590,5 @@
 
     APIC_FOREACH_IN_SET_BEGIN(pDev, pDstSet);
-        apic_set_irq(pDev, pCurApic, vector_num, trigger_mode);
+        apic_set_irq(pDev, pCurApic, vector_num, trigger_mode, uTagSrc);
     APIC_FOREACH_END();
     return VINF_SUCCESS;
@@ -830,5 +835,6 @@
                                       vector,
                                       0 /* Polarity - conform to the bus */,
-                                      0 /* Trigger mode - edge */);
+                                      0 /* Trigger mode - edge */,
+                                      0 /*uTagSrc*/);
                 APIC_UNLOCK(pDev);
                 break;
@@ -1077,13 +1083,13 @@
 PDMBOTHCBDECL(int) apicBusDeliverCallback(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
                                           uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
-                                          uint8_t u8TriggerMode)
+                                          uint8_t u8TriggerMode, uint32_t uTagSrc)
 {
     APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
-    LogFlow(("apicBusDeliverCallback: pDevIns=%p u8Dest=%#x u8DestMode=%#x u8DeliveryMode=%#x iVector=%#x u8Polarity=%#x u8TriggerMode=%#x\n",
-             pDevIns, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
+    LogFlow(("apicBusDeliverCallback: pDevIns=%p u8Dest=%#x u8DestMode=%#x u8DeliveryMode=%#x iVector=%#x u8Polarity=%#x u8TriggerMode=%#x uTagSrc=%#x\n",
+             pDevIns, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc));
     VMCPUSET DstSet;
     return apic_bus_deliver(pDev, apic_get_delivery_bitmask(pDev, u8Dest, u8DestMode, &DstSet),
-                            u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
+                            u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc);
 }
 
@@ -1269,7 +1275,8 @@
 }
 
-static void apic_set_irq(APICDeviceInfo *pDev,  APICState* s, int vector_num, int trigger_mode)
-{
-    LogFlow(("CPU%d: apic_set_irq vector=%x, trigger_mode=%x\n", s->phys_id, vector_num, trigger_mode));
+static void apic_set_irq(APICDeviceInfo *pDev,  APICState* s, int vector_num, int trigger_mode, uint32_t uTagSrc)
+{
+    LogFlow(("CPU%d: apic_set_irq vector=%x trigger_mode=%x uTagSrc=%#x\n", s->phys_id, vector_num, trigger_mode, uTagSrc));
+
     Apic256BitReg_SetBit(&s->irr, vector_num);
     if (trigger_mode)
@@ -1277,4 +1284,10 @@
     else
         Apic256BitReg_ClearBit(&s->tmr, vector_num);
+
+    if (!s->auTags[vector_num])
+        s->auTags[vector_num] = uTagSrc;
+    else
+        s->auTags[vector_num] |= RT_BIT_32(31);
+
     apic_update_irq(pDev, s);
 }
@@ -1368,5 +1381,5 @@
 {
     int dest_shorthand = (s->icr[0] >> 18) & 3;
-    LogFlow(("apic_deliver dest=%x dest_mode=%x dest_shorthand=%x delivery_mode=%x vector_num=%x polarity=%x trigger_mode=%x\n", dest, dest_mode, dest_shorthand, delivery_mode, vector_num, polarity, trigger_mode));
+    LogFlow(("apic_deliver dest=%x dest_mode=%x dest_shorthand=%x delivery_mode=%x vector_num=%x polarity=%x trigger_mode=%x uTagSrc=%#x\n", dest, dest_mode, dest_shorthand, delivery_mode, vector_num, polarity, trigger_mode));
 
     VMCPUSET DstSet;
@@ -1420,9 +1433,9 @@
 
     return apic_bus_deliver(pDev, &DstSet, delivery_mode, vector_num,
-                            polarity, trigger_mode);
-}
-
-
-PDMBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns)
+                            polarity, trigger_mode, 0 /* uTagSrc*/);
+}
+
+
+PDMBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns, uint32_t *puTagSrc)
 {
     APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
@@ -1455,11 +1468,18 @@
     if (s->tpr && (uint32_t)intno <= s->tpr)
     {
+        *puTagSrc = 0;
         Log(("apic_get_interrupt: returns %d (sp)\n", s->spurious_vec & 0xff));
         return s->spurious_vec & 0xff;
     }
+
     Apic256BitReg_ClearBit(&s->irr, intno);
     Apic256BitReg_SetBit(&s->isr, intno);
+
+    *puTagSrc = s->auTags[intno];
+    s->auTags[intno] = 0;
+
     apic_update_irq(pDev, s);
-    LogFlow(("CPU%d: apic_get_interrupt: returns %d\n", s->phys_id, intno));
+
+    LogFlow(("CPU%d: apic_get_interrupt: returns %d / %#x\n", s->phys_id, intno, *puTagSrc));
     return intno;
 }
@@ -1679,5 +1699,5 @@
     if (!(pApic->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
         LogFlow(("apic_timer: trigger irq\n"));
-        apic_set_irq(pDev, pApic, pApic->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE);
+        apic_set_irq(pDev, pApic, pApic->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE, 0 /*uTagSrc*/);
 
         if (   (pApic->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC)
Index: /trunk/src/VBox/Devices/PC/DevIoApic.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevIoApic.cpp	(revision 40906)
+++ /trunk/src/VBox/Devices/PC/DevIoApic.cpp	(revision 40907)
@@ -87,4 +87,6 @@
     uint32_t                irr;
     uint64_t                ioredtbl[IOAPIC_NUM_PINS];
+    /** The IRQ tags and source IDs for each pin (tracing purposes). */
+    uint32_t                auTagSrc[IOAPIC_NUM_PINS];
 
     /** The device instance - R3 Ptr. */
@@ -157,4 +159,6 @@
                 else
                     vector = entry & 0xff;
+                uint32_t uTagSrc = pThis->auTagSrc[vector];
+                pThis->auTagSrc[vector] = 0;
 
                 int rc = pThis->CTX_SUFF(pIoApicHlp)->pfnApicBusDeliver(pThis->CTX_SUFF(pDevIns),
@@ -164,5 +168,6 @@
                                                                         vector,
                                                                         polarity,
-                                                                        trig_mode);
+                                                                        trig_mode,
+                                                                        uTagSrc);
                 /* We must be sure that attempts to reschedule in R3
                    never get here */
@@ -174,5 +179,5 @@
 
 
-static void ioapic_set_irq(void *opaque, int vector, int level)
+static void ioapic_set_irq(void *opaque, int vector, int level, uint32_t uTagSrc)
 {
     IOAPICState *pThis = (IOAPICState*)opaque;
@@ -189,5 +194,11 @@
             {
                 pThis->irr |= mask;
+                if (!pThis->auTagSrc[vector])
+                    pThis->auTagSrc[vector] = uTagSrc;
+                else
+                    pThis->auTagSrc[vector] = RT_BIT_32(31);
+
                 ioapic_service(pThis);
+
                 if ((level & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP)
                     pThis->irr &= ~mask;
@@ -202,4 +213,9 @@
             {
                 pThis->irr |= mask;
+                if (!pThis->auTagSrc[vector])
+                    pThis->auTagSrc[vector] = uTagSrc;
+                else
+                    pThis->auTagSrc[vector] = RT_BIT_32(31);
+
                 ioapic_service(pThis);
             }
@@ -372,14 +388,14 @@
 }
 
-PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
 {
     /* PDM lock is taken here; */ /** @todo add assertion */
     IOAPICState *pThis = PDMINS_2_DATA(pDevIns, IOAPICState *);
     STAM_COUNTER_INC(&pThis->CTXSUFF(StatSetIrq));
-    LogFlow(("ioapicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
-    ioapic_set_irq(pThis, iIrq, iLevel);
-}
-
-PDMBOTHCBDECL(void) ioapicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue)
+    LogFlow(("ioapicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
+    ioapic_set_irq(pThis, iIrq, iLevel, uTagSrc);
+}
+
+PDMBOTHCBDECL(void) ioapicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc)
 {
     IOAPICState *pThis = PDMINS_2_DATA(pDevIns, IOAPICState *);
@@ -406,5 +422,6 @@
                                                             vector_num,
                                                             0 /* polarity, n/a */,
-                                                            trigger_mode);
+                                                            trigger_mode,
+                                                            uTagSrc);
     /* We must be sure that attempts to reschedule in R3
        never get here */
Index: /trunk/src/VBox/Devices/PC/DevPIC.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevPIC.cpp	(revision 40906)
+++ /trunk/src/VBox/Devices/PC/DevPIC.cpp	(revision 40907)
@@ -51,6 +51,6 @@
 RT_C_DECLS_BEGIN
 
-PDMBOTHCBDECL(void) picSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
-PDMBOTHCBDECL(int) picGetInterrupt(PPDMDEVINS pDevIns);
+PDMBOTHCBDECL(void) picSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc);
+PDMBOTHCBDECL(int) picGetInterrupt(PPDMDEVINS pDevIns, uint32_t *puTagSrc);
 PDMBOTHCBDECL(int) picIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
 PDMBOTHCBDECL(int) picIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
@@ -109,10 +109,13 @@
     uint8_t elcr_mask;
     /** Pointer to the device instance, R3 Ptr. */
-    PPDMDEVINSR3 pDevInsR3;
+    PPDMDEVINSR3    pDevInsR3;
     /** Pointer to the device instance, R0 Ptr. */
-    PPDMDEVINSR0 pDevInsR0;
+    PPDMDEVINSR0    pDevInsR0;
     /** Pointer to the device instance, RC Ptr. */
-    PPDMDEVINSRC pDevInsRC;
-    RTRCPTR      Alignment0; /**< Structure size alignment. */
+    PPDMDEVINSRC    pDevInsRC;
+    RTRCPTR         Alignment0; /**< Structure size alignment. */
+    /** The IRQ tags and source IDs for each (tracing purposes). */
+    uint32_t        auTags[8];
+
 } PicState;
 
@@ -164,5 +167,5 @@
 
 /* set irq level. If an edge is detected, then the IRR is set to 1 */
-static inline void pic_set_irq1(PicState *s, int irq, int level)
+static inline void pic_set_irq1(PicState *s, int irq, int level, uint32_t uTagSrc)
 {
     int mask;
@@ -194,4 +197,14 @@
         }
     }
+
+    /* Save the tag. */
+    if (level)
+    {
+        if (!s->auTags[irq])
+            s->auTags[irq] = uTagSrc;
+        else
+            s->auTags[irq] |= RT_BIT_32(31);
+    }
+
     DumpPICState(s, "pic_set_irq1");
 }
@@ -251,8 +264,8 @@
     if (irq2 >= 0) {
         /* if irq request by slave pic, signal master PIC */
-        pic_set_irq1(&pics[0], 2, 1);
+        pic_set_irq1(&pics[0], 2, 1, pics[1].auTags[irq2]);
     } else {
         /* If not, clear the IR on the master PIC. */
-        pic_set_irq1(&pics[0], 2, 0);
+        pic_set_irq1(&pics[0], 2, 0, 0 /*uTagSrc*/);
     }
     /* look at requested irq */
@@ -352,6 +365,7 @@
  * @param   iIrq            IRQ number to set.
  * @param   iLevel          IRQ level.
- */
-PDMBOTHCBDECL(void) picSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+ * @param   uTagSrc         The IRQ tag and source ID (for tracing).
+ */
+PDMBOTHCBDECL(void) picSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
 {
     PDEVPIC     pThis = PDMINS_2_DATA(pDevIns, PDEVPIC);
@@ -371,8 +385,8 @@
          * line must be held high for a while to avoid spurious interrupts.
          */
-        pic_set_irq1(&pThis->aPics[iIrq >> 3], iIrq & 7, 0);
+        pic_set_irq1(&pThis->aPics[iIrq >> 3], iIrq & 7, 0, uTagSrc);
         pic_update_irq(pThis);
     }
-    pic_set_irq1(&pThis->aPics[iIrq >> 3], iIrq & 7, iLevel & PDM_IRQ_LEVEL_HIGH);
+    pic_set_irq1(&pThis->aPics[iIrq >> 3], iIrq & 7, iLevel & PDM_IRQ_LEVEL_HIGH, uTagSrc);
     pic_update_irq(pThis);
 }
@@ -402,6 +416,7 @@
  * @returns Pending interrupt number.
  * @param   pDevIns         Device instance of the PICs.
- */
-PDMBOTHCBDECL(int) picGetInterrupt(PPDMDEVINS pDevIns)
+ * @param   puTagSrc        Where to return the IRQ tag and source ID.
+ */
+PDMBOTHCBDECL(int) picGetInterrupt(PPDMDEVINS pDevIns, uint32_t *puTagSrc)
 {
     PDEVPIC     pThis = PDMINS_2_DATA(pDevIns, PDEVPIC);
@@ -431,10 +446,15 @@
             }
             intno = pThis->aPics[1].irq_base + irq2;
-            Log2(("picGetInterrupt1: %x base=%x irq=%x\n", intno, pThis->aPics[1].irq_base, irq2));
+            *puTagSrc = pThis->aPics[0].auTags[irq2];
+            pThis->aPics[0].auTags[irq2] = 0;
+            Log2(("picGetInterrupt1: %x base=%x irq=%x uTagSrc=%#x\n", intno, pThis->aPics[1].irq_base, irq2, *puTagSrc));
             irq = irq2 + 8;
         }
-        else {
+        else
+        {
             intno = pThis->aPics[0].irq_base + irq;
-            Log2(("picGetInterrupt0: %x base=%x irq=%x\n", intno, pThis->aPics[0].irq_base, irq));
+            *puTagSrc = pThis->aPics[0].auTags[irq];
+            pThis->aPics[0].auTags[irq] = 0;
+            Log2(("picGetInterrupt0: %x base=%x irq=%x uTagSrc=%#x\n", intno, pThis->aPics[0].irq_base, irq, *puTagSrc));
         }
     }
@@ -445,4 +465,5 @@
         irq = 7;
         intno = pThis->aPics[0].irq_base + irq;
+        *puTagSrc = 0;
     }
     pic_update_irq(pThis);
Index: /trunk/src/VBox/VMM/Makefile.kmk
===================================================================
--- /trunk/src/VBox/VMM/Makefile.kmk	(revision 40906)
+++ /trunk/src/VBox/VMM/Makefile.kmk	(revision 40907)
@@ -372,4 +372,5 @@
 
  VMMRC_SOURCES   = \
+ 	VBoxVMM.d \
  	VMMRC/VMMRC0.asm \
  	VMMRC/VMMRCDeps.cpp \
Index: /trunk/src/VBox/VMM/VBoxVMM.d
===================================================================
--- /trunk/src/VBox/VMM/VBoxVMM.d	(revision 40906)
+++ /trunk/src/VBox/VMM/VBoxVMM.d	(revision 40907)
@@ -30,8 +30,8 @@
     /*^^VMM-ALT-TP: "%04x:%08llx rc=%d", (a_pCtx)->cs, (a_pCtx)->rip, (a_rc) */
 
-    probe em__ff__high(struct VMCPU *a_pVCpu, unsigned int a_fGlobal, unsigned int a_fLocal, int a_rc);
+    probe em__ff__high(struct VMCPU *a_pVCpu, uint32_t a_fGlobal, uint32_t a_fLocal, int a_rc);
     /*^^VMM-ALT-TP: "vm=%#x cpu=%#x rc=%d", (a_fGlobal), (a_fLocal), (a_rc) */
 
-    probe em__ff__all(struct VMCPU *a_pVCpu, unsigned int a_fGlobal, unsigned int a_fLocal, int a_rc);
+    probe em__ff__all(struct VMCPU *a_pVCpu, uint32_t a_fGlobal, uint32_t a_fLocal, int a_rc);
     /*^^VMM-ALT-TP: "vm=%#x cpu=%#x rc=%d", (a_fGlobal), (a_fLocal), (a_rc) */
 
@@ -39,5 +39,5 @@
     /*^^VMM-ALT-TP: "%d", (a_rc) */
 
-    probe em__ff__raw(struct VMCPU *a_pVCpu, unsigned int a_fGlobal, unsigned int a_fLocal);
+    probe em__ff__raw(struct VMCPU *a_pVCpu, uint32_t a_fGlobal, uint32_t a_fLocal);
     /*^^VMM-ALT-TP: "vm=%#x cpu=%#x", (a_fGlobal), (a_fLocal) */
 
@@ -45,5 +45,11 @@
     /*^^VMM-ALT-TP: "%d", (a_rc) */
 
-    probe r0__gvmm__vm__created(void *a_pGVM, void *a_pVM, unsigned int a_Pid, void *a_hEMT0, unsigned int a_cCpus);
+    probe pdm__irq__get(       struct VMCPU *a_pVCpu, uint32_t a_uTag, uint32_t a_idSource, uint32_t a_iIrq);
+    probe pdm__irq__high(       struct VMCPU *a_pVCpu, uint32_t a_uTag, uint32_t a_idSource);
+    probe pdm__irq__low(     struct VMCPU *a_pVCpu, uint32_t a_uTag, uint32_t a_idSource);
+    probe pdm__irq__hilo(struct VMCPU *a_pVCpu, uint32_t a_uTag, uint32_t a_idSource);
+
+
+    probe r0__gvmm__vm__created(void *a_pGVM, void *a_pVM, uint32_t a_Pid, void *a_hEMT0, uint32_t a_cCpus);
     probe r0__hmsvm__vmexit(struct VMCPU *a_pVM, struct CPUMCTX *a_pCtx, uint64_t a_ExitCode,
                             uint64_t a_ExitInfo1, uint64_t a_ExitInfo2, uint64_t a_ExitIntInfo,
Index: /trunk/src/VBox/VMM/VMMAll/PDMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PDMAll.cpp	(revision 40906)
+++ /trunk/src/VBox/VMM/VMMAll/PDMAll.cpp	(revision 40907)
@@ -31,4 +31,8 @@
 #include <iprt/assert.h>
 
+#include "PDMInline.h"
+#include "dtrace/VBoxVMM.h"
+
+
 
 /**
@@ -53,5 +57,6 @@
         Assert(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
         Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt));
-        int i = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
+        uint32_t uTagSrc;
+        int i = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), &uTagSrc);
         AssertMsg(i <= 255 && i >= 0, ("i=%d\n", i));
         if (i >= 0)
@@ -59,4 +64,5 @@
             pdmUnlock(pVM);
             *pu8Interrupt = (uint8_t)i;
+            VBOXVMM_PDM_IRQ_GET(pVCpu, RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc), i);
             return VINF_SUCCESS;
         }
@@ -71,5 +77,6 @@
         Assert(pVM->pdm.s.Pic.CTX_SUFF(pDevIns));
         Assert(pVM->pdm.s.Pic.CTX_SUFF(pfnGetInterrupt));
-        int i = pVM->pdm.s.Pic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Pic.CTX_SUFF(pDevIns));
+        uint32_t uTagSrc;
+        int i = pVM->pdm.s.Pic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Pic.CTX_SUFF(pDevIns), &uTagSrc);
         AssertMsg(i <= 255 && i >= 0, ("i=%d\n", i));
         if (i >= 0)
@@ -77,4 +84,5 @@
             pdmUnlock(pVM);
             *pu8Interrupt = (uint8_t)i;
+            VBOXVMM_PDM_IRQ_GET(pVCpu, RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc), i);
             return VINF_SUCCESS;
         }
@@ -94,9 +102,19 @@
  * @param   pVM             VM handle.
  * @param   u8Irq           The IRQ line.
- * @param   u8Level         The new level.
- */
-VMMDECL(int) PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level)
+ * @param   u8Level         The new level. 
+ * @param   uTagSrc         The IRQ tag and source tracer ID.  
+ */
+VMMDECL(int) PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc)
 {
     pdmLock(pVM);
+
+    /** @todo put the IRQ13 code elsewhere to avoid this unnecessary bloat. */
+    if (!uTagSrc && (u8Level & PDM_IRQ_LEVEL_HIGH)) /* FPU IRQ */
+    {
+        if (u8Level == PDM_IRQ_LEVEL_HIGH)
+            VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), 0, 0);
+        else
+            VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), 0, 0);
+    }
 
     int rc = VERR_PDM_NO_PIC_INSTANCE;
@@ -104,5 +122,5 @@
     {
         Assert(pVM->pdm.s.Pic.CTX_SUFF(pfnSetIrq));
-        pVM->pdm.s.Pic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.Pic.CTX_SUFF(pDevIns), u8Irq, u8Level);
+        pVM->pdm.s.Pic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.Pic.CTX_SUFF(pDevIns), u8Irq, u8Level, uTagSrc);
         rc = VINF_SUCCESS;
     }
@@ -112,5 +130,5 @@
         Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq));
 
-        /**
+        /*
          * Apply Interrupt Source Override rules.
          * See ACPI 4.0 specification 5.2.12.4 and 5.2.12.5 for details on
@@ -124,8 +142,10 @@
             u8Irq = 2;
 
-        pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Irq, u8Level);
+        pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Irq, u8Level, uTagSrc);
         rc = VINF_SUCCESS;
     }
 
+    if (!uTagSrc && u8Level == PDM_IRQ_LEVEL_LOW)
+        VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), 0, 0);
     pdmUnlock(pVM);
     return rc;
@@ -140,6 +160,7 @@
  * @param   u8Irq           The IRQ line.
  * @param   u8Level         The new level.
- */
-VMMDECL(int) PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level)
+ * @param   uTagSrc         The IRQ tag and source tracer ID.  
+ */
+VMM_INT_DECL(int) PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc)
 {
     if (pVM->pdm.s.IoApic.CTX_SUFF(pDevIns))
@@ -147,5 +168,5 @@
         Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq));
         pdmLock(pVM);
-        pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Irq, u8Level);
+        pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Irq, u8Level, uTagSrc);
         pdmUnlock(pVM);
         return VINF_SUCCESS;
@@ -161,6 +182,7 @@
  * @param   GCAddr          Request address.
  * @param   u8Value         Request value.
- */
-VMMDECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue)
+ * @param   uTagSrc         The IRQ tag and source tracer ID.  
+ */
+VMM_INT_DECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc)
 {
     if (pVM->pdm.s.IoApic.CTX_SUFF(pDevIns))
@@ -168,5 +190,5 @@
         Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSendMsi));
         pdmLock(pVM);
-        pVM->pdm.s.IoApic.CTX_SUFF(pfnSendMsi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), GCAddr, uValue);
+        pVM->pdm.s.IoApic.CTX_SUFF(pfnSendMsi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), GCAddr, uValue, uTagSrc);
         pdmUnlock(pVM);
         return VINF_SUCCESS;
Index: /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 40906)
+++ /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 40907)
@@ -36,4 +36,7 @@
 #include <iprt/assert.h>
 #include <iprt/string.h>
+
+#include "dtrace/VBoxVMM.h"
+#include "PDMInline.h"
 
 
@@ -56,7 +59,5 @@
 *   Internal Functions                                                         *
 *******************************************************************************/
-static void pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel);
-static void pdmR0IoApicSetIrq(PVM pVM, int iIrq, int iLevel);
-static void pdmR0IoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue);
+static bool pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel, uint32_t uTagSrc);
 
 
@@ -71,34 +72,50 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
-
     PVM          pVM     = pDevIns->Internal.s.pVMR0;
     PPCIDEVICE   pPciDev = pDevIns->Internal.s.pPciDeviceR0;
     PPDMPCIBUS   pPciBus = pDevIns->Internal.s.pPciBusR0;
+
+    pdmLock(pVM);
+    uint32_t uTagSrc;
+    if (iLevel & PDM_IRQ_LEVEL_HIGH)
+    {
+        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
+        if (iLevel == PDM_IRQ_LEVEL_HIGH)
+            VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+        else
+            VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+    }
+    else
+        uTagSrc = pDevIns->Internal.s.uLastIrqTag;
+
     if (    pPciDev
         &&  pPciBus
         &&  pPciBus->pDevInsR0)
     {
-        pdmLock(pVM);
-        pPciBus->pfnSetIrqR0(pPciBus->pDevInsR0, pPciDev, iIrq, iLevel);
+        pPciBus->pfnSetIrqR0(pPciBus->pDevInsR0, pPciDev, iIrq, iLevel, uTagSrc);
+
         pdmUnlock(pVM);
+
+        if (iLevel == PDM_IRQ_LEVEL_LOW)
+            VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
     }
     else
     {
+        pdmUnlock(pVM);
+
         /* queue for ring-3 execution. */
         PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0);
-        if (pTask)
-        {
-            pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
-            pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
-            pTask->u.SetIRQ.iIrq = iIrq;
-            pTask->u.SetIRQ.iLevel = iLevel;
-
-            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
-        }
-        else
-            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
-    }
-
-    LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
+        AssertReturnVoid(pTask);
+
+        pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
+        pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
+        pTask->u.SetIRQ.iIrq = iIrq;
+        pTask->u.SetIRQ.iLevel = iLevel;
+        pTask->u.SetIRQ.uTagSrc = uTagSrc;
+
+        PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
+    }
+
+    LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
 }
 
@@ -109,8 +126,25 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
-
-    pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
-
-    LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
+    PVM pVM = pDevIns->Internal.s.pVMR0;
+
+    pdmLock(pVM);
+    uint32_t uTagSrc;
+    if (iLevel & PDM_IRQ_LEVEL_HIGH)
+    {
+        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
+        if (iLevel == PDM_IRQ_LEVEL_HIGH)
+            VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+        else
+            VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+    }
+    else
+        uTagSrc = pDevIns->Internal.s.uLastIrqTag;
+
+    bool fRc = pdmR0IsaSetIrq(pVM, iIrq, iLevel, uTagSrc);
+
+    if (iLevel == PDM_IRQ_LEVEL_LOW && fRc)
+        VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+    pdmUnlock(pVM);
+    LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
 }
 
@@ -213,5 +247,5 @@
 
 
-/** @copydoc PDMDEVHLPR0::pdmR0DevHlp_PATMSetMMIOPatchInfo*/
+/** @interface_method_impl{PDMDEVHLPR0,pfnPATMSetMMIOPatchInfo} */
 static DECLCALLBACK(int) pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
 {
@@ -233,13 +267,4 @@
     LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
     return pDevIns->Internal.s.pVMR0;
-}
-
-
-/** @interface_method_impl{PDMDEVHLPR0,pfnCanEmulateIoBlock} */
-static DECLCALLBACK(bool) pdmR0DevHlp_CanEmulateIoBlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return HWACCMCanEmulateIoBlock(VMMGetCpu(pDevIns->Internal.s.pVMR0));
 }
 
@@ -288,4 +313,13 @@
     LogFlow(("pdmR3DevHlp_DBGFTraceBuf: caller='%p'/%d: returns %p\n", pDevIns, pDevIns->iInstance, hTraceBuf));
     return hTraceBuf;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnCanEmulateIoBlock} */
+static DECLCALLBACK(bool) pdmR0DevHlp_CanEmulateIoBlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
+    return HWACCMCanEmulateIoBlock(VMMGetCpu(pDevIns->Internal.s.pVMR0));
 }
 
@@ -568,13 +602,14 @@
 /** @interface_method_impl{PDMIOAPICHLPR0,pfnApicBusDeliver} */
 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)
+                                                       uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM pVM = pDevIns->Internal.s.pVMR0;
-    LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
-             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
+    LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
+             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc));
     Assert(pVM->pdm.s.Apic.pDevInsR0);
     if (pVM->pdm.s.Apic.pfnBusDeliverR0)
-        return 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, uTagSrc);
     return VINF_SUCCESS;
 }
@@ -619,27 +654,67 @@
 
 /** @interface_method_impl{PDMPCIHLPR0,pfnIsaSetIrq} */
-static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
-    pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
+static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
+    PVM pVM = pDevIns->Internal.s.pVMR0;
+
+    pdmLock(pVM);
+    pdmR0IsaSetIrq(pVM, iIrq, iLevel, uTagSrc);
+    pdmUnlock(pVM);
 }
 
 
 /** @interface_method_impl{PDMPCIHLPR0,pfnIoApicSetIrq} */
-static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmR0PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
-    pdmR0IoApicSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
-}
+static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmR0PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
+    PVM pVM = pDevIns->Internal.s.pVMR0;
+
+    if (pVM->pdm.s.IoApic.pDevInsR0)
+    {
+        pdmLock(pVM);
+        pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel, uTagSrc);
+        pdmUnlock(pVM);
+    }
+    else if (pVM->pdm.s.IoApic.pDevInsR3)
+    {
+        /* queue for ring-3 execution. */
+        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0);
+        if (pTask)
+        {
+            pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
+            pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
+            pTask->u.SetIRQ.iIrq = iIrq;
+            pTask->u.SetIRQ.iLevel = iLevel;
+            pTask->u.SetIRQ.uTagSrc = uTagSrc;
+
+            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
+        }
+        else
+            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
+    }
+}
+
 
 /** @interface_method_impl{PDMPCIHLPR0,pfnIoApicSendMsi} */
-static DECLCALLBACK(void) pdmR0PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmR0PciHlp_IoApicSendMsi: Address=%p Value=%d\n", GCAddr, uValue));
-    pdmR0IoApicSendMsi(pDevIns->Internal.s.pVMR0, GCAddr, uValue);
-}
+static DECLCALLBACK(void) pdmR0PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmR0PciHlp_IoApicSendMsi: GCPhys=%p uValue=%d uTagSrc=%#x\n", GCPhys, uValue, uTagSrc));
+    PVM pVM = pDevIns->Internal.s.pVMR0;
+    if (pVM->pdm.s.IoApic.pDevInsR0)
+    {
+        pdmLock(pVM);
+        pVM->pdm.s.IoApic.pfnSendMsiR0(pVM->pdm.s.IoApic.pDevInsR0, GCPhys, uValue, uTagSrc);
+        pdmUnlock(pVM);
+    }
+    else
+    {
+        AssertFatalMsgFailed(("Lazy bastards!"));
+    }
+}
+
 
 /** @interface_method_impl{PDMPCIHLPR0,pfnLock} */
@@ -814,74 +889,40 @@
 
 /**
- * Sets an irq on the I/O APIC.
+ * Sets an irq on the PIC and I/O APIC.
  *
- * @param   pVM     The VM handle.
- * @param   iIrq    The irq.
- * @param   iLevel  The new level.
- */
-static void pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel)
-{
-    if (    (   pVM->pdm.s.IoApic.pDevInsR0
-             || !pVM->pdm.s.IoApic.pDevInsR3)
-        &&  (   pVM->pdm.s.Pic.pDevInsR0
-             || !pVM->pdm.s.Pic.pDevInsR3))
-    {
-        pdmLock(pVM);
+ * @returns true if     delivered, false if postponed.
+ * @param   pVM         The VM handle.
+ * @param   iIrq        The irq.
+ * @param   iLevel      The new level.
+ * @param   uTagSrc     The IRQ tag and source.
+ *
+ * @remarks The caller holds the PDM lock.
+ */
+static bool pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel, uint32_t uTagSrc)
+{
+    if (RT_LIKELY(    (   pVM->pdm.s.IoApic.pDevInsR0
+                       || !pVM->pdm.s.IoApic.pDevInsR3)
+                  &&  (   pVM->pdm.s.Pic.pDevInsR0
+                       || !pVM->pdm.s.Pic.pDevInsR3)))
+    {
         if (pVM->pdm.s.Pic.pDevInsR0)
-            pVM->pdm.s.Pic.pfnSetIrqR0(pVM->pdm.s.Pic.pDevInsR0, iIrq, iLevel);
+            pVM->pdm.s.Pic.pfnSetIrqR0(pVM->pdm.s.Pic.pDevInsR0, iIrq, iLevel, uTagSrc);
         if (pVM->pdm.s.IoApic.pDevInsR0)
-            pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel);
-        pdmUnlock(pVM);
-    }
-    else
-    {
-        /* queue for ring-3 execution. */
-        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0);
-        if (pTask)
-        {
-            pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
-            pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
-            pTask->u.SetIRQ.iIrq = iIrq;
-            pTask->u.SetIRQ.iLevel = iLevel;
-
-            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
-        }
-        else
-            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
-    }
-}
-
-
-/**
- * Sets an irq on the I/O APIC.
- *
- * @param   pVM     The VM handle.
- * @param   iIrq    The irq.
- * @param   iLevel  The new level.
- */
-static void pdmR0IoApicSetIrq(PVM pVM, int iIrq, int iLevel)
-{
-    if (pVM->pdm.s.IoApic.pDevInsR0)
-    {
-        pdmLock(pVM);
-        pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel);
-        pdmUnlock(pVM);
-    }
-    else if (pVM->pdm.s.IoApic.pDevInsR3)
-    {
-        /* queue for ring-3 execution. */
-        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0);
-        if (pTask)
-        {
-            pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
-            pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
-            pTask->u.SetIRQ.iIrq = iIrq;
-            pTask->u.SetIRQ.iLevel = iLevel;
-
-            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
-        }
-        else
-            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
-    }
+            pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel, uTagSrc);
+        return true;
+    }
+
+    /* queue for ring-3 execution. */
+    PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0);
+    AssertReturn(pTask, false);
+
+    pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
+    pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
+    pTask->u.SetIRQ.iIrq = iIrq;
+    pTask->u.SetIRQ.iLevel = iLevel;
+    pTask->u.SetIRQ.uTagSrc = uTagSrc;
+
+    PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
+    return false;
 }
 
@@ -913,18 +954,2 @@
 }
 
-/**
- * Sends an MSI to I/O APIC.
- *
- * @param   pVM     The VM handle.
- * @param   GCAddr  Address of the message.
- * @param   uValue  Value of the message.
- */
-static void pdmR0IoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue)
-{
-    if (pVM->pdm.s.IoApic.pDevInsR0)
-    {
-        pdmLock(pVM);
-        pVM->pdm.s.IoApic.pfnSendMsiR0(pVM->pdm.s.IoApic.pDevInsR0, GCAddr, uValue);
-        pdmUnlock(pVM);
-    }
-}
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 40906)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 40907)
@@ -44,4 +44,7 @@
 #include <iprt/thread.h>
 
+#include "dtrace/VBoxVMM.h"
+#include "PDMInline.h"
+
 
 /*******************************************************************************
@@ -1342,5 +1345,6 @@
      * Validate input.
      */
-    /** @todo iIrq and iLevel checks. */
+    Assert(iIrq == 0);
+    Assert((uint32_t)iLevel <= PDM_IRQ_LEVEL_FLIP_FLOP);
 
     /*
@@ -1353,6 +1357,22 @@
         Assert(pBus);
         PVM pVM = pDevIns->Internal.s.pVMR3;
+
         pdmLock(pVM);
-        pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel);
+        uint32_t uTagSrc;
+        if (iLevel & PDM_IRQ_LEVEL_HIGH)
+        {
+            pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
+            if (iLevel == PDM_IRQ_LEVEL_HIGH)
+                VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+            else
+                VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+        }
+        else
+            uTagSrc = pDevIns->Internal.s.uLastIrqTag;
+
+        pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel, uTagSrc);
+
+        if (iLevel == PDM_IRQ_LEVEL_LOW)
+            VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
         pdmUnlock(pVM);
     }
@@ -1411,8 +1431,30 @@
      * Validate input.
      */
-    /** @todo iIrq and iLevel checks. */
-
-    PVM pVM = pDevIns->Internal.s.pVMR3;
-    PDMIsaSetIrq(pVM, iIrq, iLevel);    /* (The API takes the lock.) */
+    Assert(iIrq < 16);
+    Assert((uint32_t)iLevel <= PDM_IRQ_LEVEL_FLIP_FLOP);
+
+    PVM pVM = pDevIns->Internal.s.pVMR3;
+
+    /*
+     * Do the job.
+     */
+    pdmLock(pVM);
+    uint32_t uTagSrc;
+    if (iLevel & PDM_IRQ_LEVEL_HIGH)
+    {
+        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
+        if (iLevel == PDM_IRQ_LEVEL_HIGH)
+            VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+        else
+            VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+    }
+    else
+        uTagSrc = pDevIns->Internal.s.uLastIrqTag;
+
+    PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc);  /* (The API takes the lock recursively.) */
+
+    if (iLevel == PDM_IRQ_LEVEL_LOW)
+        VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+    pdmUnlock(pVM);
 
     LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
@@ -3604,13 +3646,29 @@
     {
         case PDMDEVHLPTASKOP_ISA_SET_IRQ:
-            PDMIsaSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);
+            PDMIsaSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel, pTask->u.SetIRQ.uTagSrc);
             break;
 
         case PDMDEVHLPTASKOP_PCI_SET_IRQ:
-            pdmR3DevHlp_PCISetIrq(pTask->pDevInsR3, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);
+        {
+            /* Same as pdmR3DevHlp_PCISetIrq, except we've got a tag already. */
+            PPDMDEVINS pDevIns = pTask->pDevInsR3;
+            PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceR3;
+            if (pPciDev)
+            {
+                PPDMPCIBUS pBus = pDevIns->Internal.s.pPciBusR3; /** @todo the bus should be associated with the PCI device not the PDM device. */
+                Assert(pBus);
+
+                pdmLock(pVM);
+                pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, pTask->u.SetIRQ.iIrq,
+                                  pTask->u.SetIRQ.iLevel, pTask->u.SetIRQ.uTagSrc);
+                pdmUnlock(pVM);
+            }
+            else
+                AssertReleaseMsgFailed(("No PCI device registered!\n"));
             break;
+        }
 
         case PDMDEVHLPTASKOP_IOAPIC_SET_IRQ:
-            PDMIoApicSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel);
+            PDMIoApicSetIrq(pVM, pTask->u.SetIRQ.iIrq, pTask->u.SetIRQ.iLevel, pTask->u.SetIRQ.uTagSrc);
             break;
 
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp	(revision 40906)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp	(revision 40907)
@@ -35,4 +35,8 @@
 #include <iprt/assert.h>
 #include <iprt/thread.h>
+
+
+#include "PDMInline.h"
+#include "dtrace/VBoxVMM.h"
 
 
@@ -378,12 +382,12 @@
 /** @interface_method_impl{PDMIOAPICHLPR3,pfnApicBusDeliver} */
 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)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMR3;
-    LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
-             pDevIns->pReg->szName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
+                                                        uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMR3;
+    LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
+             pDevIns->pReg->szName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc));
     if (pVM->pdm.s.Apic.pfnBusDeliverR3)
-        return 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, uTagSrc);
     return VINF_SUCCESS;
 }
@@ -462,25 +466,26 @@
 
 /** @interface_method_impl{PDMPCIHLPR3,pfnIsaSetIrq} */
-static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
-    PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel);
+static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
+    PVM pVM = pDevIns->Internal.s.pVMR3;
+    PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
 }
 
 /** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSetIrq} */
-static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmR3PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
-    PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel);
+static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmR3PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
+    PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
 }
 
 /** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSendMsi} */
-static DECLCALLBACK(void) pdmR3PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmR3PciHlp_IoApicSendMsi: address=%p value=%x\n", GCAddr, uValue));
-    PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, GCAddr, uValue);
+static DECLCALLBACK(void) pdmR3PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmR3PciHlp_IoApicSendMsi: address=%p value=%x uTagSrc=%#x\n", GCAddr, uValue, uTagSrc));
+    PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, GCAddr, uValue, uTagSrc);
 }
 
@@ -612,5 +617,24 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmR3HpetHlp_SetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
-    PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel);
+    PVM pVM = pDevIns->Internal.s.pVMR3;
+
+    pdmLock(pVM);
+    uint32_t uTagSrc;
+    if (iLevel & PDM_IRQ_LEVEL_HIGH)
+    {
+        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
+        if (iLevel == PDM_IRQ_LEVEL_HIGH)
+            VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+        else
+            VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+    }
+    else
+        uTagSrc = pDevIns->Internal.s.uLastIrqTag;
+
+    PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
+
+    if (iLevel == PDM_IRQ_LEVEL_LOW)
+        VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+    pdmUnlock(pVM);
     return 0;
 }
Index: /trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp	(revision 40906)
+++ /trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp	(revision 40907)
@@ -34,4 +34,7 @@
 #include <iprt/assert.h>
 #include <iprt/string.h>
+
+#include "dtrace/VBoxVMM.h"
+#include "PDMInline.h"
 
 
@@ -54,7 +57,6 @@
 *   Internal Functions                                                         *
 *******************************************************************************/
-static void pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel);
-static void pdmRCIoApicSetIrq(PVM pVM, int iIrq, int iLevel);
-static void pdmRCIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue);
+static bool pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel, uint32_t uTagSrc);
+
 
 /** @name Raw-Mode Context Device Helpers
@@ -71,30 +73,47 @@
     PPCIDEVICE  pPciDev = pDevIns->Internal.s.pPciDeviceRC;
     PPDMPCIBUS  pPciBus = pDevIns->Internal.s.pPciBusRC;
+
+    pdmLock(pVM);
+    uint32_t uTagSrc;
+    if (iLevel & PDM_IRQ_LEVEL_HIGH)
+    {
+        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
+        if (iLevel == PDM_IRQ_LEVEL_HIGH)
+            VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+        else
+            VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+    }
+    else
+        uTagSrc = pDevIns->Internal.s.uLastIrqTag;
+
     if (    pPciDev
         &&  pPciBus
         &&  pPciBus->pDevInsRC)
     {
-        pdmLock(pVM);
-        pPciBus->pfnSetIrqRC(pPciBus->pDevInsRC, pPciDev, iIrq, iLevel);
+        pPciBus->pfnSetIrqRC(pPciBus->pDevInsRC, pPciDev, iIrq, iLevel, uTagSrc);
+
         pdmUnlock(pVM);
+
+        if (iLevel == PDM_IRQ_LEVEL_LOW)
+            VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
     }
     else
     {
+        pdmUnlock(pVM);
+
         /* queue for ring-3 execution. */
         PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC);
-        if (pTask)
-        {
-            pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
-            pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
-            pTask->u.SetIRQ.iIrq = iIrq;
-            pTask->u.SetIRQ.iLevel = iLevel;
-
-            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
-        }
-        else
-            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
-    }
-
-    LogFlow(("pdmRCDevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
+        AssertReturnVoid(pTask);
+
+        pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
+        pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
+        pTask->u.SetIRQ.iIrq = iIrq;
+        pTask->u.SetIRQ.iLevel = iLevel;
+        pTask->u.SetIRQ.uTagSrc = uTagSrc;
+
+        PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
+    }
+
+    LogFlow(("pdmRCDevHlp_PCISetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
 }
 
@@ -105,8 +124,25 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmRCDevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
-
-    pdmRCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
-
-    LogFlow(("pdmRCDevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
+    PVM pVM = pDevIns->Internal.s.pVMRC;
+
+    pdmLock(pVM);
+    uint32_t uTagSrc;
+    if (iLevel & PDM_IRQ_LEVEL_HIGH)
+    {
+        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
+        if (iLevel == PDM_IRQ_LEVEL_HIGH)
+            VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+        else
+            VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+    }
+    else
+        uTagSrc = pDevIns->Internal.s.uLastIrqTag;
+
+    bool fRc = pdmRCIsaSetIrq(pVM, iIrq, iLevel, uTagSrc);
+
+    if (iLevel == PDM_IRQ_LEVEL_LOW && fRc)
+        VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
+    pdmUnlock(pVM);
+    LogFlow(("pdmRCDevHlp_ISASetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
 }
 
@@ -531,12 +567,14 @@
 /** @interface_method_impl{PDMIOAPICHLPRC,pfnApicBusDeliver} */
 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)
+                                                       uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM pVM = pDevIns->Internal.s.pVMRC;
-    LogFlow(("pdmRCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
-             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
+    LogFlow(("pdmRCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
+             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc));
+    Assert(pVM->pdm.s.Apic.pDevInsRC);
     if (pVM->pdm.s.Apic.pfnBusDeliverRC)
-        return 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, uTagSrc);
     return VINF_SUCCESS;
 }
@@ -581,26 +619,66 @@
 
 /** @interface_method_impl{PDMPCIHLPRC,pfnIsaSetIrq} */
-static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
-    pdmRCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
+static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
+    PVM pVM = pDevIns->Internal.s.pVMRC;
+
+    pdmLock(pVM);
+    pdmRCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel, uTagSrc);
+    pdmUnlock(pVM);
 }
 
 
 /** @interface_method_impl{PDMPCIHLPRC,pfnIoApicSetIrq} */
-static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmRCPciHlp_IoApicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
-    pdmRCIoApicSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
-}
+static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmRCPciHlp_IoApicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
+    PVM pVM = pDevIns->Internal.s.pVMRC;
+
+    if (pVM->pdm.s.IoApic.pDevInsRC)
+    {
+        pdmLock(pVM);
+        pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel, uTagSrc);
+        pdmUnlock(pVM);
+    }
+    else if (pVM->pdm.s.IoApic.pDevInsR3)
+    {
+        /* queue for ring-3 execution. */
+        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC);
+        if (pTask)
+        {
+            pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
+            pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
+            pTask->u.SetIRQ.iIrq = iIrq;
+            pTask->u.SetIRQ.iLevel = iLevel;
+            pTask->u.SetIRQ.uTagSrc = uTagSrc;
+
+            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
+        }
+        else
+            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
+    }
+}
+
 
 /** @interface_method_impl{PDMPCIHLPRC,pfnIoApicSendMsi} */
-static DECLCALLBACK(void) pdmRCPciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmRCPciHlp_IoApicSendMsi: Address=%p Value=%d\n", GCAddr, uValue));
-    pdmRCIoApicSendMsi(pDevIns->Internal.s.pVMRC, GCAddr, uValue);
+static DECLCALLBACK(void) pdmRCPciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmRCPciHlp_IoApicSendMsi: GCPhys=%p uValue=%d uTagSrc=%#x\n", GCPhys, uValue, uTagSrc));
+    PVM pVM = pDevIns->Internal.s.pVMRC;
+
+    if (pVM->pdm.s.IoApic.pDevInsRC)
+    {
+        pdmLock(pVM);
+        pVM->pdm.s.IoApic.pfnSendMsiRC(pVM->pdm.s.IoApic.pDevInsRC, GCPhys, uValue, uTagSrc);
+        pdmUnlock(pVM);
+    }
+    else
+    {
+        AssertFatalMsgFailed(("Lazy bastarts!"));
+    }
 }
 
@@ -764,91 +842,40 @@
 
 /**
- * Sets an irq on the I/O APIC.
+ * Sets an irq on the PIC and I/O APIC.
  *
- * @param   pVM     The VM handle.
- * @param   iIrq    The irq.
- * @param   iLevel  The new level.
- */
-static void pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel)
-{
-    if (    (   pVM->pdm.s.IoApic.pDevInsRC
-             || !pVM->pdm.s.IoApic.pDevInsR3)
-        &&  (   pVM->pdm.s.Pic.pDevInsRC
-             || !pVM->pdm.s.Pic.pDevInsR3))
-    {
-        pdmLock(pVM);
+ * @returns true if     delivered, false if postponed.
+ * @param   pVM         The VM handle.
+ * @param   iIrq        The irq.
+ * @param   iLevel      The new level.
+ * @param   uTagSrc     The IRQ tag and source.
+ *
+ * @remarks The caller holds the PDM lock.
+ */
+static bool pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel, uint32_t uTagSrc)
+{
+    if (RT_LIKELY(    (   pVM->pdm.s.IoApic.pDevInsRC
+                       || !pVM->pdm.s.IoApic.pDevInsR3)
+                  &&  (   pVM->pdm.s.Pic.pDevInsRC
+                       || !pVM->pdm.s.Pic.pDevInsR3)))
+    {
         if (pVM->pdm.s.Pic.pDevInsRC)
-            pVM->pdm.s.Pic.pfnSetIrqRC(pVM->pdm.s.Pic.pDevInsRC, iIrq, iLevel);
+            pVM->pdm.s.Pic.pfnSetIrqRC(pVM->pdm.s.Pic.pDevInsRC, iIrq, iLevel, uTagSrc);
         if (pVM->pdm.s.IoApic.pDevInsRC)
-            pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel);
-        pdmUnlock(pVM);
-    }
-    else
-    {
-        /* queue for ring-3 execution. */
-        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC);
-        if (pTask)
-        {
-            pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
-            pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
-            pTask->u.SetIRQ.iIrq = iIrq;
-            pTask->u.SetIRQ.iLevel = iLevel;
-
-            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
-        }
-        else
-            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
-    }
-}
-
-
-/**
- * Sets an irq on the I/O APIC.
- *
- * @param   pVM     The VM handle.
- * @param   iIrq    The irq.
- * @param   iLevel  The new level.
- */
-static void pdmRCIoApicSetIrq(PVM pVM, int iIrq, int iLevel)
-{
-    if (pVM->pdm.s.IoApic.pDevInsRC)
-    {
-        pdmLock(pVM);
-        pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel);
-        pdmUnlock(pVM);
-    }
-    else if (pVM->pdm.s.IoApic.pDevInsR3)
-    {
-        /* queue for ring-3 execution. */
-        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC);
-        if (pTask)
-        {
-            pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
-            pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
-            pTask->u.SetIRQ.iIrq = iIrq;
-            pTask->u.SetIRQ.iLevel = iLevel;
-
-            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
-        }
-        else
-            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
-    }
-}
-
-
-/**
- * Sends an MSI to I/O APIC.
- *
- * @param   pVM     The VM handle.
- * @param   GCAddr  Address of the message.
- * @param   uValue  Value of the message.
- */
-static void pdmRCIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue)
-{
-    if (pVM->pdm.s.IoApic.pDevInsRC)
-    {
-        pdmLock(pVM);
-        pVM->pdm.s.IoApic.pfnSendMsiRC(pVM->pdm.s.IoApic.pDevInsRC, GCAddr, uValue);
-        pdmUnlock(pVM);
-    }
-}
+            pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel, uTagSrc);
+        return true;
+    }
+
+    /* queue for ring-3 execution. */
+    PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC);
+    AssertReturn(pTask, false);
+
+    pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
+    pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */
+    pTask->u.SetIRQ.iIrq = iIrq;
+    pTask->u.SetIRQ.iLevel = iLevel;
+    pTask->u.SetIRQ.uTagSrc = uTagSrc;
+
+    PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
+    return false;
+}
+
Index: /trunk/src/VBox/VMM/include/PDMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/PDMInternal.h	(revision 40906)
+++ /trunk/src/VBox/VMM/include/PDMInternal.h	(revision 40907)
@@ -149,4 +149,8 @@
     /** Flags, see PDMDEVINSINT_FLAGS_XXX. */
     uint32_t                        fIntFlags;
+    /** The last IRQ tag (for tracing it thru clearing). */
+    uint32_t                        uLastIrqTag;
+    /** Size padding. */
+    uint32_t                        u32Padding;
 } PDMDEVINSINT;
 
@@ -454,21 +458,21 @@
     PPDMDEVINSR3                    pDevInsR3;
     /** @copydoc PDMPICREG::pfnSetIrqR3 */
-    DECLR3CALLBACKMEMBER(void,      pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+    DECLR3CALLBACKMEMBER(void,      pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
     /** @copydoc PDMPICREG::pfnGetInterruptR3 */
-    DECLR3CALLBACKMEMBER(int,       pfnGetInterruptR3,(PPDMDEVINS pDevIns));
+    DECLR3CALLBACKMEMBER(int,       pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
 
     /** Pointer to the PIC device instance - R0. */
     PPDMDEVINSR0                    pDevInsR0;
     /** @copydoc PDMPICREG::pfnSetIrqR3 */
-    DECLR0CALLBACKMEMBER(void,      pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+    DECLR0CALLBACKMEMBER(void,      pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
     /** @copydoc PDMPICREG::pfnGetInterruptR3 */
-    DECLR0CALLBACKMEMBER(int,       pfnGetInterruptR0,(PPDMDEVINS pDevIns));
+    DECLR0CALLBACKMEMBER(int,       pfnGetInterruptR0,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
 
     /** Pointer to the PIC device instance - RC. */
     PPDMDEVINSRC                    pDevInsRC;
     /** @copydoc PDMPICREG::pfnSetIrqR3 */
-    DECLRCCALLBACKMEMBER(void,      pfnSetIrqRC,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+    DECLRCCALLBACKMEMBER(void,      pfnSetIrqRC,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
     /** @copydoc PDMPICREG::pfnGetInterruptR3 */
-    DECLRCCALLBACKMEMBER(int,       pfnGetInterruptRC,(PPDMDEVINS pDevIns));
+    DECLRCCALLBACKMEMBER(int,       pfnGetInterruptRC,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
     /** Alignment padding. */
     RTRCPTR                         RCPtrPadding;
@@ -484,5 +488,5 @@
     PPDMDEVINSR3                    pDevInsR3;
     /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
-    DECLR3CALLBACKMEMBER(int,       pfnGetInterruptR3,(PPDMDEVINS pDevIns));
+    DECLR3CALLBACKMEMBER(int,       pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
     /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */
     DECLR3CALLBACKMEMBER(bool,      pfnHasPendingIrqR3,(PPDMDEVINS pDevIns));
@@ -501,5 +505,5 @@
     /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
     DECLR3CALLBACKMEMBER(int,       pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
+                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
     /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
     DECLR3CALLBACKMEMBER(int,       pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
@@ -508,5 +512,5 @@
     PPDMDEVINSR0                    pDevInsR0;
     /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
-    DECLR0CALLBACKMEMBER(int,       pfnGetInterruptR0,(PPDMDEVINS pDevIns));
+    DECLR0CALLBACKMEMBER(int,       pfnGetInterruptR0,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
     /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */
     DECLR0CALLBACKMEMBER(bool,      pfnHasPendingIrqR0,(PPDMDEVINS pDevIns));
@@ -525,5 +529,5 @@
     /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
     DECLR0CALLBACKMEMBER(int,       pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
+                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
     /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
     DECLR0CALLBACKMEMBER(int,       pfnLocalInterruptR0,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
@@ -532,5 +536,5 @@
     PPDMDEVINSRC                    pDevInsRC;
     /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
-    DECLRCCALLBACKMEMBER(int,       pfnGetInterruptRC,(PPDMDEVINS pDevIns));
+    DECLRCCALLBACKMEMBER(int,       pfnGetInterruptRC,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
     /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */
     DECLRCCALLBACKMEMBER(bool,      pfnHasPendingIrqRC,(PPDMDEVINS pDevIns));
@@ -549,5 +553,5 @@
     /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
     DECLRCCALLBACKMEMBER(int,       pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
+                                                     uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
     /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
     DECLRCCALLBACKMEMBER(int,       pfnLocalInterruptRC,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
@@ -565,21 +569,21 @@
     PPDMDEVINSR3                    pDevInsR3;
     /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
-    DECLR3CALLBACKMEMBER(void,      pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+    DECLR3CALLBACKMEMBER(void,      pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
     /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
-    DECLR3CALLBACKMEMBER(void,      pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
+    DECLR3CALLBACKMEMBER(void,      pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc));
 
     /** Pointer to the PIC device instance - R0. */
     PPDMDEVINSR0                    pDevInsR0;
     /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
-    DECLR0CALLBACKMEMBER(void,      pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+    DECLR0CALLBACKMEMBER(void,      pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
     /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
-    DECLR0CALLBACKMEMBER(void,      pfnSendMsiR0,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
+    DECLR0CALLBACKMEMBER(void,      pfnSendMsiR0,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc));
 
     /** Pointer to the APIC device instance - RC Ptr. */
     PPDMDEVINSRC                    pDevInsRC;
     /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
-    DECLRCCALLBACKMEMBER(void,      pfnSetIrqRC,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+    DECLRCCALLBACKMEMBER(void,      pfnSetIrqRC,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
      /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
-    DECLRCCALLBACKMEMBER(void,      pfnSendMsiRC,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
+    DECLRCCALLBACKMEMBER(void,      pfnSendMsiRC,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc));
 
     uint8_t                         Alignment[4];
@@ -601,5 +605,5 @@
     PPDMDEVINSR3                    pDevInsR3;
     /** @copydoc PDMPCIBUSREG::pfnSetIrqR3 */
-    DECLR3CALLBACKMEMBER(void,      pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
+    DECLR3CALLBACKMEMBER(void,      pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
     /** @copydoc PDMPCIBUSREG::pfnRegisterR3 */
     DECLR3CALLBACKMEMBER(int,       pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev));
@@ -622,10 +626,10 @@
     R0PTRTYPE(PPDMDEVINS)           pDevInsR0;
     /** @copydoc PDMPCIBUSREG::pfnSetIrqR3 */
-    DECLR0CALLBACKMEMBER(void,      pfnSetIrqR0,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
+    DECLR0CALLBACKMEMBER(void,      pfnSetIrqR0,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
 
     /** Pointer to PCI Bus device instance. */
     PPDMDEVINSRC                    pDevInsRC;
     /** @copydoc PDMPCIBUSREG::pfnSetIrqR3 */
-    DECLRCCALLBACKMEMBER(void,      pfnSetIrqRC,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
+    DECLRCCALLBACKMEMBER(void,      pfnSetIrqRC,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
 } PDMPCIBUS;
 
@@ -892,5 +896,10 @@
             /** The new level. */
             int                     iLevel;
+            /** The IRQ tag and source. */
+            uint32_t                uTagSrc;
         } SetIRQ;
+
+        /** Expanding the structure.. */
+        uint64_t    au64[2];
     } u;
 } PDMDEVHLPTASK;
@@ -1006,6 +1015,6 @@
      * See PDM_QUEUE_FLUSH_FLAG_ACTIVE and PDM_QUEUE_FLUSH_FLAG_PENDING. */
     uint32_t volatile               fQueueFlushing;
-    /** Alignment padding. */
-    uint32_t                        u32Padding2;
+    /** The current IRQ tag (tracing purposes). */
+    uint32_t                        uIrqTag;
 
     /** @name   VMM device heap
Index: /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 40906)
+++ /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 40907)
@@ -162,7 +162,6 @@
     do \
     { \
-        printf("info: %s::%s offset %#x (%d) sizeof %d\n",  #strct, #member, (int)RT_OFFSETOF(strct, member), (int)RT_OFFSETOF(strct, member), (int)RT_SIZEOFMEMB(strct, member)); \
-    } while (0)
-
+        printf("info: %10s::%-24s offset %#6x (%6d) sizeof %4d\n",  #strct, #member, (int)RT_OFFSETOF(strct, member), (int)RT_OFFSETOF(strct, member), (int)RT_SIZEOFMEMB(strct, member)); \
+    } while (0)
 
 
@@ -336,10 +335,19 @@
 
     /* pdm */
+    PRINT_OFFSET(PDMDEVINS, Internal);
+    PRINT_OFFSET(PDMDEVINS, achInstanceData);
     CHECK_MEMBER_ALIGNMENT(PDMDEVINS, achInstanceData, 64);
     CHECK_PADDING(PDMDEVINS, Internal, 1);
-    CHECK_MEMBER_ALIGNMENT(PDMUSBINS, achInstanceData, 16);
+
+    PRINT_OFFSET(PDMUSBINS, Internal);
+    PRINT_OFFSET(PDMUSBINS, achInstanceData);
+    CHECK_MEMBER_ALIGNMENT(PDMUSBINS, achInstanceData, 32);
     CHECK_PADDING(PDMUSBINS, Internal, 1);
-    CHECK_MEMBER_ALIGNMENT(PDMDRVINS, achInstanceData, 16);
+
+    PRINT_OFFSET(PDMDRVINS, Internal);
+    PRINT_OFFSET(PDMDRVINS, achInstanceData);
+    CHECK_MEMBER_ALIGNMENT(PDMDRVINS, achInstanceData, 32);
     CHECK_PADDING(PDMDRVINS, Internal, 1);
+
     CHECK_PADDING2(PDMCRITSECT);
 
Index: /trunk/src/recompiler/VBoxREMWrapper.cpp
===================================================================
--- /trunk/src/recompiler/VBoxREMWrapper.cpp	(revision 40906)
+++ /trunk/src/recompiler/VBoxREMWrapper.cpp	(revision 40907)
@@ -763,5 +763,6 @@
     { REMPARMDESC_FLAGS_INT,        sizeof(PVM),                NULL },
     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t),            NULL },
-    { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t),            NULL }
+    { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t),            NULL },
+    { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t),           NULL }
 };
 static const REMPARMDESC g_aArgsPDMR3CritSectInit[] =
Index: /trunk/src/recompiler/VBoxRecompiler.c
===================================================================
--- /trunk/src/recompiler/VBoxRecompiler.c	(revision 40906)
+++ /trunk/src/recompiler/VBoxRecompiler.c	(revision 40907)
@@ -4452,5 +4452,5 @@
 void cpu_set_ferr(CPUX86State *env)
 {
-    int rc = PDMIsaSetIrq(env->pVM, 13, 1);
+    int rc = PDMIsaSetIrq(env->pVM, 13, 1, 0 /*uTagSrc*/);
     LogFlow(("cpu_set_ferr: rc=%d\n", rc)); NOREF(rc);
 }
