lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250610115532.7591-1-ilpo.jarvinen@linux.intel.com>
Date: Tue, 10 Jun 2025 14:55:31 +0300
From: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
To: Lukas Wunner <lukas@...ner.de>,
	Krzysztof Wilczyński <kw@...ux.com>,
	Bjorn Helgaas <bhelgaas@...gle.com>,
	Mika Westerberg <mika.westerberg@...ux.intel.com>,
	linux-pci@...r.kernel.org,
	linux-kernel@...r.kernel.org
Cc: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
Subject: [PATCH 1/1] PCI: Fix secondary bus wait return value when D3cold delay = 0

If D3cold delay is zero, pci_bridge_wait_for_secondary_bus()
immediately returns 0 which is inconsistent with the rest of the
function.

When D3cold delay is 0, infer the return value like in the other cases.
With link_active_reporting, use Data Link Layer Link Active (PCIe spec
r6.2 sec. 7.5.3.8) and otherwise call pci_dev_wait() with zero delay.

Fixes: ad9001f2f411 ("PCI/PM: Add missing link delays required by the PCIe spec")
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
---

I've not seen this to cause issue anywhere, it's just the inconsistency
that caught my eye while trying to figure an entirely unrelated issue.

 drivers/pci/pci.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e9448d55113b..a6182261b433 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4848,6 +4848,7 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
 {
 	struct pci_dev *child __free(pci_dev_put) = NULL;
 	int delay;
+	u16 status;
 
 	if (pci_dev_is_disconnected(dev))
 		return 0;
@@ -4870,15 +4871,19 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
 
 	/* Take d3cold_delay requirements into account */
 	delay = pci_bus_max_d3cold_delay(dev->subordinate);
-	if (!delay) {
-		up_read(&pci_bus_sem);
-		return 0;
-	}
 
 	child = pci_dev_get(list_first_entry(&dev->subordinate->devices,
 					     struct pci_dev, bus_list));
 	up_read(&pci_bus_sem);
 
+	if (!delay) {
+		if (dev->link_active_reporting) {
+			pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &status);
+			return status & PCI_EXP_LNKSTA_DLLLA ? 0 : -ENOTTY;
+		}
+		return pci_dev_wait(child, reset_type, 0);
+	}
+
 	/*
 	 * Conventional PCI and PCI-X we need to wait Tpvrh + Trhfa before
 	 * accessing the device after reset (that is 1000 ms + 100 ms).
@@ -4908,8 +4913,6 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
 		return 0;
 
 	if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) {
-		u16 status;
-
 		pci_dbg(dev, "waiting %d ms for downstream link\n", delay);
 		msleep(delay);
 

base-commit: 19272b37aa4f83ca52bdf9c16d5d81bdd1354494
-- 
2.39.5


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