LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] serial: mvebu-uart: Fix local flags handling on termios update
@ 2018-04-22 12:33 Marc Zyngier
  2018-04-22 15:55 ` Russell King - ARM Linux
  0 siblings, 1 reply; 6+ messages in thread
From: Marc Zyngier @ 2018-04-22 12:33 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Allen Yan, Miquel Raynal, Gregory CLEMENT, Greg Kroah-Hartman

Commit 68a0db1d7da2 reworked the baud rate selection, but also added
a (not so) subtle change in the way the local flags (c_lflag in the
termios structure) are handled, forcing the new flags to always be the
same as the old ones.

The reason for that particular change is both obscure and undocumented.
It also completely breaks userspace. Something as trivial as getty is
unusable:

<example>
	Debian GNU/Linux 9 sy-borg ttyMV0

	sy-borg login: root
	root
	[timeout]

	Debian GNU/Linux 9 sy-borg ttyMV0
</example>

which is quite obvious in retrospect: getty cannot get in control of
the echo mode, is stuck in canonical mode, and times out without ever
seeing anything valid. It also begs the question of how this change was
ever tested.

The fix is pretty obvious: stop messing with c_lflag, and the world
will be a happier place.

Cc: stable@vger.kernel.org # 4.15+
Fixes: 68a0db1d7da2 ("serial: mvebu-uart: add function to change baudrate")
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/tty/serial/mvebu-uart.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
index 750e5645dc85..f503fab1e268 100644
--- a/drivers/tty/serial/mvebu-uart.c
+++ b/drivers/tty/serial/mvebu-uart.c
@@ -495,7 +495,6 @@ static void mvebu_uart_set_termios(struct uart_port *port,
 		termios->c_iflag |= old->c_iflag & ~(INPCK | IGNPAR);
 		termios->c_cflag &= CREAD | CBAUD;
 		termios->c_cflag |= old->c_cflag & ~(CREAD | CBAUD);
-		termios->c_lflag = old->c_lflag;
 	}
 
 	spin_unlock_irqrestore(&port->lock, flags);
-- 
2.14.2

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] serial: mvebu-uart: Fix local flags handling on termios update
  2018-04-22 12:33 [PATCH] serial: mvebu-uart: Fix local flags handling on termios update Marc Zyngier
@ 2018-04-22 15:55 ` Russell King - ARM Linux
  2018-04-22 17:07   ` Marc Zyngier
  0 siblings, 1 reply; 6+ messages in thread
From: Russell King - ARM Linux @ 2018-04-22 15:55 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Gregory CLEMENT, Allen Yan,
	Greg Kroah-Hartman, Miquel Raynal

On Sun, Apr 22, 2018 at 01:33:46PM +0100, Marc Zyngier wrote:
> Commit 68a0db1d7da2 reworked the baud rate selection, but also added
> a (not so) subtle change in the way the local flags (c_lflag in the
> termios structure) are handled, forcing the new flags to always be the
> same as the old ones.
> 
> The reason for that particular change is both obscure and undocumented.
> It also completely breaks userspace. Something as trivial as getty is
> unusable:
> 
> <example>
> 	Debian GNU/Linux 9 sy-borg ttyMV0
> 
> 	sy-borg login: root
> 	root
> 	[timeout]
> 
> 	Debian GNU/Linux 9 sy-borg ttyMV0
> </example>
> 
> which is quite obvious in retrospect: getty cannot get in control of
> the echo mode, is stuck in canonical mode, and times out without ever
> seeing anything valid. It also begs the question of how this change was
> ever tested.
> 
> The fix is pretty obvious: stop messing with c_lflag, and the world
> will be a happier place.

The c_iflag code also looks suspicious as well.  Apparently, the driver
only supports INPCK and IGNPAR, but things such as ISTRIP, INLCR, IGNCR,
ICRNL, IUCLC, IMAXBEL and IUTF8 are all software things done by the TTY
layer and have nothing to do with the driver.

The driver should only be preserving termios modes that are not supported
by the whole system, not solely the driver.

Interestingly, this aspect of the patch was not described in the commit
message, so how did this patch get in without proper review given that
it does more than what the commit log says?

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] serial: mvebu-uart: Fix local flags handling on termios update
  2018-04-22 15:55 ` Russell King - ARM Linux
@ 2018-04-22 17:07   ` Marc Zyngier
  2018-04-22 19:58     ` Russell King - ARM Linux
  0 siblings, 1 reply; 6+ messages in thread
From: Marc Zyngier @ 2018-04-22 17:07 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: linux-arm-kernel, linux-kernel, Gregory CLEMENT, Allen Yan,
	Greg Kroah-Hartman, Miquel Raynal

On Sun, 22 Apr 2018 16:55:16 +0100
Russell King - ARM Linux <linux@armlinux.org.uk> wrote:

