From a22ba4576ad35dccb86622e71442794d09e62bce Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Fri, 27 Apr 2018 15:59:53 +1000 Subject: OPAL_PCI_SET_POWER_STATE: fix locking in error paths 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 --- core/pci-opal.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'core') diff --git a/core/pci-opal.c b/core/pci-opal.c index 77e965c..a4d6eee 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, -- cgit v1.1