diff options
author | Corey Minyard <cminyard@mvista.com> | 2018-05-24 16:07:29 -0400 |
---|---|---|
committer | Corey Minyard <cminyard@mvista.com> | 2018-05-24 16:08:30 -0400 |
commit | 048f7c3e352eeef50ed2c14dd89683f8a3af2f9b (patch) | |
tree | 1b7150f56e761fa28b8e4fee5bfdf05f8e03f60a | |
parent | 58aae18eb95ad95486bc98717c213ff48d94b98c (diff) |
ipmi: Properly release srcu locks on error conditions
When SRCU was added for handling hotplug, some error conditions
were not handled properly.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 606d561fe0e2..51832b8a2c62 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -1291,18 +1291,19 @@ int ipmi_set_my_address(struct ipmi_user *user, | |||
1291 | unsigned int channel, | 1291 | unsigned int channel, |
1292 | unsigned char address) | 1292 | unsigned char address) |
1293 | { | 1293 | { |
1294 | int index; | 1294 | int index, rv = 0; |
1295 | 1295 | ||
1296 | user = acquire_ipmi_user(user, &index); | 1296 | user = acquire_ipmi_user(user, &index); |
1297 | if (!user) | 1297 | if (!user) |
1298 | return -ENODEV; | 1298 | return -ENODEV; |
1299 | 1299 | ||
1300 | if (channel >= IPMI_MAX_CHANNELS) | 1300 | if (channel >= IPMI_MAX_CHANNELS) |
1301 | return -EINVAL; | 1301 | rv = -EINVAL; |
1302 | user->intf->addrinfo[channel].address = address; | 1302 | else |
1303 | user->intf->addrinfo[channel].address = address; | ||
1303 | release_ipmi_user(user, index); | 1304 | release_ipmi_user(user, index); |
1304 | 1305 | ||
1305 | return 0; | 1306 | return rv; |
1306 | } | 1307 | } |
1307 | EXPORT_SYMBOL(ipmi_set_my_address); | 1308 | EXPORT_SYMBOL(ipmi_set_my_address); |
1308 | 1309 | ||
@@ -1310,18 +1311,19 @@ int ipmi_get_my_address(struct ipmi_user *user, | |||
1310 | unsigned int channel, | 1311 | unsigned int channel, |
1311 | unsigned char *address) | 1312 | unsigned char *address) |
1312 | { | 1313 | { |
1313 | int index; | 1314 | int index, rv = 0; |
1314 | 1315 | ||
1315 | user = acquire_ipmi_user(user, &index); | 1316 | user = acquire_ipmi_user(user, &index); |
1316 | if (!user) | 1317 | if (!user) |
1317 | return -ENODEV; | 1318 | return -ENODEV; |
1318 | 1319 | ||
1319 | if (channel >= IPMI_MAX_CHANNELS) | 1320 | if (channel >= IPMI_MAX_CHANNELS) |
1320 | return -EINVAL; | 1321 | rv = -EINVAL; |
1321 | *address = user->intf->addrinfo[channel].address; | 1322 | else |
1323 | *address = user->intf->addrinfo[channel].address; | ||
1322 | release_ipmi_user(user, index); | 1324 | release_ipmi_user(user, index); |
1323 | 1325 | ||
1324 | return 0; | 1326 | return rv; |
1325 | } | 1327 | } |
1326 | EXPORT_SYMBOL(ipmi_get_my_address); | 1328 | EXPORT_SYMBOL(ipmi_get_my_address); |
1327 | 1329 | ||
@@ -1329,15 +1331,16 @@ int ipmi_set_my_LUN(struct ipmi_user *user, | |||
1329 | unsigned int channel, | 1331 | unsigned int channel, |
1330 | unsigned char LUN) | 1332 | unsigned char LUN) |
1331 | { | 1333 | { |
1332 | int index; | 1334 | int index, rv = 0; |
1333 | 1335 | ||
1334 | user = acquire_ipmi_user(user, &index); | 1336 | user = acquire_ipmi_user(user, &index); |
1335 | if (!user) | 1337 | if (!user) |
1336 | return -ENODEV; | 1338 | return -ENODEV; |
1337 | 1339 | ||
1338 | if (channel >= IPMI_MAX_CHANNELS) | 1340 | if (channel >= IPMI_MAX_CHANNELS) |
1339 | return -EINVAL; | 1341 | rv = -EINVAL; |
1340 | user->intf->addrinfo[channel].lun = LUN & 0x3; | 1342 | else |
1343 | user->intf->addrinfo[channel].lun = LUN & 0x3; | ||
1341 | release_ipmi_user(user, index); | 1344 | release_ipmi_user(user, index); |
1342 | 1345 | ||
1343 | return 0; | 1346 | return 0; |
@@ -1348,18 +1351,19 @@ int ipmi_get_my_LUN(struct ipmi_user *user, | |||
1348 | unsigned int channel, | 1351 | unsigned int channel, |
1349 | unsigned char *address) | 1352 | unsigned char *address) |
1350 | { | 1353 | { |
1351 | int index; | 1354 | int index, rv = 0; |
1352 | 1355 | ||
1353 | user = acquire_ipmi_user(user, &index); | 1356 | user = acquire_ipmi_user(user, &index); |
1354 | if (!user) | 1357 | if (!user) |
1355 | return -ENODEV; | 1358 | return -ENODEV; |
1356 | 1359 | ||
1357 | if (channel >= IPMI_MAX_CHANNELS) | 1360 | if (channel >= IPMI_MAX_CHANNELS) |
1358 | return -EINVAL; | 1361 | rv = -EINVAL; |
1359 | *address = user->intf->addrinfo[channel].lun; | 1362 | else |
1363 | *address = user->intf->addrinfo[channel].lun; | ||
1360 | release_ipmi_user(user, index); | 1364 | release_ipmi_user(user, index); |
1361 | 1365 | ||
1362 | return 0; | 1366 | return rv; |
1363 | } | 1367 | } |
1364 | EXPORT_SYMBOL(ipmi_get_my_LUN); | 1368 | EXPORT_SYMBOL(ipmi_get_my_LUN); |
1365 | 1369 | ||
@@ -1540,8 +1544,10 @@ int ipmi_register_for_cmd(struct ipmi_user *user, | |||
1540 | return -ENODEV; | 1544 | return -ENODEV; |
1541 | 1545 | ||
1542 | rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL); | 1546 | rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL); |
1543 | if (!rcvr) | 1547 | if (!rcvr) { |
1544 | return -ENOMEM; | 1548 | rv = -ENOMEM; |
1549 | goto out_release; | ||
1550 | } | ||
1545 | rcvr->cmd = cmd; | 1551 | rcvr->cmd = cmd; |
1546 | rcvr->netfn = netfn; | 1552 | rcvr->netfn = netfn; |
1547 | rcvr->chans = chans; | 1553 | rcvr->chans = chans; |
@@ -1559,10 +1565,11 @@ int ipmi_register_for_cmd(struct ipmi_user *user, | |||
1559 | 1565 | ||
1560 | list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); | 1566 | list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); |
1561 | 1567 | ||
1562 | out_unlock: | 1568 | out_unlock: |
1563 | mutex_unlock(&intf->cmd_rcvrs_mutex); | 1569 | mutex_unlock(&intf->cmd_rcvrs_mutex); |
1564 | if (rv) | 1570 | if (rv) |
1565 | kfree(rcvr); | 1571 | kfree(rcvr); |
1572 | out_release: | ||
1566 | release_ipmi_user(user, index); | 1573 | release_ipmi_user(user, index); |
1567 | 1574 | ||
1568 | return rv; | 1575 | return rv; |