Index: /trunk/include/VBox/msi.h
===================================================================
--- /trunk/include/VBox/msi.h	(revision 32859)
+++ /trunk/include/VBox/msi.h	(revision 32860)
@@ -96,7 +96,7 @@
 #define VBOX_MSI_CAP_PENDING_BITS_64          0x14
 
-/* At the moment, we implement MSI without per-vector masking */
-#define VBOX_MSI_CAP_SIZE_32                  0x0a
-#define VBOX_MSI_CAP_SIZE_64                  0x0c
+/* We implement MSI with per-vector masking */
+#define VBOX_MSI_CAP_SIZE_32                  0x14
+#define VBOX_MSI_CAP_SIZE_64                  0x18
 
 /**
Index: /trunk/src/VBox/Devices/Bus/DevPCI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 32859)
+++ /trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 32860)
@@ -1381,5 +1381,5 @@
         { 0x20, 2, 1, 2, "MEMORY_BASE" },       // fWritable = ??
         { 0x22, 2, 1, 2, "MEMORY_LIMIT" },      // fWritable = ??
-        { 0x24, 4, 1, 1, "BASE_ADDRESS_4" },
+        { 0x24, 4, 1, 1, "BASE_ADDRESS_5" },
         { 0x24, 2, 1, 2, "PREF_MEMORY_BASE" },  // fWritable = ??
         { 0x26, 2, 1, 2, "PREF_MEMORY_LIMIT" }, // fWritable = ??
Index: /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 32859)
+++ /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 32860)
@@ -134,5 +134,7 @@
  * Saved state version of the ICH9 PCI bus device.
  */
-#define VBOX_ICH9PCI_SAVED_STATE_VERSION 1
+#define VBOX_ICH9PCI_SAVED_STATE_VERSION_NOMSI 1
+#define VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI   2
+#define VBOX_ICH9PCI_SAVED_STATE_VERSION_CURRENT VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI
 
 /** Converts a bus instance pointer to a device instance pointer. */
@@ -180,5 +182,5 @@
 static int ich9pciRegisterInternal(PPCIBUS pBus, int iDev, PPCIDEVICE pPciDev, const char *pszName);
 static void ich9pciUpdateMappings(PCIDevice *pDev);
-static DECLCALLBACK(uint32_t) ich9pciConfigRead(PCIDevice *aDev, uint32_t u32Address, unsigned len);
+static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PCIDevice *aDev, uint32_t u32Address, unsigned len);
 DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PPCIBUS pBus, uint8_t iBus);
 static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint8_t cBridgeDepth, uint8_t *paBridgePositions);
@@ -409,5 +411,5 @@
             R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pPciAddr->iDeviceFunc];
             *pu32 = aDev->Int.s.pfnConfigRead(aDev, pPciAddr->iRegister, len);
-            Log(("ich9pciConfigRead: %s: addr=%02x val=%08x len=%d\n", aDev->name, pPciAddr->iRegister, *pu32, len));
+            Log(("ich9pciDataReadAddr: %s: addr=%02x val=%08x len=%d\n", aDev->name, pPciAddr->iRegister, *pu32, len));
 #else
             return VINF_IOM_HC_IOPORT_READ;
@@ -529,5 +531,7 @@
     {
         Log2(("Raise a MSI interrupt: %d\n", iIrq));
-        MSINotify(pGlobals->aPciBus.CTX_SUFF(pDevIns), pPciDev, 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);
         return;
     }
@@ -673,5 +677,5 @@
             {
                 /* IO access allowed */
-                uNew = ich9pciConfigRead(pDev, uConfigReg, 4);
+                uNew = ich9pciConfigReadDev(pDev, uConfigReg, 4);
                 uNew &= ~(iRegionSize - 1);
                 uLast = uNew + iRegionSize - 1;
@@ -687,5 +691,5 @@
             if (iCmd & PCI_COMMAND_MEMACCESS)
             {
-                uNew = ich9pciConfigRead(pDev, uConfigReg, 4);
+                uNew = ich9pciConfigReadDev(pDev, uConfigReg, 4);
                 /* the ROM slot has a specific enable bit */
                 if (iRegion == PCI_ROM_SLOT && !(uNew & 1))
@@ -885,8 +889,29 @@
             SSMR3PutMem(pSSM, pDev->config, sizeof(pDev->config));
 
-            /* IRQ pin state */
-            int rc = SSMR3PutS32(pSSM, pDev->Int.s.uIrqPinState);
+            /* Device flags */
+            int rc = SSMR3PutU32(pSSM, pDev->Int.s.uFlags);
             if (RT_FAILURE(rc))
                 return rc;
+
+            /* IRQ pin state */
+            rc = SSMR3PutS32(pSSM, pDev->Int.s.uIrqPinState);
+            if (RT_FAILURE(rc))
+                return rc;
+
+            /* MSI info */
+            rc = SSMR3PutU8(pSSM, pDev->Int.s.u8MsiCapOffset);
+            if (RT_FAILURE(rc))
+                return rc;
+            rc = SSMR3PutU8(pSSM, pDev->Int.s.u8MsiCapSize);
+            if (RT_FAILURE(rc))
+                return rc;
+
+            /* MSI-X info */
+            rc = SSMR3PutU8(pSSM, pDev->Int.s.u8MsixCapOffset);
+            if (RT_FAILURE(rc))
+                return rc;
+            rc = SSMR3PutU8(pSSM, pDev->Int.s.u8MsixCapSize);
+            if (RT_FAILURE(rc))
+                return rc;
         }
     }
