Index: /trunk/include/VBox/vmm/pdmcommon.h
===================================================================
--- /trunk/include/VBox/vmm/pdmcommon.h	(revision 64695)
+++ /trunk/include/VBox/vmm/pdmcommon.h	(revision 64696)
@@ -53,4 +53,19 @@
 #define PDM_VERSION_MAKE(uMagic, uMajor, uMinor) \
     ( ((uint32_t)(uMagic) << 16) | ((uint32_t)((uMajor) & 0xff) << 4) | ((uint32_t)((uMinor) & 0xf) << 0) )
+
+/**
+ * Version of PDM_VERSION_MAKE that's compatible with the preprocessor.
+ *
+ * @returns 32-bit structure version number.
+ *
+ * @param   uMagic      16-bit magic value, no suffix.  This must be unique.
+ * @param   uMajor      12-bit major version number, no suffix.  Structures with
+ *                      different major numbers are not compatible.
+ * @param   uMinor      4-bit minor version number, no suffix.  When only the
+ *                      minor version differs, the structures will be 100%
+ *                      backwards compatible.
+ */
+#define PDM_VERSION_MAKE_PP(uMagic, uMajor, uMinor) \
+    ( (UINT32_C(uMagic) << 16) | ((UINT32_C(uMajor) & UINT32_C(0xff)) << 4) | ((UINT32_C(uMinor) & UINT32_C(0xf)) << 0) )
 
 /** Checks if @a uVerMagic1 is compatible with @a uVerMagic2.
Index: /trunk/include/VBox/vmm/pdmdev.h
===================================================================
--- /trunk/include/VBox/vmm/pdmdev.h	(revision 64695)
+++ /trunk/include/VBox/vmm/pdmdev.h	(revision 64696)
@@ -1876,4 +1876,9 @@
 /** @}   */
 
+/** Current PDMDEVHLPR3 version number.
+ * @todo Next major revision should add piBus to pfnPCIBusRegister.  */
+#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 19, 1)
+//#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
+
 /**
  * PDM Device API.
@@ -2970,14 +2975,31 @@
     DECLR3CALLBACKMEMBER(int, pfnRTCRegister,(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp));
 
-    /**
-     * Register the PCI Bus.
-     *
-     * @returns VBox status code.
+#if PDM_DEVHLPR3_VERSION >= PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
+    /**
+     * Register a PCI Bus.
+     *
+     * @returns VBox status code, but the positive values 0..31 are used to indicate
+     *          bus number rather than informational status codes.
      * @param   pDevIns             The device instance.
      * @param   pPciBusReg          Pointer to PCI bus registration structure.
      * @param   ppPciHlpR3          Where to store the pointer to the PCI Bus
      *                              helpers.
+     * @param   piBus               Where to return the PDM bus number. Optional.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnPCIBusRegister,(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg,
+                                                 PCPDMPCIHLPR3 *ppPciHlpR3, uint32_t *piBus));
+#else
+    /**
+     * Register a PCI Bus.
+     *
+     * @returns VBox status code, but the positive values 0..31 are used to indicate
+     *          bus number rather than informational status codes.
+     * @param   pDevIns             The device instance.
+     * @param   pPciBusReg          Pointer to PCI bus registration structure.
+     * @param   ppPciHlpR3          Where to store the pointer to the PCI Bus
+     *                              helpers.
      */
     DECLR3CALLBACKMEMBER(int, pfnPCIBusRegister,(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3));
+#endif
 
     /**
@@ -3452,7 +3474,4 @@
 /** Pointer to the R3 PDM Device API, const variant. */
 typedef R3PTRTYPE(const struct PDMDEVHLPR3 *) PCPDMDEVHLPR3;
-
-/** Current PDMDEVHLPR3 version number. */
-#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE(0xffe7, 19, 0)
 
 
@@ -5010,8 +5029,15 @@
  * @copydoc PDMDEVHLPR3::pfnPCIBusRegister
  */