> On Sun, Apr 22, 2018 at 01:33:46PM +0100, Marc Zyngier wrote:
> > Commit 68a0db1d7da2 reworked the baud rate selection, but also added
> > a (not so) subtle change in the way the local flags (c_lflag in the
> > termios structure) are handled, forcing the new flags to always be the
> > same as the old ones.
> > 
> > The reason for that particular change is both obscure and undocumented.
> > It also completely breaks userspace. Something as trivial as getty is
> > unusable:
> > 
> > <example>
> > 	Debian GNU/Linux 9 sy-borg ttyMV0
> > 
> > 	sy-borg login: root
> > 	root
> > 	[timeout]
> > 
> > 	Debian GNU/Linux 9 sy-borg ttyMV0
> > </example>
> > 
> > which is quite obvious in retrospect: getty cannot get in control of
> > the echo mode, is stuck in canonical mode, and times out without ever
> > seeing anything valid. It also begs the question of how this change was
> > ever tested.
> > 
> > The fix is pretty obvious: stop messing with c_lflag, and the world
> > will be a happier place.  
> 
> The c_iflag code also looks suspicious as well.  Apparently, the driver
> only supports INPCK and IGNPAR, but things such as ISTRIP, INLCR, IGNCR,
> ICRNL, IUCLC, IMAXBEL and IUTF8 are all software things done by the TTY
> layer and have nothing to do with the driver.

Indeed. I stuck with the most glaring issue (well, the one that
prevented me from using this particular box), but the whole termios
massaging is quite odd. Someone with a good understanding of the
intricacies of the TTY layer should definitely have a look at this.

	M.
-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] serial: mvebu-uart: Fix local flags handling on termios update
  2018-04-22 17:07   ` Marc Zyngier
@ 2018-04-22 19:58     ` Russell King - ARM Linux
  2018-04-23 15:04       ` Russell King - ARM Linux
  0 siblings, 1 reply; 6+ messages in thread
From: Russell King - ARM Linux @ 2018-04-22 19:58 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, linux-kernel, Gregory CLEMENT, Allen Yan,
	Greg Kroah-Hartman, Miquel Raynal

On Sun, Apr 22, 2018 at 06:07:28PM +0100, Marc Zyngier wrote:
> On Sun, 22 Apr 2018 16:55:16 +0100
> Russell King - ARM Linux <linux@armlinux.org.uk> wrote:
> 
> > On Sun, Apr 22, 2018 at 01:33:46PM +0100, Marc Zyngier wrote:
> > > Commit 68a0db1d7da2 reworked the baud rate selection, but also added
> > > a (not so) subtle change in the way the local flags (c_lflag in the
> > > termios structure) are handled, forcing the new flags to always be the
> > > same as the old ones.
> > > 
> > > The reason for that particular change is both obscure and undocumented.
> > > It also completely breaks userspace. Something as trivial as getty is
> > > unusable:
> > > 
> > > <example>
> > > 	Debian GNU/Linux 9 sy-borg ttyMV0
> > > 
> > > 	sy-borg login: root
> > > 	root
> > > 	[timeout]
> > > 
> > > 	Debian GNU/Linux 9 sy-borg ttyMV0
> > > </example>
> > > 
> > > which is quite obvious in retrospect: getty cannot get in control of
> > > the echo mode, is stuck in canonical mode, and times out without ever
> > > seeing anything valid. It also begs the question of how this change was
> > > ever tested.
> > > 
> > > The fix is pretty obvious: stop messing with c_lflag, and the world
> > > will be a happier place.  
> > 
> > The c_iflag code also looks suspicious as well.  Apparently, the driver
> > only supports INPCK and IGNPAR, but things such as ISTRIP, INLCR, IGNCR,
> > ICRNL, IUCLC, IMAXBEL and IUTF8 are all software things done by the TTY
> > layer and have nothing to do with the driver.
> 
> Indeed. I stuck with the most glaring issue (well, the one that
> prevented me from using this particular box), but the whole termios
> massaging is quite odd. Someone with a good understanding of the
> intricacies of the TTY layer should definitely have a look at this.

Right, remember, I'm the author of the serial core layer (I took over
from tytso back in the 2.x era.)

POSIX requirements are:

  The tcsetattr() function shall return successfully if it
  was able to perform any of the requested actions, even if
  some of the requested actions could not be performed. It
  shall set all the attributes that the implementation
  supports as requested and leave all the attributes not
  supported by the implementation unchanged.

In other words, if the system does not support two stop bits, asking
for CSTOPB to be set results in CSTOPB being ignored but all other
supported modes being updated.  This is what the code in that commit
is trying to implement, but it forgets that the TTY layer implements
a whole load of termios modes that are not specific to the serial
driver.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] serial: mvebu-uart: Fix local flags handling on termios update
  2018-04-22 19:58     ` Russell King - ARM Linux