@@ -896,6 +921,20 @@
 static DECLCALLBACK(int) ich9pciR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
 {
-    PPCIBUS pThis = PDMINS_2_DATA(pDevIns, PPCIBUS);
-    return ich9pciR3CommonSaveExec(pThis, pSSM);
+    PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
+
+    /*
+     * Bus state data.
+     */
+    SSMR3PutU32(pSSM, pThis->uConfigReg);
+
+    /*
+     * Save IRQ states.
+     */
+    for (int i = 0; i < PCI_APIC_IRQ_PINS; i++)
+        SSMR3PutU32(pSSM, pThis->uaPciApicIrqLevels[i]);
+
+    SSMR3PutU32(pSSM, ~0);        /* separator */
+
+    return ich9pciR3CommonSaveExec(&pThis->aPciBus, pSSM);
 }
 
@@ -997,5 +1036,5 @@
         { VBOX_PCI_CLASS_PROG, 1, 0, 3, "CLASS_PROG" },
         { VBOX_PCI_CLASS_SUB, 1, 0, 3, "CLASS_SUB" },
-        { VBOX_PCI_CLASS_DEVICE, 1, 0, 3, "CLASS_BASE" },
+        { VBOX_PCI_CLASS_BASE, 1, 0, 3, "CLASS_BASE" },
         { VBOX_PCI_CACHE_LINE_SIZE, 1, 1, 3, "CACHE_LINE_SIZE" },
         { VBOX_PCI_LATENCY_TIMER, 1, 1, 3, "LATENCY_TIMER" },
@@ -1016,5 +1055,5 @@
         { VBOX_PCI_MEMORY_BASE, 2, 1, 2, "MEMORY_BASE" },       // fWritable = ??
         { VBOX_PCI_MEMORY_LIMIT, 2, 1, 2, "MEMORY_LIMIT" },      // fWritable = ??
-        { VBOX_PCI_BASE_ADDRESS_4, 4, 1, 1, "BASE_ADDRESS_4" },
+        { VBOX_PCI_BASE_ADDRESS_5, 4, 1, 1, "BASE_ADDRESS_5" },
         { VBOX_PCI_PREF_MEMORY_BASE, 2, 1, 2, "PREF_MEMORY_BASE" },  // fWritable = ??
         { VBOX_PCI_PREF_MEMORY_LIMIT, 2, 1, 2, "PREF_MEMORY_LIMIT" }, // fWritable = ??
@@ -1034,5 +1073,5 @@
         { VBOX_PCI_MIN_GNT, 1, 0, 1, "MIN_GNT" },
         { VBOX_PCI_BRIDGE_CONTROL, 2, 1, 2, "BRIDGE_CONTROL" },    // fWritable = !?
-        { VBOX_PCI_MAX_LAT, 1, 0, 3, "MAX_LAT" },           // fBridge=!?
+        { VBOX_PCI_MAX_LAT, 1, 0, 1, "MAX_LAT" },
         /* The COMMAND register must come last as it requires the *ADDRESS*
            registers to be restored before we pretent to change it from 0 to
@@ -1206,8 +1245,33 @@
 
         /* get the data */
+        DevTmp.Int.s.uFlags = 0;
+        DevTmp.Int.s.u8MsiCapOffset = 0;
+        DevTmp.Int.s.u8MsiCapSize = 0;
+        DevTmp.Int.s.u8MsixCapOffset = 0;
+        DevTmp.Int.s.u8MsixCapSize = 0;
         DevTmp.Int.s.uIrqPinState = ~0; /* Invalid value in case we have an older saved state to force a state change in pciSetIrq. */
         SSMR3GetMem(pSSM, DevTmp.config, sizeof(DevTmp.config));
 