+#if PDM_DEVHLPR3_VERSION >= PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
+DECLINLINE(int) PDMDevHlpPCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3, uint32_t *piBus)
+{
+    return pDevIns->pHlpR3->pfnPCIBusRegister(pDevIns, pPciBusReg, ppPciHlpR3, piBus);
+}
+#else
 DECLINLINE(int) PDMDevHlpPCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)
 {
     return pDevIns->pHlpR3->pfnPCIBusRegister(pDevIns, pPciBusReg, ppPciHlpR3);
 }
+#endif
 
 /**
Index: /trunk/src/VBox/Devices/Bus/DevPCI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 64695)
+++ /trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 64696)
@@ -1269,8 +1269,14 @@
     PciBusReg.pszSetIrqRC             = fGCEnabled ? "pciSetIrq" : NULL;
     PciBusReg.pszSetIrqR0             = fR0Enabled ? "pciSetIrq" : NULL;
+#if PDM_DEVHLPR3_VERSION >= PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
+    rc = PDMDevHlpPCIBusRegister(pDevIns, &PciBusReg, &pBus->pPciHlpR3, &pBus->iBus);
+#else
     rc = PDMDevHlpPCIBusRegister(pDevIns, &PciBusReg, &pBus->pPciHlpR3);
+    pBus->iBus = rc;
+#endif
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Failed to register ourselves as a PCI Bus"));
+    Assert(pBus->iBus == 0);
     if (pBus->pPciHlpR3->u32Version != PDM_PCIHLPR3_VERSION)
         return PDMDevHlpVMSetError(pDevIns, VERR_VERSION_MISMATCH, RT_SRC_POS,
@@ -1606,8 +1612,14 @@
     PciBusReg.pszSetIrqRC             = fGCEnabled ? "pcibridgeSetIrq" : NULL;
     PciBusReg.pszSetIrqR0             = fR0Enabled ? "pcibridgeSetIrq" : NULL;
+#if PDM_DEVHLPR3_VERSION >= PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
+    rc = PDMDevHlpPCIBusRegister(pDevIns, &PciBusReg, &pBus->pPciHlpR3, &pBus->iBus);
+#else
     rc = PDMDevHlpPCIBusRegister(pDevIns, &PciBusReg, &pBus->pPciHlpR3);
+    pBus->iBus = rc;
+#endif
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Failed to register ourselves as a PCI Bus"));
+    Assert(pBus->iBus == (uint32_t)iInstance + 1); /* Can be removed when adding support for multiple bridge implementations. */
     if (pBus->pPciHlpR3->u32Version != PDM_PCIHLPR3_VERSION)
         return PDMDevHlpVMSetError(pDevIns, VERR_VERSION_MISMATCH, RT_SRC_POS,
@@ -1649,13 +1661,4 @@
 
     pBus->iDevSearch = 0;
-    /*
-     * The iBus property doesn't really represent the bus number
-     * because the guest and the BIOS can choose different bus numbers
-     * for them.
-     * The bus number is mainly for the setIrq function to indicate
-     * when the host bus is reached which will have iBus = 0.
-     * That's why the + 1.
-     */
-    pBus->iBus = iInstance + 1;
 
     /*
Index: /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 64695)
+++ /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 64696)
@@ -2462,8 +2462,14 @@
     PciBusReg.pszSetIrqRC             = fGCEnabled ? "ich9pciSetIrq" : NULL;
     PciBusReg.pszSetIrqR0             = fR0Enabled ? "ich9pciSetIrq" : NULL;
+#if PDM_DEVHLPR3_VERSION >= PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
+    rc = PDMDevHlpPCIBusRegister(pDevIns, &PciBusReg, &pBus->pPciHlpR3, &pBus->iBus);
+#else
     rc = PDMDevHlpPCIBusRegister(pDevIns, &PciBusReg, &pBus->pPciHlpR3);
+    pBus->iBus = rc;
+#endif
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Failed to register ourselves as a PCI Bus"));
+    Assert(pBus->iBus == 0);
     if (pBus->pPciHlpR3->u32Version != PDM_PCIHLPR3_VERSION)
         return PDMDevHlpVMSetError(pDevIns, VERR_VERSION_MISMATCH, RT_SRC_POS,
@@ -2734,8 +2740,14 @@
     PciBusReg.pszSetIrqRC             = fGCEnabled ? "ich9pcibridgeSetIrq" : NULL;
     PciBusReg.pszSetIrqR0             = fR0Enabled ? "ich9pcibridgeSetIrq" : NULL;
+#if PDM_DEVHLPR3_VERSION >= PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
+    rc = PDMDevHlpPCIBusRegister(pDevIns, &PciBusReg, &pBus->pPciHlpR3, &pBus->iBus);
+#else
     rc = PDMDevHlpPCIBusRegister(pDevIns, &PciBusReg, &pBus->pPciHlpR3);
+    pBus->iBus = rc;
+#endif
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Failed to register ourselves as a PCI Bus"));
+    Assert(pBus->iBus == (uint32_t)iInstance + 1); /* Can be removed when adding support for multiple bridge implementations. */
     if (pBus->pPciHlpR3->u32Version != PDM_PCIHLPR3_VERSION)
         return PDMDevHlpVMSetError(pDevIns, VERR_VERSION_MISMATCH, RT_SRC_POS,
@@ -2745,4 +2757,5 @@
     pBus->pPciHlpRC = pBus->pPciHlpR3->pfnGetRCHelpers(pDevIns);
     pBus->pPciHlpR0 = pBus->pPciHlpR3->pfnGetR0Helpers(pDevIns);
+
 
     /* Disable default device locking. */
@@ -2779,14 +2792,4 @@
     pBus->PciDev.Int.s.pfnBridgeConfigRead  = ich9pcibridgeConfigRead;
     pBus->PciDev.Int.s.pfnBridgeConfigWrite = ich9pcibridgeConfigWrite;
-
-    /*
-     * The iBus property doesn't really represent the bus number
-     * because the guest and the BIOS can choose different bus numbers
-     * for them.
-     * The bus number is mainly for the setIrq function to indicate
-     * when the host bus is reached which will have iBus = 0.
-     * That's why the + 1.
-     */
-    pBus->iBus = iInstance + 1;
 
     /*
Index: /trunk/src/VBox/Devices/Bus/DevPciInternal.h
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPciInternal.h	(revision 64695)
+++ /trunk/src/VBox/Devices/Bus/DevPciInternal.h	(revision 64696)
@@ -31,5 +31,5 @@
 {
     /** Bus number. */
-    int32_t                 iBus;
+    uint32_t                iBus;
     /** Number of bridges attached to the bus. */
     uint32_t                cBridges;
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 64695)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 64696)
@@ -570,5 +570,5 @@
                                                                                  pfLockTaken));
         rc = PGM_BTH_NAME(SyncPage)(pVCpu, PdeSrcDummy, pvFault, 1, uErr);
