diff options
author | Stewart Smith <stewart@linux.ibm.com> | 2018-04-27 15:59:53 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.ibm.com> | 2018-04-29 19:52:30 -0500 |
commit | b5f8695e8983afc18caab65003cffe6b5bf4d5ec (patch) | |
tree | 7884775ad2a08cc4ec6b3634dbfa9fc1e7faa971 | |
parent | 4acd876d21b71d15b9eca2ddf741f7f5aea0c7b8 (diff) | |
download | skiboot-b5f8695e8983afc18caab65003cffe6b5bf4d5ec.zip skiboot-b5f8695e8983afc18caab65003cffe6b5bf4d5ec.tar.gz skiboot-b5f8695e8983afc18caab65003cffe6b5bf4d5ec.tar.bz2 |
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 <stewart@linux.ibm.com>
(cherry picked from commit a22ba4576ad35dccb86622e71442794d09e62bce)
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
-rw-r--r-- | core/pci-opal.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/core/pci-opal.c b/core/pci-opal.c index 27872aa..5dc05fc 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, |