+        rc = SSMR3GetU32(pSSM, &DevTmp.Int.s.uFlags);
+        if (RT_FAILURE(rc))
+            return rc;
+
         rc = SSMR3GetS32(pSSM, &DevTmp.Int.s.uIrqPinState);
+        if (RT_FAILURE(rc))
+            return rc;
+
+        rc = SSMR3GetU8(pSSM, &DevTmp.Int.s.u8MsiCapOffset);
+        if (RT_FAILURE(rc))
+            return rc;
+
+        rc = SSMR3GetU8(pSSM, &DevTmp.Int.s.u8MsiCapSize);
+        if (RT_FAILURE(rc))
+            return rc;
+
+        rc = SSMR3GetU8(pSSM, &DevTmp.Int.s.u8MsixCapOffset);
+        if (RT_FAILURE(rc))
+            return rc;
+
+        rc = SSMR3GetU8(pSSM, &DevTmp.Int.s.u8MsixCapSize);
         if (RT_FAILURE(rc))
             return rc;
@@ -1255,14 +1319,40 @@
 static DECLCALLBACK(int) ich9pciR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
 {
+    PPCIGLOBALS pThis = PDMINS_2_DATA(pDevIns, PPCIGLOBALS);
+    PPCIBUS     pBus  = &pThis->aPciBus;
+    uint32_t    u32;
+    int         rc;
+
+    /* We ignore this version as there's no saved state with it anyway */
+    if (uVersion == VBOX_ICH9PCI_SAVED_STATE_VERSION_NOMSI)
+        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
+    if (uVersion > VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI)
+        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
+
+    /*
+     * Bus state data.
+     */
+    SSMR3GetU32(pSSM, &pThis->uConfigReg);
+
+    /*
+     * Load IRQ states.
+     */
+    for (int i = 0; i < PCI_APIC_IRQ_PINS; i++)
+        SSMR3GetU32(pSSM, (uint32_t*)&pThis->uaPciApicIrqLevels[i]);
+
+    /* separator */
+    rc = SSMR3GetU32(pSSM, &u32);
+    if (RT_FAILURE(rc))
+        return rc;
+    if (u32 != (uint32_t)~0)
+        AssertMsgFailedReturn(("u32=%#x\n", u32), rc);
+
+    return ich9pciR3CommonLoadExec(pBus, pSSM, uVersion, uPass);
+}
+
+static DECLCALLBACK(int) ich9pcibridgeR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
+{
     PPCIBUS pThis = PDMINS_2_DATA(pDevIns, PPCIBUS);
-    if (uVersion > VBOX_ICH9PCI_SAVED_STATE_VERSION)
-        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
-    return ich9pciR3CommonLoadExec(pThis, pSSM, uVersion, uPass);
-}
-
-static DECLCALLBACK(int) ich9pcibridgeR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
-{
-    PPCIBUS pThis = PDMINS_2_DATA(pDevIns, PPCIBUS);
-    if (uVersion > VBOX_ICH9PCI_SAVED_STATE_VERSION)
+    if (uVersion > VBOX_ICH9PCI_SAVED_STATE_VERSION_MSI)
         return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
     return ich9pciR3CommonLoadExec(pThis, pSSM, uVersion, uPass);
@@ -1584,5 +1674,5 @@
 }
 
-static DECLCALLBACK(uint32_t) ich9pciConfigRead(PCIDevice *aDev, uint32_t u32Address, unsigned len)
+static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PCIDevice *aDev, uint32_t u32Address, unsigned len)
 {
     if ((u32Address + len) > 256 && (u32Address + len) < 4096)
@@ -1596,5 +1686,5 @@
        )
     {
-        return MSIPciConfigRead(aDev, u32Address, len);
+        return MSIPciConfigRead(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, len);
     }
 
@@ -1618,6 +1708,6 @@
  * registers and their writability policy.
  */
-static DECLCALLBACK(void) ich9pciConfigWrite(PCIDevice *aDev, uint32_t u32Address,
-                                             uint32_t val, unsigned len)
+static DECLCALLBACK(void) ich9pciConfigWriteDev(PCIDevice *aDev, uint32_t u32Address,
+                                                uint32_t val, unsigned len)
 {
     if ((u32Address + len) > 256 && (u32Address + len) < 4096)
@@ -1633,5 +1723,5 @@
        )
     {
-        MSIPciConfigWrite(aDev, u32Address, val, len);
+        MSIPciConfigWrite(aDev->Int.s.CTX_SUFF(pBus)->CTX_SUFF(pDevIns), aDev, u32Address, val, len);
         return;
     }
