Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ff76a92 authored by Huang Shijie's avatar Huang Shijie Committed by Brian Norris
Browse files

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: default avatarHuang Shijie <shijie8@gmail.com>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent 06f216c8
Loading
Loading
Loading
Loading
+17 −14
Original line number Diff line number Diff line
@@ -367,26 +367,29 @@ 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 */
	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) {
		if (ret == 0)
			goto map_fail;

		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, PAGE_SIZE);
	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);
		memcpy(this->data_buffer_dma, 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");
	dma_map_sg(this->dev, sgl, 1, dr);

	this->direct_dma_map_ok = false;
}
}

/* This will be called after the DMA operation is finished. */
static void dma_irq_callback(void *param)