• John Ogness's avatar
    serial: 8250: lock port in startup() callbacks · b1207d86
    John Ogness authored
    uart_ops startup() callback is called without interrupts
    disabled and without port->lock locked, relatively late during the
    boot process (from the call path of console_on_rootfs()). If the
    device is a console, it was already previously registered and could
    be actively printing messages.
    
    The console printing function serial8250_console_write() modifies
    the interrupt register (UART_IER) under the port->lock with the
    pattern: read, clear, restore.
    
    Since some startup() callbacks are modifying UART_IER without the
    port->lock locked, it is possible that the value intended to be
    written by the startup() callback will get overwritten and be
    lost.
    
    CPU0                           CPU1
    serial8250_console_write       omap_8250_startup
    --------------------------     -----------------
    spin_lock(port->lock)
    oldval = read(UART_IER)
    uart_console_write()
                                   write(newval, UART_IER)
    write(oldval, UART_IER)
    spin_unlock(port->lock)
    
    Add port->lock synchronization to the 8250 startup() callbacks
    where they need to access UART_IER. This avoids racing with
    serial8250_console_write().
    Signed-off-by: default avatarJohn Ogness <john.ogness@linutronix.de>
    Link: https://lore.kernel.org/r/20230525093159.223817-2-john.ogness@linutronix.deSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    b1207d86
8250_port.c 89.6 KB