| Message ID | 20260902062153.31048-2-logang@deltatee.com |
|---|---|
| State | New |
| Headers | show |
| Series | dmaengine: miscellaneous fixes for ioat, switchtec_dma and plx_dma | expand |
> switchtec_dma_free_desc() frees swdma_chan->hw_sq, hw_cq, and every > desc_ring[] entry without clearing the pointers afterward. If > switchtec_dma_alloc_chan_resources() fails partway through and calls > it during unwind, then a later retry of alloc_chan_resources() fails > in switchtec_dma_alloc_desc() before reallocating one of those > pointers, its own failure path calls switchtec_dma_free_desc() again > and frees the same, already-freed pointers a second time. > > NULL out each pointer as it's freed so a subsequent call is a no-op > for anything already released. > > Fixes: 30eba9df76ad ("dmaengine: switchtec-dma: Implement hardware initialization and cleanup") > Reviewed-by: Frank Li <Frank.Li@nxp.com> > Signed-off-by: Logan Gunthorpe <logang@deltatee.com> Sashiko has reviewed this patch and found no issues. It looks great!
diff --git a/drivers/dma/switchtec_dma.c b/drivers/dma/switchtec_dma.c index c133535d3765..a10818efba4e 100644 --- a/drivers/dma/switchtec_dma.c +++ b/drivers/dma/switchtec_dma.c @@ -886,14 +886,18 @@ static void switchtec_dma_free_desc(struct switchtec_dma_chan *swdma_chan) if (swdma_chan->hw_sq) dma_free_coherent(swdma_dev->dma_dev.dev, size, swdma_chan->hw_sq, swdma_chan->dma_addr_sq); + swdma_chan->hw_sq = NULL; size = SWITCHTEC_DMA_CQ_SIZE * sizeof(*swdma_chan->hw_cq); if (swdma_chan->hw_cq) dma_free_coherent(swdma_dev->dma_dev.dev, size, swdma_chan->hw_cq, swdma_chan->dma_addr_cq); + swdma_chan->hw_cq = NULL; - for (i = 0; i < SWITCHTEC_DMA_RING_SIZE; i++) + for (i = 0; i < SWITCHTEC_DMA_RING_SIZE; i++) { kfree(swdma_chan->desc_ring[i]); + swdma_chan->desc_ring[i] = NULL; + } } static int switchtec_dma_alloc_desc(struct switchtec_dma_chan *swdma_chan)
switchtec_dma_free_desc() frees swdma_chan->hw_sq, hw_cq, and every desc_ring[] entry without clearing the pointers afterward. If switchtec_dma_alloc_chan_resources() fails partway through and calls it during unwind, then a later retry of alloc_chan_resources() fails in switchtec_dma_alloc_desc() before reallocating one of those pointers, its own failure path calls switchtec_dma_free_desc() again and frees the same, already-freed pointers a second time. NULL out each pointer as it's freed so a subsequent call is a no-op for anything already released. Fixes: 30eba9df76ad ("dmaengine: switchtec-dma: Implement hardware initialization and cleanup") Reviewed-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Logan Gunthorpe <logang@deltatee.com> --- drivers/dma/switchtec_dma.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)