Devicetree
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Paul Louvel" <paul.louvel@bootlin.com>
Cc: robh@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org,
	wsa+renesas@sang-engineering.com
Subject: Re: [PATCH v4 2/3] EDAC/cadence: Add Cadence DDR EDAC driver
Date: Mon, 28 Sep 2026 10:55:21 +0000	[thread overview]
Message-ID: <20260928105521.9BC471F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260928-paul-v7-3-rc1-edac-v4-2-4646a5b7cac9@bootlin.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] edac: use-after-free of mci structure in interrupt handler
- [Medium] edac: incomplete memory size calculation misses discontiguous banks
--

commit a92ae5cd8100995af0607d832e0079266536f567
Author: Paul Louvel <paul.louvel@bootlin.com>

EDAC/cadence: Add Cadence DDR EDAC driver

Add the Cadence EDAC driver found on Renesas RZ/N1x SoC.
The memory controller supports ECC, software scrubbing, and SECDED.

> diff --git a/drivers/edac/cadence_edac.c b/drivers/edac/cadence_edac.c
> new file mode 100644
> index 0000000000000..3f27bbb94c53c
> --- /dev/null
> +++ b/drivers/edac/cadence_edac.c

[ ... ]

> +static int cdns_get_mem_sz(resource_size_t *mem_sz)
> +{
> +	struct device_node *np;
> +	struct resource res;
> +	int ret;
> +
> +	np = of_find_node_by_name(NULL, "memory");
> +	if (!np)
> +		return -ENODEV;
> +
> +	ret = of_address_to_resource(np, 0, &res);

[Severity: Medium]
By hardcoding index 0 in of_address_to_resource(), does this calculation
only fetch the first contiguous memory region? On systems with multiple
memory nodes or discontiguous memory banks, it appears this will
under-report the total system memory capacity to the EDAC core. Could we
iterate over all available memory regions instead?

> +
> +	of_node_put(np);

[ ... ]

> +static int cdns_setup_irq(struct platform_device *pdev, struct mem_ctl_info *mci)
> +{
> +	int irq, ret;
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq < 0)
> +		return dev_err_probe(&pdev->dev, irq, "unable to get irq\n");
> +
> +	ret = devm_request_irq(&pdev->dev, irq, cdns_mc_err_handler, 0, dev_name(&pdev->dev), mci);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret, "unable to request irq %d\n", irq);
> +
> +	return 0;
> +}

[ ... ]

> +static int cdns_setup_mc(struct platform_device *pdev, void __iomem *io_base)
> +{

[ ... ]

> +	ret = cdns_setup_irq(pdev, mci);
> +	if (ret)
> +		goto free_edac_mc;
> +
> +	ret = edac_mc_add_mc(mci);
> +	if (ret) {
> +		dev_err_probe(&pdev->dev, ret, "failed to add mc\n");
> +		goto free_edac_mc;
> +	}
> +
> +#ifdef CONFIG_EDAC_DEBUG
> +	cdns_setup_debugfs(mci);
> +#endif
> +
> +	edac_mc_chipset_printk(mci, KERN_DEBUG, DRV_NAME, "ECC %s\n",
> +			       (mci->edac_cap == EDAC_FLAG_NONE) ? "disabled" : "enabled");
> +
> +	return 0;
> +
> +free_edac_mc:
> +	edac_mc_free(mci);

[Severity: High]
In the probe error path, mci is explicitly freed while the devres-managed
interrupt handler is still registered. Since hardware interrupts are triggered
asynchronously, could a spurious interrupt fire before the devres cleanup
runs?

If it does, the interrupt handler cdns_mc_err_handler() will dereference the
freed mci and priv pointers:

static irqreturn_t cdns_mc_err_handler(int irq, void *dev_id)
{
        struct mem_ctl_info *mci = dev_id;
        struct cdns_mc_priv *priv = mci->pvt_info;
        ...

Would it be safer to explicitly free the irq or use the non-devres variant
of request_irq() to ensure it is freed before the mci structure?

> +	return ret;
> +}

[ ... ]

> +static void cdns_mc_remove(struct platform_device *pdev)
> +{
> +	struct mem_ctl_info *mci = platform_get_drvdata(pdev);
> +	struct cdns_mc_priv *priv = mci->pvt_info;
> +
> +	writel(CDNS_DDR_ECC_INT_CTRL_MASK_ALL, priv->io_base + CDNS_DDR_ECC_INT_CTRL);
> +#ifdef CONFIG_EDAC_DEBUG
> +	edac_debugfs_remove_recursive(priv->debugfs);
> +#endif
> +	edac_mc_del_mc(&pdev->dev);
> +	edac_mc_free(mci);

[Severity: High]
Similarly, since the interrupt handler was registered using devm_request_irq(),
its cleanup is deferred until after this remove function completes. Does
explicitly calling edac_mc_free() here create a window where a concurrent
interrupt could fire and access the freed mci structure?

Even though interrupts are masked at the device level earlier in this
function, an interrupt handler could already be executing concurrently on
another CPU when edac_mc_free() is called.

> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260928-paul-v7-3-rc1-edac-v4-0-4646a5b7cac9@bootlin.com?part=2

  reply	other threads:[~2026-09-28 10:55 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-28 10:45 [PATCH v4 0/3] Add Renesas RZ/N1x EDAC driver Paul Louvel
2026-09-28 10:45 ` [PATCH v4 1/3] dt-bindings: edac: cdns,ddr-edac: add Cadence DDR EDAC binding Paul Louvel
2026-09-29  9:05   ` Krzysztof Kozlowski
2026-09-29  9:18     ` Miquel Raynal
2026-09-30 10:29       ` Krzysztof Kozlowski
2026-09-28 10:45 ` [PATCH v4 2/3] EDAC/cadence: Add Cadence DDR EDAC driver Paul Louvel
2026-09-28 10:55   ` sashiko-bot [this message]
2026-09-28 10:45 ` [PATCH v4 3/3] ARM: dts: renesas: r9a06g032: add EDAC node Paul Louvel

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=20260928105521.9BC471F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=paul.louvel@bootlin.com \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=wsa+renesas@sang-engineering.com \
    /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