@ 2018-04-23 15:04       ` Russell King - ARM Linux
  2018-04-23 17:39         ` Russell King - ARM Linux
  0 siblings, 1 reply; 6+ messages in thread
From: Russell King - ARM Linux @ 2018-04-23 15:04 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Greg Kroah-Hartman, linux-kernel, Allen Yan, Miquel Raynal,
	Gregory CLEMENT, linux-arm-kernel

On Sun, Apr 22, 2018 at 08:58:04PM +0100, Russell King - ARM Linux wrote:
> On Sun, Apr 22, 2018 at 06:07:28PM +0100, Marc Zyngier wrote:
> > On Sun, 22 Apr 2018 16:55:16 +0100
> > Russell King - ARM Linux <linux@armlinux.org.uk> wrote:
> > 
> > > On Sun, Apr 22, 2018 at 01:33:46PM +0100, Marc Zyngier wrote:
> > > > Commit 68a0db1d7da2 reworked the baud rate selection, but also added
> > > > a (not so) subtle change in the way the local flags (c_lflag in the
> > > > termios structure) are handled, forcing the new flags to always be the
> > > > same as the old ones.
> > > > 
> > > > The reason for that particular change is both obscure and undocumented.
> > > > It also completely breaks userspace. Something as trivial as getty is
> > > > unusable:
> > > > 
> > > > <example>
> > > > 	Debian GNU/Linux 9 sy-borg ttyMV0
> > > > 
> > > > 	sy-borg login: root
> > > > 	root
> > > > 	[timeout]
> > > > 
> > > > 	Debian GNU/Linux 9 sy-borg ttyMV0
> > > > </example>
> > > > 
> > > > which is quite obvious in retrospect: getty cannot get in control of
> > > > the echo mode, is stuck in canonical mode, and times out without ever
> > > > seeing anything valid. It also begs the question of how this change was
> > > > ever tested.
> > > > 
> > > > The fix is pretty obvious: stop messing with c_lflag, and the world
> > > > will be a happier place.  
> > > 
> > > The c_iflag code also looks suspicious as well.  Apparently, the driver
> > > only supports INPCK and IGNPAR, but things such as ISTRIP, INLCR, IGNCR,
> > > ICRNL, IUCLC, IMAXBEL and IUTF8 are all software things done by the TTY
> > > layer and have nothing to do with the driver.
> > 
> > Indeed. I stuck with the most glaring issue (well, the one that
> > prevented me from using this particular box), but the whole termios
> > massaging is quite odd. Someone with a good understanding of the
> > intricacies of the TTY layer should definitely have a look at this.
> 
> Right, remember, I'm the author of the serial core layer (I took over
> from tytso back in the 2.x era.)
> 
> POSIX requirements are:
> 
>   The tcsetattr() function shall return successfully if it
>   was able to perform any of the requested actions, even if
>   some of the requested actions could not be performed. It
>   shall set all the attributes that the implementation
>   supports as requested and leave all the attributes not
>   supported by the implementation unchanged.
> 
> In other words, if the system does not support two stop bits, asking
> for CSTOPB to be set results in CSTOPB being ignored but all other
> supported modes being updated.  This is what the code in that commit
> is trying to implement, but it forgets that the TTY layer implements
> a whole load of termios modes that are not specific to the serial
> driver.

I've just been talking to Jon Nettleton about this, and it seems that
he reported the exact same bug that you've found to Marvell a while
back, yet it seems that the bug was still propagated into mainline.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] serial: mvebu-uart: Fix local flags handling on termios update
  2018-04-23 15:04       ` Russell King - ARM Linux
@ 2018-04-23 17:39         ` Russell King - ARM Linux
  0 siblings, 0 replies; 6+ messages in thread
From: Russell King - ARM Linux @ 2018-04-23 17:39 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Greg Kroah-Hartman, linux-kernel, Allen Yan, Miquel Raynal,
	Gregory CLEMENT, linux-arm-kernel

