[Skiboot] [PATCH] OPAL_PCI_SET_POWER_STATE: fix locking in error paths

Stewart Smith stewart at linux.ibm.com
Fri Apr 27 15:59:53 AEST 2018


Otherwise we could exit OPAL holding locks, potentially leading
to all sorts of problems later on.

Cc: stable # 5.3+
Fixes: 7a3e2c4ee3aa0
Signed-off-by: Stewart Smith <stewart at linux.ibm.com>
---
 core/pci-opal.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/core/pci-opal.c b/core/pci-opal.c
index 77e965cc2065..a4d6eeed9b58 100644
--- a/core/pci-opal.c
+++ b/core/pci-opal.c
@@ -785,8 +785,10 @@ static int64_t opal_pci_set_power_state(uint64_t async_token,
 	switch (*state) {
 	case OPAL_PCI_SLOT_POWER_OFF:
 		if (!slot->ops.prepare_link_change ||
-		    !slot->ops.set_power_state)
+		    !slot->ops.set_power_state) {
+			phb_unlock(phb);
 			return OPAL_UNSUPPORTED;
+		}
 
 		slot->async_token = async_token;
 		slot->ops.prepare_link_change(slot, false);
@@ -794,22 +796,28 @@ static int64_t opal_pci_set_power_state(uint64_t async_token,
 		break;
 	case OPAL_PCI_SLOT_POWER_ON:
 		if (!slot->ops.set_power_state ||
-		    !slot->ops.get_link_state)
+		    !slot->ops.get_link_state) {
+			phb_unlock(phb);
 			return OPAL_UNSUPPORTED;
+		}
 
 		slot->async_token = async_token;
 		rc = slot->ops.set_power_state(slot, PCI_SLOT_POWER_ON);
 		break;
 	case OPAL_PCI_SLOT_OFFLINE:
-		if (!pd)
+		if (!pd) {
+			phb_unlock(phb);
 			return OPAL_PARAMETER;
+		}
 
 		pci_remove_bus(phb, &pd->children);
 		phb_unlock(phb);
 		return OPAL_SUCCESS;
 	case OPAL_PCI_SLOT_ONLINE:
-		if (!pd)
+		if (!pd) {
+			phb_unlock(phb);
 			return OPAL_PARAMETER;
+		}
 		pci_scan_bus(phb, pd->secondary_bus, pd->subordinate_bus,
 			     &pd->children, pd, true);
 		pci_add_device_nodes(phb, &pd->children, pd->dn,
-- 
2.14.3



More information about the Skiboot mailing list