瀏覽代碼

ARM: OMAP: Fix for possible race condition in omap_free_dma()

Fix the possible race condition in omap_free_dma(). Function omap_free_dma()
sets the dev_id = -1 and then accesses the channel afterwards to clear it.
But setting the dev_id=-1 makes the channel available for allocation again.
So it is possible someone else can grab it and results are unpredictable.
To avod this DMA channle is cleared first and then the dev_id = -1 is set.

Thanks to McNeil, Sean <sean.mcneil@ti.com> for ointing out this issue.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Santosh Shilimkar 16 年之前
父節點
當前提交
da1b94e6a6
共有 1 個文件被更改,包括 6 次插入7 次删除
  1. 6 7
      arch/arm/plat-omap/dma.c

+ 6 - 7
arch/arm/plat-omap/dma.c

@@ -760,19 +760,12 @@ void omap_free_dma(int lch)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&dma_chan_lock, flags);
 	if (dma_chan[lch].dev_id == -1) {
 		pr_err("omap_dma: trying to free unallocated DMA channel %d\n",
 		       lch);
-		spin_unlock_irqrestore(&dma_chan_lock, flags);
 		return;
 	}
 
-	dma_chan[lch].dev_id = -1;
-	dma_chan[lch].next_lch = -1;
-	dma_chan[lch].callback = NULL;
-	spin_unlock_irqrestore(&dma_chan_lock, flags);
-
 	if (cpu_class_is_omap1()) {
 		/* Disable all DMA interrupts for the channel. */
 		dma_write(0, CICR(lch));
@@ -798,6 +791,12 @@ void omap_free_dma(int lch)
 		dma_write(0, CCR(lch));
 		omap_clear_dma(lch);
 	}
+
+	spin_lock_irqsave(&dma_chan_lock, flags);
+	dma_chan[lch].dev_id = -1;
+	dma_chan[lch].next_lch = -1;
+	dma_chan[lch].callback = NULL;
+	spin_unlock_irqrestore(&dma_chan_lock, flags);
 }
 EXPORT_SYMBOL(omap_free_dma);