Index: /trunk/src/VBox/Main/src-client/BusAssignmentManager.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/BusAssignmentManager.cpp	(revision 70237)
+++ /trunk/src/VBox/Main/src-client/BusAssignmentManager.cpp	(revision 70238)
@@ -33,5 +33,5 @@
 struct DeviceAssignmentRule
 {
-    const char* pszName;
+    const char *pszName;
     int         iBus;
     int         iDevice;
@@ -42,6 +42,6 @@
 struct DeviceAliasRule
 {
-    const char* pszDevName;
-    const char* pszDevAlias;
+    const char *pszDevName;
+    const char *pszDevAlias;
 };
 
@@ -133,14 +133,14 @@
     {"ich9pcibridge", 0, 24, 0,  10},
     {"ich9pcibridge", 0, 25, 0,  10},
-    {"ich9pcibridge", 1, 24, 0,   9},
-    {"ich9pcibridge", 1, 25, 0,   9},
-    {"ich9pcibridge", 2, 24, 0,   8},
-    {"ich9pcibridge", 2, 25, 0,   8},
-    {"ich9pcibridge", 3, 24, 0,   7},
-    {"ich9pcibridge", 3, 25, 0,   7},
-    {"ich9pcibridge", 4, 24, 0,   6},
-    {"ich9pcibridge", 4, 25, 0,   6},
-    {"ich9pcibridge", 5, 24, 0,   5},
-    {"ich9pcibridge", 5, 25, 0,   5},
+    {"ich9pcibridge", 2, 24, 0,   9}, /* Bridges must be instantiated depth */
+    {"ich9pcibridge", 2, 25, 0,   9}, /* first (assumption in PDM and other */
+    {"ich9pcibridge", 4, 24, 0,   8}, /* places), so make sure that nested */
+    {"ich9pcibridge", 4, 25, 0,   8}, /* bridges are added to the last bridge */
+    {"ich9pcibridge", 6, 24, 0,   7}, /* only, avoiding the need to re-sort */
+    {"ich9pcibridge", 6, 25, 0,   7}, /* everything before starting the VM. */
+    {"ich9pcibridge", 8, 24, 0,   6},
+    {"ich9pcibridge", 8, 25, 0,   6},
+    {"ich9pcibridge", 10, 24, 0,  5},
+    {"ich9pcibridge", 10, 25, 0,  5},
 
     /* Storage controllers */
@@ -236,5 +236,5 @@
         PCIBusAddress HostAddress;
 
-        PCIDeviceRecord(const char* pszName, PCIBusAddress aHostAddress)
+        PCIDeviceRecord(const char *pszName, PCIBusAddress aHostAddress)
         {
             RTStrCopy(this->szDevName, sizeof(szDevName), pszName);
@@ -242,5 +242,5 @@
         }
 
-        PCIDeviceRecord(const char* pszName)
+        PCIDeviceRecord(const char *pszName)
         {
             RTStrCopy(this->szDevName, sizeof(szDevName), pszName);
@@ -265,9 +265,10 @@
     volatile int32_t cRefCnt;
     ChipsetType_T    mChipsetType;
+    const char *     mpszBridgeName;
     PCIMap           mPCIMap;
     ReversePCIMap    mReversePCIMap;
 
     State()
-        : cRefCnt(1), mChipsetType(ChipsetType_Null)
+        : cRefCnt(1), mChipsetType(ChipsetType_Null), mpszBridgeName("unknownbridge")
     {}
     ~State()
@@ -276,11 +277,11 @@
     HRESULT init(ChipsetType_T chipsetType);
 
-    HRESULT record(const char* pszName, PCIBusAddress& GuestAddress, PCIBusAddress HostAddress);
-    HRESULT autoAssign(const char* pszName, PCIBusAddress& Address);
+    HRESULT record(const char *pszName, PCIBusAddress& GuestAddress, PCIBusAddress HostAddress);
+    HRESULT autoAssign(const char *pszName, PCIBusAddress& Address);
     bool    checkAvailable(PCIBusAddress& Address);
-    bool    findPCIAddress(const char* pszDevName, int iInstance, PCIBusAddress& Address);
-
-    const char* findAlias(const char* pszName);
-    void addMatchingRules(const char* pszName, PCIRulesList& aList);
+    bool    findPCIAddress(const char *pszDevName, int iInstance, PCIBusAddress& Address);
+
+    const char *findAlias(const char *pszName);
+    void addMatchingRules(const char *pszName, PCIRulesList& aList);
     void listAttachedPCIDevices(std::vector<PCIDeviceInfo> &aAttached);
 };
@@ -289,8 +290,21 @@
 {
     mChipsetType = chipsetType;
+    switch (chipsetType)
+    {
+        case ChipsetType_PIIX3:
+            mpszBridgeName = "pcibridge";
+            break;
+        case ChipsetType_ICH9:
+            mpszBridgeName = "ich9pcibridge";
+            break;
+        default:
+            mpszBridgeName = "unknownbridge";
+            AssertFailed();
+            break;
+    }
     return S_OK;
 }
 
-HRESULT BusAssignmentManager::State::record(const char* pszName, PCIBusAddress& Address, PCIBusAddress HostAddress)
+HRESULT BusAssignmentManager::State::record(const char *pszName, PCIBusAddress& Address, PCIBusAddress HostAddress)
 {
     PCIDeviceRecord devRec(pszName, HostAddress);
@@ -312,5 +326,5 @@
 }
 
-bool    BusAssignmentManager::State::findPCIAddress(const char* pszDevName, int iInstance, PCIBusAddress& Address)
+bool    BusAssignmentManager::State::findPCIAddress(const char *pszDevName, int iInstance, PCIBusAddress& Address)
 {
     PCIDeviceRecord devRec(pszDevName);
@@ -327,8 +341,8 @@
 }
 
-void BusAssignmentManager::State::addMatchingRules(const char* pszName, PCIRulesList& aList)
+void BusAssignmentManager::State::addMatchingRules(const char *pszName, PCIRulesList& aList)
 {
     size_t iRuleset, iRule;
-    const DeviceAssignmentRule* aArrays[2] = {aGenericRules, NULL};
+    const DeviceAssignmentRule *aArrays[2] = {aGenericRules, NULL};
 
     switch (mChipsetType)
@@ -341,5 +355,5 @@
             break;
         default:
-            Assert(false);
+            AssertFailed();
             break;
     }
@@ -358,5 +372,5 @@
 }
 
