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

Commit 5733fa26 authored by Thomas Fourier's avatar Thomas Fourier Committed by Greg Kroah-Hartman
Browse files

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



[ Upstream commit 60095aca6b471b7b7a79c80b7395f7e4e414b479 ]

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>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 80d0535f
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 capabilites from the platform data */
	dma_dev->cap_mask = cap_mask;
@@ -1156,6 +1166,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);
}