Index: trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
===================================================================
--- trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 32933)
+++ trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 32935)
@@ -528,10 +528,13 @@
 static void ich9pciSetIrqInternal(PPCIGLOBALS pGlobals, uint8_t uDevFn, PPCIDEVICE pPciDev, int iIrq, int iLevel)
 {
-    if (MSIIsEnabled(pPciDev))
+    if (MsiIsEnabled(pPciDev))
     {
         Log2(("Raise a MSI interrupt: %d\n", iIrq));
         /* We only trigger MSI on level up, as technically it's matching flip-flop best (maybe even assert that level == PDM_IRQ_LEVEL_FLIP_FLOP) */
         if ((iLevel & PDM_IRQ_LEVEL_HIGH) != 0)
-            MSINotify(pGlobals->aPciBus.CTX_SUFF(pDevIns), pPciDev, iIrq);
+        {
+            PPDMDEVINS pDevIns = pGlobals->aPciBus.CTX_SUFF(pDevIns);
+            MsiNotify(pDevIns, pGlobals->aPciBus.CTX_SUFF(pPciHlp), pPciDev, iIrq);
+        }
         return;
     }
@@ -786,5 +789,5 @@
 static DECLCALLBACK(int) ich9pciRegisterMsi(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg)
 {
-    return MSIInit(pPciDev, pMsiReg);
+    return MsiInit(pPciDev, pMsiReg);
 }
 
@@ -1686,5 +1689,5 @@
        )
     {
-        return MSIPciConfigRead(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, len);
+        return MsiPciConfigRead(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, len);
     }
 
@@ -1723,5 +1726,7 @@
        )
     {
-        MSIPciConfigWrite(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, val, len);
+        MsiPciConfigWrite(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns),
+                          aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pPciHlp),
+                          aDev, u32Address, val, len);
         return;
     }
Index: trunk/src/VBox/Devices/Bus/MsiCommon.cpp
===================================================================
--- trunk/src/VBox/Devices/Bus/MsiCommon.cpp	(revision 32933)
+++ trunk/src/VBox/Devices/Bus/MsiCommon.cpp	(revision 32935)
@@ -92,5 +92,5 @@
 
 
-void     MSIPciConfigWrite(PPDMDEVINS pDevIns, 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;
@@ -113,5 +113,5 @@
                 /* don't change read-only bits: 1-3,7 */
                 val &= UINT32_C(~0x8e);
-                pDev->config[uAddr] &= ~val;
+                pDev->config[uAddr] = val;
                 break;
             case VBOX_MSI_CAP_MESSAGE_CONTROL + 1:
@@ -149,5 +149,5 @@
                                 /* To ensure that we're no longer masked */
                                 pDev->config[uAddr] &= ~iBit;
-                                MSINotify(pDevIns, pDev, maskUpdated*8 + iBitNum);
+                                MsiNotify(pDevIns, pPciHlp, pDev, maskUpdated*8 + iBitNum);
                             }
                         }
@@ -162,5 +162,5 @@
 }
 
-uint32_t MSIPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len)
+uint32_t MsiPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len)
 {
     int32_t iOff = u32Address - pDev->Int.s.u8MsiCapOffset;
@@ -172,8 +172,8 @@
     {
         case 1:
-            rv = PCIDevGetByte(pDev, u32Address);
+            rv = PCIDevGetByte(pDev,  u32Address);
             break;
         case 2:
-            rv = PCIDevGetWord(pDev, u32Address);
+            rv = PCIDevGetWord(pDev,  u32Address);
             break;
         case 4:
@@ -190,5 +190,5 @@
 
 
-int MSIInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg)
+int MsiInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg)
 {
     uint16_t   cVectors    = pMsiReg->cVectors;
@@ -225,10 +225,10 @@
 
 
-bool     MSIIsEnabled(PPCIDEVICE pDev)
+bool     MsiIsEnabled(PPCIDEVICE pDev)
 {
     return PCIIsMsiCapable(pDev) && msiIsEnabled(pDev);
 }
 
-void MSINotify(PPDMDEVINS pDevIns, PPCIDEVICE pDev, int iVector)
+void MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector)
 {
     Log2(("MSINotify: %d\n", iVector));
@@ -250,4 +250,5 @@
     *upPending &= ~(1<<iVector);
 
-    PDMDevHlpPhysWrite(pDevIns, GCAddr, &u32Value, sizeof(u32Value));
-}
+    Assert(pPciHlp->pfnIoApicSendMsi != NULL);
+    pPciHlp->pfnIoApicSendMsi(pDevIns, GCAddr, u32Value);
+}
Index: trunk/src/VBox/Devices/Bus/MsiCommon.h
===================================================================
--- trunk/src/VBox/Devices/Bus/MsiCommon.h	(revision 32933)
+++ trunk/src/VBox/Devices/Bus/MsiCommon.h	(revision 32935)
@@ -15,13 +15,27 @@
  */
 
