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
next prev parent reply other threads:[~2026-11-11 21:54 UTC|newest]
Thread overview: 18+ 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 ` 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 22:32 ` sashiko-bot
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 ` Lee Jones
2026-11-11 22:23 ` sashiko-bot
2026-11-11 22:23 ` sashiko-bot
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 22:26 ` [PATCH 07/10] dmaengine: bestcomm: Defer publishing bcom_eng until initialisation completes sashiko-bot
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 22:26 ` sashiko-bot
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.