[PATCH 3.2 134/147] staging: reduce stack usage in prism2fw.c

From: Ben Hutchings
Date: Mon Nov 06 2017 - 20:25:42 EST


3.2.95-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Randy Dunlap <rdunlap@xxxxxxxxxxxx>

commit c90e3e80b9751335cc98934ae32188fa7de6bccd upstream.

Fix frame size (stack usage) warning by allocating and freeing
pointers to the data.

drivers/staging/wlan-ng/prism2fw.c:1115:1: warning: the frame size of 4288 bytes is larger than 2048 bytes

Signed-off-by: Randy Dunlap <rdunlap@xxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx>
---
drivers/staging/wlan-ng/prism2fw.c | 124 +++++++++++++++++++++----------------
1 file changed, 69 insertions(+), 55 deletions(-)

--- a/drivers/staging/wlan-ng/prism2fw.c
+++ b/drivers/staging/wlan-ng/prism2fw.c
@@ -980,9 +980,8 @@ int writeimage(wlandevice_t *wlandev, st
unsigned int nfchunks)
{
int result = 0;
- struct p80211msg_p2req_ramdl_state rstatemsg;
- struct p80211msg_p2req_ramdl_write rwritemsg;
- struct p80211msg *msgp;
+ struct p80211msg_p2req_ramdl_state *rstmsg;
+ struct p80211msg_p2req_ramdl_write *rwrmsg;
u32 resultcode;
int i;
int j;
@@ -991,57 +990,68 @@ int writeimage(wlandevice_t *wlandev, st
u32 currlen;
u32 currdaddr;

+ rstmsg = kmalloc(sizeof(*rstmsg), GFP_KERNEL);
+ rwrmsg = kmalloc(sizeof(*rwrmsg), GFP_KERNEL);
+ if (!rstmsg || !rwrmsg) {
+ kfree(rstmsg);
+ kfree(rwrmsg);
+ printk(KERN_ERR
+ "writeimage: no memory for firmware download, "
+ "aborting download\n");
+ return -ENOMEM;
+ }
+
/* Initialize the messages */
- memset(&rstatemsg, 0, sizeof(rstatemsg));
- strcpy(rstatemsg.devname, wlandev->name);
- rstatemsg.msgcode = DIDmsg_p2req_ramdl_state;
- rstatemsg.msglen = sizeof(rstatemsg);
- rstatemsg.enable.did = DIDmsg_p2req_ramdl_state_enable;
- rstatemsg.exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr;
- rstatemsg.resultcode.did = DIDmsg_p2req_ramdl_state_resultcode;
- rstatemsg.enable.status = P80211ENUM_msgitem_status_data_ok;
- rstatemsg.exeaddr.status = P80211ENUM_msgitem_status_data_ok;
- rstatemsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
- rstatemsg.enable.len = sizeof(u32);
- rstatemsg.exeaddr.len = sizeof(u32);
- rstatemsg.resultcode.len = sizeof(u32);
-
- memset(&rwritemsg, 0, sizeof(rwritemsg));
- strcpy(rwritemsg.devname, wlandev->name);
- rwritemsg.msgcode = DIDmsg_p2req_ramdl_write;
- rwritemsg.msglen = sizeof(rwritemsg);
- rwritemsg.addr.did = DIDmsg_p2req_ramdl_write_addr;
- rwritemsg.len.did = DIDmsg_p2req_ramdl_write_len;
- rwritemsg.data.did = DIDmsg_p2req_ramdl_write_data;
- rwritemsg.resultcode.did = DIDmsg_p2req_ramdl_write_resultcode;
- rwritemsg.addr.status = P80211ENUM_msgitem_status_data_ok;
- rwritemsg.len.status = P80211ENUM_msgitem_status_data_ok;
- rwritemsg.data.status = P80211ENUM_msgitem_status_data_ok;
- rwritemsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
- rwritemsg.addr.len = sizeof(u32);
- rwritemsg.len.len = sizeof(u32);
- rwritemsg.data.len = WRITESIZE_MAX;
- rwritemsg.resultcode.len = sizeof(u32);
+ memset(rstmsg, 0, sizeof(*rstmsg));
+ strcpy(rstmsg->devname, wlandev->name);
+ rstmsg->msgcode = DIDmsg_p2req_ramdl_state;
+ rstmsg->msglen = sizeof(*rstmsg);
+ rstmsg->enable.did = DIDmsg_p2req_ramdl_state_enable;
+ rstmsg->exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr;
+ rstmsg->resultcode.did = DIDmsg_p2req_ramdl_state_resultcode;
+ rstmsg->enable.status = P80211ENUM_msgitem_status_data_ok;
+ rstmsg->exeaddr.status = P80211ENUM_msgitem_status_data_ok;
+ rstmsg->resultcode.status = P80211ENUM_msgitem_status_no_value;
+ rstmsg->enable.len = sizeof(u32);
+ rstmsg->exeaddr.len = sizeof(u32);
+ rstmsg->resultcode.len = sizeof(u32);
+
+ memset(rwrmsg, 0, sizeof(*rwrmsg));
+ strcpy(rwrmsg->devname, wlandev->name);
+ rwrmsg->msgcode = DIDmsg_p2req_ramdl_write;
+ rwrmsg->msglen = sizeof(*rwrmsg);
+ rwrmsg->addr.did = DIDmsg_p2req_ramdl_write_addr;
+ rwrmsg->len.did = DIDmsg_p2req_ramdl_write_len;
+ rwrmsg->data.did = DIDmsg_p2req_ramdl_write_data;
+ rwrmsg->resultcode.did = DIDmsg_p2req_ramdl_write_resultcode;
+ rwrmsg->addr.status = P80211ENUM_msgitem_status_data_ok;
+ rwrmsg->len.status = P80211ENUM_msgitem_status_data_ok;
+ rwrmsg->data.status = P80211ENUM_msgitem_status_data_ok;
+ rwrmsg->resultcode.status = P80211ENUM_msgitem_status_no_value;
+ rwrmsg->addr.len = sizeof(u32);
+ rwrmsg->len.len = sizeof(u32);
+ rwrmsg->data.len = WRITESIZE_MAX;
+ rwrmsg->resultcode.len = sizeof(u32);

/* Send xxx_state(enable) */
pr_debug("Sending dl_state(enable) message.\n");
- rstatemsg.enable.data = P80211ENUM_truth_true;
- rstatemsg.exeaddr.data = startaddr;
+ rstmsg->enable.data = P80211ENUM_truth_true;
+ rstmsg->exeaddr.data = startaddr;

- msgp = (struct p80211msg *) &rstatemsg;
- result = prism2mgmt_ramdl_state(wlandev, msgp);
+ result = prism2mgmt_ramdl_state(wlandev, rstmsg);
if (result) {
printk(KERN_ERR
"writeimage state enable failed w/ result=%d, "
"aborting download\n", result);
- return result;
+ goto free_result;
}
- resultcode = rstatemsg.resultcode.data;
+ resultcode = rstmsg->resultcode.data;
if (resultcode != P80211ENUM_resultcode_success) {
printk(KERN_ERR
"writeimage()->xxxdl_state msg indicates failure, "
"w/ resultcode=%d, aborting download.\n", resultcode);
- return 1;
+ result = 1;
+ goto free_result;
}

/* Now, loop through the data chunks and send WRITESIZE_MAX data */
@@ -1059,9 +1069,9 @@ int writeimage(wlandevice_t *wlandev, st
curroff = j * WRITESIZE_MAX;
currdaddr = fchunk[i].addr + curroff;
/* Setup the message */
- rwritemsg.addr.data = currdaddr;
- rwritemsg.len.data = currlen;
- memcpy(rwritemsg.data.data,
+ rwrmsg->addr.data = currdaddr;
+ rwrmsg->len.data = currlen;
+ memcpy(rwrmsg->data.data,
fchunk[i].data + curroff, currlen);

/* Send flashdl_write(pda) */
@@ -1069,23 +1079,23 @@ int writeimage(wlandevice_t *wlandev, st
("Sending xxxdl_write message addr=%06x len=%d.\n",
currdaddr, currlen);

- msgp = (struct p80211msg *) &rwritemsg;
- result = prism2mgmt_ramdl_write(wlandev, msgp);
+ result = prism2mgmt_ramdl_write(wlandev, rwrmsg);

/* Check the results */
if (result) {
printk(KERN_ERR
"writeimage chunk write failed w/ result=%d, "
"aborting download\n", result);
- return result;
+ goto free_result;
}
- resultcode = rstatemsg.resultcode.data;
+ resultcode = rstmsg->resultcode.data;
if (resultcode != P80211ENUM_resultcode_success) {
printk(KERN_ERR
"writeimage()->xxxdl_write msg indicates failure, "
"w/ resultcode=%d, aborting download.\n",
resultcode);
- return 1;
+ result = 1;
+ goto free_result;
}

}
@@ -1093,24 +1103,28 @@ int writeimage(wlandevice_t *wlandev, st

/* Send xxx_state(disable) */
pr_debug("Sending dl_state(disable) message.\n");
- rstatemsg.enable.data = P80211ENUM_truth_false;
- rstatemsg.exeaddr.data = 0;
+ rstmsg->enable.data = P80211ENUM_truth_false;
+ rstmsg->exeaddr.data = 0;

- msgp = (struct p80211msg *) &rstatemsg;
- result = prism2mgmt_ramdl_state(wlandev, msgp);
+ result = prism2mgmt_ramdl_state(wlandev, rstmsg);
if (result) {
printk(KERN_ERR
"writeimage state disable failed w/ result=%d, "
"aborting download\n", result);
- return result;
+ goto free_result;
}
- resultcode = rstatemsg.resultcode.data;
+ resultcode = rstmsg->resultcode.data;
if (resultcode != P80211ENUM_resultcode_success) {
printk(KERN_ERR
"writeimage()->xxxdl_state msg indicates failure, "
"w/ resultcode=%d, aborting download.\n", resultcode);
- return 1;
+ result = 1;
+ goto free_result;
}
+
+free_result:
+ kfree(rstmsg);
+ kfree(rwrmsg);
return result;
}