linux-stable/drivers/pci
Rafael J. Wysocki 9a87375bb5 PCI/PM: Drain runtime-idle callbacks before driver removal
[ Upstream commit 9d5286d4e7 ]

A race condition between the .runtime_idle() callback and the .remove()
callback in the rtsx_pcr PCI driver leads to a kernel crash due to an
unhandled page fault [1].

The problem is that rtsx_pci_runtime_idle() is not expected to be running
after pm_runtime_get_sync() has been called, but the latter doesn't really
guarantee that.  It only guarantees that the suspend and resume callbacks
will not be running when it returns.

However, if a .runtime_idle() callback is already running when
pm_runtime_get_sync() is called, the latter will notice that the runtime PM
status of the device is RPM_ACTIVE and it will return right away without
waiting for the former to complete.  In fact, it cannot wait for
.runtime_idle() to complete because it may be called from that callback (it
arguably does not make much sense to do that, but it is not strictly
prohibited).

Thus in general, whoever is providing a .runtime_idle() callback needs
to protect it from running in parallel with whatever code runs after
pm_runtime_get_sync().  [Note that .runtime_idle() will not start after
pm_runtime_get_sync() has returned, but it may continue running then if it
has started earlier.]

One way to address that race condition is to call pm_runtime_barrier()
after pm_runtime_get_sync() (not before it, because a nonzero value of the
runtime PM usage counter is necessary to prevent runtime PM callbacks from
being invoked) to wait for the .runtime_idle() callback to complete should
it be running at that point.  A suitable place for doing that is in
pci_device_remove() which calls pm_runtime_get_sync() before removing the
driver, so it may as well call pm_runtime_barrier() subsequently, which
will prevent the race in question from occurring, not just in the rtsx_pcr
driver, but in any PCI drivers providing .runtime_idle() callbacks.

Link: https://lore.kernel.org/lkml/20240229062201.49500-1-kai.heng.feng@canonical.com/ # [1]
Link: https://lore.kernel.org/r/5761426.DvuYhMxLoT@kreacher
Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Ricky Wu <ricky_wu@realtek.com>
Acked-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2024-04-13 12:50:06 +02:00
..
controller PCI: mediatek: Clear interrupt status before dispatching handler 2024-02-23 08:12:38 +01:00
endpoint PCI: endpoint: Fix missing destroy_workqueue() 2021-05-22 10:59:43 +02:00
hotplug Revert "PCI: acpiphp: Reassign resources on bridge if necessary" 2023-12-20 15:38:01 +01:00
pcie PCI/ASPM: Use RMW accessors for changing LNKCTL 2023-09-23 10:48:05 +02:00
switch
Kconfig
Makefile
access.c PCI: Reduce warnings on possible RW1C corruption 2022-04-15 14:14:50 +02:00
ats.c PCI/ATS: Add pci_prg_resp_pasid_required() interface. 2023-09-23 10:48:05 +02:00
bus.c
ecam.c
host-bridge.c
iov.c
irq.c PCI: Check for alloc failure in pci_request_irq() 2023-01-18 11:30:21 +01:00
mmap.c
msi.c PCI/MSI: Prevent MSI hardware interrupt number truncation 2024-03-01 13:06:11 +01:00
of.c
pci-acpi.c PCI/sysfs: Protect driver's D3cold preference from user space 2023-11-28 16:46:34 +00:00
pci-driver.c PCI/PM: Drain runtime-idle callbacks before driver removal 2024-04-13 12:50:06 +02:00
pci-label.c PCI/sysfs: Fix dsm_label_utf16s_to_utf8s() buffer overrun 2021-07-20 16:16:12 +02:00
pci-mid.c
pci-pf-stub.c
pci-stub.c
pci-sysfs.c PCI/sysfs: Protect driver's D3cold preference from user space 2023-11-28 16:46:34 +00:00
pci.c PCI: Decode PCIe 32 GT/s link speed 2023-09-23 10:48:05 +02:00
pci.h PCI: thunder: Fix compile testing 2021-05-22 10:59:48 +02:00
probe.c PCI: Decode PCIe 32 GT/s link speed 2023-09-23 10:48:05 +02:00
proc.c
quirks.c PCI: Mark 3ware-9650SE Root Port Extended Tags as broken 2024-03-26 18:22:40 -04:00
remove.c
rom.c
search.c
setup-bus.c
setup-irq.c
setup-res.c PCI: Sanitise firmware BAR assignments behind a PCI-PCI bridge 2022-10-26 13:19:22 +02:00
slot.c PCI: Decode PCIe 32 GT/s link speed 2023-09-23 10:48:05 +02:00
syscall.c PCI: Return ~0 data on pciconfig_read() CAP_SYS_ADMIN failure 2021-09-22 11:48:00 +02:00
vc.c
vpd.c
xen-pcifront.c