RE: [PATCH net] ptp: netc: fix potential interrupt storm caused by incorrect unbind order

"Wei Fang (OSS)" <[email protected]>
Newsgroups dev.linux.lists.imx,dev.linux.lists.sashiko-reviews,org.kernel.vger.netdev
Message-ID <GV2PR04MB11739D22B9ABBFA122A56BBAE88CC2@GV2PR04MB11739.eurprd04.prod.outlook.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?

That is indeed a problem, I will fix it in next version.

> 
> 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.