-#endif
+#   endif
         AssertRC(rc);
         PGM_INVL_PG(pVCpu, pvFault);
@@ -634,6 +634,8 @@
             return VINF_SUCCESS;
         }
-        //AssertMsg(GstWalk.Pde.u == GstWalk.pPde->u || GstWalk.pPte->u == GstWalk.pPde->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pde.u, (uint64_t)GstWalk.pPde->u)); - triggers with smp w7 guests.
-        //AssertMsg(GstWalk.Core.fBigPage || GstWalk.Pte.u == GstWalk.pPte->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pte.u, (uint64_t)GstWalk.pPte->u)); - ditto.
+#ifdef DEBUG_bird
+        AssertMsg(GstWalk.Pde.u == GstWalk.pPde->u || GstWalk.pPte->u == GstWalk.pPde->u || pVM->cCpus > 1, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pde.u, (uint64_t)GstWalk.pPde->u)); // - triggers with smp w7 guests.
+        AssertMsg(GstWalk.Core.fBigPage || GstWalk.Pte.u == GstWalk.pPte->u || pVM->cCpus > 1, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pte.u, (uint64_t)GstWalk.pPte->u)); // - ditto.
+#endif
     }
 
@@ -676,5 +678,5 @@
     }
 
-#  if   PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) && !defined(PGM_WITHOUT_MAPPINGS)
+#  if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) && !defined(PGM_WITHOUT_MAPPINGS)
     /*
      * Check if this address is within any of our mappings.
@@ -1132,4 +1134,5 @@
                 rc2 = PGMShwGetPage(pVCpu, pvFault, &fPageShw, NULL);
 
+#if 0
                 /*
                  * Compare page flags.
@@ -1145,4 +1148,18 @@
                           ("Page flags mismatch! pvFault=%RGv uErr=%x GCPhys=%RGp fPageShw=%RX64 fPageGst=%RX64 rc=%d\n",
                            pvFault, (uint32_t)uErr, GCPhys, fPageShw, fPageGst, rc));
+01:01:15.623511 00:08:43.266063 Expression: (fPageShw & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK)) == (fPageGst & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK)) || ( pVCpu->pgm.s.cNetwareWp0Hacks > 0 && (fPageShw & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK | X86_PTE_RW | X86_PTE_US)) == (fPageGst & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK | X86_PTE_RW | X86_PTE_US)) && (fPageShw & (X86_PTE_RW | X86_PTE_US)) == X86_PTE_RW && (fPageGst & (X86_PTE_RW | X86_PTE_US)) == X86_PTE_US)
+01:01:15.623511 00:08:43.266064 Location  : e:\vbox\svn\trunk\srcPage flags mismatch! pvFault=fffff801b0d7b000 uErr=11 GCPhys=0000000019b52000 fPageShw=0 fPageGst=77b0000000000121 rc=0
+
+01:01:15.625516 00:08:43.268051 Expression: (fPageShw & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK)) == (fPageGst & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK)) || ( pVCpu->pgm.s.cNetwareWp0Hacks > 0 && (fPageShw & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK | X86_PTE_RW | X86_PTE_US)) == (fPageGst & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK | X86_PTE_RW | X86_PTE_US)) && (fPageShw & (X86_PTE_RW | X86_PTE_US)) == X86_PTE_RW && (fPageGst & (X86_PTE_RW | X86_PTE_US)) == X86_PTE_US)
+01:01:15.625516 00:08:43.268051 Location  :
+e:\vbox\svn\trunk\srcPage flags mismatch!
+pvFault=fffff801b0d7b000
+                uErr=11     X86_TRAP_PF_ID | X86_TRAP_PF_P
+GCPhys=0000000019b52000
+fPageShw=0
+fPageGst=77b0000000000121
+rc=0
+#endif
+
             }
             else
Index: /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp	(revision 64695)
+++ /trunk/src/VBox/VMM/VMMR3/IEMR3.cpp	(revision 64696)
@@ -125,7 +125,7 @@
 # define IEM_DO_INSTR_STAT(a_Name, a_szDesc) \
             STAMR3RegisterF(pVM, &pVCpu->iem.s.pStatsCCR3->a_Name, STAMTYPE_U32_RESET, STAMVISIBILITY_USED, \
-                            STAMUNIT_COUNT, a_szDesc, "/IEM/CPU%u/r0-rc-Instr/" #a_Name, idCpu); \
+                            STAMUNIT_COUNT, a_szDesc, "/IEM/CPU%u/instr-RZ/" #a_Name, idCpu); \
             STAMR3RegisterF(pVM, &pVCpu->iem.s.pStatsR3->a_Name, STAMTYPE_U32_RESET, STAMVISIBILITY_USED, \
-                            STAMUNIT_COUNT, a_szDesc, "/IEM/CPU%u/r3-Instr/" #a_Name, idCpu);
+                            STAMUNIT_COUNT, a_szDesc, "/IEM/CPU%u/instr-R3/" #a_Name, idCpu);
 # include "IEMInstructionStatisticsTmpl.h"
 # undef IEM_DO_INSTR_STAT
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 64695)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 64696)
@@ -2576,9 +2576,22 @@
 
 /** @interface_method_impl{PDMDEVHLPR3,pfnPCIBusRegister} */
