linux-stable/drivers/pci/hotplug
Igor Mammedov cc22522fd5 PCI: acpiphp: Use pci_assign_unassigned_bridge_resources() only for non-root bus
40613da52b ("PCI: acpiphp: Reassign resources on bridge if necessary")
changed acpiphp hotplug to use pci_assign_unassigned_bridge_resources()
which depends on bridge being available, however enable_slot() can be
called without bridge associated:

  1. Legitimate case of hotplug on root bus (widely used in virt world)

  2. A (misbehaving) firmware, that sends ACPI Bus Check notifications to
     non existing root ports (Dell Inspiron 7352/0W6WV0), which end up at
     enable_slot(..., bridge = 0) where bus has no bridge assigned to it.
     acpihp doesn't know that it's a bridge, and bus specific 'PCI
     subsystem' can't augment ACPI context with bridge information since
     the PCI device to get this data from is/was not available.

Issue is easy to reproduce with QEMU's 'pc' machine, which supports PCI
hotplug on hostbridge slots. To reproduce, boot kernel at commit
40613da52b in VM started with following CLI (assuming guest root fs is
installed on sda1 partition):

  # qemu-system-x86_64 -M pc -m 1G -enable-kvm -cpu host \
        -monitor stdio -serial file:serial.log           \
        -kernel arch/x86/boot/bzImage                    \
        -append "root=/dev/sda1 console=ttyS0"           \
        guest_disk.img

Once guest OS is fully booted at qemu prompt:

  (qemu) device_add e1000

(check serial.log) it will cause NULL pointer dereference at:

  void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
  {
    struct pci_bus *parent = bridge->subordinate;

  BUG: kernel NULL pointer dereference, address: 0000000000000018

   ? pci_assign_unassigned_bridge_resources+0x1f/0x260
   enable_slot+0x21f/0x3e0
   acpiphp_hotplug_notify+0x13d/0x260
   acpi_device_hotplug+0xbc/0x540
   acpi_hotplug_work_fn+0x15/0x20
   process_one_work+0x1f7/0x370
   worker_thread+0x45/0x3b0

The issue was discovered on Dell Inspiron 7352/0W6WV0 laptop with following
sequence:

  1. Suspend to RAM
  2. Wake up with the same backtrace being observed:
  3. 2nd suspend to RAM attempt makes laptop freeze

Fix it by using __pci_bus_assign_resources() instead of
pci_assign_unassigned_bridge_resources() as we used to do, but only in case
when bus doesn't have a bridge associated (to cover for the case of ACPI
event on hostbridge or non existing root port).

That lets us keep hotplug on root bus working like it used to and at the
same time keeps resource reassignment usable on root ports (and other 1st
level bridges) that was fixed by 40613da52b.