@@ -1905,6 +1995,6 @@
     pPciDev->Int.s.pBusR0           = MMHyperR3ToR0(PDMDevHlpGetVM(pBus->CTX_SUFF(pDevIns)), pBus);
     pPciDev->Int.s.pBusRC           = MMHyperR3ToRC(PDMDevHlpGetVM(pBus->CTX_SUFF(pDevIns)), pBus);
-    pPciDev->Int.s.pfnConfigRead    = ich9pciConfigRead;
-    pPciDev->Int.s.pfnConfigWrite   = ich9pciConfigWrite;
+    pPciDev->Int.s.pfnConfigRead    = ich9pciConfigReadDev;
+    pPciDev->Int.s.pfnConfigWrite   = ich9pciConfigWriteDev;
     pBus->apDevices[iDev]           = pPciDev;
     if (PCIIsPci2PciBridge(pPciDev))
@@ -2145,4 +2235,12 @@
     }
 
+    rc = PDMDevHlpSSMRegisterEx(pDevIns, VBOX_ICH9PCI_SAVED_STATE_VERSION_CURRENT,
+                                sizeof(*pBus) + 16*128, "pgm",
+                                NULL, NULL, NULL,
+                                NULL, ich9pciR3SaveExec, NULL,
+                                NULL, ich9pciR3LoadExec, NULL);
+    if (RT_FAILURE(rc))
+        return rc;
+
 
     /** @todo: other chipset devices shall be registered too */
@@ -2286,5 +2384,7 @@
      * to make changes easier.
      */