+#if PDM_DEVHLPR3_VERSION >= PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
+static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg,
+                                                    PCPDMPCIHLPR3 *ppPciHlpR3, uint32_t *piBus)
+#else
 static DECLCALLBACK(int) pdmR3DevHlp_PCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMR3;
-    VM_ASSERT_EMT(pVM);
+#endif
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMR3;
+    VM_ASSERT_EMT(pVM);
+#if PDM_DEVHLPR3_VERSION >= PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
+    LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: pPciBusReg=%p:{.u32Version=%#x, .pfnRegisterR3=%p, .pfnIORegionRegisterR3=%p, "
+             ".pfnSetIrqR3=%p, .pfnFakePCIBIOSR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppPciHlpR3=%p piBus=%p\n",
+             pDevIns->pReg->szName, pDevIns->iInstance, pPciBusReg, pPciBusReg->u32Version, pPciBusReg->pfnRegisterR3,
+             pPciBusReg->pfnIORegionRegisterR3, pPciBusReg->pfnSetIrqR3, pPciBusReg->pfnFakePCIBIOSR3,
+             pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqR0, pPciBusReg->pszSetIrqR0,
+             ppPciHlpR3, piBus));
+#else
     LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: pPciBusReg=%p:{.u32Version=%#x, .pfnRegisterR3=%p, .pfnIORegionRegisterR3=%p, "
              ".pfnSetIrqR3=%p, .pfnFakePCIBIOSR3=%p, .pszSetIrqRC=%p:{%s}, .pszSetIrqR0=%p:{%s}} ppPciHlpR3=%p\n",
@@ -2586,4 +2599,5 @@
              pPciBusReg->pfnIORegionRegisterR3, pPciBusReg->pfnSetIrqR3, pPciBusReg->pfnFakePCIBIOSR3,
              pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqRC, pPciBusReg->pszSetIrqR0, pPciBusReg->pszSetIrqR0, ppPciHlpR3));