Fixes: 40613da52b ("PCI: acpiphp: Reassign resources on bridge if necessary")
Link: https://lore.kernel.org/r/20230726123518.2361181-2-imammedo@redhat.com
Reported-by: Woody Suwalski <terraluna977@gmail.com>
Tested-by: Woody Suwalski <terraluna977@gmail.com>
Tested-by: Michal Koutný <mkoutny@suse.com>
Link: https://lore.kernel.org/r/11fc981c-af49-ce64-6b43-3e282728bd1a@gmail.com
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael@kernel.org>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
2023-08-08 14:30:00 -05:00
..
Kconfig PCI: pciehp: Enable by default if USB4 enabled 2022-11-15 09:25:21 -06:00
Makefile
TODO PCI: shpchp: Remove unused get_mode1_ECC_cap callback 2022-11-22 14:09:51 -06:00
acpi_pcihp.c PCI: Fix kernel-doc errors 2021-03-11 17:37:20 -06:00
acpiphp.h PCI: acpiphp: Fix whitespace issue 2021-04-16 14:32:18 -05:00
acpiphp_core.c PCI: Remove MODULE_LICENSE so boolean drivers don't look like modules 2023-02-17 08:47:58 -06:00
acpiphp_glue.c PCI: acpiphp: Use pci_assign_unassigned_bridge_resources() only for non-root bus 2023-08-08 14:30:00 -05:00
acpiphp_ibm.c PCI/ACPI: Replace acpi_bus_get_device() with acpi_fetch_acpi_dev() 2022-02-04 17:10:44 -06:00
cpci_hotplug.h PCI: cpcihp: Declare cpci_debug in header file 2021-07-01 15:32:45 -05:00
cpci_hotplug_core.c PCI: Remove unnecessary returns 2019-08-30 14:00:34 -05:00
cpci_hotplug_pci.c PCI: cpcihp: Declare cpci_debug in header file 2021-07-01 15:32:45 -05:00
cpcihp_generic.c
cpcihp_zt5550.c
cpcihp_zt5550.h
cpqphp.h PCI: cpqphp: Use <linux/io.h> instead of <asm/io.h> 2021-11-02 14:41:58 -05:00
cpqphp_core.c PCI: cpqphp: Remove unused assignments 2022-03-22 11:24:40 -05:00
cpqphp_ctrl.c PCI: cpqphp: Remove unused assignments 2022-03-22 11:24:40 -05:00
cpqphp_nvram.c PCI: cpqphp: Use DEFINE_SPINLOCK() for int15_lock 2021-04-14 15:24:10 -05:00
cpqphp_nvram.h PCI: Remove unnecessary returns 2019-08-30 14:00:34 -05:00
cpqphp_pci.c PCI: cpqphp: Remove unused assignments 2022-03-22 11:24:40 -05:00
cpqphp_sysfs.c
ibmphp.h PCI: Correct misspelled and remove duplicated words 2021-10-08 17:14:04 -05:00
ibmphp_core.c PCI: ibmphp: Remove commented-out functions 2021-12-10 09:55:47 -06:00
ibmphp_ebda.c PCI: ibmphp: Fix double unmap of io_mem 2021-09-02 12:02:50 -05:00
ibmphp_hpc.c PCI: ibmphp: Remove unused assignments 2022-03-22 11:24:48 -05:00
ibmphp_pci.c PCI: ibmphp: Remove unneeded break 2020-11-20 11:17:55 -06:00
ibmphp_res.c PCI: ibmphp: Remove unused assignments 2022-03-22 11:24:48 -05:00
pci_hotplug_core.c PCI/sysfs: Use sysfs_emit() and sysfs_emit_at() in "show" functions 2021-06-03 22:14:47 -05:00
pciehp.h PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors 2022-01-12 06:42:51 -06:00
pciehp_core.c PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors 2022-01-12 06:42:51 -06:00
pciehp_ctrl.c PCI: pciehp: Cancel bringup sequence if card is not present 2023-05-24 11:52:38 -05:00
pciehp_hpc.c Merge branch 'pci/hotplug' 2023-06-26 12:59:56 -05:00
pciehp_pci.c PCI: pciehp: Fix AB-BA deadlock between reset_lock and device_lock 2023-04-11 13:18:30 -05:00
pnv_php.c PCI: hotplug: Clean up include files 2022-04-05 11:13:33 -05:00
rpadlpar.h
rpadlpar_core.c PCI: hotplug: Clean up include files 2022-04-05 11:13:33 -05:00
rpadlpar_sysfs.c PCI/sysfs: Use sysfs_emit() and sysfs_emit_at() in "show" functions 2021-06-03 22:14:47 -05:00
rpaphp.h
rpaphp_core.c PCI: Use of_property_present() for testing DT property presence 2023-04-18 16:01:37 -05:00
rpaphp_pci.c PCI: hotplug: Clean up include files 2022-04-05 11:13:33 -05:00
rpaphp_slot.c PCI: hotplug: Clean up include files 2022-04-05 11:13:33 -05:00
s390_pci_hpc.c s390/pci: implement reset_slot for hotplug slot 2021-11-08 14:17:49 +01:00
shpchp.h PCI: shpchp: Remove unused get_mode1_ECC_cap callback 2022-11-22 14:09:51 -06:00
shpchp_core.c PCI: Remove MODULE_LICENSE so boolean drivers don't look like modules 2023-02-17 08:47:58 -06:00
shpchp_ctrl.c pci-v5.10-changes 2020-10-22 12:41:00 -07:00
shpchp_hpc.c PCI: shpchp: Remove unused get_mode1_ECC_cap callback 2022-11-22 14:09:51 -06:00
shpchp_pci.c PCI: shpchp: Make shpchp_unconfigure_device() void 2020-05-21 15:23:20 -05:00
shpchp_sysfs.c PCI: Make pci_bus_for_each_resource() index optional 2023-04-05 15:10:09 -05:00