Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: core: Use port lock wrappers

When a serial port is used for kernel console output, then all
modifications to the UART registers which are done from other contexts,
e.g. getty, termios, are interference points for the kernel console.

So far this has been ignored and the printk output is based on the
principle of hope. The rework of the console infrastructure which aims to
support threaded and atomic consoles, requires to mark sections which
modify the UART registers as unsafe. This allows the atomic write function
to make informed decisions and eventually to restore operational state. It
also allows to prevent the regular UART code from modifying UART registers
while printk output is in progress.

All modifications of UART registers are guarded by the UART port lock,
which provides an obvious synchronization point with the console
infrastructure.

To avoid adding this functionality to all UART drivers, wrap the
spin_[un]lock*() invocations for uart_port::lock into helper functions
which just contain the spin_[un]lock*() invocations for now. In a
subsequent step these helpers will gain the console synchronization
mechanisms.

Converted with coccinelle. No functional change.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Link: https://lore.kernel.org/r/20230914183831.587273-58-john.ogness@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Thomas Gleixner and committed by
Greg Kroah-Hartman
559c7ff4 603445a6

+46 -46
+44 -44
drivers/tty/serial/serial_core.c
··· 79 79 ({ \ 80 80 struct uart_port *__uport = uart_port_ref(state); \ 81 81 if (__uport) \ 82 - spin_lock_irqsave(&__uport->lock, flags); \ 82 + uart_port_lock_irqsave(__uport, &flags); \ 83 83 __uport; \ 84 84 }) 85 85 ··· 87 87 ({ \ 88 88 struct uart_port *__uport = uport; \ 89 89 if (__uport) { \ 90 - spin_unlock_irqrestore(&__uport->lock, flags); \ 90 + uart_port_unlock_irqrestore(__uport, flags); \ 91 91 uart_port_deref(__uport); \ 92 92 } \ 93 93 }) ··· 179 179 unsigned long flags; 180 180 unsigned int old; 181 181 182 - spin_lock_irqsave(&port->lock, flags); 182 + uart_port_lock_irqsave(port, &flags); 183 183 old = port->mctrl; 184 184 port->mctrl = (old & ~clear) | set; 185 185 if (old != port->mctrl && !(port->rs485.flags & SER_RS485_ENABLED)) 186 186 port->ops->set_mctrl(port, port->mctrl); 187 - spin_unlock_irqrestore(&port->lock, flags); 187 + uart_port_unlock_irqrestore(port, flags); 188 188 } 189 189 190 190 #define uart_set_mctrl(port, set) uart_update_mctrl(port, set, 0) ··· 219 219 /* 220 220 * Set modem status enables based on termios cflag 221 221 */ 222 - spin_lock_irq(&uport->lock); 222 + uart_port_lock_irq(uport); 223 223 if (termios->c_cflag & CRTSCTS) 224 224 uport->status |= UPSTAT_CTS_ENABLE; 225 225 else ··· 240 240 else 241 241 __uart_start(state); 242 242 } 243 - spin_unlock_irq(&uport->lock); 243 + uart_port_unlock_irq(uport); 244 244 } 245 245 246 246 /* ··· 702 702 if (port->ops->send_xchar) 703 703 port->ops->send_xchar(port, ch); 704 704 else { 705 - spin_lock_irqsave(&port->lock, flags); 705 + uart_port_lock_irqsave(port, &flags); 706 706 port->x_char = ch; 707 707 if (ch) 708 708 port->ops->start_tx(port); 709 - spin_unlock_irqrestore(&port->lock, flags); 709 + uart_port_unlock_irqrestore(port, flags); 710 710 } 711 711 uart_port_deref(port); 712 712 } ··· 1085 1085 1086 1086 if (!tty_io_error(tty)) { 1087 1087 result = uport->mctrl; 1088 - spin_lock_irq(&uport->lock); 1088 + uart_port_lock_irq(uport); 1089 1089 result |= uport->ops->get_mctrl(uport); 1090 - spin_unlock_irq(&uport->lock); 1090 + uart_port_unlock_irq(uport); 1091 1091 } 1092 1092 out: 1093 1093 mutex_unlock(&port->mutex); ··· 1223 1223 uport = uart_port_ref(state); 1224 1224 if (!uport) 1225 1225 return -EIO; 1226 - spin_lock_irq(&uport->lock); 1226 + uart_port_lock_irq(uport); 1227 1227 memcpy(&cprev, &uport->icount, sizeof(struct uart_icount)); 1228 1228 uart_enable_ms(uport); 1229 - spin_unlock_irq(&uport->lock); 1229 + uart_port_unlock_irq(uport); 1230 1230 1231 1231 add_wait_queue(&port->delta_msr_wait, &wait); 1232 1232 for (;;) { 1233 - spin_lock_irq(&uport->lock); 1233 + uart_port_lock_irq(uport); 1234 1234 memcpy(&cnow, &uport->icount, sizeof(struct uart_icount)); 1235 - spin_unlock_irq(&uport->lock); 1235 + uart_port_unlock_irq(uport); 1236 1236 1237 1237 set_current_state(TASK_INTERRUPTIBLE); 1238 1238 ··· 1277 1277 uport = uart_port_ref(state); 1278 1278 if (!uport) 1279 1279 return -EIO; 1280 - spin_lock_irq(&uport->lock); 1280 + uart_port_lock_irq(uport); 1281 1281 memcpy(&cnow, &uport->icount, sizeof(struct uart_icount)); 1282 - spin_unlock_irq(&uport->lock); 1282 + uart_port_unlock_irq(uport); 1283 1283 uart_port_deref(uport); 1284 1284 1285 1285 icount->cts = cnow.cts; ··· 1422 1422 unsigned long flags; 1423 1423 struct serial_rs485 aux; 1424 1424 1425 - spin_lock_irqsave(&port->lock, flags); 1425 + uart_port_lock_irqsave(port, &flags); 1426 1426 aux = port->rs485; 1427 - spin_unlock_irqrestore(&port->lock, flags); 1427 + uart_port_unlock_irqrestore(port, flags); 1428 1428 1429 1429 if (copy_to_user(rs485, &aux, sizeof(aux))) 1430 1430 return -EFAULT; ··· 1451 1451 uart_sanitize_serial_rs485(port, &rs485); 1452 1452 uart_set_rs485_termination(port, &rs485); 1453 1453 1454 - spin_lock_irqsave(&port->lock, flags); 1454 + uart_port_lock_irqsave(port, &flags); 1455 1455 ret = port->rs485_config(port, &tty->termios, &rs485); 1456 1456 if (!ret) { 1457 1457 port->rs485 = rs485; ··· 1460 1460 if (!(rs485.flags & SER_RS485_ENABLED)) 1461 1461 port->ops->set_mctrl(port, port->mctrl); 1462 1462 } 1463 - spin_unlock_irqrestore(&port->lock, flags); 1463 + uart_port_unlock_irqrestore(port, flags); 1464 1464 if (ret) 1465 1465 return ret; 1466 1466 ··· 1479 1479 if (!port->iso7816_config) 1480 1480 return -ENOTTY; 1481 1481 1482 - spin_lock_irqsave(&port->lock, flags); 1482 + uart_port_lock_irqsave(port, &flags); 1483 1483 aux = port->iso7816; 1484 - spin_unlock_irqrestore(&port->lock, flags); 1484 + uart_port_unlock_irqrestore(port, flags); 1485 1485 1486 1486 if (copy_to_user(iso7816, &aux, sizeof(aux))) 1487 1487 return -EFAULT; ··· 1510 1510 if (iso7816.reserved[i]) 1511 1511 return -EINVAL; 1512 1512 1513 - spin_lock_irqsave(&port->lock, flags); 1513 + uart_port_lock_irqsave(port, &flags); 1514 1514 ret = port->iso7816_config(port, &iso7816); 1515 - spin_unlock_irqrestore(&port->lock, flags); 1515 + uart_port_unlock_irqrestore(port, flags); 1516 1516 if (ret) 1517 1517 return ret; 1518 1518 ··· 1729 1729 if (WARN(!uport, "detached port still initialized!\n")) 1730 1730 return; 1731 1731 1732 - spin_lock_irq(&uport->lock); 1732 + uart_port_lock_irq(uport); 1733 1733 uport->ops->stop_rx(uport); 1734 - spin_unlock_irq(&uport->lock); 1734 + uart_port_unlock_irq(uport); 1735 1735 1736 1736 uart_port_shutdown(port); 1737 1737 ··· 1745 1745 /* 1746 1746 * Free the transmit buffer. 1747 1747 */ 1748 - spin_lock_irq(&uport->lock); 1748 + uart_port_lock_irq(uport); 1749 1749 buf = state->xmit.buf; 1750 1750 state->xmit.buf = NULL; 1751 - spin_unlock_irq(&uport->lock); 1751 + uart_port_unlock_irq(uport); 1752 1752 1753 1753 free_page((unsigned long)buf); 1754 1754 ··· 1891 1891 */ 1892 1892 if (WARN_ON(!uport)) 1893 1893 return true; 1894 - spin_lock_irq(&uport->lock); 1894 + uart_port_lock_irq(uport); 1895 1895 uart_enable_ms(uport); 1896 1896 mctrl = uport->ops->get_mctrl(uport); 1897 - spin_unlock_irq(&uport->lock); 1897 + uart_port_unlock_irq(uport); 1898 1898 uart_port_deref(uport); 1899 1899 1900 1900 return mctrl & TIOCM_CAR; ··· 2011 2011 pm_state = state->pm_state; 2012 2012 if (pm_state != UART_PM_STATE_ON) 2013 2013 uart_change_pm(state, UART_PM_STATE_ON); 2014 - spin_lock_irq(&uport->lock); 2014 + uart_port_lock_irq(uport); 2015 2015 status = uport->ops->get_mctrl(uport); 2016 - spin_unlock_irq(&uport->lock); 2016 + uart_port_unlock_irq(uport); 2017 2017 if (pm_state != UART_PM_STATE_ON) 2018 2018 uart_change_pm(state, pm_state); 2019 2019 ··· 2352 2352 */ 2353 2353 if (!console_suspend_enabled && uart_console(uport)) { 2354 2354 if (uport->ops->start_rx) { 2355 - spin_lock_irq(&uport->lock); 2355 + uart_port_lock_irq(uport); 2356 2356 uport->ops->stop_rx(uport); 2357 - spin_unlock_irq(&uport->lock); 2357 + uart_port_unlock_irq(uport); 2358 2358 } 2359 2359 goto unlock; 2360 2360 } ··· 2369 2369 tty_port_set_suspended(port, true); 2370 2370 tty_port_set_initialized(port, false); 2371 2371 2372 - spin_lock_irq(&uport->lock); 2372 + uart_port_lock_irq(uport); 2373 2373 ops->stop_tx(uport); 2374 2374 if (!(uport->rs485.flags & SER_RS485_ENABLED)) 2375 2375 ops->set_mctrl(uport, 0); ··· 2377 2377 mctrl = uport->mctrl; 2378 2378 uport->mctrl = 0; 2379 2379 ops->stop_rx(uport); 2380 - spin_unlock_irq(&uport->lock); 2380 + uart_port_unlock_irq(uport); 2381 2381 2382 2382 /* 2383 2383 * Wait for the transmitter to empty. ··· 2449 2449 uart_change_pm(state, UART_PM_STATE_ON); 2450 2450 uport->ops->set_termios(uport, &termios, NULL); 2451 2451 if (!console_suspend_enabled && uport->ops->start_rx) { 2452 - spin_lock_irq(&uport->lock); 2452 + uart_port_lock_irq(uport); 2453 2453 uport->ops->start_rx(uport); 2454 - spin_unlock_irq(&uport->lock); 2454 + uart_port_unlock_irq(uport); 2455 2455 } 2456 2456 if (console_suspend_enabled) 2457 2457 console_start(uport->cons); ··· 2462 2462 int ret; 2463 2463 2464 2464 uart_change_pm(state, UART_PM_STATE_ON); 2465 - spin_lock_irq(&uport->lock); 2465 + uart_port_lock_irq(uport); 2466 2466 if (!(uport->rs485.flags & SER_RS485_ENABLED)) 2467 2467 ops->set_mctrl(uport, 0); 2468 - spin_unlock_irq(&uport->lock); 2468 + uart_port_unlock_irq(uport); 2469 2469 if (console_suspend_enabled || !uart_console(uport)) { 2470 2470 /* Protected by port mutex for now */ 2471 2471 struct tty_struct *tty = port->tty; ··· 2474 2474 if (ret == 0) { 2475 2475 if (tty) 2476 2476 uart_change_line_settings(tty, state, NULL); 2477 - spin_lock_irq(&uport->lock); 2477 + uart_port_lock_irq(uport); 2478 2478 if (!(uport->rs485.flags & SER_RS485_ENABLED)) 2479 2479 ops->set_mctrl(uport, uport->mctrl); 2480 2480 else 2481 2481 uart_rs485_config(uport); 2482 2482 ops->start_tx(uport); 2483 - spin_unlock_irq(&uport->lock); 2483 + uart_port_unlock_irq(uport); 2484 2484 tty_port_set_initialized(port, true); 2485 2485 } else { 2486 2486 /* ··· 2583 2583 * keep the DTR setting that is set in uart_set_options() 2584 2584 * We probably don't need a spinlock around this, but 2585 2585 */ 2586 - spin_lock_irqsave(&port->lock, flags); 2586 + uart_port_lock_irqsave(port, &flags); 2587 2587 port->mctrl &= TIOCM_DTR; 2588 2588 if (!(port->rs485.flags & SER_RS485_ENABLED)) 2589 2589 port->ops->set_mctrl(port, port->mctrl); 2590 2590 else 2591 2591 uart_rs485_config(port); 2592 - spin_unlock_irqrestore(&port->lock, flags); 2592 + uart_port_unlock_irqrestore(port, flags); 2593 2593 2594 2594 /* 2595 2595 * If this driver supports console, and it hasn't been
+2 -2
drivers/tty/serial/serial_port.c
··· 35 35 goto out; 36 36 37 37 /* Flush any pending TX for the port */ 38 - spin_lock_irqsave(&port->lock, flags); 38 + uart_port_lock_irqsave(port, &flags); 39 39 if (__serial_port_busy(port)) 40 40 port->ops->start_tx(port); 41 - spin_unlock_irqrestore(&port->lock, flags); 41 + uart_port_unlock_irqrestore(port, flags); 42 42 43 43 out: 44 44 pm_runtime_mark_last_busy(dev);