+#endif
 
     /*
@@ -2622,5 +2636,5 @@
         return VERR_INVALID_PARAMETER;
     }
-     if (!ppPciHlpR3)
+    if (!ppPciHlpR3)
     {
         Assert(ppPciHlpR3);
@@ -2628,4 +2642,9 @@
         return VERR_INVALID_PARAMETER;
     }
+#if PDM_DEVHLPR3_VERSION >= PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
+    AssertLogRelMsgReturn(RT_VALID_PTR(piBus) || !piBus,
+                          ("caller='%s'/%d: piBus=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, piBus),
+                          VERR_INVALID_POINTER);
+#endif
 
     /*
@@ -2700,6 +2719,13 @@
     /* set the helper pointer and return. */
     *ppPciHlpR3 = &g_pdmR3DevPciHlp;
-    LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
+#if PDM_DEVHLPR3_VERSION >= PDM_VERSION_MAKE_PP(0xffe7, 20, 0)
+    if (piBus)
+        *piBus = iBus;
+    LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %Rrc *piBus=%u\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS, iBus));
     return VINF_SUCCESS;
+#else
+    LogFlow(("pdmR3DevHlp_PCIBusRegister: caller='%s'/%d: returns %u\n", pDevIns->pReg->szName, pDevIns->iInstance, iBus));
+    return (int)iBus;
+#endif
 }
 
