}
 
        res->end = res->start + new_size - 1;
-       remove_from_list(add_list, res);
+
+       /* If the resource is part of the add_list, remove it now */
+       if (add_list)
+               remove_from_list(add_list, res);
 }
 
 static void remove_dev_resource(struct resource *avail, struct pci_dev *dev,
        if (!bridge->is_hotplug_bridge)
                return;
 
+       pci_dbg(bridge, "distributing available resources\n");
+
        /* Take the initial extra resources from the hotplug port */
        available_io = bridge->resource[PCI_BRIDGE_IO_WINDOW];
        available_mmio = bridge->resource[PCI_BRIDGE_MEM_WINDOW];
                                               available_mmio_pref);
 }
 
+static bool pci_bridge_resources_not_assigned(struct pci_dev *dev)
+{
+       const struct resource *r;
+
+       /*
+        * If the child device's resources are not yet assigned it means we
+        * are configuring them (not the boot firmware), so we should be
+        * able to extend the upstream bridge resources in the same way we
+        * do with the normal hotplug case.
+        */
+       r = &dev->resource[PCI_BRIDGE_IO_WINDOW];
+       if (r->flags && !(r->flags & IORESOURCE_STARTALIGN))
+               return false;
+       r = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
+       if (r->flags && !(r->flags & IORESOURCE_STARTALIGN))
+               return false;
+       r = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
+       if (r->flags && !(r->flags & IORESOURCE_STARTALIGN))
+               return false;
+
+       return true;
+}
+
+static void
+pci_root_bus_distribute_available_resources(struct pci_bus *bus,
+                                           struct list_head *add_list)
+{
+       struct pci_dev *dev, *bridge = bus->self;
+
+       for_each_pci_bridge(dev, bus) {
+               struct pci_bus *b;
+
+               b = dev->subordinate;
+               if (!b)
+                       continue;
+
+               /*
+                * Need to check "bridge" here too because it is NULL
+                * in case of root bus.
+                */
+               if (bridge && pci_bridge_resources_not_assigned(dev))
+                       pci_bridge_distribute_available_resources(bridge,
+                                                                 add_list);
+               else
+                       pci_root_bus_distribute_available_resources(b, add_list);
+       }
+}
+
 /*
  * First try will not touch PCI bridge res.
  * Second and later try will clear small leaf bridge res.
         */
        __pci_bus_size_bridges(bus, add_list);
 
+       pci_root_bus_distribute_available_resources(bus, add_list);
+
        /* Depth last, allocate resources and update the hardware. */
        __pci_bus_assign_resources(bus, add_list, &fail_head);
        if (add_list)