mtd: gpmi: add sanity check when mapping DMA for read_buf/write_buf
Linux-MTD Mailing List
linux-mtd at lists.infradead.org
Tue Jan 28 00:59:07 EST 2014
Gitweb: http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=0ff76a920e3558307567b45aa0a91fb914924bfc
Commit: 0ff76a920e3558307567b45aa0a91fb914924bfc
Parent: 06f216c83c25adadc231469d51ab133afdfe110a
Author: Huang Shijie <shijie8 at gmail.com>
AuthorDate: Wed Dec 18 23:41:00 2013 +0800
Committer: Brian Norris <computersforpeace at gmail.com>
CommitDate: Mon Jan 27 21:55:03 2014 -0800
mtd: gpmi: add sanity check when mapping DMA for read_buf/write_buf
The buffer pointer passed from the upper layer may points to
a buffer in the stack or a buffer allocated by vmalloc, and etc..
This patch adds more sanity check to this buffer.
After this patch, if we meet a buffer which is allocated by vmalloc or
a buffer in the stack, we will use our own DMA buffer @data_buffer_dma
to do the DMA operations. If the buffer is not the cases above, we will
map it for DMA operations directly.
Signed-off-by: Huang Shijie <shijie8 at gmail.com>
Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index d1d13d8..ca6369f 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -367,25 +367,28 @@ void prepare_data_dma(struct gpmi_nand_data *this, enum dma_data_direction dr)
struct scatterlist *sgl = &this->data_sgl;
int ret;
- this->direct_dma_map_ok = true;
-
/* first try to map the upper buffer directly */
- sg_init_one(sgl, this->upper_buf, this->upper_len);
- ret = dma_map_sg(this->dev, sgl, 1, dr);
- if (ret == 0) {
- /* We have to use our own DMA buffer. */
- sg_init_one(sgl, this->data_buffer_dma, PAGE_SIZE);
-
- if (dr == DMA_TO_DEVICE)
- memcpy(this->data_buffer_dma, this->upper_buf,
- this->upper_len);
-
+ if (virt_addr_valid(this->upper_buf) &&
+ !object_is_on_stack(this->upper_buf)) {
+ sg_init_one(sgl, this->upper_buf, this->upper_len);
ret = dma_map_sg(this->dev, sgl, 1, dr);
if (ret == 0)
- dev_err(this->dev, "DMA mapping failed.\n");
+ goto map_fail;
- this->direct_dma_map_ok = false;
+ this->direct_dma_map_ok = true;
+ return;
}
+
+map_fail:
+ /* We have to use our own DMA buffer. */
+ sg_init_one(sgl, this->data_buffer_dma, this->upper_len);
+
+ if (dr == DMA_TO_DEVICE)
+ memcpy(this->data_buffer_dma, this->upper_buf, this->upper_len);
+
+ dma_map_sg(this->dev, sgl, 1, dr);
+
+ this->direct_dma_map_ok = false;
}
/* This will be called after the DMA operation is finished. */
More information about the linux-mtd-cvs
mailing list