-    rc = PDMDevHlpSSMRegisterEx(pDevIns, VBOX_ICH9PCI_SAVED_STATE_VERSION, sizeof(*pBus) + 16*128, "pgm",
+    rc = PDMDevHlpSSMRegisterEx(pDevIns, VBOX_ICH9PCI_SAVED_STATE_VERSION_CURRENT,
+                                sizeof(*pBus) + 16*128,
+                                "pgm" /* before */,
                                 NULL, NULL, NULL,
                                 NULL, ich9pcibridgeR3SaveExec, NULL,
Index: /trunk/src/VBox/Devices/Bus/MsiCommon.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/MsiCommon.cpp	(revision 32859)
+++ /trunk/src/VBox/Devices/Bus/MsiCommon.cpp	(revision 32860)
@@ -35,4 +35,18 @@
 }
 
+DECLINLINE(uint32_t*) msiGetMaskBits(PPCIDEVICE pDev)
+{
+    uint8_t iOff = msiIs64Bit(pDev) ? VBOX_MSI_CAP_MASK_BITS_64 : VBOX_MSI_CAP_MASK_BITS_32;
+    iOff += pDev->Int.s.u8MsiCapOffset;
+    return (uint32_t*)(pDev->config + iOff);
+}
+
+DECLINLINE(uint32_t*) msiGetPendingBits(PPCIDEVICE pDev)
+{
+    uint8_t iOff = msiIs64Bit(pDev) ? VBOX_MSI_CAP_PENDING_BITS_64 : VBOX_MSI_CAP_PENDING_BITS_32;
+    iOff += pDev->Int.s.u8MsiCapOffset;
+    return (uint32_t*)(pDev->config + iOff);
+}
+
 DECLINLINE(bool) msiIsEnabled(PPCIDEVICE pDev)
 {
@@ -70,5 +84,13 @@
 }
 
-void     MSIPciConfigWrite(PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len)
+DECLINLINE(bool) msiBitJustCleared(uint32_t u32OldValue,
+                                   uint32_t u32NewValue,
+                                   uint32_t u32Mask)
+{
+    return (!!(u32OldValue & u32Mask) && !(u32NewValue & u32Mask));
+}
+
+
+void     MSIPciConfigWrite(PPDMDEVINS pDevIns, PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len)
 {
     int32_t iOff = u32Address - pDev->Int.s.u8MsiCapOffset;
@@ -78,21 +100,60 @@
 
     uint32_t uAddr = u32Address;
+    bool f64Bit = msiIs64Bit(pDev);
+
     for (uint32_t i = 0; i < len; i++)
     {
-        switch (i + iOff)
+        uint32_t reg = i + iOff;
+        switch (reg)
         {
             case 0: /* Capability ID, ro */
             case 1: /* Next pointer,  ro */
                 break;
-            case 2:
+            case VBOX_MSI_CAP_MESSAGE_CONTROL:
                 /* don't change read-only bits: 1-3,7 */
                 val &= UINT32_C(~0x8e);
                 pDev->config[uAddr] &= ~val;
                 break;
-            case 3:
+            case VBOX_MSI_CAP_MESSAGE_CONTROL + 1:
                 /* don't change read-only bit 8, and reserved 9-15 */
                 break;
             default:
-                pDev->config[uAddr] = val;
+                if (pDev->config[uAddr] != val)
+                {
+                    int32_t maskUpdated = -1;
+
+                    /* If we're enabling masked vector, and have pending messages
+                       for this vector, we have to send this message now */
+                    if (    !f64Bit
+                         && (reg >= VBOX_MSI_CAP_MASK_BITS_32)
+                         && (reg < VBOX_MSI_CAP_MASK_BITS_32 + 4)
+                        )
+                    {
+                        maskUpdated = reg - VBOX_MSI_CAP_MASK_BITS_32;
+                    }
+                    if (    f64Bit
+                         && (reg >= VBOX_MSI_CAP_MASK_BITS_64)
+                         && (reg < VBOX_MSI_CAP_MASK_BITS_64 + 4)
+                       )
+                    {
+                        maskUpdated = reg - VBOX_MSI_CAP_MASK_BITS_64;
+                    }
+
+                    if (maskUpdated != -1)
+                    {
+                        for (int iBitNum = 0; i<8; i++)
+                        {
+                            int32_t iBit = 1 << iBitNum;
+                            if (msiBitJustCleared(pDev->config[uAddr], val, iBit))
+                            {
+                                /* To ensure that we're no longer masked */
+                                pDev->config[uAddr] &= ~iBit;
+                                MSINotify(pDevIns, pDev, maskUpdated*8 + iBitNum);
+                            }
+                        }
+                    }
+
+                    pDev->config[uAddr] = val;
+                }
         }
         uAddr++;
@@ -101,22 +162,29 @@
 }
 
-uint32_t MSIPciConfigRead (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;
 
-    Log2(("MSIPciConfigRead: %d (%d)\n", iOff, len));
-
     Assert(iOff >= 0 && (PCIIsMsiCapable(pDev) && iOff < pDev->Int.s.u8MsiCapSize));
+    uint32_t rv = 0;
 
     switch (len)
     {
         case 1:
-            return PCIDevGetByte(pDev, u32Address);
+            rv = PCIDevGetByte(pDev, u32Address);
+            break;
         case 2:
-            return PCIDevGetWord(pDev, u32Address);
+            rv = PCIDevGetWord(pDev, u32Address);
+            break;
+        case 4:
+            rv = PCIDevGetDWord(pDev, u32Address);
+            break;
         default:
-        case 4:
-            return PCIDevGetDWord(pDev, u32Address);
-    }
+            Assert(false);
+    }
+
+    Log2(("MSIPciConfigRead: %d (%d) -> %x\n", iOff, len, rv));
+
+    return rv;
 }
 
@@ -137,4 +205,6 @@
 
     bool f64bit = (iMsiFlags & VBOX_PCI_MSI_FLAGS_64BIT) != 0;
+    /* We always support per-vector masking */
+    iMsiFlags |= VBOX_PCI_MSI_FLAGS_MASKBIT;
 
     pDev->Int.s.u8MsiCapOffset = iCapOffset;
@@ -162,7 +232,18 @@
     AssertMsg(msiIsEnabled(pDev), ("Must be enabled to use that"));
 
+    uint32_t   uMask = *msiGetMaskBits(pDev);
+    uint32_t*  upPending = msiGetPendingBits(pDev);
+
+    if ((uMask & (1<<iVector)) != 0)
+    {
+        *upPending |= (1<<iVector);
+        return;
+    }
+
     RTGCPHYS   GCAddr = msiGetMsiAddress(pDev);
     uint32_t   u32Value = msiGetMsiData(pDev, iVector);
 
+    *upPending &= ~(1<<iVector);
+
     PDMDevHlpPhysWrite(pDevIns, GCAddr, &u32Value, sizeof(u32Value));
 }
Index: /trunk/src/VBox/Devices/Bus/MsiCommon.h
===================================================================
--- /trunk/src/VBox/Devices/Bus/MsiCommon.h	(revision 32859)
+++ /trunk/src/VBox/Devices/Bus/MsiCommon.h	(revision 32860)
@@ -24,4 +24,4 @@
 
 /* PCI config space accessors for MSI registers */
-void     MSIPciConfigWrite(PPCIDEVICE pDev, uint32_t u32Address, uint32_t val, unsigned len);
-uint32_t MSIPciConfigRead (PPCIDEVICE pDev, uint32_t u32Address, unsigned len);
+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);
