Skip to content

Commit

Permalink
ARM: OMAP: Fix for possible race condition in omap_free_dma()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Santosh Shilimkar authored and Tony Lindgren committed Apr 23, 2009
1 parent 0910697 commit da1b94e
Showing 1 changed file with 6 additions and 7 deletions.
13 changes: 6 additions & 7 deletions arch/arm/plat-omap/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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);

Expand Down

0 comments on commit da1b94e

Please sign in to comment.