aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorey Minyard <cminyard@mvista.com>2018-05-24 16:07:29 -0400
committerCorey Minyard <cminyard@mvista.com>2018-05-24 16:08:30 -0400
commit048f7c3e352eeef50ed2c14dd89683f8a3af2f9b (patch)
tree1b7150f56e761fa28b8e4fee5bfdf05f8e03f60a
parent58aae18eb95ad95486bc98717c213ff48d94b98c (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.c43
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}
1307EXPORT_SYMBOL(ipmi_set_my_address); 1308EXPORT_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}
1326EXPORT_SYMBOL(ipmi_get_my_address); 1328EXPORT_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}
1364EXPORT_SYMBOL(ipmi_get_my_LUN); 1368EXPORT_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: 1568out_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);
1572out_release:
1566 release_ipmi_user(user, index); 1573 release_ipmi_user(user, index);
1567 1574
1568 return rv; 1575 return rv;