Skip to content

Commit

Permalink
drivers/dma/dma-jz4780: Fix race condition between probe and irq handler
Browse files Browse the repository at this point in the history
In probe, IRQ is requested before zchan->id is initialized which can be
read in the irq handler. Hence, shift request irq after other initializations
complete.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Madhuparna Bhowmik <madhuparnabhowmik10@gmail.com>
Reviewed-by: Paul Cercueil <paul@crapouillou.net>
Link: https://lore.kernel.org/r/20200821034423.12713-1-madhuparnabhowmik10@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
  • Loading branch information
Madhuparna Bhowmik authored and Vinod Koul committed Aug 25, 2020
1 parent 0565554 commit 6d6018f
Showing 1 changed file with 19 additions and 19 deletions.
38 changes: 19 additions & 19 deletions drivers/dma/dma-jz4780.c
Original file line number Diff line number Diff line change
Expand Up @@ -879,24 +879,11 @@ static int jz4780_dma_probe(struct platform_device *pdev)
return -EINVAL;
}

ret = platform_get_irq(pdev, 0);
if (ret < 0)
return ret;

jzdma->irq = ret;

ret = request_irq(jzdma->irq, jz4780_dma_irq_handler, 0, dev_name(dev),
jzdma);
if (ret) {
dev_err(dev, "failed to request IRQ %u!\n", jzdma->irq);
return ret;
}

jzdma->clk = devm_clk_get(dev, NULL);
if (IS_ERR(jzdma->clk)) {
dev_err(dev, "failed to get clock\n");
ret = PTR_ERR(jzdma->clk);
goto err_free_irq;
return ret;
}

clk_prepare_enable(jzdma->clk);
Expand Down Expand Up @@ -949,28 +936,41 @@ static int jz4780_dma_probe(struct platform_device *pdev)
jzchan->vchan.desc_free = jz4780_dma_desc_free;
}

ret = platform_get_irq(pdev, 0);
if (ret < 0)
goto err_disable_clk;

jzdma->irq = ret;

ret = request_irq(jzdma->irq, jz4780_dma_irq_handler, 0, dev_name(dev),
jzdma);
if (ret) {
dev_err(dev, "failed to request IRQ %u!\n", jzdma->irq);
goto err_disable_clk;
}

ret = dmaenginem_async_device_register(dd);
if (ret) {
dev_err(dev, "failed to register device\n");
goto err_disable_clk;
goto err_free_irq;
}

/* Register with OF DMA helpers. */
ret = of_dma_controller_register(dev->of_node, jz4780_of_dma_xlate,
jzdma);
if (ret) {
dev_err(dev, "failed to register OF DMA controller\n");
goto err_disable_clk;
goto err_free_irq;
}

dev_info(dev, "JZ4780 DMA controller initialised\n");
return 0;

err_disable_clk:
clk_disable_unprepare(jzdma->clk);

err_free_irq:
free_irq(jzdma->irq, jzdma);

err_disable_clk:
clk_disable_unprepare(jzdma->clk);
return ret;
}

Expand Down

0 comments on commit 6d6018f

Please sign in to comment.