diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2018-06-25 08:17:33 -0500 |
---|---|---|
committer | Bjorn Helgaas <helgaas@kernel.org> | 2018-06-26 08:22:45 -0500 |
commit | 6f6f42466d902c92f21b46a45e6af22d1d663607 (patch) | |
tree | 473b6e3aefa5dfaabcfac86f29dd075628fbef43 /drivers/pci | |
parent | ce397d215ccd07b8ae3f71db689aedb85d56ab40 (diff) |
PCI: shpchp: Manage SHPC unconditionally on non-ACPI systems
An SHPC can be operated either by platform firmware or by the OS. The OS
uses a host bridge ACPI _OSC method to negotiate for control of SHPC. If
firmware wants to prevent an OS from operating an SHPC, it must supply an
_OSC method that declines to grant SHPC ownership to the OS.
If acpi_pci_find_root() returns NULL, it means there's no ACPI host bridge
device (PNP0A03 or PNP0A08) and hence no _OSC method, so the OS is always
allowed to manage the SHPC.
Fix a NULL pointer dereference when CONFIG_ACPI=y but the current
hardware/firmware platform doesn't support ACPI. In that case,
acpi_get_hp_hw_control_from_firmware() is implemented but
acpi_pci_find_root() returns NULL.
Fixes: 90cc0c3cc709 ("PCI: shpchp: Add shpchp_is_native()")
Link: https://lkml.kernel.org/r/20180621164715.28160-1-marc.zyngier@arm.com
Reported-by: Marc Zyngier <marc.zyngier@arm.com>
Tested-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/acpi_pcihp.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 3979f89b250a..5bd6c1573295 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c @@ -7,7 +7,6 @@ * All rights reserved. * * Send feedback to <kristen.c.accardi@intel.com> - * */ #include <linux/module.h> @@ -87,8 +86,17 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev) return 0; /* If _OSC exists, we should not evaluate OSHP */ + + /* + * If there's no ACPI host bridge (i.e., ACPI support is compiled + * into the kernel but the hardware platform doesn't support ACPI), + * there's nothing to do here. + */ host = pci_find_host_bridge(pdev->bus); root = acpi_pci_find_root(ACPI_HANDLE(&host->dev)); + if (!root) + return 0; + if (root->osc_support_set) goto no_control; |