+/* Maybe belongs to types.h */
+#ifdef IN_RING3
+typedef PCPDMPCIHLPR3 PCPDMPCIHLP;
+#endif
+
+#ifdef IN_RING0
+typedef PCPDMPCIHLPR0 PCPDMPCIHLP;
+#endif
+
+#ifdef IN_RC
+typedef PCPDMPCIHLPRC PCPDMPCIHLP;
+#endif
+
 /* Init MSI support in the device. */
-int      MSIInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg);
+int      MsiInit(PPCIDEVICE pDev, PPDMMSIREG pMsiReg);
 
 /* If MSI is enabled, so that MSINotify() shall be used for notifications.  */
-bool     MSIIsEnabled(PPCIDEVICE pDev);
+bool     MsiIsEnabled(PPCIDEVICE pDev);
+
 /* Device notification (aka interrupt). */
-void     MSINotify(PPDMDEVINS pDevIns, PPCIDEVICE pDev, int iVector);
+void     MsiNotify(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, int iVector);
 
 /* PCI config space accessors for MSI registers */
-void     MSIPciConfigWrite(PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len);
-uint32_t MSIPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len);
+void     MsiPciConfigWrite(PPDMDEVINS pDevIns, PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len);
+uint32_t MsiPciConfigRead (PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, unsigned len);
Index: trunk/src/VBox/Devices/PC/DevAPIC.cpp
===================================================================
--- trunk/src/VBox/Devices/PC/DevAPIC.cpp	(revision 32933)
+++ trunk/src/VBox/Devices/PC/DevAPIC.cpp	(revision 32935)
@@ -356,4 +356,5 @@
 PDMBOTHCBDECL(int)  ioapicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
 PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
+PDMBOTHCBDECL(void) ioapicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue);
 
 static void apic_update_tpr(APICDeviceInfo *dev, APICState* s, uint32_t val);
@@ -1531,27 +1532,4 @@
     return val;
 }
