From patchwork Sun Mar 29 11:58:57 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Santosh Shilimkar X-Patchwork-Id: 14966 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n2TBxeAw015346 for ; Sun, 29 Mar 2009 11:59:40 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752268AbZC2L7K (ORCPT ); Sun, 29 Mar 2009 07:59:10 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753896AbZC2L7K (ORCPT ); Sun, 29 Mar 2009 07:59:10 -0400 Received: from comal.ext.ti.com ([198.47.26.152]:57012 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752268AbZC2L7I convert rfc822-to-8bit (ORCPT ); Sun, 29 Mar 2009 07:59:08 -0400 Received: from dbdp20.itg.ti.com ([172.24.170.38]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id n2TBwwC3030452 for ; Sun, 29 Mar 2009 06:59:04 -0500 Received: from dbde70.ent.ti.com (localhost [127.0.0.1]) by dbdp20.itg.ti.com (8.13.8/8.13.8) with ESMTP id n2TBww4F027783 for ; Sun, 29 Mar 2009 17:28:58 +0530 (IST) Received: from dbde02.ent.ti.com ([172.24.170.145]) by dbde70.ent.ti.com ([172.24.170.148]) with mapi; Sun, 29 Mar 2009 17:28:58 +0530 From: "Shilimkar, Santosh" To: "'linux-omap@vger.kernel.org'" Date: Sun, 29 Mar 2009 17:28:57 +0530 Subject: [OMAP][sDMA]Fix for possible race condition in omap_free_dma() Thread-Topic: [OMAP][sDMA]Fix for possible race condition in omap_free_dma() Thread-Index: AcmwZb12vmrPi2RzQWqCsM4HbbVcWw== Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org From: Santosh Shilimkar 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 for ointing out this issue. Signed-off-by: Santosh Shilimkar --- arch/arm/plat-omap/dma.c | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) Regards, Santosh -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: omapkernel/arch/arm/plat-omap/dma.c =================================================================== --- omapkernel.orig/arch/arm/plat-omap/dma.c +++ omapkernel/arch/arm/plat-omap/dma.c @@ -785,19 +785,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)); @@ -823,6 +816,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);