Re: [PATCH] serial: 8250_omap: fix wake irq cleared during suspend

[email protected]
Newsgroups org.kernel.vger.linux-serial
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [Medium] Calling `dev_pm_clear_wake_irq()` after `pm_runtime_put_sync()` in the teardown paths creates a race window that can leave the device permanently active.

Pre-existing issues:
- [High] Invalid hardware access via `pm_runtime_get_noresume()` in the IRQ handler allows access to powered-off hardware.
--

--- Patch [1]: [PATCH] serial: 8250_omap: fix wake irq cleared during suspend ---
commit 69c0ce16c163036cdb1ba2600546648c535da1c2
Author: Kendall Willis <[email protected]>

serial: 8250_omap: fix wake irq cleared during suspend
    
The wake irq was cleared in shutdown(), which runs during the suspend
sequence, making it impossible to wake the system via UART. Move wake
irq setup to probe() and teardown to remove() so the irq remains armed
during suspend when the UART is a wakeup source.

> diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
> index 3c7775df27eff..9cc88d2c510ce 100644
> --- a/drivers/tty/serial/8250/8250_omap.c
> +++ b/drivers/tty/serial/8250/8250_omap.c

[ ... ]

> @@ -1608,6 +1607,7 @@ static int omap8250_probe(struct platform_device *pdev)
>  	flush_work(&priv->qos_work);
>  	pm_runtime_disable(&pdev->dev);
>  	cpu_latency_qos_remove_request(&priv->pm_qos_request);
> +	dev_pm_clear_wake_irq(&pdev->dev);

[Severity: Medium]
Does calling dev_pm_clear_wake_irq() after pm_runtime_put_sync() create a
race condition?

When pm_runtime_put_sync() synchronously suspends the device earlier in the
cleanup path, the PM core enables the wake IRQ. If the wake IRQ fires before
dev_pm_clear_wake_irq() can disable it, the threaded handler may call
pm_runtime_resume().

The subsequent pm_runtime_disable() will then wait for the resume to finish,
leaving the device permanently locked in the RPM_ACTIVE state.

>  	return ret;
>  }
>  
> @@ -1630,6 +1630,7 @@ static void omap8250_remove(struct platform_device *pdev)
>  	flush_work(&priv->qos_work);
>  	pm_runtime_disable(&pdev->dev);
>  	cpu_latency_qos_remove_request(&priv->pm_qos_request);
> +	dev_pm_clear_wake_irq(&pdev->dev);

[Severity: Medium]
Could this teardown order leave the device permanently active here as well?

Similarly to the probe error path above, calling dev_pm_clear_wake_irq()
after pm_runtime_put_sync() opens a window where a wake IRQ could cause the
device to resume.

The pm_runtime_disable() would then wait for the resume to finish, locking
the device in RPM_ACTIVE.

>  	device_set_wakeup_capable(&pdev->dev, false);
>  }

[Severity: High]
This is a pre-existing issue, but does using pm_runtime_get_noresume() in
the interrupt handler allow access to powered-off hardware?

Looking at omap8250_irq() in drivers/tty/serial/8250/8250_omap.c:

omap8250_irq() {
	pm_runtime_get_noresume(port->dev);

	/* Shallow idle state wake-up to an IO interrupt? */
	...
	lsr = serial_port_in(port, UART_LSR);
	iir = serial_port_in(port, UART_IIR);
	...
}

pm_runtime_get_noresume() only increments the usage counter but does not
initiate a resume or check the runtime status.

If the IO interrupt fires while the device is in a shallow idle state, the
code may proceed to read registers while the hardware is suspended or has
lost context.

Should this use pm_runtime_get_if_active() to verify the device is actually
active before accessing hardware registers?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?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.