mirror-linux/arch/s390/pci
Benjamin Block 4cb92fa763 s390/pci: Fix cyclic dead-lock in zpci_zdev_put() and zpci_scan_devices()
When triggering PCI device recovery by writing into the SysFS attribute
`recover` of a Physical Function with existing child SR-IOV Virtual
Functions, lockdep is reporting a possible deadlock between three
threads:

         Thread (A)             Thread (B)             Thread (C)
             |                      |                      |
      recover_store()      zpci_scan_devices()    zpci_scan_devices()
lock(pci_rescan_remove_lock)        |                      |
             |                      |                      |
             |                      |            zpci_bus_scan_busses()
             |                      |             lock(zbus_list_lock)
             |              zpci_add_device()              |
             |          lock(zpci_add_remove_lock)         |
             |                      |                      ┴
             |                      |             zpci_bus_scan_bus()
             |                      |         lock(pci_rescan_remove_lock)
             ┴                      |
      zpci_zdev_put()               |
 lock(zpci_add_remove_lock)         |
                                    ┴
                              zpci_bus_get()
                           lock(zbus_list_lock)

In zpci_bus_scan_busses() the `zbus_list_lock` is taken for the whole
duration of the function, which also includes taking
`pci_rescan_remove_lock`, among other things. But `zbus_list_lock` only
really needs to protect the modification of the global registration
`zbus_list`, it can be dropped while the functions within the list
iteration run; this way we break the cycle above.

Break up zpci_bus_scan_busses() into an "iterator" zpci_bus_get_next()
that iterates over `zbus_list` element by element, and acquires and
releases `zbus_list_lock` as necessary, but never keep holding it.
References to `zpci_bus` objects are also acquired and released.

The reference counting on `zpci_bus` objects is also changed so that all
put() and get() operations are done under the protection of
`zbus_list_lock`, and if the operation results in a modification of
`zpci_bus_list`, this modification is done in the same critical section
(apart the very first initialization). This way objects are never seen
on the list that are about to be released and/or half-initialized.

Fixes: 14c87ba812 ("s390/pci: separate zbus registration from scanning")
Suggested-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Gerd Bayer <gbayer@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
2025-12-14 11:03:58 +01:00
..
Makefile s390/pci: Support mmap() of PCI resources except for ISM devices 2025-03-21 14:54:16 -05:00
pci.c s390/pci: Fix cyclic dead-lock in zpci_zdev_put() and zpci_scan_devices() 2025-12-14 11:03:58 +01:00
pci_bus.c s390/pci: Fix cyclic dead-lock in zpci_zdev_put() and zpci_scan_devices() 2025-12-14 11:03:58 +01:00
pci_bus.h s390/pci: Fix cyclic dead-lock in zpci_zdev_put() and zpci_scan_devices() 2025-12-14 11:03:58 +01:00
pci_clp.c s390: Remove KMSG_COMPONENT macro 2025-11-24 11:45:21 +01:00
pci_debug.c s390: Remove KMSG_COMPONENT macro 2025-11-24 11:45:21 +01:00
pci_event.c s390 updates for 6.19 merge window 2025-12-02 16:37:00 -08:00
pci_fixup.c s390/pci: Support mmap() of PCI resources except for ISM devices 2025-03-21 14:54:16 -05:00
pci_insn.c s390: Remove superfluous newlines from inline assemblies 2025-09-29 13:52:08 +02:00
pci_iov.c s390: Remove KMSG_COMPONENT macro 2025-11-24 11:45:21 +01:00
pci_iov.h s390/pci: Fix handling of isolated VFs 2025-02-11 19:35:08 +01:00
pci_irq.c s390/pci: Migrate s390 IRQ logic to IRQ domain API 2025-12-07 16:15:23 +01:00
pci_kvm_hook.c s390: Explicitly include <linux/export.h> 2025-06-17 18:18:02 +02:00
pci_mmio.c s390/pci: Fix __pcilg_mio_inuser() inline assembly 2025-05-21 12:02:27 +02:00
pci_report.c s390: Remove KMSG_COMPONENT macro 2025-11-24 11:45:21 +01:00
pci_report.h s390/pci: Report PCI error recovery results via SCLP 2024-12-16 16:14:26 +01:00
pci_sysfs.c s390: Remove KMSG_COMPONENT macro 2025-11-24 11:45:21 +01:00