All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net] ptp: netc: fix potential interrupt storm caused by incorrect unbind order
@ 2026-07-24  6:51 wei.fang
  2026-07-24 11:00 ` Vadim Fedorenko
  2026-07-25  6:47 ` sashiko-bot
  0 siblings, 2 replies; 3+ messages in thread
From: wei.fang @ 2026-07-24  6:51 UTC (permalink / raw)
  To: richardcochran, xiaoning.wang, andrew+netdev, davem, edumazet,
	kuba, pabeni, Frank.Li, vadim.fedorenko
  Cc: wei.fang, imx, netdev, linux-kernel

From: Wei Fang <wei.fang@nxp.com>

In netc_timer_remove(), hardware interrupts are disabled by clearing
TMR_TEMASK before ptp_clock_unregister() is called. This may cause a
race condition during driver unbind that could leave hardware interrupts
active. For example, a concurrent PTP_CLK_REQ_EXTTS ioctl can re-enable
TMR_TEMASK after it has been cleared, leaving a pending hardware
interrupt when the driver unbinds.

Since the NETC Timer does not support PCIe FLR, hardware state is not
reset during probe. When the driver is rebound and the IRQ is registered,
the pending interrupt fires immediately. At that point priv->tmr_emask
is still zero, so netc_timer_isr() does not clear the interrupt status
and unconditionally returns IRQ_HANDLED, resulting in an uninterruptible
infinite interrupt storm.

Therefore, move ptp_clock_unregister() before the register writes that
clear NETC_TMR_TEMASK and NETC_TMR_CTRL. This guarantees that no
in-flight or concurrent ioctl can re-enable hardware interrupts, so no
pending interrupt is left when the driver unbinds.

Fixes: 671e266835b8 ("ptp: netc: add periodic pulse output support")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260720012508.23227-1-wei.fang%40oss.nxp.com
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
 drivers/ptp/ptp_netc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/ptp/ptp_netc.c b/drivers/ptp/ptp_netc.c
index 5e381c354d74..3bab86afe8e2 100644
--- a/drivers/ptp/ptp_netc.c
+++ b/drivers/ptp/ptp_netc.c
@@ -1019,9 +1019,9 @@ static void netc_timer_remove(struct pci_dev *pdev)
 {
 	struct netc_timer *priv = pci_get_drvdata(pdev);
 
+	ptp_clock_unregister(priv->clock);
 	netc_timer_wr(priv, NETC_TMR_TEMASK, 0);
 	netc_timer_wr(priv, NETC_TMR_CTRL, 0);
-	ptp_clock_unregister(priv->clock);
 	netc_timer_free_msix_irq(priv);
 	netc_timer_pci_remove(pdev);
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH net] ptp: netc: fix potential interrupt storm caused by incorrect unbind order
  2026-07-24  6:51 [PATCH net] ptp: netc: fix potential interrupt storm caused by incorrect unbind order wei.fang
@ 2026-07-24 11:00 ` Vadim Fedorenko
  2026-07-25  6:47 ` sashiko-bot
  1 sibling, 0 replies; 3+ messages in thread
From: Vadim Fedorenko @ 2026-07-24 11:00 UTC (permalink / raw)
  To: wei.fang, richardcochran, xiaoning.wang, andrew+netdev, davem,
	edumazet, kuba, pabeni, Frank.Li
  Cc: wei.fang, imx, netdev, linux-kernel

On 24/07/2026 07:51, wei.fang@oss.nxp.com wrote:
> From: Wei Fang <wei.fang@nxp.com>
> 
> In netc_timer_remove(), hardware interrupts are disabled by clearing
> TMR_TEMASK before ptp_clock_unregister() is called. This may cause a
> race condition during driver unbind that could leave hardware interrupts
> active. For example, a concurrent PTP_CLK_REQ_EXTTS ioctl can re-enable
> TMR_TEMASK after it has been cleared, leaving a pending hardware
> interrupt when the driver unbinds.
> 
> Since the NETC Timer does not support PCIe FLR, hardware state is not
> reset during probe. When the driver is rebound and the IRQ is registered,
> the pending interrupt fires immediately. At that point priv->tmr_emask
> is still zero, so netc_timer_isr() does not clear the interrupt status
> and unconditionally returns IRQ_HANDLED, resulting in an uninterruptible
> infinite interrupt storm.
> 
> Therefore, move ptp_clock_unregister() before the register writes that
> clear NETC_TMR_TEMASK and NETC_TMR_CTRL. This guarantees that no
> in-flight or concurrent ioctl can re-enable hardware interrupts, so no
> pending interrupt is left when the driver unbinds.
> 
> Fixes: 671e266835b8 ("ptp: netc: add periodic pulse output support")
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Closes: https://sashiko.dev/#/patchset/20260720012508.23227-1-wei.fang%40oss.nxp.com
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
> ---
>   drivers/ptp/ptp_netc.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/ptp/ptp_netc.c b/drivers/ptp/ptp_netc.c
> index 5e381c354d74..3bab86afe8e2 100644
> --- a/drivers/ptp/ptp_netc.c
> +++ b/drivers/ptp/ptp_netc.c
> @@ -1019,9 +1019,9 @@ static void netc_timer_remove(struct pci_dev *pdev)
>   {
>   	struct netc_timer *priv = pci_get_drvdata(pdev);
>   
> +	ptp_clock_unregister(priv->clock);
>   	netc_timer_wr(priv, NETC_TMR_TEMASK, 0);
>   	netc_timer_wr(priv, NETC_TMR_CTRL, 0);
> -	ptp_clock_unregister(priv->clock);
>   	netc_timer_free_msix_irq(priv);
>   	netc_timer_pci_remove(pdev);
>   }

Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net] ptp: netc: fix potential interrupt storm caused by incorrect unbind order
  2026-07-24  6:51 [PATCH net] ptp: netc: fix potential interrupt storm caused by incorrect unbind order wei.fang
  2026-07-24 11:00 ` Vadim Fedorenko
@ 2026-07-25  6:47 ` sashiko-bot
  1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-07-25  6:47 UTC (permalink / raw)
  To: wei.fang; +Cc: Frank.Li, imx

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

