summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorStewart Smith <stewart@linux.ibm.com>2018-04-27 15:59:53 +1000
committerStewart Smith <stewart@linux.ibm.com>2018-04-29 19:52:06 -0500
commita22ba4576ad35dccb86622e71442794d09e62bce (patch)
tree0d062e0fde43832357195e48998e80defbf85130 /core
parenteab215a0bc28dfbc05047b62180313ecdb72c24f (diff)
downloadtalos-skiboot-a22ba4576ad35dccb86622e71442794d09e62bce.tar.gz
talos-skiboot-a22ba4576ad35dccb86622e71442794d09e62bce.zip
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>
Diffstat (limited to 'core')
-rw-r--r--core/pci-opal.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/core/pci-opal.c b/core/pci-opal.c
index 77e965cc..a4d6eeed 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,
OpenPOWER on IntegriCloud