serial: core: Fix port count when uart_open() errors
A port count mismatch occurs if mutex_lock_interruptible() exits uart_open() and the port has already been opened. This may prematurely close a port on an open tty. Since uart_close() is _always_ called if uart_open() fails, the port count must be corrected if errors occur. Always increment the port count in uart_open(), regardless of errors; always decrement the port count in uart_close(). Note that tty_port_close_start() decrements the port count when uart_open() was successful. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
64dbee3105
commit
91b32f5413
|
@ -1338,8 +1338,16 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
|
|||
struct uart_port *uport;
|
||||
unsigned long flags;
|
||||
|
||||
if (!state)
|
||||
if (!state) {
|
||||
struct uart_driver *drv = tty->driver->driver_state;
|
||||
|
||||
state = drv->state + tty->index;
|
||||
port = &state->port;
|
||||
spin_lock_irq(&port->lock);
|
||||
--port->count;
|
||||
spin_unlock_irq(&port->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
uport = state->uart_port;
|
||||
port = &state->port;
|
||||
|
@ -1556,6 +1564,10 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
|
|||
|
||||
pr_debug("uart_open(%d) called\n", line);
|
||||
|
||||
spin_lock_irq(&port->lock);
|
||||
++port->count;
|
||||
spin_unlock_irq(&port->lock);
|
||||
|
||||
/*
|
||||
* We take the semaphore here to guarantee that we won't be re-entered
|
||||
* while allocating the state structure, or while we request any IRQs
|
||||
|
@ -1568,17 +1580,11 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
|
|||
goto end;
|
||||
}
|
||||
|
||||
port->count++;
|
||||
if (!state->uart_port || state->uart_port->flags & UPF_DEAD) {
|
||||
retval = -ENXIO;
|
||||
goto err_dec_count;
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Once we set tty->driver_data here, we are guaranteed that
|
||||
* uart_close() will decrement the driver module use count.
|
||||
* Any failures from here onwards should not touch the count.
|
||||
*/
|
||||
tty->driver_data = state;
|
||||
state->uart_port->state = state;
|
||||
state->port.low_latency =
|
||||
|
@ -1599,8 +1605,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
|
|||
|
||||
end:
|
||||
return retval;
|
||||
err_dec_count:
|
||||
port->count--;
|
||||
err_unlock:
|
||||
mutex_unlock(&port->mutex);
|
||||
goto end;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue