mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Lee Jones <lee@kernel.org>
To: lee@kernel.org, Vinod Koul <vkoul@kernel.org>,
	Frank Li <Frank.Li@kernel.org>, Sylvain Munaut <tnt@246tNt.com>,
	Andrey Volkov <avolkov@varma-el.com>,
	Dale Farnsworth <dfarnsworth@mvista.com>,
	Grant Likely <grant.likely@secretlab.ca>,
	dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: stable@vger.kernel.org
Subject: [PATCH 07/10] dmaengine: bestcomm: Defer publishing bcom_eng until initialisation completes
Date: Wed, 11 Nov 2026 21:52:45 +0000	[thread overview]
Message-ID: <20261111215349.1983909-8-lee@kernel.org> (raw)
In-Reply-To: <20261111215349.1983909-1-lee@kernel.org>

mpc52xx_bcom_probe() assigns the newly allocated struct bcom_engine to
the global bcom_eng pointer before calling bcom_engine_init().  A
concurrent call to bcom_task_alloc() can observe a non-NULL bcom_eng
pointer before its spinlock and task descriptor table are initialised.

Initialise the engine via a local pointer and only publish bcom_eng
once initialisation has succeeded.

Fixes: 2f9ea1bde0d1 ("[POWERPC] bestcomm: core bestcomm support for Freescale MPC5200")
Closes: https://sashiko.dev/#/bug/linux-0a202799-4946-44bf-b035-fbb2e329e666
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/dma/bestcomm/bestcomm.c | 69 +++++++++++++++++----------------
 1 file changed, 36 insertions(+), 33 deletions(-)

diff --git a/drivers/dma/bestcomm/bestcomm.c b/drivers/dma/bestcomm/bestcomm.c
index 241a91936fe8..dbc3ce5fc446 100644
--- a/drivers/dma/bestcomm/bestcomm.c
+++ b/drivers/dma/bestcomm/bestcomm.c
@@ -270,7 +270,7 @@ static u32 fdt_ops[] = {
 };
 
 