On Mon, Apr 23, 2018 at 04:04:06PM +0100, Russell King - ARM Linux wrote:
> On Sun, Apr 22, 2018 at 08:58:04PM +0100, Russell King - ARM Linux wrote:
> > On Sun, Apr 22, 2018 at 06:07:28PM +0100, Marc Zyngier wrote:
> > > On Sun, 22 Apr 2018 16:55:16 +0100
> > > Russell King - ARM Linux <linux@armlinux.org.uk> wrote:
> > > 
> > > > On Sun, Apr 22, 2018 at 01:33:46PM +0100, Marc Zyngier wrote:
> > > > > Commit 68a0db1d7da2 reworked the baud rate selection, but also added
> > > > > a (not so) subtle change in the way the local flags (c_lflag in the
> > > > > termios structure) are handled, forcing the new flags to always be the
> > > > > same as the old ones.
> > > > > 
> > > > > The reason for that particular change is both obscure and undocumented.
> > > > > It also completely breaks userspace. Something as trivial as getty is
> > > > > unusable:
> > > > > 
> > > > > <example>
> > > > > 	Debian GNU/Linux 9 sy-borg ttyMV0
> > > > > 
> > > > > 	sy-borg login: root
> > > > > 	root
> > > > > 	[timeout]
> > > > > 
> > > > > 	Debian GNU/Linux 9 sy-borg ttyMV0
> > > > > </example>
> > > > > 
> > > > > which is quite obvious in retrospect: getty cannot get in control of
> > > > > the echo mode, is stuck in canonical mode, and times out without ever
> > > > > seeing anything valid. It also begs the question of how this change was
> > > > > ever tested.
> > > > > 
> > > > > The fix is pretty obvious: stop messing with c_lflag, and the world
> > > > > will be a happier place.  
> > > > 
> > > > The c_iflag code also looks suspicious as well.  Apparently, the driver
> > > > only supports INPCK and IGNPAR, but things such as ISTRIP, INLCR, IGNCR,
> > > > ICRNL, IUCLC, IMAXBEL and IUTF8 are all software things done by the TTY
> > > > layer and have nothing to do with the driver.
> > > 
> > > Indeed. I stuck with the most glaring issue (well, the one that
> > > prevented me from using this particular box), but the whole termios
> > > massaging is quite odd. Someone with a good understanding of the
> > > intricacies of the TTY layer should definitely have a look at this.
> > 
> > Right, remember, I'm the author of the serial core layer (I took over
> > from tytso back in the 2.x era.)
> > 
> > POSIX requirements are:
> > 
> >   The tcsetattr() function shall return successfully if it
> >   was able to perform any of the requested actions, even if
> >   some of the requested actions could not be performed. It
> >   shall set all the attributes that the implementation
> >   supports as requested and leave all the attributes not
> >   supported by the implementation unchanged.
> > 
> > In other words, if the system does not support two stop bits, asking
> > for CSTOPB to be set results in CSTOPB being ignored but all other
> > supported modes being updated.  This is what the code in that commit
> > is trying to implement, but it forgets that the TTY layer implements
> > a whole load of termios modes that are not specific to the serial
> > driver.
> 
> I've just been talking to Jon Nettleton about this, and it seems that
> he reported the exact same bug that you've found to Marvell a while
> back, yet it seems that the bug was still propagated into mainline.

Erm...

I wonder if anyone has _really_ looked at the commit?

+       baud = uart_get_baud_rate(port, termios, old, 0, 230400);
+       if (mvebu_uart_baud_rate_set(port, baud)) {
+               /* No clock available, baudrate cannot be changed */
+               if (old)
+                       baud = uart_get_baud_rate(port, old, NULL, 0, 230400);
+       } else {
+               tty_termios_encode_baud_rate(termios, baud, baud);
+               uart_update_timeout(port, termios->c_cflag, baud);
+       }

What is the effect if mvebu_uart_baud_rate_set() returns non-zero?  We
get the baud rate for the _old_ termios correctly, but then what do we
do with it?  "baud" is not used by this function after this point, so
what's the point of making that second call to uart_get_baud_rate()?

uart_get_baud_rate() already contains the logic to select the supported
baud rate from the new or old termios depending on the supplied
capabilities.

If there is no UART clock provided, then the above quite simply becomes
a complete no-op.

The whole thing can be simplified to:

	if (!IS_ERR(mvuart->clk)) {
		baud = uart_get_baud_rate(port, termios, old, 0, 230400);
		mvebu_uart_baud_rate_set(port, baud);
		tty_termios_encode_baud_rate(termios, baud, baud);
		uart_update_timeout(port, termios->c_cflag, baud);
	}

and the conditional in mvebu_uart_baud_rate_set() removed.

However, I suspect that the real intention of the code is actually
this:

	if (!IS_ERR(mvuart->clk)) {
		baud = uart_get_baud_rate(port, termios, old, 0, 230400);
		mvebu_uart_baud_rate_set(port, baud);
	} else {
		baud = uart_get_baud_rate(port, old, NULL, 0, 230400);
	}

	tty_termios_encode_baud_rate(termios, baud, baud);
	uart_update_timeout(port, termios->c_cflag, baud);

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-04-23 17:39 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-22 12:33 [PATCH] serial: mvebu-uart: Fix local flags handling on termios update Marc Zyngier
2018-04-22 15:55 ` Russell King - ARM Linux
2018-04-22 17:07   ` Marc Zyngier
2018-04-22 19:58     ` Russell King - ARM Linux
2018-04-23 15:04       ` Russell King - ARM Linux
2018-04-23 17:39         ` Russell King - ARM Linux

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).