diff options
author | Peter Hurley <peter@hurleysoftware.com> | 2015-01-22 12:24:31 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-02-02 13:11:27 -0500 |
commit | e9cef8625e997a5ade9cddd2d501257dfee7cb62 (patch) | |
tree | b76b44f9d048028855a3233e02c1d03515b87676 | |
parent | 4516d50aabedbe5ae334155193e4d35c02390d9a (diff) |
serial: 8250: Prevent concurrent updates to shadow registers
The port shadow registers, ->fcr and ->mcr, must be protected from
concurrent updates. Relocate the shadow register updates in
serial8250_do_set_termios() to the port lock critical section.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/tty/serial/8250/8250_core.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 1449c56506b7..57d13b058a48 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -2549,6 +2549,15 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2549 | port->uartclk / 16); | 2549 | port->uartclk / 16); |
2550 | quot = serial8250_get_divisor(up, baud, &frac); | 2550 | quot = serial8250_get_divisor(up, baud, &frac); |
2551 | 2551 | ||
2552 | /* | ||
2553 | * Ok, we're now changing the port state. Do it with | ||
2554 | * interrupts disabled. | ||
2555 | */ | ||
2556 | serial8250_rpm_get(up); | ||
2557 | spin_lock_irqsave(&port->lock, flags); | ||
2558 | |||
2559 | up->lcr = cval; /* Save computed LCR */ | ||
2560 | |||
2552 | if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { | 2561 | if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { |
2553 | /* NOTE: If fifo_bug is not set, a user can set RX_trigger. */ | 2562 | /* NOTE: If fifo_bug is not set, a user can set RX_trigger. */ |
2554 | if ((baud < 2400 && !up->dma) || up->fifo_bug) { | 2563 | if ((baud < 2400 && !up->dma) || up->fifo_bug) { |
@@ -2572,15 +2581,6 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2572 | } | 2581 | } |
2573 | 2582 | ||
2574 | /* | 2583 | /* |
2575 | * Ok, we're now changing the port state. Do it with | ||
2576 | * interrupts disabled. | ||
2577 | */ | ||
2578 | serial8250_rpm_get(up); | ||
2579 | spin_lock_irqsave(&port->lock, flags); | ||
2580 | |||
2581 | up->lcr = cval; /* Save computed LCR */ | ||
2582 | |||
2583 | /* | ||
2584 | * Update the per-port timeout. | 2584 | * Update the per-port timeout. |
2585 | */ | 2585 | */ |
2586 | uart_update_timeout(port, termios->c_cflag, baud); | 2586 | uart_update_timeout(port, termios->c_cflag, baud); |