-static int bcom_engine_init(void)
+static int bcom_engine_init(struct bcom_engine *eng)
 {
 	int task;
 	phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa;
@@ -282,56 +282,59 @@ static int bcom_engine_init(void)
 	var_size = BCOM_MAX_TASKS * (BCOM_VAR_SIZE + BCOM_INC_SIZE);
 	fdt_size = BCOM_FDT_SIZE;
 
-	bcom_eng->tdt = bcom_sram_alloc(tdt_size, sizeof(u32), &tdt_pa);
-	bcom_eng->ctx = bcom_sram_alloc(ctx_size, BCOM_CTX_ALIGN, &ctx_pa);
-	bcom_eng->var = bcom_sram_alloc(var_size, BCOM_VAR_ALIGN, &var_pa);
-	bcom_eng->fdt = bcom_sram_alloc(fdt_size, BCOM_FDT_ALIGN, &fdt_pa);
+	eng->tdt = bcom_sram_alloc(tdt_size, sizeof(u32), &tdt_pa);
+	eng->ctx = bcom_sram_alloc(ctx_size, BCOM_CTX_ALIGN, &ctx_pa);
+	eng->var = bcom_sram_alloc(var_size, BCOM_VAR_ALIGN, &var_pa);
+	eng->fdt = bcom_sram_alloc(fdt_size, BCOM_FDT_ALIGN, &fdt_pa);
 
-	if (!bcom_eng->tdt || !bcom_eng->ctx || !bcom_eng->var || !bcom_eng->fdt) {
+	if (!eng->tdt || !eng->ctx || !eng->var || !eng->fdt) {
 		printk(KERN_ERR "DMA: SRAM alloc failed in engine init !\n");
 
-		bcom_sram_free(bcom_eng->tdt);
-		bcom_sram_free(bcom_eng->ctx);
-		bcom_sram_free(bcom_eng->var);
-		bcom_sram_free(bcom_eng->fdt);
+		bcom_sram_free(eng->tdt);
+		bcom_sram_free(eng->ctx);
+		bcom_sram_free(eng->var);
+		bcom_sram_free(eng->fdt);
 
 		return -ENOMEM;
 	}
 
-	memset_io(bcom_eng->tdt, 0x00, tdt_size);
-	memset_io(bcom_eng->ctx, 0x00, ctx_size);
-	memset_io(bcom_eng->var, 0x00, var_size);
-	memset_io(bcom_eng->fdt, 0x00, fdt_size);
+	memset_io(eng->tdt, 0x00, tdt_size);
+	memset_io(eng->ctx, 0x00, ctx_size);
+	memset_io(eng->var, 0x00, var_size);
+	memset_io(eng->fdt, 0x00, fdt_size);
 
 	/* Copy the FDT for the EU#3 */
-	memcpy_toio(&bcom_eng->fdt[48], fdt_ops, sizeof(fdt_ops));
+	memcpy_toio(&eng->fdt[48], fdt_ops, sizeof(fdt_ops));
 
 	/* Initialize Task base structure */
 	for (task=0; task<BCOM_MAX_TASKS; task++)
 	{
-		out_be16(&bcom_eng->regs->tcr[task], 0);
-		out_8(&bcom_eng->regs->ipr[task], 0);
+		out_be16(&eng->regs->tcr[task], 0);
+		out_8(&eng->regs->ipr[task], 0);
 
-		bcom_eng->tdt[task].context	= ctx_pa;
-		bcom_eng->tdt[task].var	= var_pa;
-		bcom_eng->tdt[task].fdt	= fdt_pa;
+		eng->tdt[task].context	= ctx_pa;
+		eng->tdt[task].var	= var_pa;
+		eng->tdt[task].fdt	= fdt_pa;
 
 		var_pa += BCOM_VAR_SIZE + BCOM_INC_SIZE;
 		ctx_pa += BCOM_CTX_SIZE;
 	}
 
-	out_be32(&bcom_eng->regs->taskBar, tdt_pa);
+	out_be32(&eng->regs->taskBar, tdt_pa);
 
 	/* Init 'always' initiator */
-	out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
+	out_8(&eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
+
+	/* Init lock */
+	spin_lock_init(&eng->lock);
+
+	/* Ensure all engine fields are visible before publishing bcom_eng */
+	smp_store_release(&bcom_eng, eng);
 
 	/* Disable COMM Bus Prefetch on the original 5200; it's broken */
 	if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR)
 		bcom_disable_prefetch();
 
-	/* Init lock */
-	spin_lock_init(&bcom_eng->lock);
-
 	return 0;
 }
 
@@ -363,6 +366,7 @@ bcom_engine_cleanup(void)
 
 static int mpc52xx_bcom_probe(struct platform_device *op)
 {
+	struct bcom_engine *eng;
 	struct device_node *ofn_sram;
 	struct resource *res_bcom;
 	void __iomem *regs;
@@ -398,20 +402,20 @@ static int mpc52xx_bcom_probe(struct platform_device *op)
 	}
 
 	/* Get a clean struct */
-	bcom_eng = kzalloc_obj(struct bcom_engine);
-	if (!bcom_eng) {
+	eng = kzalloc_obj(struct bcom_engine);
+	if (!eng) {
 		rv = -ENOMEM;
 		goto error_sramclean;
 	}
 
 	/* Save the node */
-	bcom_eng->ofnode = op->dev.of_node;
+	eng->ofnode = op->dev.of_node;
 
-	bcom_eng->regs = regs;
-	bcom_eng->regs_base = res_bcom->start;
+	eng->regs = regs;
+	eng->regs_base = res_bcom->start;
 
 	/* Now, do the real init */
-	rv = bcom_engine_init();
+	rv = bcom_engine_init(eng);
 	if (rv)
 		goto error_sramclean;
 
@@ -423,8 +427,7 @@ static int mpc52xx_bcom_probe(struct platform_device *op)
 
 	/* Error path */
 error_sramclean:
-	kfree(bcom_eng);
-	bcom_eng = NULL;
+	kfree(eng);
 	bcom_sram_cleanup();
 error_ofput:
 	of_node_put(op->dev.of_node);
-- 
2.56.0.567.gdb80ae8cd5-goog


  parent reply	other threads:[~2026-11-11 21:54 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11 21:52 [PATCH 00/10] dmaengine: Fix teardown races, resource leaks, and error handling Lee Jones
2026-11-11 21:52 ` [PATCH 01/10] dmaengine: pl08x: Defer OF DMA controller registration until slave setup Lee Jones
2026-11-11 21:52 ` [PATCH 02/10] dmaengine: ae4dma: Unregister DMA engine in ae4_pci_remove() Lee Jones
2026-11-11 21:52 ` [PATCH 03/10] dmaengine: ptdma: Unmap descriptor in pt_do_cleanup() Lee Jones
2026-11-11 21:52 ` [PATCH 04/10] dmaengine: ptdma: Remove completed descriptor under vc.lock in pt_cmd_callback_work() Lee Jones
2026-11-11 21:52 ` [PATCH 05/10] dmaengine: amlogic: Destroy free_wq after devres DMA device unregistration Lee Jones
2026-11-11 21:52 ` [PATCH 06/10] dmaengine: arm-dma350: Query dma_cookie_status() under vc.lock in d350_tx_status() Lee Jones
2026-11-11 21:52 ` Lee Jones [this message]
2026-11-11 21:52 ` [PATCH 08/10] dmaengine: bestcomm: Check rh_create() return value in bcom_sram_init() Lee Jones
2026-11-11 21:52 ` [PATCH 09/10] dmaengine: jz4780: Fix descriptor cleanup on hwdesc setup failure Lee Jones
2026-11-11 21:52 ` [PATCH 10/10] dmaengine: dmatest: Avoid unsigned underflow in min_odd() Lee Jones

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261111215349.1983909-8-lee@kernel.org \
    --to=lee@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=avolkov@varma-el.com \
    --cc=dfarnsworth@mvista.com \
    --cc=dmaengine@vger.kernel.org \
    --cc=grant.likely@secretlab.ca \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tnt@246tNt.com \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®