Inherit bus numbers from the previous kernel during a Live Update when one or more PCI devices are being preserved. This is necessary so that preserved devices can DMA through the IOMMU during a Live Update (changing bus numbers would break IOMMU translation).
Signed-off-by: David Matlack <[email protected]> --- drivers/pci/probe.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index af6356c5a156..ca6e5f79debb 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1351,6 +1351,20 @@ static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub) return true; } +static bool pci_assign_all_busses(void) +{ + /* + * During a Live Update where devices are preserved by the previous + * kernel, inherit all bus numbers assigned by the previous kernel. Bus + * numbers must remain stable for preserved devices so that they can + * perform DMA during the Live Update uninterrupted. + */ + if (pci_liveupdate_incoming_nr_devices()) + return false; + + return pcibios_assign_all_busses(); +} + /* * pci_scan_bridge_extend() - Scan buses behind a bridge * @bus: Parent bus the bridge is on @@ -1378,6 +1392,7 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, int max, unsigned int available_buses, int pass) { + bool assign_all_busses = pci_assign_all_busses(); struct pci_bus *child; int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); u32 buses, i, j = 0; @@ -1424,7 +1439,7 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); - if ((secondary || subordinate) && !pcibios_assign_all_busses() && + if ((secondary || subordinate) && !assign_all_busses && !is_cardbus && !broken) { unsigned int cmax, buses; @@ -1467,7 +1482,7 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, * do in the second pass. */ if (!pass) { - if (pcibios_assign_all_busses() || broken || is_cardbus) + if (assign_all_busses || broken || is_cardbus) /* * Temporarily disable forwarding of the @@ -1542,7 +1557,7 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, max+i+1)) break; while (parent->parent) { - if ((!pcibios_assign_all_busses()) && + if (!assign_all_busses && (parent->busn_res.end > max) && (parent->busn_res.end <= max+i)) { j = 1; -- 2.53.0.rc1.225.gd81095ad13-goog
