diff options
| author | Johan Hovold <johan@kernel.org> | 2025-11-17 17:12:43 +0100 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-01-23 11:21:33 +0100 |
| commit | f3c23b7e941349505c3d40de2cc0acd93d9ac057 (patch) | |
| tree | f1f563ebd20bccddd389330f3bb4f20ccd40b39b | |
| parent | 3706be7cbcd5f9981dd9e0296edb6743596fdd10 (diff) | |
| download | linux-f3c23b7e941349505c3d40de2cc0acd93d9ac057.tar.gz linux-f3c23b7e941349505c3d40de2cc0acd93d9ac057.tar.bz2 linux-f3c23b7e941349505c3d40de2cc0acd93d9ac057.zip | |
dmaengine: at_hdmac: fix device leak on of_dma_xlate()
commit b9074b2d7a230b6e28caa23165e9d8bc0677d333 upstream.
Make sure to drop the reference taken when looking up the DMA platform
device during of_dma_xlate() when releasing channel resources.
Note that commit 3832b78b3ec2 ("dmaengine: at_hdmac: add missing
put_device() call in at_dma_xlate()") fixed the leak in a couple of
error paths but the reference is still leaking on successful allocation.
Fixes: bbe89c8e3d59 ("at_hdmac: move to generic DMA binding")
Fixes: 3832b78b3ec2 ("dmaengine: at_hdmac: add missing put_device() call in at_dma_xlate()")
Cc: stable@vger.kernel.org # 3.10: 3832b78b3ec2
Cc: Yu Kuai <yukuai3@huawei.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20251117161258.10679-2-johan@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/dma/at_hdmac.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 2d147712cbc6..dffe5becd6c3 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -1765,6 +1765,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan) static void atc_free_chan_resources(struct dma_chan *chan) { struct at_dma_chan *atchan = to_at_dma_chan(chan); + struct at_dma_slave *atslave; BUG_ON(atc_chan_is_enabled(atchan)); @@ -1774,8 +1775,12 @@ static void atc_free_chan_resources(struct dma_chan *chan) /* * Free atslave allocated in at_dma_xlate() */ - kfree(chan->private); - chan->private = NULL; + atslave = chan->private; + if (atslave) { + put_device(atslave->dma_dev); + kfree(atslave); + chan->private = NULL; + } dev_vdbg(chan2dev(chan), "free_chan_resources: done\n"); } |
