Index: /trunk/include/VBox/vmm/pdmdev.h
===================================================================
--- /trunk/include/VBox/vmm/pdmdev.h	(revision 77298)
+++ /trunk/include/VBox/vmm/pdmdev.h	(revision 77299)
@@ -1890,5 +1890,5 @@
 
 /** Current PDMDEVHLPR3 version number. */
-#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 22, 1)
+#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 22, 2)
 
 /**
@@ -3380,4 +3380,22 @@
     DECLR3CALLBACKMEMBER(void, pfnPhysBulkReleasePageMappingLocks,(PPDMDEVINS pDevIns, uint32_t cPages, PPGMPAGEMAPLOCK paLocks));
 
+    /**
+     * Changes the number of an MMIO2 or pre-registered MMIO region.
+     *
+     * This should only be used to deal with saved state problems, so there is no
+     * convenience inline wrapper for this method.
+     *
+     * @returns VBox status code.
+     * @param   pDevIns             The device instance.
+     * @param   pPciDev             The PCI device the region is associated with, or
+     *                              NULL if not associated with any.
+     * @param   iRegion             The region.
+     * @param   iNewRegion          The new region index.
+     *
+     * @sa      @bugref{9359}
+     */
+    DECLR3CALLBACKMEMBER(int, pfnMMIOExChangeRegionNo,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
+                                                       uint32_t iNewRegion));
+
     /** Space reserved for future members.
      * @{ */
@@ -3388,5 +3406,5 @@
     DECLR3CALLBACKMEMBER(void, pfnReserved5,(void));
     DECLR3CALLBACKMEMBER(void, pfnReserved6,(void));
-    DECLR3CALLBACKMEMBER(void, pfnReserved7,(void));
+    /*DECLR3CALLBACKMEMBER(void, pfnReserved7,(void)); */
     /*DECLR3CALLBACKMEMBER(void, pfnReserved8,(void)); */
     /*DECLR3CALLBACKMEMBER(void, pfnReserved9,(void)); */
Index: /trunk/include/VBox/vmm/pdmpcidev.h
===================================================================
--- /trunk/include/VBox/vmm/pdmpcidev.h	(revision 77298)
+++ /trunk/include/VBox/vmm/pdmpcidev.h	(revision 77299)
@@ -122,4 +122,17 @@
 typedef FNPCIIOREGIONOLDSETTER *PFNPCIIOREGIONOLDSETTER;
 
+/**
+ * Swaps two PCI I/O regions from within a PDMPCIDEV::pfnRegionLoadChangeHookR3
+ * callback.
+ *
+ * @returns VBox status code.
+ * @param   pPciDev         Pointer to the PCI device.
+ * @param   iRegion         The region number.
+ * @param   iOtherRegion    The number of the region swap with.
+ * @sa      @bugref{9359}
+ */
+typedef DECLCALLBACK(int) FNPCIIOREGIONSWAP(PPDMPCIDEV pPciDev, uint32_t iRegion, uint32_t iOtherRegion);
+/** Pointer to a FNPCIIOREGIONSWAP() function. */
+typedef FNPCIIOREGIONSWAP *PFNPCIIOREGIONSWAP;
 
 
@@ -188,8 +201,12 @@
      * @param   pfnOldSetter    Callback for setting size and type for call
      *                          regarding old saved states.  NULL otherwise.
+     * @param   pfnSwapRegions  Used to swaps two regions. The second one must be a
+     *                          higher number than @a iRegion.  NULL if old saved
+     *                          state.
      */
     DECLR3CALLBACKMEMBER(int, pfnRegionLoadChangeHookR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
                                                          uint64_t cbRegion, PCIADDRESSSPACE enmType,
-                                                         PFNPCIIOREGIONOLDSETTER pfnOldSetter));
+                                                         PFNPCIIOREGIONOLDSETTER pfnOldSetter,
+                                                         PFNPCIIOREGIONSWAP pfnSwapRegion));
 } PDMPCIDEV;
 #ifdef PDMPCIDEVINT_DECLARED
Index: /trunk/include/VBox/vmm/pgm.h
===================================================================
--- /trunk/include/VBox/vmm/pgm.h	(revision 77298)
+++ /trunk/include/VBox/vmm/pgm.h	(revision 77299)
@@ -842,4 +842,6 @@
 VMMR3_INT_DECL(int) PGMR3PhysMMIO2GetHCPhys(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS off, PRTHCPHYS pHCPhys);
 VMMR3_INT_DECL(int) PGMR3PhysMMIO2MapKernel(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTR0PTR pR0Ptr);