-const char* BusAssignmentManager::State::findAlias(const char* pszDev)
+const char *BusAssignmentManager::State::findAlias(const char *pszDev)
 {
     for (size_t iAlias = 0; iAlias < RT_ELEMENTS(aDeviceAliases); iAlias++)
@@ -368,15 +382,15 @@
 }
 
-static bool  RuleComparator(const DeviceAssignmentRule* r1, const DeviceAssignmentRule* r2)
+static bool  RuleComparator(const DeviceAssignmentRule *r1, const DeviceAssignmentRule *r2)
 {
     return (r1->iPriority > r2->iPriority);
 }
 
-HRESULT BusAssignmentManager::State::autoAssign(const char* pszName, PCIBusAddress& Address)
+HRESULT BusAssignmentManager::State::autoAssign(const char *pszName, PCIBusAddress& Address)
 {
     PCIRulesList matchingRules;
 
     addMatchingRules(pszName,  matchingRules);
-    const char* pszAlias = findAlias(pszName);
+    const char *pszAlias = findAlias(pszName);
     if (pszAlias)
         addMatchingRules(pszAlias, matchingRules);
@@ -388,5 +402,5 @@
     for (size_t iRule = 0; iRule < matchingRules.size(); iRule++)
     {
-        const DeviceAssignmentRule* rule = matchingRules[iRule];
+        const DeviceAssignmentRule *rule = matchingRules[iRule];
 
         Address.miBus = rule->iBus;
@@ -397,5 +411,5 @@
             return S_OK;
     }
-    AssertMsgFailed(("All possible candidate positions for %s exhausted\n", pszName));
+    AssertLogRelMsgFailed(("BusAssignmentManager: All possible candidate positions for %s exhausted\n", pszName));
 
     return E_INVALIDARG;
@@ -440,7 +454,7 @@
 }
 
