| From 206680c4e46b62fd8909385e0874a36952595b85 Mon Sep 17 00:00:00 2001 |
| From: Xiaomeng Tong <xiam0nd.tong@gmail.com> |
| Date: Sun, 27 Mar 2022 14:11:54 +0800 |
| Subject: dma: at_xdmac: fix a missing check on list iterator |
| |
| From: Xiaomeng Tong <xiam0nd.tong@gmail.com> |
| |
| commit 206680c4e46b62fd8909385e0874a36952595b85 upstream. |
| |
| The bug is here: |
| __func__, desc, &desc->tx_dma_desc.phys, ret, cookie, residue); |
| |
| The list iterator 'desc' will point to a bogus position containing |
| HEAD if the list is empty or no element is found. To avoid dev_dbg() |
| prints a invalid address, use a new variable 'iter' as the list |
| iterator, while use the origin variable 'desc' as a dedicated |
| pointer to point to the found element. |
| |
| Cc: stable@vger.kernel.org |
| Fixes: 82e2424635f4c ("dmaengine: xdmac: fix print warning on dma_addr_t variable") |
| Signed-off-by: Xiaomeng Tong <xiam0nd.tong@gmail.com> |
| Link: https://lore.kernel.org/r/20220327061154.4867-1-xiam0nd.tong@gmail.com |
| Signed-off-by: Vinod Koul <vkoul@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/dma/at_xdmac.c | 12 +++++++----- |
| 1 file changed, 7 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/dma/at_xdmac.c |
| +++ b/drivers/dma/at_xdmac.c |
| @@ -1392,7 +1392,7 @@ at_xdmac_tx_status(struct dma_chan *chan |
| { |
| struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); |
| struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); |
| - struct at_xdmac_desc *desc, *_desc; |
| + struct at_xdmac_desc *desc, *_desc, *iter; |
| struct list_head *descs_list; |
| enum dma_status ret; |
| int residue, retry; |
| @@ -1507,11 +1507,13 @@ at_xdmac_tx_status(struct dma_chan *chan |
| * microblock. |
| */ |
| descs_list = &desc->descs_list; |
| - list_for_each_entry_safe(desc, _desc, descs_list, desc_node) { |
| - dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg); |
| - residue -= (desc->lld.mbr_ubc & 0xffffff) << dwidth; |
| - if ((desc->lld.mbr_nda & 0xfffffffc) == cur_nda) |
| + list_for_each_entry_safe(iter, _desc, descs_list, desc_node) { |
| + dwidth = at_xdmac_get_dwidth(iter->lld.mbr_cfg); |
| + residue -= (iter->lld.mbr_ubc & 0xffffff) << dwidth; |
| + if ((iter->lld.mbr_nda & 0xfffffffc) == cur_nda) { |
| + desc = iter; |
| break; |
| + } |
| } |
| residue += cur_ubc << dwidth; |
| |