summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorHeiner Kallweit <hkallweit1@gmail.com>2023-10-11 10:46:45 +0300
committerBjorn Helgaas <bhelgaas@google.com>2023-10-25 00:50:30 +0300
commit8e37372ad0bea4c9b4712d9943f6ae96cff9491f (patch)
tree6cf0a0128ab1f94963def5eba6d1a887ebdb8c78 /drivers/pci
parent3cb4f534bac010258b2688395c2f13459a932be9 (diff)
downloadlinux-8e37372ad0bea4c9b4712d9943f6ae96cff9491f.tar.xz
PCI/ASPM: Fix L1 substate handling in aspm_attr_store_common()
aspm_attr_store_common(), which handles sysfs control of ASPM, has the same problem as fb097dcd5a28 ("PCI/ASPM: Disable only ASPM_STATE_L1 when driver disables L1"): disabling L1 adds only ASPM_L1 (but not any of the L1.x substates) to the "aspm_disable" mask. Enabling one substate, e.g., L1.1, via sysfs removes ASPM_L1 from the disable mask. Since disabling L1 via sysfs doesn't add any of the substates to the disable mask, enabling L1.1 actually enables *all* the substates. In this scenario: - Write 0 to "l1_aspm" to disable L1 - Write 1 to "l1_1_aspm" to enable L1.1 the intention is to disable L1 and all L1.x substates, then enable just L1.1, but in fact, *all* L1.x substates are enabled. Fix this by explicitly disabling all the L1.x substates when disabling L1. Fixes: 72ea91afbfb0 ("PCI/ASPM: Add sysfs attributes for controlling ASPM link states") Link: https://lore.kernel.org/r/6ba7dd79-9cfe-4ed0-a002-d99cb842f361@gmail.com Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pcie/aspm.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index dc203b8e5a63..99656d669f00 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -1255,6 +1255,8 @@ static ssize_t aspm_attr_store_common(struct device *dev,
link->aspm_disable &= ~ASPM_STATE_L1;
} else {
link->aspm_disable |= state;
+ if (state & ASPM_STATE_L1)
+ link->aspm_disable |= ASPM_STATE_L1SS;
}
pcie_config_aspm_link(link, policy_to_aspm_state(link));