Patch "serial: 8250: Fix race condition in RTS-after-send handling" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    serial: 8250: Fix race condition in RTS-after-send handling

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     serial-8250-fix-race-condition-in-rts-after-send-han.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 23b37f776f2ee455475bfecf59c95efddc5a20cc
Author: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
Date:   Tue Feb 15 17:02:36 2022 +0100

    serial: 8250: Fix race condition in RTS-after-send handling
    
    [ Upstream commit dedab69fd650ea74710b2e626e63fd35584ef773 ]
    
    Set em485->active_timer = NULL isn't always enough to take out the stop
    timer. While there is a check that it acts in the right state (i.e.
    waiting for RTS-after-send to pass after sending some chars) but the
    following might happen:
    
     - CPU1: some chars send, shifter becomes empty, stop tx timer armed
     - CPU0: more chars send before RTS-after-send expired
     - CPU0: shifter empty irq, port lock taken
     - CPU1: tx timer triggers, waits for port lock
     - CPU0: em485->active_timer = &em485->stop_tx_timer, hrtimer_start(),
       releases lock()
     - CPU1: get lock, see em485->active_timer == &em485->stop_tx_timer,
       tear down RTS too early
    
    This fix bases on research done by Steffen Trumtrar.
    
    Fixes: b86f86e8e7c5 ("serial: 8250: fix potential deadlock in rs485-mode")
    Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20220215160236.344236-1-u.kleine-koenig@xxxxxxxxxxxxxx
    Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index b470bc747b99..868ccb3e16cf 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1623,6 +1623,18 @@ static inline void start_tx_rs485(struct uart_port *port)
 	struct uart_8250_port *up = up_to_u8250p(port);
 	struct uart_8250_em485 *em485 = up->em485;
 
+	/*
+	 * While serial8250_em485_handle_stop_tx() is a noop if
+	 * em485->active_timer != &em485->stop_tx_timer, it might happen that
+	 * the timer is still armed and triggers only after the current bunch of
+	 * chars is send and em485->active_timer == &em485->stop_tx_timer again.
+	 * So cancel the timer. There is still a theoretical race condition if
+	 * the timer is already running and only comes around to check for
+	 * em485->active_timer when &em485->stop_tx_timer is armed again.
+	 */
+	if (em485->active_timer == &em485->stop_tx_timer)
+		hrtimer_try_to_cancel(&em485->stop_tx_timer);
+
 	em485->active_timer = NULL;
 
 	if (em485->tx_stopped) {



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux