There is only one bounce buffer (ar_sdio->dma_buffer) which is used for both read and write without any protection. Fix this race by allocating bounce buffer every time when it is needed. Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@xxxxxxxxxxxxxxxx> --- drivers/net/wireless/ath/ath6kl/sdio.c | 18 +++++++++++------- 1 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 7695c29..06e3f09 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -383,25 +383,29 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf, u32 len, u32 request) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); - u8 *tbuf = NULL; int ret; + u8 *bounce_buf = NULL; bool bounced = false; if (request & HIF_BLOCK_BASIS) len = round_down(len, HIF_MBOX_BLOCK_SIZE); if (buf_needs_bounce(buf)) { - if (!ar_sdio->dma_buffer) + bounce_buf = kmalloc(len, GFP_ATOMIC); + if (!bounce_buf) return -ENOMEM; - tbuf = ar_sdio->dma_buffer; - memcpy(tbuf, buf, len); + memcpy(bounce_buf, buf, len); bounced = true; } else - tbuf = buf; + bounce_buf = buf; + + ret = ath6kl_sdio_io(ar_sdio->func, request, addr, bounce_buf, len); - ret = ath6kl_sdio_io(ar_sdio->func, request, addr, tbuf, len); if ((request & HIF_READ) && bounced) - memcpy(buf, tbuf, len); + memcpy(buf, bounce_buf, len); + + if (bounced) + kfree(bounce_buf); return ret; } -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html