Blob Blame History Raw
From 048f7c3e352eeef50ed2c14dd89683f8a3af2f9b Mon Sep 17 00:00:00 2001
From: Corey Minyard <cminyard@mvista.com>
Date: Thu, 24 May 2018 15:07:29 -0500
Subject: [PATCH] ipmi: Properly release srcu locks on error conditions
Git-commit: 048f7c3e352eeef50ed2c14dd89683f8a3af2f9b
Patch-mainline: v4.18-rc1
References: FATE#326156

When SRCU was added for handling hotplug, some error conditions
were not handled properly.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/char/ipmi/ipmi_msghandler.c | 43 +++++++++++++++++------------
 1 file 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,
 			unsigned int  channel,
 			unsigned char address)
 {
-	int index;
+	int index, rv = 0;
 
 	user = acquire_ipmi_user(user, &index);
 	if (!user)
 		return -ENODEV;
 
 	if (channel >= IPMI_MAX_CHANNELS)
-		return -EINVAL;
-	user->intf->addrinfo[channel].address = address;
+		rv = -EINVAL;
+	else
+		user->intf->addrinfo[channel].address = address;
 	release_ipmi_user(user, index);
 
-	return 0;
+	return rv;
 }
 EXPORT_SYMBOL(ipmi_set_my_address);
 
@@ -1310,18 +1311,19 @@ int ipmi_get_my_address(struct ipmi_user *user,
 			unsigned int  channel,
 			unsigned char *address)
 {
-	int index;
+	int index, rv = 0;
 
 	user = acquire_ipmi_user(user, &index);
 	if (!user)
 		return -ENODEV;
 
 	if (channel >= IPMI_MAX_CHANNELS)
-		return -EINVAL;
-	*address = user->intf->addrinfo[channel].address;
+		rv = -EINVAL;
+	else
+		*address = user->intf->addrinfo[channel].address;
 	release_ipmi_user(user, index);
 
-	return 0;
+	return rv;
 }
 EXPORT_SYMBOL(ipmi_get_my_address);
 
@@ -1329,15 +1331,16 @@ int ipmi_set_my_LUN(struct ipmi_user *user,
 		    unsigned int  channel,
 		    unsigned char LUN)
 {
-	int index;
+	int index, rv = 0;
 
 	user = acquire_ipmi_user(user, &index);
 	if (!user)
 		return -ENODEV;
 
 	if (channel >= IPMI_MAX_CHANNELS)
-		return -EINVAL;
-	user->intf->addrinfo[channel].lun = LUN & 0x3;
+		rv = -EINVAL;
+	else
+		user->intf->addrinfo[channel].lun = LUN & 0x3;
 	release_ipmi_user(user, index);
 
 	return 0;
@@ -1348,18 +1351,19 @@ int ipmi_get_my_LUN(struct ipmi_user *user,
 		    unsigned int  channel,
 		    unsigned char *address)
 {
-	int index;
+	int index, rv = 0;
 
 	user = acquire_ipmi_user(user, &index);
 	if (!user)
 		return -ENODEV;
 
 	if (channel >= IPMI_MAX_CHANNELS)
-		return -EINVAL;
-	*address = user->intf->addrinfo[channel].lun;
+		rv = -EINVAL;
+	else
+		*address = user->intf->addrinfo[channel].lun;
 	release_ipmi_user(user, index);
 
-	return 0;
+	return rv;
 }
 EXPORT_SYMBOL(ipmi_get_my_LUN);
 
@@ -1540,8 +1544,10 @@ int ipmi_register_for_cmd(struct ipmi_user *user,
 		return -ENODEV;
 
 	rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL);
-	if (!rcvr)
-		return -ENOMEM;
+	if (!rcvr) {
+		rv = -ENOMEM;
+		goto out_release;
+	}
 	rcvr->cmd = cmd;
 	rcvr->netfn = netfn;
 	rcvr->chans = chans;
@@ -1559,10 +1565,11 @@ int ipmi_register_for_cmd(struct ipmi_user *user,
 
 	list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
 
- out_unlock:
+out_unlock:
 	mutex_unlock(&intf->cmd_rcvrs_mutex);
 	if (rv)
 		kfree(rcvr);
+out_release:
 	release_ipmi_user(user, index);
 
 	return rv;
-- 
2.19.2