serial: core: introduce guard(uart_port_lock_check_sysrq_irqsave)
uart_handle_break() and uart_prepare_sysrq_char() (in include/linux/serial_core.h) capture a SysRq character into port->sysrq_ch while the port lock is held and rely on the unlock helper -- uart_unlock_and_check_sysrq_irqrestore() -- to dispatch the captured character to handle_sysrq() on scope exit. The existing guard(uart_port_lock_irqsave) cannot be used by IRQ handlers that process RX, because its destructor calls plain uart_port_unlock_irqrestore() and silently drops port->sysrq_ch. Add a dedicated guard(uart_port_lock_check_sysrq_irqsave) variant whose destructor is the sysrq-aware unlock helper. The lock side is identical to uart_port_lock_irqsave -- only the unlock-time behaviour differs. Callers that may capture SysRq characters must use guard(uart_port_lock_check_sysrq_irqsave); the existing guard(uart_port_lock_irqsave) keeps its current plain-unlock semantics for the many callers that do not process RX. The new macro is placed after the CONFIG_MAGIC_SYSRQ_SERIAL block so both definitions of uart_unlock_and_check_sysrq_irqrestore() (sysrq enabled and disabled) are visible at expansion time. When CONFIG_MAGIC_SYSRQ_SERIAL=n the destructor degenerates to plain uart_port_unlock_irqrestore(), so there is no overhead. No functional change on its own; users are converted in the following patches. Cc: stable@vger.kernel.org Signed-off-by: Jacques Nilo <jnilo@free.fr> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Link: https://patch.msgid.link/3849af4bc55d5d2a424fa850844e94d641b2f8a6.1778675349.git.jnilo@free.fr Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>master
parent
a3bb136bff
commit
c3cce2e67b
|
|
@ -1274,6 +1274,18 @@ static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port
|
|||
}
|
||||
#endif /* CONFIG_MAGIC_SYSRQ_SERIAL */
|
||||
|
||||
/*
|
||||
* Variant of guard(uart_port_lock_irqsave) for IRQ handlers that may capture
|
||||
* a SysRq character via uart_prepare_sysrq_char(). The destructor uses the
|
||||
* sysrq-aware unlock helper so that a captured port->sysrq_ch is dispatched
|
||||
* to handle_sysrq() on scope exit. The plain guard variant silently drops
|
||||
* sysrq_ch and must not be used by callers that process RX.
|
||||
*/
|
||||
DEFINE_LOCK_GUARD_1(uart_port_lock_check_sysrq_irqsave, struct uart_port,
|
||||
uart_port_lock_irqsave(_T->lock, &_T->flags),
|
||||
uart_unlock_and_check_sysrq_irqrestore(_T->lock, _T->flags),
|
||||
unsigned long flags);
|
||||
|
||||
/*
|
||||
* We do the SysRQ and SAK checking like this...
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue