Skip to content

Commit

Permalink
rsi: Fix failure to load firmware after memory leak fix and fix the leak
Browse files Browse the repository at this point in the history
Fixes commit eae79b4 ("rsi: fix memory leak in rsi_load_ta_instructions()")
which stopped the driver from functioning.

Firmware data has been allocated using vmalloc(), resulting in memory
that cannot be used for DMA. Hence the firmware was first copied to a
buffer allocated with kmalloc() in the original code. This patch reverts
the commit and only calls "kfree()" to release the buffer after sending
the data. This fixes the memory leak without breaking the driver.

Add a comment to the kmemdup() calls to explain why this is done, and abort
if memory allocation fails.

Tested on a Topic Miami-Florida board which contains the rsi SDIO chip.

Also added the same kfree() call to the USB glue driver. This was not
tested on actual hardware though, as I only have the SDIO version.

Fixes: eae79b4 ("rsi: fix memory leak in rsi_load_ta_instructions()")
Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
Cc: stable@vger.kernel.org
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
  • Loading branch information
Mike Looijmans authored and Kalle Valo committed Jul 31, 2015
1 parent f7c0af8 commit 5d5cd85
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
8 changes: 7 additions & 1 deletion drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ static int rsi_load_ta_instructions(struct rsi_common *common)
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
u32 len;
u32 num_blocks;
const u8 *fw;
const struct firmware *fw_entry = NULL;
u32 block_size = dev->tx_blk_size;
int status = 0;
Expand Down Expand Up @@ -200,6 +201,10 @@ static int rsi_load_ta_instructions(struct rsi_common *common)
return status;
}

/* Copy firmware into DMA-accessible memory */
fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
if (!fw)
return -ENOMEM;
len = fw_entry->size;

if (len % 4)
Expand All @@ -210,7 +215,8 @@ static int rsi_load_ta_instructions(struct rsi_common *common)
rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len);
rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks);

status = rsi_copy_to_card(common, fw_entry->data, len, num_blocks);
status = rsi_copy_to_card(common, fw, len, num_blocks);
kfree(fw);
release_firmware(fw_entry);
return status;
}
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/wireless/rsi/rsi_91x_usb_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ static int rsi_load_ta_instructions(struct rsi_common *common)
return status;
}

/* Copy firmware into DMA-accessible memory */
fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
if (!fw)
return -ENOMEM;
len = fw_entry->size;

if (len % 4)
Expand All @@ -158,6 +161,7 @@ static int rsi_load_ta_instructions(struct rsi_common *common)
rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks);

status = rsi_copy_to_card(common, fw, len, num_blocks);
kfree(fw);
release_firmware(fw_entry);
return status;
}
Expand Down

0 comments on commit 5d5cd85

Please sign in to comment.