+VMMR3_INT_DECL(int) PGMR3PhysMMIOExChangeRegionNo(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, uint32_t iNewRegion);
+
 
 /** @name PGMR3PhysRegisterRom flags.
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 77298)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 77299)
@@ -5555,14 +5555,47 @@
 static DECLCALLBACK(int) vgaR3PciRegionLoadChangeHook(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
                                                       uint64_t cbRegion, PCIADDRESSSPACE enmType,
-                                                      PFNPCIIOREGIONOLDSETTER pfnOldSetter)
+                                                      PFNPCIIOREGIONOLDSETTER pfnOldSetter, PFNPCIIOREGIONSWAP pfnSwapRegions)
 {
     PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
 
 # ifdef VBOX_WITH_VMSVGA
-    /*
-     * The VMSVGA changed the default FIFO size from 128KB to 2MB after 5.1.
-     */
     if (pThis->fVMSVGAEnabled)
     {
+        /*
+         * We messed up BAR order for the hybrid devices in 6.0 (see #9359).
+         * It should have been compatible with the VBox VGA device and had the
+         * VRAM region first and I/O second, but instead the I/O region ended
+         * up first and VRAM second like the VMSVGA device.
+         *
+         * So, we have to detect that here and reconfigure the memory regions.
+         * Region numbers are used in our (and the PCI bus') interfaction with
+         * PGM, so PGM needs to be informed too.
+         */
+        if (   iRegion == 0
+            && iRegion == pThis->pciRegions.iVRAM
+            && (enmType & PCI_ADDRESS_SPACE_IO))
+        {
+            LogRel(("VGA: Detected old BAR config, making adjustments.\n"));
+
+            /* Update the entries. */
+            pThis->pciRegions.iIO   = 0;
+            pThis->pciRegions.iVRAM = 1;
+
+            /* Update PGM on the region number change so it won't barf when restoring state. */
+            AssertLogRelReturn(pDevIns->CTX_SUFF(pHlp)->pfnMMIOExChangeRegionNo, VERR_VERSION_MISMATCH);
+            int rc = pDevIns->CTX_SUFF(pHlp)->pfnMMIOExChangeRegionNo(pDevIns, pPciDev, 0, 1);
+            AssertLogRelRCReturn(rc, rc);
+
+            /* Update the calling PCI device. */
+            AssertLogRelReturn(pfnSwapRegions, VERR_INTERNAL_ERROR_2);
+            rc = pfnSwapRegions(pPciDev, 0, 1);
+            AssertLogRelRCReturn(rc, rc);
+
+            return rc;
+        }
+
+        /*
+         * The VMSVGA changed the default FIFO size from 128KB to 2MB after 5.1.
+         */
         if (iRegion == pThis->pciRegions.iFIFO)
         {
@@ -5591,8 +5624,10 @@
 
         }
+
         /* Emulate callbacks for 5.1 and older saved states by recursion. */
-        else if (iRegion == UINT32_MAX)
+        if (iRegion == UINT32_MAX)
         {
-            int rc = vgaR3PciRegionLoadChangeHook(pDevIns, pPciDev, pThis->pciRegions.iFIFO, VMSVGA_FIFO_SIZE_OLD, PCI_ADDRESS_SPACE_MEM, NULL);
+            int rc = vgaR3PciRegionLoadChangeHook(pDevIns, pPciDev, pThis->pciRegions.iFIFO, VMSVGA_FIFO_SIZE_OLD,
+                                                  PCI_ADDRESS_SPACE_MEM, NULL, NULL);
             if (RT_SUCCESS(rc))
                 rc = pfnOldSetter(pPciDev, pThis->pciRegions.iFIFO, VMSVGA_FIFO_SIZE_OLD, PCI_ADDRESS_SPACE_MEM);
@@ -6259,5 +6294,5 @@
     Log(("VMSVGA: VMSVGAPciId   = %d\n", pThis->fVMSVGAPciId));
 
-    rc = CFGMR3QueryBoolDef(pCfg, "VMSVGAPciBarLayout", &pThis->fVMSVGAPciBarLayout, false);
+    rc = CFGMR3QueryBoolDef(pCfg, "VMSVGAPciBarLayout", &pThis->fVMSVGAPciBarLayout, pThis->fVMSVGAPciId);
     AssertLogRelRCReturn(rc, rc);
     Log(("VMSVGA: VMSVGAPciBarLayout = %d\n", pThis->fVMSVGAPciBarLayout));
@@ -6282,5 +6317,4 @@
         pThis->pciRegions.iIO   = 0;
         pThis->pciRegions.iVRAM = 1;
-        pThis->pciRegions.iFIFO = 2;
     }
     else
@@ -6288,6 +6322,6 @@
         pThis->pciRegions.iVRAM = 0;
         pThis->pciRegions.iIO   = 1;
-        pThis->pciRegions.iFIFO = 2;
-    }
+    }
+    pThis->pciRegions.iFIFO = 2;
 #else
     pThis->pciRegions.iVRAM = 0;
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 77298)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 77299)
@@ -663,4 +663,24 @@
 
     LogFlow(("pdmR3DevHlp_MMIO2MapKernel: caller='%s'/%d: returns %Rrc *pR0Ptr=%RHv\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *pR0Ptr));
+    return rc;
+}
+
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMIOExChangeRegionNo
+ */
+static DECLCALLBACK(int) pdmR3DevHlp_MMIOExChangeRegionNo(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
+                                                          uint32_t iNewRegion)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMR3;
+    VM_ASSERT_EMT(pVM);
+    LogFlow(("pdmR3DevHlp_MMIOExChangeRegionNo: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x iNewRegion=%#x\n",
+             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iRegion, iNewRegion));
+    AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
+
+    int rc = PGMR3PhysMMIOExChangeRegionNo(pVM, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, iNewRegion);
+
+    LogFlow(("pdmR3DevHlp_MMIOExChangeRegionNo: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     return rc;
 }
@@ -3798,5 +3818,5 @@
     pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
     pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
-    0,
+    pdmR3DevHlp_MMIOExChangeRegionNo,
     0,
     0,
@@ -4068,5 +4088,5 @@
     pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
     pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
-    0,
+    pdmR3DevHlp_MMIOExChangeRegionNo,
     0,
     0,
Index: /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp	(revision 77298)
+++ /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp	(revision 77299)
@@ -4169,4 +4169,46 @@
 
     return rc;
+}
+
+
+/**
+ * Changes the region number of an MMIO2 or pre-registered MMIO region.
+ *
+ * This is only for dealing with save state issues, nothing else.
+ *
+ * @return VBox status code.
+ *
+ * @param   pVM         The cross context VM structure.
+ * @param   pDevIns     The device owning the MMIO2 memory.
+ * @param   iSubDev     The sub-device number.
+ * @param   iRegion     The region.
+ * @param   iNewRegion  The new region index.
+ *
+ * @sa      @bugref{9359}
+ */
+VMMR3_INT_DECL(int) PGMR3PhysMMIOExChangeRegionNo(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion,
+                                                  uint32_t iNewRegion)
+{
+    /*
+     * Validate input.
+     */
+    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
+    AssertPtrReturn(pDevIns, VERR_INVALID_PARAMETER);
+    AssertReturn(iSubDev <= UINT8_MAX, VERR_INVALID_PARAMETER);
+    AssertReturn(iRegion <= UINT8_MAX, VERR_INVALID_PARAMETER);
+    AssertReturn(iNewRegion <= UINT8_MAX, VERR_INVALID_PARAMETER);
+
+    AssertReturn(pVM->enmVMState == VMSTATE_LOADING, VERR_INVALID_STATE);
+
+    PPGMREGMMIORANGE pFirstRegMmio = pgmR3PhysMMIOExFind(pVM, pDevIns, iSubDev, iRegion);
+    AssertReturn(pFirstRegMmio, VERR_NOT_FOUND);
+    AssertReturn(pgmR3PhysMMIOExFind(pVM, pDevIns, iSubDev, iNewRegion) == NULL, VERR_RESOURCE_IN_USE);
+
+    /*
+     * Make the change.
+     */
+    pFirstRegMmio->iRegion = (uint8_t)iNewRegion;
+
+    return VINF_SUCCESS;
 }
 
