Re: [PATCH v2 03/22] PCI: Inherit bus numbers from previous kernel during Live Update

Pranjal Shrivastava
2026-02-24T09:36:14Z

On Thu, Jan 29, 2026 at 09:24:50PM +0000, David Matlack wrote:
> 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 <dmatlack@google.com>
> ---
> 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;

Following the comment on Patch 2 regarding propagating errors, the check
if (pci_liveupdate_incoming_nr_devices()) should be made explicit to
distinguish between "Preservation Active" and "Retrieval Failed".

> +
> + 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;

Looks like we over-ride the pci=assign-busses boot param here.
We should document how this change affects the pci=assign-busses kernel
command line. If both are present, the inheritance required by LUO would
likely take precedence to prevent DMA corruption, but a doc update & a
warning to the user would be nice.

Thanks,
Praan