[PATCH] ARM: tegra: Prevent requeuing in-progress DMA requests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If a request already in the queue is passed to tegra_dma_enqueue_req,
tegra_dma_req.node->{next,prev} will end up pointing to itself instead
of at tegra_dma_channel.list, which is the way a the end-of-list
should be set up. When the DMA request completes and is list_del'd,
the list head will still point at it, yet the node's next/prev will
contain the list poison values. When the next DMA request completes,
a kernel panic will occur when those poison values are dereferenced.

This makes the DMA driver more robust in the face of buggy clients.

Signed-off-by: Stephen Warren <swarren@xxxxxxxxxxxxx>
---
This is for branch for-next

 arch/arm/mach-tegra/dma.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
index 760723c..59b2e97 100755
--- a/arch/arm/mach-tegra/dma.c
+++ b/arch/arm/mach-tegra/dma.c
@@ -320,6 +320,8 @@ int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
 	struct tegra_dma_req *req)
 {
 	unsigned long irq_flags;
+	struct tegra_dma_req *_req;
+	int found = 0;
 	int start_dma = 0;
 
 	if (req->size > NV_DMA_MAX_TRASFER_SIZE ||
@@ -330,6 +332,18 @@ int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
 
 	spin_lock_irqsave(&ch->lock, irq_flags);
 
+	list_for_each_entry(_req, &ch->list, node) {
+		if (req == _req) {
+			list_del(&req->node);
+			found = 1;
+			break;
+		}
+	}
+	if (found) {
+		spin_unlock_irqrestore(&ch->lock, irq_flags);
+		return -EEXIST;
+	}
+
 	req->bytes_transferred = 0;
 	req->status = 0;
 	req->buffer_status = 0;
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [ARM Kernel]     [Linux ARM]     [Linux ARM MSM]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux