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-prev] [day] [month] [year] [list]
Message-ID: <Z8F1z-gyXJDyR6d0@wunner.de>
Date: Fri, 28 Feb 2025 09:37:35 +0100
From: Lukas Wunner <lukas@...ner.de>
To: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
Cc: Bjorn Helgaas <bhelgaas@...gle.com>,
	Jonathan Cameron <Jonathan.Cameron@...wei.com>,
	linux-pci@...r.kernel.org, LKML <linux-kernel@...r.kernel.org>,
	Joel Mathew Thomas <proxy0@...amail.com>, stable@...r.kernel.org
Subject: Re: [PATCH 1/1] PCI/bwctrl: Disable PCIe BW controller during reset

On Thu, Feb 27, 2025 at 06:31:08AM +0100, Lukas Wunner wrote:
> pcie_bwnotif_irq() accesses the Link Status register without
> acquiring a runtime PM reference on the PCIe port.  This feels
> wrong and may also contribute to the issue reported here.
> Acquiring a runtime PM ref may sleep, so I think you need to
> change the driver to use a threaded IRQ handler.

I've realized we've had a discussion before why a threaded IRQ handler
doesn't make sense...

https://lore.kernel.org/all/Z35qJ3H_8u5LQDJ6@wunner.de/

...but I'm still worried that a Downstream Port in a nested-switch
configuration may be runtime suspended while the hardirq handler
is running.  Is there anything preventing that from happening?

To access config space of a port, it's sufficient if its upstream
bridge is runtime active (i.e. in PCI D0).

So basically the below is what I have in mind.  This assumes that
the upstream bridge is still in D0 when the interrupt handler runs
because in atomic context we can't wait for it to be runtime resumed.
Seems like a fair assumption to me but what do I know...

-- >8 --

diff --git a/drivers/pci/pcie/bwctrl.c b/drivers/pci/pcie/bwctrl.c
index 0a5e7efbce2c..fea8f7412266 100644
--- a/drivers/pci/pcie/bwctrl.c
+++ b/drivers/pci/pcie/bwctrl.c
@@ -28,6 +28,7 @@
 #include <linux/mutex.h>
 #include <linux/pci.h>
 #include <linux/pci-bwctrl.h>
+#include <linux/pm_runtime.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -235,9 +236,13 @@ static irqreturn_t pcie_bwnotif_irq(int irq, void *context)
 	struct pcie_device *srv = context;
 	struct pcie_bwctrl_data *data = srv->port->link_bwctrl;
 	struct pci_dev *port = srv->port;
+	struct device *parent __free(pm_runtime_put) = port->dev.parent;
 	u16 link_status, events;
 	int ret;
 
+	if (parent)
+		pm_runtime_get_noresume(parent);
+
 	ret = pcie_capability_read_word(port, PCI_EXP_LNKSTA, &link_status);
 	if (ret != PCIBIOS_SUCCESSFUL)
 		return IRQ_NONE;
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index d39dc863f612..038228de773d 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -448,6 +448,8 @@ static inline int pm_runtime_put(struct device *dev)
 	return __pm_runtime_idle(dev, RPM_GET_PUT | RPM_ASYNC);
 }
 
+DEFINE_FREE(pm_runtime_put, struct device *, if (_T) pm_runtime_put(_T))
+
 /**
  * __pm_runtime_put_autosuspend - Drop device usage counter and queue autosuspend if 0.
  * @dev: Target device.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