serial: cpm_uart: Avoid suspicious locking
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Thu, 3 Aug 2023 13:56:42 +0000 (15:56 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 Sep 2023 09:11:07 +0000 (11:11 +0200)
[ Upstream commit 36ef11d311f405e55ad8e848c19b212ff71ef536 ]

  CHECK   drivers/tty/serial/cpm_uart/cpm_uart_core.c
drivers/tty/serial/cpm_uart/cpm_uart_core.c:1271:39: warning: context imbalance in 'cpm_uart_console_write' - unexpected unlock

Allthough 'nolock' is not expected to change, sparse find the following
form suspicious:

if (unlikely(nolock)) {
local_irq_save(flags);
} else {
spin_lock_irqsave(&pinfo->port.lock, flags);
}

cpm_uart_early_write(pinfo, s, count, true);

if (unlikely(nolock)) {
local_irq_restore(flags);
} else {
spin_unlock_irqrestore(&pinfo->port.lock, flags);
}

Rewrite it a more obvious form:

if (unlikely(oops_in_progress)) {
local_irq_save(flags);
cpm_uart_early_write(pinfo, s, count, true);
local_irq_restore(flags);
} else {
spin_lock_irqsave(&pinfo->port.lock, flags);
cpm_uart_early_write(pinfo, s, count, true);
spin_unlock_irqrestore(&pinfo->port.lock, flags);
}

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Link: https://lore.kernel.org/r/f7da5cdc9287960185829cfef681a7d8614efa1f.1691068700.git.christophe.leroy@csgroup.eu
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/tty/serial/cpm_uart/cpm_uart_core.c

index b4369ed..bb25691 100644 (file)
@@ -1257,19 +1257,14 @@ static void cpm_uart_console_write(struct console *co, const char *s,
 {
        struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
        unsigned long flags;
-       int nolock = oops_in_progress;
 
-       if (unlikely(nolock)) {
+       if (unlikely(oops_in_progress)) {
                local_irq_save(flags);
-       } else {
-               spin_lock_irqsave(&pinfo->port.lock, flags);
-       }
-
-       cpm_uart_early_write(pinfo, s, count, true);
-
-       if (unlikely(nolock)) {
+               cpm_uart_early_write(pinfo, s, count, true);
                local_irq_restore(flags);
        } else {
+               spin_lock_irqsave(&pinfo->port.lock, flags);
+               cpm_uart_early_write(pinfo, s, count, true);
                spin_unlock_irqrestore(&pinfo->port.lock, flags);
        }
 }