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: <20210812153944.813949-1-kai.heng.feng@canonical.com>
Date:   Thu, 12 Aug 2021 23:39:44 +0800
From:   Kai-Heng Feng <kai.heng.feng@...onical.com>
To:     bhelgaas@...gle.com
Cc:     Kai-Heng Feng <kai.heng.feng@...onical.com>,
        Lukas Wunner <lukas@...ner.de>,
        Mika Westerberg <mika.westerberg@...ux.intel.com>,
        "Rafael J . Wysocki" <rafael.j.wysocki@...el.com>,
        linux-pci@...r.kernel.org (open list:PCI SUBSYSTEM),
        linux-kernel@...r.kernel.org (open list)
Subject: [PATCH v2] PCI: Check PCIe upstream port for PME support

Some platforms cannot detect ethernet hotplug once its upstream port is
runtime suspended because PME isn't granted by BIOS _OSC. The issue can
be workarounded by "pcie_ports=native".

The vendor confirmed that the PME in _OSC is disabled intentionally for
system stability issues on the other OS, so we should also honor the PME
setting here.

So before marking PME support status for the device, check
PCI_EXP_RTCTL_PMEIE bit to ensure PME interrupt is either enabled by
firmware or OS.

Cc: Lukas Wunner <lukas@...ner.de>
Cc: Mika Westerberg <mika.westerberg@...ux.intel.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@...el.com>
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=213873
Signed-off-by: Kai-Heng Feng <kai.heng.feng@...onical.com>
---
v2:
 - Instead of prevent root port from runtime suspending, skip
   initializing PME status for the downstream device.

 drivers/pci/pci.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index aacf575c15cf..4344dc302edd 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2294,6 +2294,32 @@ void pci_pme_wakeup_bus(struct pci_bus *bus)
 		pci_walk_bus(bus, pci_pme_wakeup, (void *)true);
 }
 
+#ifdef CONFIG_PCIE_PME
+static bool pci_pcie_port_pme_enabled(struct pci_dev *dev)
+{
+	struct pci_dev *bridge = pci_upstream_bridge(dev);
+	u16 val;
+	int ret;
+
+	if (!bridge)
+		return true;
+
+	if (pci_pcie_type(bridge) != PCI_EXP_TYPE_ROOT_PORT &&
+	    pci_pcie_type(bridge) != PCI_EXP_TYPE_RC_EC)
+		return true;
+
+	ret = pcie_capability_read_word(bridge, PCI_EXP_RTCTL, &val);
+	if (ret)
+		return false;
+
+	return val & PCI_EXP_RTCTL_PMEIE;
+}
+#else
+static bool pci_pcie_port_pme_enabled(struct pci_dev *dev)
+{
+	return true;
+}
+#endif
 
 /**
  * pci_pme_capable - check the capability of PCI device to generate PME#
@@ -3095,7 +3121,7 @@ void pci_pm_init(struct pci_dev *dev)
 	}
 
 	pmc &= PCI_PM_CAP_PME_MASK;
-	if (pmc) {
+	if (pmc && pci_pcie_port_pme_enabled(dev)) {
 		pci_info(dev, "PME# supported from%s%s%s%s%s\n",
 			 (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
 			 (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
-- 
2.32.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