Skip to content

Commit

Permalink
PCI/sysfs: Protect driver's D3cold preference from user space
Browse files Browse the repository at this point in the history
commit 70b70a4 upstream.

struct pci_dev contains two flags which govern whether the device may
suspend to D3cold:

* no_d3cold provides an opt-out for drivers (e.g. if a device is known
  to not wake from D3cold)

* d3cold_allowed provides an opt-out for user space (default is true,
  user space may set to false)

Since commit 9d26d3a ("PCI: Put PCIe ports into D3 during suspend"),
the user space setting overwrites the driver setting.  Essentially user
space is trusted to know better than the driver whether D3cold is
working.

That feels unsafe and wrong.  Assume that the change was introduced
inadvertently and do not overwrite no_d3cold when d3cold_allowed is
modified.  Instead, consider d3cold_allowed in addition to no_d3cold
when choosing a suspend state for the device.

That way, user space may opt out of D3cold if the driver hasn't, but it
may no longer force an opt in if the driver has opted out.

Fixes: 9d26d3a ("PCI: Put PCIe ports into D3 during suspend")
Link: https://lore.kernel.org/r/b8a7f4af2b73f6b506ad8ddee59d747cbf834606.1695025365.git.lukas@wunner.de
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Cc: stable@vger.kernel.org	# v4.8+
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
l1k authored and gregkh committed Nov 28, 2023
1 parent 5d93cb1 commit 93a0630
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 5 deletions.
2 changes: 1 addition & 1 deletion drivers/pci/pci-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -911,7 +911,7 @@ pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
{
int acpi_state, d_max;

if (pdev->no_d3cold)
if (pdev->no_d3cold || !pdev->d3cold_allowed)
d_max = ACPI_STATE_D3_HOT;
else
d_max = ACPI_STATE_D3_COLD;
Expand Down
5 changes: 1 addition & 4 deletions drivers/pci/pci-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,10 +529,7 @@ static ssize_t d3cold_allowed_store(struct device *dev,
return -EINVAL;

pdev->d3cold_allowed = !!val;
if (pdev->d3cold_allowed)
pci_d3cold_enable(pdev);
else
pci_d3cold_disable(pdev);
pci_bridge_d3_update(pdev);

pm_runtime_resume(dev);

Expand Down

0 comments on commit 93a0630

Please sign in to comment.