Blob Blame History Raw
From 6f6f42466d902c92f21b46a45e6af22d1d663607 Mon Sep 17 00:00:00 2001
From: Bjorn Helgaas <bhelgaas@google.com>
Date: Mon, 25 Jun 2018 08:17:33 -0500
Subject: [PATCH] PCI: shpchp: Manage SHPC unconditionally on non-ACPI systems
Git-commit: 6f6f42466d902c92f21b46a45e6af22d1d663607
Patch-mainline: v4.18
References: FATE#26302 FATE#326303 FATE#326325

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>
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
 drivers/pci/hotplug/acpi_pcihp.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -21,7 +21,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * Send feedback to <kristen.c.accardi@intel.com>
- *
  */
 
 #include <linux/module.h>
@@ -101,8 +100,17 @@ int acpi_get_hp_hw_control_from_firmware
 		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;