|
| 1 | +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Nathan Wolfe < [email protected]> |
| 3 | +Date: Tue, 8 Oct 2024 11:57:26 -0700 |
| 4 | +Subject: [PATCH] revert 456d8aa to fix pcie_aspm_exit_link_status |
| 5 | + |
| 6 | +For certain pci tree structures involving pci devices with sibling |
| 7 | +functions we can get a nullptr dereference when the link state goes down |
| 8 | +due to this change. |
| 9 | + |
| 10 | +https://github.com/torvalds/linux/commit/456d8aa37d0f56fc9e985e812496e861dcd6f2f2 |
| 11 | +Upstream Discussion: |
| 12 | +https://lore.kernel.org/linux-pci/20240801171103.GA107989@bhelgaas/T/#t |
| 13 | +--- |
| 14 | + drivers/pci/pcie/aspm.c | 21 +++++++++------------ |
| 15 | + 1 file changed, 9 insertions(+), 12 deletions(-) |
| 16 | + |
| 17 | +diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c |
| 18 | +index cf4acea66..188517c5a 100644 |
| 19 | +--- a/drivers/pci/pcie/aspm.c |
| 20 | ++++ b/drivers/pci/pcie/aspm.c |
| 21 | +@@ -1025,24 +1025,21 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) |
| 22 | + |
| 23 | + down_read(&pci_bus_sem); |
| 24 | + mutex_lock(&aspm_lock); |
| 25 | ++ /* |
| 26 | ++ * All PCIe functions are in one slot, remove one function will remove |
| 27 | ++ * the whole slot, so just wait until we are the last function left. |
| 28 | ++ */ |
| 29 | ++ if (!list_empty(&parent->subordinate->devices)) |
| 30 | ++ goto out; |
| 31 | + |
| 32 | + link = parent->link_state; |
| 33 | + root = link->root; |
| 34 | + parent_link = link->parent; |
| 35 | + |
| 36 | +- /* |
| 37 | +- * link->downstream is a pointer to the pci_dev of function 0. If |
| 38 | +- * we remove that function, the pci_dev is about to be deallocated, |
| 39 | +- * so we can't use link->downstream again. Free the link state to |
| 40 | +- * avoid this. |
| 41 | +- * |
| 42 | +- * If we're removing a non-0 function, it's possible we could |
| 43 | +- * retain the link state, but PCIe r6.0, sec 7.5.3.7, recommends |
| 44 | +- * programming the same ASPM Control value for all functions of |
| 45 | +- * multi-function devices, so disable ASPM for all of them. |
| 46 | +- */ |
| 47 | ++ /* All functions are removed, so just disable ASPM for the link */ |
| 48 | + pcie_config_aspm_link(link, 0); |
| 49 | + list_del(&link->sibling); |
| 50 | ++ /* Clock PM is for endpoint device */ |
| 51 | + free_link_state(link); |
| 52 | + |
| 53 | + /* Recheck latencies and configure upstream links */ |
| 54 | +@@ -1050,7 +1047,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) |
| 55 | + pcie_update_aspm_capable(root); |
| 56 | + pcie_config_aspm_path(parent_link); |
| 57 | + } |
| 58 | +- |
| 59 | ++out: |
| 60 | + mutex_unlock(&aspm_lock); |
| 61 | + up_read(&pci_bus_sem); |
| 62 | + } |
0 commit comments