From: Brian Norris briannorris@google.com
Commit 48991e493507 ("PCI/sysfs: Ensure devices are powered for config reads") was applied to various linux-stable trees. However, prior to 6.12.y, we do not have commit d2bd39c0456b ("PCI: Store all PCIe Supported Link Speeds"). Therefore, we also need to apply the change to max_link_speed_show().
This was pointed out here:
Re: Patch "PCI/sysfs: Ensure devices are powered for config reads" has been added to the 6.6-stable tree https://lore.kernel.org/all/aPEMIreBYZ7yk3cm@google.com/
Original change description follows:
The "max_link_width", "current_link_speed", "current_link_width", "secondary_bus_number", and "subordinate_bus_number" sysfs files all access config registers, but they don't check the runtime PM state. If the device is in D3cold or a parent bridge is suspended, we may see -EINVAL, bogus values, or worse, depending on implementation details.
Wrap these access in pci_config_pm_runtime_{get,put}() like most of the rest of the similar sysfs attributes.
Notably, "max_link_speed" does not access config registers; it returns a cached value since d2bd39c0456b ("PCI: Store all PCIe Supported Link Speeds").
Fixes: 56c1af4606f0 ("PCI: Add sysfs max_link_speed/width, current_link_speed/width, etc") Link: https://lore.kernel.org/all/aPEMIreBYZ7yk3cm@google.com/ Signed-off-by: Brian Norris briannorris@google.com Signed-off-by: Brian Norris briannorris@chromium.org Cc: stable@vger.kernel.org --- This patch should be applicable to any linux-stable version that has commit 48991e493507 but not d2bd39c0456b. So far, I believe that's any linux-stable branch prior to 6.12.y.
I've tested this on 6.6.y.
drivers/pci/pci-sysfs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 449d42744d33..300caafcfa10 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -186,9 +186,15 @@ static ssize_t max_link_speed_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pci_dev *pdev = to_pci_dev(dev); + ssize_t ret; + + /* We read PCI_EXP_LNKCAP, so we need the device to be accessible. */ + pci_config_pm_runtime_get(pdev); + ret = sysfs_emit(buf, "%s\n", + pci_speed_string(pcie_get_speed_cap(pdev))); + pci_config_pm_runtime_put(pdev);
- return sysfs_emit(buf, "%s\n", - pci_speed_string(pcie_get_speed_cap(pdev))); + return ret; } static DEVICE_ATTR_RO(max_link_speed);
linux-stable-mirror@lists.linaro.org