mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
In the case of fast device addition/removal, it's possible that
hv_eject_device_work() can start to run before create_root_hv_pci_bus()
starts to run; as a result, the pci_get_domain_bus_and_slot() in
hv_eject_device_work() can return a 'pdev' of NULL, and
hv_eject_device_work() can remove the 'hpdev', and immediately send a
message PCI_EJECTION_COMPLETE to the host, and the host immediately
unassigns the PCI device from the guest; meanwhile,
create_root_hv_pci_bus() and the PCI device driver can be probing the
dead PCI device and reporting timeout errors.
Fix the issue by adding a per-bus mutex 'state_lock' and grabbing the
mutex before powering on the PCI bus in hv_pci_enter_d0(): when
hv_eject_device_work() starts to run, it's able to find the 'pdev' and call
pci_stop_and_remove_bus_device(pdev): if the PCI device driver has
loaded, the PCI device driver's probe() function is already called in
create_root_hv_pci_bus() -> pci_bus_add_devices(), and now
hv_eject_device_work() -> pci_stop_and_remove_bus_device() is able
to call the PCI device driver's remove() function and remove the device
reliably; if the PCI device driver hasn't loaded yet, the function call
hv_eject_device_work() -> pci_stop_and_remove_bus_device() is able to
remove the PCI device reliably and the PCI device driver's probe()
function won't be called; if the PCI device driver's probe() is already
running (e.g., systemd-udev is loading the PCI device driver), it must
be holding the per-device lock, and after the probe() finishes and releases
the lock, hv_eject_device_work() -> pci_stop_and_remove_bus_device() is
able to proceed to remove the device reliably.
Fixes:
|
||
---|---|---|
.. | ||
cadence | ||
dwc | ||
mobiveil | ||
Kconfig | ||
Makefile | ||
pci-aardvark.c | ||
pci-ftpci100.c | ||
pci-host-common.c | ||
pci-host-generic.c | ||
pci-hyperv-intf.c | ||
pci-hyperv.c | ||
pci-ixp4xx.c | ||
pci-loongson.c | ||
pci-mvebu.c | ||
pci-rcar-gen2.c | ||
pci-tegra.c | ||
pci-thunder-ecam.c | ||
pci-thunder-pem.c | ||
pci-v3-semi.c | ||
pci-versatile.c | ||
pci-xgene-msi.c | ||
pci-xgene.c | ||
pcie-altera-msi.c | ||
pcie-altera.c | ||
pcie-apple.c | ||
pcie-brcmstb.c | ||
pcie-hisi-error.c | ||
pcie-iproc-bcma.c | ||
pcie-iproc-msi.c | ||
pcie-iproc-platform.c | ||
pcie-iproc.c | ||
pcie-iproc.h | ||
pcie-mediatek-gen3.c | ||
pcie-mediatek.c | ||
pcie-microchip-host.c | ||
pcie-mt7621.c | ||
pcie-rcar-ep.c | ||
pcie-rcar-host.c | ||
pcie-rcar.c | ||
pcie-rcar.h | ||
pcie-rockchip-ep.c | ||
pcie-rockchip-host.c | ||
pcie-rockchip.c | ||
pcie-rockchip.h | ||
pcie-xilinx-cpm.c | ||
pcie-xilinx-nwl.c | ||
pcie-xilinx.c | ||
vmd.c |