summaryrefslogtreecommitdiffstats
path: root/drivers/dma/xilinx
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2017-03-13 11:59:12 -0400
committerVinod Koul <vinod.koul@intel.com>2017-03-14 06:44:29 -0400
commitdb6a3d03e22f3daf09d8d1532bd1d3747062a561 (patch)
treee09e76c5ea1083b22d8ffedc2a98206cb78713a5 /drivers/dma/xilinx
parent676f9c26c330d087125769200bcf080c3c88488e (diff)
dmaengine: xilinx: avoid memory corruption for device_prep_dma_memcpy()
The device_prep_dma_memcpy() callback for this driver allocates a new xilinx_dma_tx_descriptor whose TX segments list is initialized as empty, but then gets invalid TX segment pointer by list_last_entry() from the empty TX segments list and memory corruption happens by the attempt to update the next descriptor in invalid TX segment pointer. This removes unnecessary memory access for nonexistent tail TX segment which causes memory corruption. Cc: Vinod Koul <vinod.koul@intel.com> Cc: Kedareswara rao Appana <appana.durga.rao@xilinx.com> Cc: Michal Simek <monstr@monstr.eu> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/xilinx')
-rw-r--r--drivers/dma/xilinx/xilinx_dma.c14
1 files changed, 2 insertions, 12 deletions
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index df1676efdd73..8cf87b1a284b 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -1661,7 +1661,7 @@ xilinx_cdma_prep_memcpy(struct dma_chan *dchan, dma_addr_t dma_dst,
1661{ 1661{
1662 struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); 1662 struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
1663 struct xilinx_dma_tx_descriptor *desc; 1663 struct xilinx_dma_tx_descriptor *desc;
1664 struct xilinx_cdma_tx_segment *segment, *prev; 1664 struct xilinx_cdma_tx_segment *segment;
1665 struct xilinx_cdma_desc_hw *hw; 1665 struct xilinx_cdma_desc_hw *hw;
1666 1666
1667 if (!len || len > XILINX_DMA_MAX_TRANS_LEN) 1667 if (!len || len > XILINX_DMA_MAX_TRANS_LEN)
@@ -1688,21 +1688,11 @@ xilinx_cdma_prep_memcpy(struct dma_chan *dchan, dma_addr_t dma_dst,
1688 hw->dest_addr_msb = upper_32_bits(dma_dst); 1688 hw->dest_addr_msb = upper_32_bits(dma_dst);
1689 } 1689 }
1690 1690
1691 /* Fill the previous next descriptor with current */
1692 prev = list_last_entry(&desc->segments,
1693 struct xilinx_cdma_tx_segment, node);
1694 prev->hw.next_desc = segment->phys;
1695
1696 /* Insert the segment into the descriptor segments list. */ 1691 /* Insert the segment into the descriptor segments list. */
1697 list_add_tail(&segment->node, &desc->segments); 1692 list_add_tail(&segment->node, &desc->segments);
1698 1693
1699 prev = segment;
1700
1701 /* Link the last hardware descriptor with the first. */
1702 segment = list_first_entry(&desc->segments,
1703 struct xilinx_cdma_tx_segment, node);
1704 desc->async_tx.phys = segment->phys; 1694 desc->async_tx.phys = segment->phys;
1705 prev->hw.next_desc = segment->phys; 1695 hw->next_desc = segment->phys;
1706 1696
1707 return &desc->async_tx; 1697 return &desc->async_tx;
1708 1698