Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91686150 authored by Xiaomeng Tong's avatar Xiaomeng Tong Committed by Greg Kroah-Hartman
Browse files

dma: at_xdmac: fix a missing check on list iterator



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: 82e24246 ("dmaengine: xdmac: fix print warning on dma_addr_t variable")
Signed-off-by: default avatarXiaomeng Tong <xiam0nd.tong@gmail.com>
Link: https://lore.kernel.org/r/20220327061154.4867-1-xiam0nd.tong@gmail.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3cca43b9
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -1392,7 +1392,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
{
	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,12 +1507,14 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
	 * 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;

	dma_set_residue(txstate, residue);