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: 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®