All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Hurley <peter@hurleysoftware.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org,
	Jiri Slaby <jslaby@suse.cz>,
	One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk>,
	Peter Hurley <peter@hurleysoftware.com>
Subject: [PATCH -next 03/10] serial: Fix locking for uart driver set_termios() method
Date: Thu, 16 Oct 2014 16:54:20 -0400	[thread overview]
Message-ID: <1413492867-20679-4-git-send-email-peter@hurleysoftware.com> (raw)
In-Reply-To: <1413492867-20679-1-git-send-email-peter@hurleysoftware.com>

The low-level uart driver may modify termios settings to override
settings that are not compatible with the uart, such as CRTSCTS.
Thus, callers of the low-level uart driver's set_termios() method must
hold termios_rwsem write lock to prevent concurrent access to termios,
in case such override occurs.

The termios_rwsem lock requirement does not extend to console setup
(ie., uart_set_options), as console setup cannot race with tty
operations. Nor does this lock requirement extend to functions which
cannot be concurrent with tty ioctls (ie., uart_port_startup() and
uart_resume_port()).

Further, always claim the port mutex to protect hardware
re-reprogramming in the set_termios() uart driver method. Note this
is unnecessary for console initialization in uart_set_options()
which cannot be concurrent with other uart operations.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
---
 Documentation/serial/driver      | 6 ++++--
 drivers/tty/serial/serial_core.c | 8 +++++++-
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/Documentation/serial/driver b/Documentation/serial/driver
index ba64e4b..c415b0e 100644
--- a/Documentation/serial/driver
+++ b/Documentation/serial/driver
@@ -59,7 +59,9 @@ The core driver uses the info->tmpbuf_sem lock to prevent multi-threaded
 access to the info->tmpbuf bouncebuffer used for port writes.
 
 The port_sem semaphore is used to protect against ports being added/
-removed or reconfigured at inappropriate times.
+removed or reconfigured at inappropriate times. Since v2.6.27, this
+semaphore has been the 'mutex' member of the tty_port struct, and
+commonly referred to as the port mutex (or port->mutex).
 
 
 uart_ops
@@ -248,7 +250,7 @@ hardware.
 	Other flags may be used (eg, xon/xoff characters) if your
 	hardware supports hardware "soft" flow control.
 
-	Locking: none.
+	Locking: caller holds port->mutex
 	Interrupts: caller dependent.
 	This call must not sleep
 
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 6203c6c..6ebe78c 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -436,7 +436,7 @@ uart_get_divisor(struct uart_port *port, unsigned int baud)
 
 EXPORT_SYMBOL(uart_get_divisor);
 
-/* FIXME: Consistent locking policy */
+/* Caller holds port mutex */
 static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
 					struct ktermios *old_termios)
 {
@@ -1172,11 +1172,15 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd,
 		break;
 
 	case TIOCSSERIAL:
+		down_write(&tty->termios_rwsem);
 		ret = uart_set_info_user(tty, state, uarg);
+		up_write(&tty->termios_rwsem);
 		break;
 
 	case TIOCSERCONFIG:
+		down_write(&tty->termios_rwsem);
 		ret = uart_do_autoconfig(tty, state);
+		up_write(&tty->termios_rwsem);
 		break;
 
 	case TIOCSERGWILD: /* obsolete */
@@ -1277,7 +1281,9 @@ static void uart_set_termios(struct tty_struct *tty,
 		return;
 	}
 
+	mutex_lock(&state->port.mutex);
 	uart_change_speed(tty, state, old_termios);
+	mutex_unlock(&state->port.mutex);
 	/* reload cflag from termios; port driver may have overriden flags */
 	cflag = tty->termios.c_cflag;
 
-- 
2.1.1

  parent reply	other threads:[~2014-10-16 20:54 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-16 20:54 [PATCH -next 00/10] serial core fixes Peter Hurley
2014-10-16 20:54 ` [PATCH -next 01/10] serial: Refactor uart_flush_buffer() from uart_close() Peter Hurley
2014-10-16 20:54 ` [PATCH -next 02/10] serial: core: Flush ldisc after dropping port mutex in uart_close() Peter Hurley
2014-10-16 20:54 ` Peter Hurley [this message]
2014-10-16 20:54 ` [PATCH -next 04/10] tty,serial: Unify UPF_* and ASYNC_* flag definitions Peter Hurley
2014-10-16 20:54 ` [PATCH -next 05/10] tty: Document defunct ASYNC_* bits in uapi header Peter Hurley
2014-10-17  8:46   ` Jiri Slaby
2014-10-17 12:44     ` Peter Hurley
2014-10-17 13:31       ` Jiri Slaby
2014-11-06  2:53         ` Greg Kroah-Hartman
2014-10-16 20:54 ` [PATCH -next 06/10] serial: core: Unwrap >80 char line in uart_close() Peter Hurley
2014-10-16 20:54 ` [PATCH -next 07/10] serial: core: Remove redundant timeout assignments Peter Hurley
2014-10-16 20:54 ` [PATCH -next 08/10] serial: core: Colocate crucial structure linkage Peter Hurley
2014-10-16 20:54 ` [PATCH -next 09/10] serial: core: Remove extra locking in uart_write() Peter Hurley
2014-10-16 20:54 ` [PATCH -next 10/10] serial: core: Fix port count when uart_open() errors Peter Hurley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1413492867-20679-4-git-send-email-peter@hurleysoftware.com \
    --to=peter@hurleysoftware.com \
    --cc=gnomes@lxorguk.ukuu.org.uk \
    --cc=gregkh@linuxfoundation.org \
    --cc=jslaby@suse.cz \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.