From: sashiko-bot@kernel.org
To: "Chunfeng Yun" <chunfeng.yun@mediatek.com>
Cc: linux-usb@vger.kernel.org
Subject: Re: [PATCH v2 4/7] thunderbolt: add platform NHI driver
Date: Tue, 10 Nov 2026 12:15:37 +0000 [thread overview]
Message-ID: <sashiko-outbox-206992@kernel.org> (raw)
In-Reply-To: <20261110114925.722014-5-chunfeng.yun@mediatek.com>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [High] thunderbolt: broken system PM when sharing tb_nhi_pm_ops on
platform_driver
- [Medium] thunderbolt: missing cleanup in nhi_platform_init_irq() and
tb_nhi_probe()
--
commit 185e80648753aea8ed254f3effc097c624617d73
Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
thunderbolt: add platform NHI driver
This commit adds a platform driver for Thunderbolt/USB4 Native Host Interface
(NHI) controllers integrated as memory-mapped platform devices via Device Tree
or ACPI, including support for an optional dedicated wakeup interrupt.
> diff --git a/drivers/thunderbolt/platform.c b/drivers/thunderbolt/platform.c
> new file mode 100644
> index 0000000000000..3562b6c7ea7db
> --- /dev/null
> +++ b/drivers/thunderbolt/platform.c
> @@ -0,0 +1,172 @@
[ ... ]
> +static int nhi_platform_init(struct tb_nhi *nhi)
> +{
> + /* avoid device link fail for pcie tunnel */
> + pm_runtime_set_active(nhi->dev);
> + pm_runtime_get_noresume(nhi->dev);
> + pm_runtime_enable(nhi->dev);
> +
> + device_set_wakeup_capable(nhi->dev, true);
> + device_enable_async_suspend(nhi->dev);
> +
> + return 0;
> +}
> +
> +static void nhi_platform_clear_wake_irq(void *dev)
> +{
> + dev_pm_clear_wake_irq(dev);
> +}
> +
> +static int nhi_platform_init_irq(struct tb_nhi *nhi)
> +{
> + struct device *dev = nhi->dev;
> + int ret;
> +
> + ret = devm_request_irq(dev, nhi->irq, tb_nhi_isr, IRQF_NO_SUSPEND,
> + dev_name(dev), nhi);
> + if (ret)
> + return dev_err_probe(dev, ret, "request irq failed\n");
> +
> + if (nhi->wake_irq) {
> + ret = dev_pm_set_dedicated_wake_irq(dev, nhi->wake_irq);
> + if (ret) {
> + return dev_err_probe(dev, ret, "set wake irq %d failed\n", nhi->wake_irq);
> + }
> +
> + dev_info(dev, "wake irq %d\n", nhi->wake_irq);
> +
> + ret = devm_add_action_or_reset(dev, nhi_platform_clear_wake_irq, dev);
> + }
> +
> + return ret;
> +}
> +
> +static void nhi_platform_exit(struct tb_nhi *nhi)
> +{
> + devm_free_irq(nhi->dev, nhi->irq, nhi);
> + flush_work(&nhi->interrupt_work);
> +
> + pm_runtime_put_noidle(nhi->dev);
> + pm_runtime_disable(nhi->dev);
> + pm_runtime_set_suspended(nhi->dev);
> +}
[Severity: Medium]
Does a probe failure before tb_domain_add() bypass nhi_platform_exit(),
leaving nhi->interrupt_work unflushed and runtime PM enabled on the unbound
device?
In tb_nhi_probe(), tb_nhi_shutdown() is only called if tb_domain_add() fails:
drivers/thunderbolt/nhi.c:tb_nhi_probe() {
...
res = nhi->ops->init_interrupts(nhi);
if (res)
return dev_err_probe(dev, res, "cannot enable interrupts, aborting\n");
spin_lock_init(&nhi->lock);
res = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
if (res)
return dev_err_probe(dev, res, "failed to set DMA mask\n");
if (nhi->ops->init) {
res = nhi->ops->init(nhi);
if (res)
return dev_err_probe(dev, res, "NHI specific init failed\n");
}
init_completion(&nhi->domain_released);
tb = nhi_select_cm(nhi);
if (!tb)
return dev_err_probe(dev, -ENODEV,
"failed to determine connection manager, aborting\n");
...
}
If dev_pm_set_dedicated_wake_irq() fails in nhi_platform_init_irq(), or if
dma_set_mask_and_coherent() or nhi_select_cm() fails in tb_nhi_probe(),
devres frees nhi->irq, unmaps nhi->iobase, and frees nhi without ever
flushing nhi->interrupt_work, which can cause a use-after-free if
tb_nhi_isr() scheduled the work item. In addition, if nhi_select_cm() fails
after nhi_platform_init() has run, runtime PM stays enabled with an elevated
usage count, so pm_runtime_reinit() in device_unbind_cleanup() bails out and
a subsequent re-probe warns on unbalanced pm_runtime_enable().
[ ... ]
> +static struct platform_driver nhi_platform_driver = {
> + .probe = nhi_platform_probe,
> + .remove = nhi_platform_remove,
> + .shutdown = nhi_platform_shutdown,
> + .driver = {
> + .name = "thunderbolt",
> + .of_match_table = of_match_ptr(nhi_platform_of_match),
> + .acpi_match_table = ACPI_PTR(nhi_platform_acpi_match),
> + .pm = &tb_nhi_pm_ops,
> + },
> +};
[Severity: High]
Can system suspend and resume run while the platform NHI is runtime-suspended
when using tb_nhi_pm_ops directly on a platform_driver?
On PCI, pci_pm_suspend() runtime-resumes the device before calling the
driver's .suspend and .suspend_noirq callbacks. Neither the platform bus,
genpd, nor nhi_suspend() does that, and device_wakeup_enable() prevents
direct_complete. If the controller has autosuspended before system suspend:
1. nhi_suspend_noirq() -> tb_domain_suspend_noirq() runs while the device is
runtime-suspended (with clocks or power domains gated) and calls
tb_ctl_stop() on rings already stopped by nhi_runtime_suspend(), triggering
dev_WARN() in tb_ring_stop().
2. On resume, nhi_resume_noirq() -> tb_domain_resume_noirq() calls
tb_ctl_start(), touching MMIO while runtime status is still RPM_SUSPENDED
and queuing ctl->rx_packets[] onto ctl->rx->in_flight.
3. In the complete phase, nhi_complete() sees pm_runtime_suspended(dev) is
still true and calls pm_runtime_resume(dev) -> nhi_runtime_resume() ->
tb_ctl_start() a second time:
drivers/thunderbolt/nhi.c:nhi_complete() {
struct tb *tb = dev_get_drvdata(dev);
/*
* If we were runtime suspended when system suspend started,
* schedule runtime resume now. It should bring the domain back
* to functional state.
*/
if (pm_runtime_suspended(dev))
pm_runtime_resume(dev);
else
tb_domain_complete(tb);
}
The second tb_ctl_start() warns that the rings are already started and calls
tb_ctl_rx_submit() -> __tb_ring_enqueue() -> list_add_tail() on
ctl->rx_packets[] frames that are already linked in ctl->rx->in_flight,
corrupting the ring list.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261110114925.722014-2-chunfeng.yun@mediatek.com?part=4
next prev parent reply other threads:[~2026-11-10 12:15 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 11:48 [PATCH 0/7] thunderbolt: Add support platform NHI driver Chunfeng Yun
2026-11-10 11:48 ` [PATCH v2 1/7] thunderbolt: Prefix NHI core functions with tb_ and tb_ring_ Chunfeng Yun
2026-11-10 11:53 ` sashiko-bot
2026-11-10 12:42 ` Konrad Dybcio
2026-11-11 2:26 ` Chunfeng Yun (云春峰)
2026-11-10 11:48 ` [PATCH v2 2/7] thunderbolt: Move ICM mailbox functions to icm.c and internalize interrupt work Chunfeng Yun
2026-11-10 12:02 ` sashiko-bot
2026-11-10 14:24 ` Mika Westerberg
2026-11-11 2:37 ` Chunfeng Yun (云春峰)
2026-11-10 11:48 ` [PATCH v2 3/7] thunderbolt: Make PCIe NHI support opt-in Chunfeng Yun
2026-11-10 12:09 ` sashiko-bot
2026-11-11 12:17 ` Chunfeng Yun (云春峰)
2026-11-10 11:48 ` [PATCH v2 4/7] thunderbolt: add platform NHI driver Chunfeng Yun
2026-11-10 12:15 ` sashiko-bot [this message]
2026-11-10 12:43 ` Konrad Dybcio
2026-11-11 13:29 ` Chunfeng Yun (云春峰)
2026-11-10 14:37 ` Mika Westerberg
2026-11-10 11:48 ` [PATCH v2 5/7] thunderbolt: increase the lane adapter link-up timeout value Chunfeng Yun
2026-11-10 11:55 ` sashiko-bot
2026-11-12 7:27 ` Chunfeng Yun (云春峰)
2026-11-10 14:39 ` Mika Westerberg
2026-11-12 7:24 ` Chunfeng Yun (云春峰)
2026-11-10 11:48 ` [PATCH v2 6/7] thunderbolt: decouple the waiting time of TB_PORT_UNPLUGGED and TB_PORT_UP Chunfeng Yun
2026-11-10 11:55 ` sashiko-bot
2026-11-10 14:40 ` Mika Westerberg
2026-11-12 8:00 ` Chunfeng Yun (云春峰)
2026-11-10 11:48 ` [PATCH v2 7/7] thunderbolt: prevent pcie tunnel activation/teardown warnings Chunfeng Yun
2026-11-10 12:01 ` sashiko-bot
2026-11-10 14:50 ` Mika Westerberg
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=sashiko-outbox-206992@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=chunfeng.yun@mediatek.com \
--cc=linux-usb@vger.kernel.org \
--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