Patch "PCI/portdrv: Prevent LS7A Bus Master clearing on shutdown" has been added to the 6.2-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    PCI/portdrv: Prevent LS7A Bus Master clearing on shutdown

to the 6.2-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pci-portdrv-prevent-ls7a-bus-master-clearing-on-shut.patch
and it can be found in the queue-6.2 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 648e2444f9a7a6957529b1378f3a5a41039f1f2d
Author: Huacai Chen <chenhuacai@xxxxxxxxxx>
Date:   Wed Feb 1 12:30:17 2023 +0800

    PCI/portdrv: Prevent LS7A Bus Master clearing on shutdown
    
    [ Upstream commit 62b6dee1b44aa23b3935543aff7df80399ec726b ]
    
    After cc27b735ad3a ("PCI/portdrv: Turn off PCIe services during shutdown")
    we observe hangs during poweroff/reboot on systems with LS7A chipset.
    
    This happens because the portdrv .shutdown() method (pcie_portdrv_remove())
    clears PCI_COMMAND_MASTER via pci_disable_device(), which prevents bridges
    from forwarding memory or I/O Requests in the upstream direction (PCIe
    r6.0, sec 7.5.1.1.3).
    
    LS7A Root Ports have a hardware defect: clearing PCI_COMMAND_MASTER *also*
    prevents the bridge from forwarding CPU MMIO requests in the downstream
    direction, and these MMIO accesses to devices below the bridge happen even
    after .shutdown(), e.g., to print console messages.  LS7A neither forwards
    the requests nor sends an unsuccessful completion to the CPU, so the CPU
    waits forever, resulting in the hang.
    
    The purpose of .shutdown() is to disable interrupts and DMA from the
    device.  PCIe ports may generate interrupts (either MSI/MSI-X or INTx) for
    AER, DPC, PME, hotplug, etc., but they never perform DMA except MSI/MSI-X.
    Clearing PCI_COMMAND_MASTER effectively disables MSI/MSI-X, but not INTx.
    
    The port service driver .remove() methods clear the interrupt enables in
    PCI_ERR_ROOT_COMMAND, PCI_EXP_DPC_CTL, PCI_EXP_SLTCTL, and PCI_EXP_RTCTL,
    etc., which disables interrupts regardless of whether they are MSI/MSI-X or
    INTx.
    
    Add a pcie_portdrv_shutdown() method that calls all the port service driver
    .remove() methods to clear the interrupt enables for each service but does
    not clear Bus Mastering on the port itself.
    
    [bhelgaas: commit log]
    Link: https://lore.kernel.org/r/20230201043018.778499-2-chenhuacai@xxxxxxxxxxx
    Signed-off-by: Huacai Chen <chenhuacai@xxxxxxxxxxx>
    Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
index 2cc2e60bcb396..46fad0d813b2b 100644
--- a/drivers/pci/pcie/portdrv.c
+++ b/drivers/pci/pcie/portdrv.c
@@ -501,7 +501,6 @@ static void pcie_port_device_remove(struct pci_dev *dev)
 {
 	device_for_each_child(&dev->dev, NULL, remove_iter);
 	pci_free_irq_vectors(dev);
-	pci_disable_device(dev);
 }
 
 /**
@@ -727,6 +726,19 @@ static void pcie_portdrv_remove(struct pci_dev *dev)
 	}
 
 	pcie_port_device_remove(dev);
+
+	pci_disable_device(dev);
+}
+
+static void pcie_portdrv_shutdown(struct pci_dev *dev)
+{
+	if (pci_bridge_d3_possible(dev)) {
+		pm_runtime_forbid(&dev->dev);
+		pm_runtime_get_noresume(&dev->dev);
+		pm_runtime_dont_use_autosuspend(&dev->dev);
+	}
+
+	pcie_port_device_remove(dev);
 }
 
 static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
@@ -777,7 +789,7 @@ static struct pci_driver pcie_portdriver = {
 
 	.probe		= pcie_portdrv_probe,
 	.remove		= pcie_portdrv_remove,
-	.shutdown	= pcie_portdrv_remove,
+	.shutdown	= pcie_portdrv_shutdown,
 
 	.err_handler	= &pcie_portdrv_err_handler,
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux