Linux PCI subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Manivannan Sadhasivam" <manivannan.sadhasivam@oss.qualcomm.com>
Cc: linux-pci@vger.kernel.org
Subject: Re: [PATCH v2] PCI: mediatek: Fix IRQ domain leak when port fails to enable
Date: Thu, 21 May 2026 18:26:22 +0000	[thread overview]
Message-ID: <20260521182622.DC3891F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260521174617.17692-1-mani@kernel.org>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

Pre-existing issues:
- [High] Freeing the `port` structure in `mtk_pcie_resume_noirq()` on failure without IRQ teardown leaves dangling pointers in active IRQ domains and chained handlers.
- [High] Probe error paths fail to tear down IRQ domains and chained handlers if an error occurs after a port's IRQs are configured, leading to a Use-After-Free.
- [High] `mtk_pcie_resume_noirq()` illegally calls `clk_prepare_enable()`, which acquires a sleeping mutex, inside a NOIRQ suspend/resume callback.
- [High] A double powerdown occurs during driver removal if all ports failed to link up during probe.
--

commit 9862107995188d91184cf0a5c63549b0feed587c
Author: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>

PCI: mediatek: Fix IRQ domain leak when port fails to enable

This commit fixes an IRQ domain leak by refactoring IRQ teardown into a
per-port helper and calling it when mtk_pcie_enable_port() fails.
mtk_pcie_enable_port() is modified to return an error code to distinguish
between probe and resume error paths.

Cc: stable@vger.kernel.org # 5.10
Cc: Caleb James DeLisle <cjd@cjdns.fr>

> diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> index 75722524fe744..907ae4285ecb1 100644
> --- a/drivers/pci/controller/pcie-mediatek.c
> +++ b/drivers/pci/controller/pcie-mediatek.c

[ ... ]

> @@ -1109,8 +1117,13 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie)
>  		return err;
>  
>  	/* enable each port, and then check link status */
> -	list_for_each_entry_safe(port, tmp, &pcie->ports, list)
> -		mtk_pcie_enable_port(port);
> +	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> +		err = mtk_pcie_enable_port(port);
> +		if (err) {
> +			mtk_pcie_irq_teardown_port(port);
> +			mtk_pcie_port_free(port);
> +		}
> +	}

[Severity: High]
This is a pre-existing issue, but do probe error paths fail to tear down
IRQ domains and chained handlers if an error occurs after a port's IRQs are
configured?

Earlier in mtk_pcie_setup(), if mtk_pcie_parse_port() fails for a
subsequent port, or if mtk_pcie_subsys_powerup() fails, the function
returns the error directly. 

This causes mtk_pcie_probe() to exit without calling mtk_pcie_irq_teardown().
The devm subsystem automatically frees the allocated port structures, but the
IRQ domains and chained handlers initialized for the previously successful
ports are never torn down. Does this leave them active with dangling pointers
to the freed port memory, leading to a use-after-free on the next interrupt?

>  	/* power down PCIe subsys if slots are all empty (link down) */
>  	if (list_empty(&pcie->ports))

[Severity: High]
This is a pre-existing issue, but does a double powerdown occur during
driver removal if all ports failed to link up during probe?

If all ports fail to link up during mtk_pcie_setup(), the driver calls
mtk_pcie_subsys_powerdown(pcie) but still successfully returns 0 from probe.

Later, if the driver is unbound, mtk_pcie_remove() unconditionally calls
mtk_pcie_put_resources(), which invokes mtk_pcie_subsys_powerdown(pcie)
again. Does this disable the clocks (e.g., free_ck) and call
pm_runtime_put_sync() for a second time, underflowing their respective
reference counts?

[ ... ]

> @@ -1209,14 +1222,18 @@ static int mtk_pcie_resume_noirq(struct device *dev)
>  {
>  	struct mtk_pcie *pcie = dev_get_drvdata(dev);
>  	struct mtk_pcie_port *port, *tmp;
> +	int err;
>  
>  	if (list_empty(&pcie->ports))
>  		return 0;
>  
>  	clk_prepare_enable(pcie->free_ck);

[Severity: High]
This is a pre-existing issue, but does mtk_pcie_resume_noirq() illegally
call clk_prepare_enable() inside a NOIRQ suspend/resume callback?

The NOIRQ power management callbacks execute in an atomic context with local
hardware interrupts disabled. However, mtk_pcie_resume_noirq() calls
clk_prepare_enable() (both directly for pcie->free_ck and indirectly via
mtk_pcie_enable_port() for sys_ck, ahb_ck, etc.).

Since clk_prepare() inherently acquires a global mutex (prepare_lock), which
sleeps, will this trigger a 'sleeping in atomic context' bug?

>  
> -	list_for_each_entry_safe(port, tmp, &pcie->ports, list)
> -		mtk_pcie_enable_port(port);
> +	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> +		err = mtk_pcie_enable_port(port);
> +		if (err)
> +			mtk_pcie_port_free(port);
> +	}

[Severity: High]
This is a pre-existing issue, but does freeing the port structure in
mtk_pcie_resume_noirq() on failure without IRQ teardown leave dangling
pointers?

If a port fails to resume, the driver frees the port structure using
mtk_pcie_port_free(). However, because tearing down IRQs requires sleeping
locks, mtk_pcie_irq_teardown_port() is skipped here.

Does this leave active IRQ domains and chained interrupt handlers pointing
to freed memory, causing a use-after-free crash on subsequent hardware
interrupts or interactions with the IRQ domain?

>  	/* In case of EP was removed while system suspend. */
>  	if (list_empty(&pcie->ports))

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260521174617.17692-1-mani@kernel.org?part=1

  reply	other threads:[~2026-05-21 18:26 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-21 17:46 [PATCH v2] PCI: mediatek: Fix IRQ domain leak when port fails to enable Manivannan Sadhasivam
2026-05-21 18:26 ` sashiko-bot [this message]
2026-06-09 16:50 ` Manivannan Sadhasivam

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=20260521182622.DC3891F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=manivannan.sadhasivam@oss.qualcomm.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /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