Commit 60095aca authored by Thomas Fourier's avatar Thomas Fourier Committed by Vinod Koul
Browse files

dmaengine: mv_xor: Fix missing check after DMA map and missing unmap



The DMA map functions can fail and should be tested for errors.

In case of error, unmap the already mapped regions.

Fixes: 22843545 ("dma: mv_xor: Add support for DMA_INTERRUPT")
Signed-off-by: default avatarThomas Fourier <fourier.thomas@gmail.com>
Link: https://lore.kernel.org/r/20250701123753.46935-2-fourier.thomas@gmail.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent b330d77c
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -1061,8 +1061,16 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
	 */
	mv_chan->dummy_src_addr = dma_map_single(dma_dev->dev,
		mv_chan->dummy_src, MV_XOR_MIN_BYTE_COUNT, DMA_FROM_DEVICE);
	if (dma_mapping_error(dma_dev->dev, mv_chan->dummy_src_addr))
		return ERR_PTR(-ENOMEM);

	mv_chan->dummy_dst_addr = dma_map_single(dma_dev->dev,
		mv_chan->dummy_dst, MV_XOR_MIN_BYTE_COUNT, DMA_TO_DEVICE);
	if (dma_mapping_error(dma_dev->dev, mv_chan->dummy_dst_addr)) {
		ret = -ENOMEM;
		goto err_unmap_src;
	}


	/* allocate coherent memory for hardware descriptors
	 * note: writecombine gives slightly better performance, but
@@ -1071,8 +1079,10 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
	mv_chan->dma_desc_pool_virt =
	  dma_alloc_wc(&pdev->dev, MV_XOR_POOL_SIZE, &mv_chan->dma_desc_pool,
		       GFP_KERNEL);
	if (!mv_chan->dma_desc_pool_virt)
		return ERR_PTR(-ENOMEM);
	if (!mv_chan->dma_desc_pool_virt) {
		ret = -ENOMEM;
		goto err_unmap_dst;
	}

	/* discover transaction capabilities from the platform data */
	dma_dev->cap_mask = cap_mask;
@@ -1155,6 +1165,13 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
err_free_dma:
	dma_free_coherent(&pdev->dev, MV_XOR_POOL_SIZE,
			  mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool);
err_unmap_dst:
	dma_unmap_single(dma_dev->dev, mv_chan->dummy_dst_addr,
			 MV_XOR_MIN_BYTE_COUNT, DMA_TO_DEVICE);
err_unmap_src:
	dma_unmap_single(dma_dev->dev, mv_chan->dummy_src_addr,
			 MV_XOR_MIN_BYTE_COUNT, DMA_FROM_DEVICE);

	return ERR_PTR(ret);
}