New issues:
- [High] Moving ptp_clock_unregister() before disabling hardware interrupts and freeing the IRQ introduces a critical Use-After-Free vulnerability in the interrupt handler.

Pre-existing issues:
- [High] Missing hardware state reset in probe and an unconditional IRQ_HANDLED in the ISR combined with a failure to clear unmasked events causes an unrecoverable hard lockup.
--

--- Patch [1]: [PATCH net] ptp: netc: fix potential interrupt storm caused by incorrect unbind order ---
commit 013a4be8e793c3f4970ce39a1488e2416c4cea60
Author: Wei Fang <wei.fang@nxp.com>

ptp: netc: fix potential interrupt storm caused by incorrect unbind order

This commit reorders operations in netc_timer_remove() to unregister
the PTP clock before clearing the timer event mask and control registers.
This aims to prevent a race condition during driver unbind that could
leave hardware interrupts active and cause an interrupt storm.

Closes: https://sashiko.dev/#/patchset/20260720012508.23227-1-wei.fang%40oss.nxp.com

> diff --git a/drivers/ptp/ptp_netc.c b/drivers/ptp/ptp_netc.c
> index 5e381c354d746..3bab86afe8e23 100644
> --- a/drivers/ptp/ptp_netc.c
> +++ b/drivers/ptp/ptp_netc.c
> @@ -1019,9 +1019,9 @@ static void netc_timer_remove(struct pci_dev *pdev)
>  {
>  	struct netc_timer *priv = pci_get_drvdata(pdev);
>  
> +	ptp_clock_unregister(priv->clock);
> +	netc_timer_wr(priv, NETC_TMR_TEMASK, 0);

[Severity: High]
Does moving ptp_clock_unregister() before masking hardware interrupts
introduce a use-after-free regression in the interrupt handler?

If EXTTS events are configured, ptp_clock_unregister() drops the final
device reference and frees priv->clock if no file descriptors are open.

Because the hardware interrupt mask (NETC_TMR_TEMASK) is not cleared until
the next instruction, and free_irq() has not yet been called, the hardware
can still fire an EXTTS interrupt.

If this occurs, the ISR netc_timer_isr() processes the event and
unconditionally dereferences the freed clock object:

netc_timer_isr() -> netc_timer_handle_etts_event() {
    ...
    ptp_clock_event(priv->clock, &event);
    ...
}

>  	netc_timer_wr(priv, NETC_TMR_CTRL, 0);
> -	ptp_clock_unregister(priv->clock);
>  	netc_timer_free_msix_irq(priv);
>  	netc_timer_pci_remove(pdev);
>  }

[Severity: High]
This isn't a bug introduced by this patch, but can the driver encounter a
hard lockup during probe on kexec or an unclean shutdown?

Because the NETC timer does not support PCIe FLR, hardware registers
retain their state. In netc_timer_probe(), the driver requests the IRQ via
netc_timer_init_msix_irq() before resetting the hardware state.

If the hardware has a pending interrupt, it fires immediately upon
request_irq(). At this point, priv->tmr_emask is 0.

The ISR netc_timer_isr() masks the hardware status with priv->tmr_emask
and writes 0 back to the Write-1-to-Clear (W1C) register, failing to clear
the pending hardware interrupt:

netc_timer_isr() {
    ...
    tmr_event = netc_timer_rd(priv, NETC_TMR_TEVENT);
    tmr_event &= priv->tmr_emask;
    /* Clear interrupts status */
    netc_timer_wr(priv, NETC_TMR_TEVENT, tmr_event);
    ...
}

The ISR then defeats the kernel's spurious interrupt detection by
unconditionally returning IRQ_HANDLED, causing the interrupt controller to
re-invoke the ISR in an infinite loop:

netc_timer_isr() {
    ...
    return IRQ_HANDLED;
}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260724065116.521893-1-wei.fang@oss.nxp.com?part=1

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-25  6:47 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-24  6:51 [PATCH net] ptp: netc: fix potential interrupt storm caused by incorrect unbind order wei.fang
2026-07-24 11:00 ` Vadim Fedorenko
2026-07-25  6:47 ` sashiko-bot

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.