On Tue, 2019-11-05 at 12:21 -0800, Jeffrey Hugo wrote: > Commit 7667819385457b4aeb5fac94f67f52ab52cc10d5 upstream. > > bam_dma_terminate_all() will leak resources if any of the transactions are > committed to the hardware (present in the desc fifo), and not complete. > Since bam_dma_terminate_all() does not cause the hardware to be updated, > the hardware will still operate on any previously committed transactions. > This can cause memory corruption if the memory for the transaction has been > reassigned, and will cause a sync issue between the BAM and its client(s). > > Fix this by properly updating the hardware in bam_dma_terminate_all(). > > Fixes: e7c0fe2a5c84 ("dmaengine: add Qualcomm BAM dma driver") > Signed-off-by: Jeffrey Hugo <jeffrey.l.hugo@xxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > Link: https://lore.kernel.org/r/20191017152606.34120-1-jeffrey.l.hugo@xxxxxxxxx > Signed-off-by: Vinod Koul <vkoul@xxxxxxxxxx> > --- > Backported to 4.4 which is lacking 6b4faeac05bc > ("dmaengine: qcom-bam: Process multiple pending descriptors") This seems to be needed for 3.16 as well, so I've queued it up. Let me know if this is wrong. Ben. > --- > drivers/dma/qcom_bam_dma.c | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > > diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c > index 5a250cdc8376..eca5b106d7d4 100644 > --- a/drivers/dma/qcom_bam_dma.c > +++ b/drivers/dma/qcom_bam_dma.c > @@ -671,7 +671,21 @@ static int bam_dma_terminate_all(struct dma_chan *chan) > > /* remove all transactions, including active transaction */ > spin_lock_irqsave(&bchan->vc.lock, flag); > + /* > + * If we have transactions queued, then some might be committed to the > + * hardware in the desc fifo. The only way to reset the desc fifo is > + * to do a hardware reset (either by pipe or the entire block). > + * bam_chan_init_hw() will trigger a pipe reset, and also reinit the > + * pipe. If the pipe is left disabled (default state after pipe reset) > + * and is accessed by a connected hardware engine, a fatal error in > + * the BAM will occur. There is a small window where this could happen > + * with bam_chan_init_hw(), but it is assumed that the caller has > + * stopped activity on any attached hardware engine. Make sure to do > + * this first so that the BAM hardware doesn't cause memory corruption > + * by accessing freed resources. > + */ > if (bchan->curr_txd) { > + bam_chan_init_hw(bchan, bchan->curr_txd->dir); > list_add(&bchan->curr_txd->vd.node, &bchan->vc.desc_issued); > bchan->curr_txd = NULL; > } -- Ben Hutchings Larkinson's Law: All laws are basically false.
Attachment:
signature.asc
Description: This is a digitally signed message part