Skip to content

Commit

Permalink
MLK-24825-2: dmaengine: fsl-edma: checking ACTIVE bit for channel stop
Browse files Browse the repository at this point in the history
Checking ACTIVE bit to ensure channel stop indeed, otherwise, there is risk
that illegal memory touch after channel not stopped with buffer freed.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
Reviewed-by: Fugang Duan <fugang.duan@nxp.com>
  • Loading branch information
Robin Gong committed Sep 27, 2020
1 parent ed1ff2a commit 48cea8a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
16 changes: 15 additions & 1 deletion drivers/dma/fsl-edma-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// Copyright (c) 2017 Sysam, Angelo Dureghello <angelo@sysam.it>

#include <linux/dmapool.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
Expand Down Expand Up @@ -160,11 +161,24 @@ EXPORT_SYMBOL_GPL(fsl_edma_free_desc);
int fsl_edma_terminate_all(struct dma_chan *chan)
{
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
struct edma_regs *regs = &fsl_chan->edma->regs;
u32 ch = fsl_chan->vchan.chan.chan_id;
unsigned long flags;
int count = 0;
LIST_HEAD(head);

spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
fsl_edma_disable_request(fsl_chan);

/*
* Checking ACTIVE to ensure minor loop stop indeed to prevent the
* potential illegal memory write if channel not stopped with buffer
* freed.
*/
while (count++ < EDMA_MINOR_LOOP_TIMEOUT && (EDMA_TCD_CSR_ACTIVE &
edma_readw(fsl_chan->edma, &regs->tcd[ch].csr)))
udelay(1);

spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
fsl_chan->edesc = NULL;
fsl_chan->idle = true;
vchan_get_all_descriptors(&fsl_chan->vchan, &head);
Expand Down
10 changes: 10 additions & 0 deletions drivers/dma/fsl-edma-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@

#define DMAMUX_NR 2

#define EDMA_MINOR_LOOP_TIMEOUT 500 /* us */

#define FSL_EDMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
Expand Down Expand Up @@ -183,6 +185,14 @@ static inline u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr)
return ioread32(addr);
}

static inline u32 edma_readw(struct fsl_edma_engine *edma, void __iomem *addr)
{
if (edma->big_endian)
return ioread16be(addr);
else
return ioread16(addr);
}

static inline void edma_writeb(struct fsl_edma_engine *edma,
u8 val, void __iomem *addr)
{
Expand Down

0 comments on commit 48cea8a

Please sign in to comment.