-BusAssignmentManager* BusAssignmentManager::createInstance(ChipsetType_T chipsetType)
-{
-    BusAssignmentManager* pInstance = new BusAssignmentManager();
+BusAssignmentManager *BusAssignmentManager::createInstance(ChipsetType_T chipsetType)
+{
+    BusAssignmentManager *pInstance = new BusAssignmentManager();
     pInstance->pState->init(chipsetType);
     Assert(pInstance);
@@ -458,5 +472,5 @@
 }
 
-DECLINLINE(HRESULT) InsertConfigInteger(PCFGMNODE pCfg,  const char* pszName, uint64_t u64)
+DECLINLINE(HRESULT) InsertConfigInteger(PCFGMNODE pCfg,  const char *pszName, uint64_t u64)
 {
     int vrc = CFGMR3InsertInteger(pCfg, pszName, u64);
@@ -467,5 +481,15 @@
 }
 
-HRESULT BusAssignmentManager::assignPCIDeviceImpl(const char* pszDevName,
+DECLINLINE(HRESULT) InsertConfigNode(PCFGMNODE pNode, const char *pcszName, PCFGMNODE *ppChild)
+{
+    int vrc = CFGMR3InsertNode(pNode, pcszName, ppChild);
+    if (RT_FAILURE(vrc))
+        return E_INVALIDARG;
+
+    return S_OK;
+}
+
+
+HRESULT BusAssignmentManager::assignPCIDeviceImpl(const char *pszDevName,
                                                   PCFGMNODE pCfg,
                                                   PCIBusAddress& GuestAddress,
@@ -509,9 +533,40 @@
         return rc;
 
+    /* Check if the bus is still unknown, i.e. the bridge to it is missing */
+    if (   GuestAddress.miBus > 0
+        && !hasPCIDevice(pState->mpszBridgeName, GuestAddress.miBus - 1))
+    {
+        PCFGMNODE pDevices = CFGMR3GetParent(CFGMR3GetParent(pCfg));
+        AssertLogRelMsgReturn(pDevices, ("BusAssignmentManager: cannot find base device configuration\n"), E_UNEXPECTED);
+        PCFGMNODE pBridges = CFGMR3GetChild(pDevices, "ich9pcibridge");
+        AssertLogRelMsgReturn(pBridges, ("BusAssignmentManager: cannot find bridge configuration base\n"), E_UNEXPECTED);
+
+        /* Device should be on a not yet existing bus, add it automatically */
+        for (int iBridge = 0; iBridge <= GuestAddress.miBus - 1; iBridge++)
+        {
+            if (!hasPCIDevice(pState->mpszBridgeName, iBridge))
+            {
+                PCIBusAddress BridgeGuestAddress;
+                rc = pState->autoAssign(pState->mpszBridgeName, BridgeGuestAddress);
+                if (FAILED(rc))
+                    return rc;
+                if (BridgeGuestAddress.miBus > iBridge)
+                    AssertLogRelMsgFailedReturn(("BusAssignmentManager: cannot create bridge for bus %i because the possible parent bus positions are exhausted\n", iBridge + 1), E_UNEXPECTED);
+
+                PCFGMNODE pInst;
+                InsertConfigNode(pBridges, Utf8StrFmt("%d", iBridge).c_str(), &pInst);
+                InsertConfigInteger(pInst, "Trusted", 1);
+                rc = assignPCIDevice(pState->mpszBridgeName, pInst);
+                if (FAILED(rc))
+                    return rc;
+            }
+        }
+    }
+
     return S_OK;
 }
 
 
-bool BusAssignmentManager::findPCIAddress(const char* pszDevName, int iInstance, PCIBusAddress& Address)
+bool BusAssignmentManager::findPCIAddress(const char *pszDevName, int iInstance, PCIBusAddress& Address)
 {
     return pState->findPCIAddress(pszDevName, iInstance, Address);
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 70237)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 70238)
@@ -558,38 +558,4 @@
 # endif
 
-    PCFGMNODE pBridges = CFGMR3GetChild(pDevices, "ich9pcibridge");
-    Assert(pBridges);
-
-    /* Find required bridges, and add missing ones */
-    for (size_t iDev = 0; iDev < assignments.size(); iDev++)
-    {
-        ComPtr<IPCIDeviceAttachment> assignment = assignments[iDev];
-        LONG guest = 0;
-        PCIBusAddress GuestPCIAddress;
-
-        hrc = assignment->COMGETTER(GuestAddress)(&guest);   H();
-        GuestPCIAddress.fromLong(guest);
-        Assert(GuestPCIAddress.valid());
-
-        if (GuestPCIAddress.miBus > 0)
-        {
-            int iBridgesMissed = 0;
-            int iBase = GuestPCIAddress.miBus - 1;
-
-            while (!pBusMgr->hasPCIDevice("ich9pcibridge", iBase) && iBase > 0)
-            {
-                iBridgesMissed++; iBase--;
-            }
-            iBase++;
-
-            for (int iBridge = 0; iBridge < iBridgesMissed; iBridge++)
-            {
-                InsertConfigNode(pBridges, Utf8StrFmt("%d", iBase + iBridge).c_str(), &pInst);
-                InsertConfigInteger(pInst, "Trusted",              1);
-                hrc = pBusMgr->assignPCIDevice("ich9pcibridge", pInst);
-            }
-        }
-    }
-
     /* Now actually add devices */
     PCFGMNODE pPCIDevs = NULL;
@@ -1455,7 +1421,10 @@
         {
             default:
-                Assert(false);
+                AssertFailed();
                 RT_FALL_THRU();
             case ChipsetType_PIIX3:
+                /* Create the base for adding bridges on demand */
+                InsertConfigNode(pDevices, "pcibridge", NULL);
+
                 InsertConfigNode(pDevices, "pci", &pDev);
                 uHbcPCIAddress = (0x0 << 16) | 0;
@@ -1463,4 +1432,7 @@
                 break;
             case ChipsetType_ICH9:
+                /* Create the base for adding bridges on demand */
+                InsertConfigNode(pDevices, "ich9pcibridge", NULL);
+
                 InsertConfigNode(pDevices, "ich9pci", &pDev);
                 uHbcPCIAddress = (0x1e << 16) | 0;
@@ -1478,18 +1450,7 @@
             InsertConfigInteger(pCfg,  "McfgLength", cbMcfgLength);
 
-
-            /* And register 2 bridges */
-            InsertConfigNode(pDevices, "ich9pcibridge", &pDev);
-            InsertConfigNode(pDev,     "0", &pInst);
-            InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
-            hrc = pBusMgr->assignPCIDevice("ich9pcibridge", pInst);                         H();
-
-            InsertConfigNode(pDev,     "1", &pInst);
-            InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
-            hrc = pBusMgr->assignPCIDevice("ich9pcibridge", pInst);                         H();
-
 #ifdef VBOX_WITH_PCI_PASSTHROUGH
             /* Add PCI passthrough devices */
-            hrc = i_attachRawPCIDevices(pUVM, pBusMgr, pDevices);                             H();
+            hrc = i_attachRawPCIDevices(pUVM, pBusMgr, pDevices);                           H();
 #endif
         }
@@ -2376,17 +2337,4 @@
                     hrc = ctrls[i]->COMGETTER(PortCount)(&cPorts);                          H();
                     InsertConfigInteger(pCfg, "NamespacesMax", cPorts);
-
-                    /* For ICH9 we need to create a new PCI bridge if there is more than one NVMe instance. */
-                    if (   ulInstance > 0
-                        && chipsetType == ChipsetType_ICH9
-                        && !pBusMgr->hasPCIDevice("ich9pcibridge", 2))
-                    {
-                        PCFGMNODE pBridges = CFGMR3GetChild(pDevices, "ich9pcibridge");
-                        Assert(pBridges);
-
-                        InsertConfigNode(pBridges, "2", &pInst);
-                        InsertConfigInteger(pInst, "Trusted",              1);
-                        hrc = pBusMgr->assignPCIDevice("ich9pcibridge", pInst);
-                    }
 
                     /* Attach the status driver */
