dmaengine: xilinx_dma: Add missing check for empty list
The DMA transfer might finish just after checking the state with dma_cookie_status, but before the lock is acquired. Not checking for an empty list in xilinx_dma_tx_status may result in reading random data or data corruption when desc is written to. This can be reliably triggered by using dma_sync_wait to wait for DMA completion. Signed-off-by: Sebastian von Ohr <vonohr@smaract.com> Tested-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com> Link: https://lore.kernel.org/r/20200303130518.333-1-vonohr@smaract.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
172d59ecd6
commit
b269426011
|
@ -1230,16 +1230,16 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
|
|||
return ret;
|
||||
|
||||
spin_lock_irqsave(&chan->lock, flags);
|
||||
|
||||
desc = list_last_entry(&chan->active_list,
|
||||
struct xilinx_dma_tx_descriptor, node);
|
||||
/*
|
||||
* VDMA and simple mode do not support residue reporting, so the
|
||||
* residue field will always be 0.
|
||||
*/
|
||||
if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA)
|
||||
residue = xilinx_dma_get_residue(chan, desc);
|
||||
|
||||
if (!list_empty(&chan->active_list)) {
|
||||
desc = list_last_entry(&chan->active_list,
|
||||
struct xilinx_dma_tx_descriptor, node);
|
||||
/*
|
||||
* VDMA and simple mode do not support residue reporting, so the
|
||||
* residue field will always be 0.
|
||||
*/
|
||||
if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA)
|
||||
residue = xilinx_dma_get_residue(chan, desc);
|
||||
}
|
||||
spin_unlock_irqrestore(&chan->lock, flags);
|
||||
|
||||
dma_set_residue(txstate, residue);
|
||||
|
|
Loading…
Reference in New Issue