-/**
- * See chapter 10.11 MESSAGE SIGNALLED INTERRUPTS of IA-32 Intel Architecture
- * Software Developer's Manual, Volume 3A: System Programming Guide, Part 1
- * for details on MSI and LAPIC interaction.
- */
-static int apicSendMsi(APICDeviceInfo* dev, RTGCPHYS addr, uint32_t val)
-{
-    uint8_t  dest = (addr & VBOX_MSI_ADDR_DEST_ID_MASK) >> VBOX_MSI_ADDR_DEST_ID_SHIFT;
-    uint8_t  vector_num = (val & VBOX_MSI_DATA_VECTOR_MASK) >> VBOX_MSI_DATA_VECTOR_SHIFT;
-    uint8_t  dest_mode = (addr >> VBOX_MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
-    uint8_t  trigger_mode = (val >> VBOX_MSI_DATA_TRIGGER_SHIFT) & 0x1;
-    uint8_t  delivery_mode = (val >> VBOX_MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
-    /**
-     * This bit indicates whether the message should be directed to the
-     * processor with the lowest interrupt priority among
-     * processors that can receive the interrupt, ignored ATM.
-     */
-    uint8_t  redir_hint = (addr >> VBOX_MSI_ADDR_REDIRECTION_SHIFT) & 0x1;
-    uint32_t deliver_bitmask = apic_get_delivery_bitmask(dev, dest, dest_mode);
-
-    return apic_bus_deliver(dev, deliver_bitmask, delivery_mode,
-                            vector_num, 0 /* polarity */, trigger_mode);
-}
 
 static int apic_mem_writel(APICDeviceInfo* dev, APICState *s, RTGCPHYS addr, uint32_t val)
@@ -1564,9 +1542,5 @@
 #endif
 
-    index = (addr >> 4) & 0xff;
-    addr -= (s->apicbase & ~0xfff);
-
-    if (addr > 0xfff || (index == 0))
-        return apicSendMsi(dev, addr, val);
+    index = (addr >> 4) & 0xff;  
 
     switch(index) {
@@ -2503,6 +2477,5 @@
      */
     uint32_t ApicBase = pThis->paLapicsR3[0].apicbase & ~0xfff;
-    /* See comment in msi.h, on why LAPIC and MSI share same region */
-    rc = PDMDevHlpMMIORegister(pDevIns, ApicBase, VBOX_MSI_ADDR_SIZE, pThis,
+    rc = PDMDevHlpMMIORegister(pDevIns, ApicBase, 0x1000, pThis,
                                apicMMIOWrite, apicMMIORead, NULL, "APIC Memory");
     if (RT_FAILURE(rc))
@@ -2513,5 +2486,5 @@
         pThis->pCritSectRC = pThis->pApicHlpR3->pfnGetRCCritSect(pDevIns);
 
-        rc = PDMDevHlpMMIORegisterRC(pDevIns, ApicBase, VBOX_MSI_ADDR_SIZE, 0,
+        rc = PDMDevHlpMMIORegisterRC(pDevIns, ApicBase, 0x1000, 0,
                                      "apicMMIOWrite", "apicMMIORead", NULL);
         if (RT_FAILURE(rc))
@@ -2523,5 +2496,5 @@
         pThis->pCritSectR0 = pThis->pApicHlpR3->pfnGetR0CritSect(pDevIns);
 
-        rc = PDMDevHlpMMIORegisterR0(pDevIns, ApicBase, VBOX_MSI_ADDR_SIZE, 0,
+        rc = PDMDevHlpMMIORegisterR0(pDevIns, ApicBase, 0x1000, 0,
                                      "apicMMIOWrite", "apicMMIORead", NULL);
         if (RT_FAILURE(rc))
@@ -2704,4 +2677,33 @@
 }
 
+PDMBOTHCBDECL(void) ioapicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue)
+{
+    IOAPICState *pThis = PDMINS_2_DATA(pDevIns, IOAPICState *);
+
+    LogFlow(("ioapicSendMsi: Address=%p uValue=%\n", GCAddr, uValue));
+
+    uint8_t  dest = (GCAddr & VBOX_MSI_ADDR_DEST_ID_MASK) >> VBOX_MSI_ADDR_DEST_ID_SHIFT;
+    uint8_t  vector_num = (uValue & VBOX_MSI_DATA_VECTOR_MASK) >> VBOX_MSI_DATA_VECTOR_SHIFT;
+    uint8_t  dest_mode = (GCAddr >> VBOX_MSI_ADDR_DEST_MODE_SHIFT) & 0x1;
+    uint8_t  trigger_mode = (uValue >> VBOX_MSI_DATA_TRIGGER_SHIFT) & 0x1;
+    uint8_t  delivery_mode = (uValue >> VBOX_MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
+    /**
+     * This bit indicates whether the message should be directed to the
+     * processor with the lowest interrupt priority among
+     * processors that can receive the interrupt, ignored ATM.
+     */
+    uint8_t  redir_hint = (GCAddr >> VBOX_MSI_ADDR_REDIRECTION_SHIFT) & 0x1;
+
+    int rc = pThis->CTX_SUFF(pIoApicHlp)->pfnApicBusDeliver(pDevIns,
+                                                            dest,
+                                                            dest_mode,
+                                                            delivery_mode,
+                                                            vector_num,
+                                                            0 /* polarity, n/a */,
+                                                            trigger_mode);
+    /* We must be sure that attempts to reschedule in R3
+       never get here */
+    Assert(rc == VINF_SUCCESS);
+}
 
 #ifdef IN_RING3
@@ -2848,7 +2850,11 @@
      */
     IoApicReg.u32Version  = PDM_IOAPICREG_VERSION;
-    IoApicReg.pfnSetIrqR3 = ioapicSetIrq;
+    IoApicReg.pfnSetIrqR3 = ioapicSetIrq;    
     IoApicReg.pszSetIrqRC = fGCEnabled ? "ioapicSetIrq" : NULL;
     IoApicReg.pszSetIrqR0 = fR0Enabled ? "ioapicSetIrq" : NULL;
+    IoApicReg.pfnSendMsiR3 = ioapicSendMsi;
+    IoApicReg.pszSendMsiRC = fGCEnabled ? "ioapicSendMsi" : NULL;
+    IoApicReg.pszSendMsiR0 = fR0Enabled ? "ioapicSendMsi" : NULL;
+
     rc = PDMDevHlpIOAPICRegister(pDevIns, &IoApicReg, &s->pIoApicHlpR3);
     if (RT_FAILURE(rc))
Index: trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 32933)
+++ trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 32935)
@@ -48,4 +48,7 @@
 /** Maximum number of entries in the release log. */
 #define MAX_REL_LOG_ERRORS 1024
+
+/* If LSI shall emulate MSI support */
+#define LSILOGIC_WITH_MSI
 
 /**
@@ -4848,4 +4851,9 @@
     PCIDevSetInterruptPin(&pThis->PciDev,   0x01); /* Interrupt pin A */
 
+#ifdef LSILOGIC_WITH_MSI
+    PCIDevSetStatus(&pThis->PciDev,   VBOX_PCI_STATUS_CAP_LIST);
+    PCIDevSetCapabilityList(&pThis->PciDev, 0x80);
+#endif
+
     pThis->pDevInsR3 = pDevIns;
     pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
@@ -4860,4 +4868,16 @@
     if (RT_FAILURE(rc))
         return rc;
+
+#ifdef LSILOGIC_WITH_MSI
+    PDMMSIREG aMsiReg;
+    aMsiReg.cVectors = 1;
+    aMsiReg.iCapOffset = 0x80;
+    aMsiReg.iNextOffset = 0x0;
+    aMsiReg.iMsiFlags = 0;
+    rc = PDMDevHlpPCIRegisterMsi(pDevIns, &aMsiReg);
+    AssertRC(rc);
+    if (RT_FAILURE (rc))
+        return rc;
+#endif
 
     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, LSILOGIC_PCI_SPACE_IO_SIZE, PCI_ADDRESS_SPACE_IO, lsilogicMap);
@@ -5150,3 +5170,2 @@
 #endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
-
Index: trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
===================================================================
--- trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 32933)
+++ trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 32935)
@@ -3195,3 +3195,2 @@
 };
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
-
