2010-11-12 21:34:23

by Greg KH

[permalink] [raw]
Subject: [GIT PATCH] TTY/serial fixes for .37-rc1

Here are a number of tty and serial fixes for your .37-rc1 tree.

Full details are below, but there's just a range of bug fixes all over
the place, some of them having lived in the tree for quite some time,
and it's nice to get them finally resolved.

Please pull from:
master.kernel.org:/pub/scm/linux/kernel/git/gregkh/tty-2.6.git/ tty-linus

Patches will be sent to the linux-kernel mailing list, if anyone wants
to see them.

thanks,

greg k-h

------------

MAINTAINERS | 4 +-
drivers/char/amiserial.c | 1 -
drivers/char/nozomi.c | 1 -
drivers/char/pcmcia/synclink_cs.c | 1 +
drivers/serial/8250.c | 5 +++-
drivers/serial/8250_pci.c | 5 ++++
drivers/serial/bfin_5xx.c | 31 ++++++++++++++++-------
drivers/tty/n_gsm.c | 5 ++-
drivers/tty/tty_buffer.c | 14 +++++++++-
drivers/tty/tty_ldisc.c | 49 +++++++++++++++++++++++++++++++-----
drivers/tty/vt/vc_screen.c | 6 ++--
include/linux/tty.h | 2 +-
12 files changed, 94 insertions(+), 30 deletions(-)

---------------

Alan Cox (2):
tty: Fix formatting in tty.h
nozomi: Fix warning from the previous TIOCGCOUNT changes

Andres Salomon (1):
tty: fix warning in synclink driver

Geert Uytterhoeven (1):
amiserial: Remove unused variable icount

Greg Kroah-Hartman (1):
tty: the development tree is now done in git

Jiri Olsa (1):
tty: prevent DOS in the flush_to_ldisc

Jiri Slaby (1):
TTY: restore tty_ldisc_wait_idle

Joe Perches (1):
drivers/serial/bfin_5xx.c: Fix line continuation defects

Ken Mills (2):
n_gsm: Copy n2 over when configuring via ioctl interface
n_gsm: Fix length handling

Lawrence Rust (1):
8250: Fix tcsetattr to avoid ioctl(TIOCMIWAIT) hang

Maciej Szmigiero (1):
SERIAL: blacklist si3052 chip

Mikulas Patocka (1):
8250: add support for Kouwell KW-L221N-2

Nicolas Pitre (1):
vcs: make proper usage of the poll flags

Philippe R?tornaz (1):
tty_ldisc: Fix BUG() on hangup

Sonic Zhang (4):
serial: bfin_5xx: always include DMA headers
serial: bfin_5xx: remove redundant SSYNC to improve TX speed
serial: bfin_5xx: disable CON_PRINTBUFFER for consoles
serial: bfin_5xx: grab port lock before making port termios changes


2010-11-12 21:41:21

by Greg KH

[permalink] [raw]
Subject: [PATCH 05/19] 8250: add support for Kouwell KW-L221N-2

From: Mikulas Patocka <[email protected]>

Add support for Kouwell KW-L221N-2 card.

Signed-off-by: Mikulas Patocka <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/serial/8250_pci.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 53be4d3..2ada93e 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -2863,6 +2863,9 @@ static struct pci_device_id serial_pci_tbl[] = {
PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL,
0, 0,
pbn_b0_4_1152000 },
+ { PCI_VENDOR_ID_OXSEMI, 0x9505,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b0_bt_2_921600 },

/*
* The below card is a little controversial since it is the
--
1.7.1

2010-11-12 21:41:32

by Greg KH

[permalink] [raw]
Subject: [PATCH 18/19] n_gsm: Copy n2 over when configuring via ioctl interface

From: Ken Mills <[email protected]>

The n2 field is settable but didn't get propogated

Signed-off-by: Ken Mills <[email protected]>
Signed-off-by: Alan Cox <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/tty/n_gsm.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 04ef3ef..7f79044 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -2375,6 +2375,7 @@ static int gsmld_config(struct tty_struct *tty, struct gsm_mux *gsm,
gsm->mru = c->mru;
gsm->encoding = c->encapsulation;
gsm->adaption = c->adaption;
+ gsm->n2 = c->n2;

if (c->i == 1)
gsm->ftype = UIH;
--
1.7.1

2010-11-12 21:41:23

by Greg KH

[permalink] [raw]
Subject: [PATCH 14/19] serial: bfin_5xx: always include DMA headers

From: Sonic Zhang <[email protected]>

On Blackfin systems, peripherals that have optional DMA support always
route their interrupts through the corresponding DMA channel -- even
when DMA is not being used. So in PIO mode, we still need to request
the DMA channel (so interrupts are delivered) which means we need to
always include the DMA header for the DMA defines/functions.

Signed-off-by: Sonic Zhang <[email protected]>
Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/serial/bfin_5xx.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 351cc03..c8ca3b4 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -23,6 +23,7 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
+#include <linux/dma-mapping.h>

#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
@@ -33,12 +34,10 @@
#include <asm/gpio.h>
#include <mach/bfin_serial_5xx.h>

-#ifdef CONFIG_SERIAL_BFIN_DMA
-#include <linux/dma-mapping.h>
+#include <asm/dma.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/cacheflush.h>
-#endif

#ifdef CONFIG_SERIAL_BFIN_MODULE
# undef CONFIG_EARLY_PRINTK
@@ -688,6 +687,13 @@ static int bfin_serial_startup(struct uart_port *port)

# ifdef CONFIG_BF54x
{
+ /*
+ * UART2 and UART3 on BF548 share interrupt PINs and DMA
+ * controllers with SPORT2 and SPORT3. UART rx and tx
+ * interrupts are generated in PIO mode only when configure
+ * their peripheral mapping registers properly, which means
+ * request corresponding DMA channels in PIO mode as well.
+ */
unsigned uart_dma_ch_rx, uart_dma_ch_tx;

switch (uart->port.irq) {
--
1.7.1

2010-11-12 21:41:26

by Greg KH

[permalink] [raw]
Subject: [PATCH 15/19] serial: bfin_5xx: remove redundant SSYNC to improve TX speed

From: Sonic Zhang <[email protected]>

We don't need to force a SSYNC here as the LSR register will already
be updated by the time we get back to reading it. This speeds up TX
throughput and lowers general system overhead (since SSYNC is system
wide, not peripheral-specific).

Signed-off-by: Sonic Zhang <[email protected]>
Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/serial/bfin_5xx.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index c8ca3b4..a454e42 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -359,7 +359,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
UART_PUT_CHAR(uart, xmit->buf[xmit->tail]);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
uart->port.icount.tx++;
- SSYNC();
}

if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
--
1.7.1

2010-11-12 21:41:25

by Greg KH

[permalink] [raw]
Subject: [PATCH 16/19] serial: bfin_5xx: disable CON_PRINTBUFFER for consoles

From: Sonic Zhang <[email protected]>

If we are using early serial, don't let the normal console rewind
the log buffer, since that causes things to be printed multiple times.

Signed-off-by: Sonic Zhang <[email protected]>
Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/serial/bfin_5xx.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index a454e42..9655321 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -1324,6 +1324,14 @@ struct console __init *bfin_earlyserial_init(unsigned int port,
struct bfin_serial_port *uart;
struct ktermios t;

+#ifdef CONFIG_SERIAL_BFIN_CONSOLE
+ /*
+ * If we are using early serial, don't let the normal console rewind
+ * log buffer, since that causes things to be printed multiple times
+ */
+ bfin_serial_console.flags &= ~CON_PRINTBUFFER;
+#endif
+
if (port == -1 || port >= nr_active_ports)
port = 0;
bfin_serial_init_ports();
--
1.7.1

2010-11-12 21:41:29

by Greg KH

[permalink] [raw]
Subject: [PATCH 19/19] n_gsm: Fix length handling

From: Ken Mills <[email protected]>

If the mux is configured with a large mru/mtu the existing code gets the
byte ordering wrong for the header.

Signed-off-by: Ken Mills <[email protected]>
Signed-off-by: Alan Cox <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/tty/n_gsm.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 7f79044..81b4658 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -716,8 +716,8 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
if (msg->len < 128)
*--dp = (msg->len << 1) | EA;
else {
- *--dp = (msg->len >> 6) | EA;
- *--dp = (msg->len & 127) << 1;
+ *--dp = ((msg->len & 127) << 1) | EA;
+ *--dp = (msg->len >> 6) & 0xfe;
}
}

--
1.7.1

2010-11-12 21:41:16

by Greg KH

[permalink] [raw]
Subject: [PATCH 02/19] tty: Fix formatting in tty.h

From: Alan Cox <[email protected]>

Someone added a new ldisc number and messed up the tabbing. Fix it before
anyone else copies it.

Signed-off-by: Alan Cox <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/tty.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/linux/tty.h b/include/linux/tty.h
index 2a75474..c7ea9bc 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -50,7 +50,7 @@
#define N_V253 19 /* Codec control over voice modem */
#define N_CAIF 20 /* CAIF protocol for talking to modems */
#define N_GSM0710 21 /* GSM 0710 Mux */
-#define N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */
+#define N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */

/*
* This character is the same as _POSIX_VDISABLE: it cannot be used as
--
1.7.1

2010-11-12 21:41:19

by Greg KH

[permalink] [raw]
Subject: [PATCH 04/19] nozomi: Fix warning from the previous TIOCGCOUNT changes

From: Alan Cox <[email protected]>

Just remove a now unused variable

Signed-off-by: Alan Cox <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/nozomi.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c
index dd3f9b1..294d03e 100644
--- a/drivers/char/nozomi.c
+++ b/drivers/char/nozomi.c
@@ -1828,7 +1828,6 @@ static int ntty_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct port *port = tty->driver_data;
- void __user *argp = (void __user *)arg;
int rval = -ENOIOCTLCMD;

DBG1("******** IOCTL, cmd: %d", cmd);
--
1.7.1

2010-11-12 21:42:36

by Greg KH

[permalink] [raw]
Subject: [PATCH 17/19] serial: bfin_5xx: grab port lock before making port termios changes

From: Sonic Zhang <[email protected]>

The port lock exists to protect these resources, so we need to grab it
before making changes.

Signed-off-by: Sonic Zhang <[email protected]>
Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/serial/bfin_5xx.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 9655321..19cac9f 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -849,6 +849,8 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
if (termios->c_cflag & CMSPAR)
lcr |= STP;

+ spin_lock_irqsave(&uart->port.lock, flags);
+
port->read_status_mask = OE;
if (termios->c_iflag & INPCK)
port->read_status_mask |= (FE | PE);
@@ -878,8 +880,6 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
if (termios->c_line != N_IRDA)
quot -= ANOMALY_05000230;

- spin_lock_irqsave(&uart->port.lock, flags);
-
UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);

/* Disable UART */
--
1.7.1

2010-11-12 21:41:14

by Greg KH

[permalink] [raw]
Subject: [PATCH 01/19] tty: the development tree is now done in git

So properly mark it as such in the MAINTAINERS file.

Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
MAINTAINERS | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0094224..4c43733 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -161,7 +161,7 @@ M: Greg Kroah-Hartman <[email protected]>
L: [email protected]
W: http://serial.sourceforge.net
S: Maintained
-T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
F: drivers/serial/8250*
F: include/linux/serial_8250.h

@@ -5910,7 +5910,7 @@ S: Maintained
TTY LAYER
M: Greg Kroah-Hartman <[email protected]>
S: Maintained
-T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
F: drivers/char/tty_*
F: drivers/serial/serial_core.c
F: include/linux/serial_core.h
--
1.7.1

2010-11-12 21:42:56

by Greg KH

[permalink] [raw]
Subject: [PATCH 13/19] vcs: make proper usage of the poll flags

From: Nicolas Pitre <[email protected]>

Kay Sievers pointed out that usage of POLLIN is well defined by POSIX,
and the current usage here doesn't follow that definition. So let's
duplicate the same semantics as implemented by sysfs_poll() instead.

Signed-off-by: Nicolas Pitre <[email protected]>
Acked-by: Kay Sievers <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/tty/vt/vc_screen.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
index 273ab44..eab3a1f 100644
--- a/drivers/tty/vt/vc_screen.c
+++ b/drivers/tty/vt/vc_screen.c
@@ -553,12 +553,12 @@ static unsigned int
vcs_poll(struct file *file, poll_table *wait)
{
struct vcs_poll_data *poll = vcs_poll_data_get(file);
- int ret = 0;
+ int ret = DEFAULT_POLLMASK|POLLERR|POLLPRI;

if (poll) {
poll_wait(file, &poll->waitq, wait);
- if (!poll->seen_last_update)
- ret = POLLIN | POLLRDNORM;
+ if (poll->seen_last_update)
+ ret = DEFAULT_POLLMASK;
}
return ret;
}
--
1.7.1

2010-11-12 21:42:59

by Greg KH

[permalink] [raw]
Subject: [PATCH 12/19] amiserial: Remove unused variable icount

From: Geert Uytterhoeven <[email protected]>

drivers/char/amiserial.c: In function ?rs_ioctl?:
drivers/char/amiserial.c:1302: warning: unused variable ?icount?

commit 0587102cf9f427c185bfdeb2cef41e13ee0264b1 ("tty: icount changeover for
other main devices") removed the users, but not the actual variable.

Signed-off-by: Geert Uytterhoeven <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/amiserial.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index b0a7046..c0bd6f4 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -1299,7 +1299,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
{
struct async_struct * info = tty->driver_data;
struct async_icount cprev, cnow; /* kernel counter temps */
- struct serial_icounter_struct icount;
void __user *argp = (void __user *)arg;
unsigned long flags;

--
1.7.1

2010-11-12 21:43:04

by Greg KH

[permalink] [raw]
Subject: [PATCH 11/19] 8250: Fix tcsetattr to avoid ioctl(TIOCMIWAIT) hang

From: Lawrence Rust <[email protected]>

Calling tcsetattr prevents any thread(s) currently suspended in ioctl
TIOCMIWAIT for the same device from ever resuming.

If a thread is suspended inside a call to ioctl TIOCMIWAIT, waiting for
a modem status change, then the 8250 driver enables modem status
interrupts (MSI). The device interrupt service routine resumes the
suspended thread(s) on the next MSI.

If while the thread(s) are suspended, another thread calls tcsetattr
then the 8250 driver disables MSI (unless CTS/RTS handshaking is
enabled) thus preventing the suspended thread(s) from ever being
resumed.

This patch only disables MSI in tcsetattr handling if there are no
suspended threads.

Program to demonstrate bug & fix:

/* gcc miwait.c -o miwait -l pthread */
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <linux/serial.h>

static void* monitor( void* pv);
static int s_fd;

int main( void)
{
const char kszDev[] = "/dev/ttyS0";
pthread_t t;
struct termios tio;

s_fd = open( kszDev, O_RDWR | O_NONBLOCK);
if ( s_fd < 0)
return fprintf( stderr, "Error(%d) opening %s: %s\n", errno, kszDev, strerror( errno)), 1;

pthread_create( &t, NULL, &monitor, NULL);

/* Modem status changes seen here */
puts( "Main: awaiting status changes");
sleep( 5);

tcgetattr( s_fd, &tio);
tio.c_cflag ^= CSTOPB;

/* But not after here */
puts( "Main: tcsetattr called");
tcsetattr( s_fd, TCSANOW, &tio);

for (;;)
sleep( 1);
}

static void* monitor( void* pv)
{
(void)pv;
for(;;)
{
unsigned uModem;
struct serial_icounter_struct cnt;

if ( ioctl( s_fd, TIOCMGET, &uModem) < 0)
fprintf( stderr, "Error(%d) in TIOCMGET: %s\n", errno, strerror( errno));
printf( "Modem status:%s%s%s%s%s%s\n",
(uModem & TIOCM_RTS) ? " RTS" : "",
(uModem & TIOCM_DTR) ? " DTR" : "",
(uModem & TIOCM_CTS) ? " CTS" : "",
(uModem & TIOCM_DSR) ? " DSR" : "",
(uModem & TIOCM_CD) ? " CD" : "",
(uModem & TIOCM_RI) ? " RI" : ""
);

if ( ioctl( s_fd, TIOCGICOUNT, &cnt) < 0)
fprintf( stderr, "Error(%d) in TIOCGICOUNT: %s\n", errno, strerror( errno));
printf( "Irqs: CTS:%d DSR:%d RNG:%d DCD:%d Rx:%d Tx:%d Frame:%d Orun:%d Par:%d Brk:%d Oflow:%d\n",
cnt.cts, cnt.dsr, cnt.rng, cnt.dcd,
cnt.rx, cnt.tx, cnt.frame, cnt.overrun, cnt.parity,
cnt.brk, cnt.buf_overrun
);

fputs( "Waiting...", stdout), fflush( stdout);
if ( 0 > ioctl( s_fd, TIOCMIWAIT, (unsigned long)(TIOCM_CAR | TIOCM_RNG | TIOCM_DSR | TIOCM_CTS)))
fprintf( stderr, "\nError(%d) in TIOCMIWAIT: %s\n", errno, strerror( errno));
fputs( "\n", stdout);
}
return NULL;
}

Signed-off by Lawrence Rust <[email protected]>

Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/serial/8250.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 4d8e14b..dd5e1ac 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2343,8 +2343,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,

/*
* CTS flow control flag and modem status interrupts
+ * Only disable MSI if no threads are waiting in
+ * serial_core::uart_wait_modem_status
*/
- up->ier &= ~UART_IER_MSI;
+ if (!waitqueue_active(&up->port.state->port.delta_msr_wait))
+ up->ier &= ~UART_IER_MSI;
if (!(up->bugs & UART_BUG_NOMSR) &&
UART_ENABLE_MS(&up->port, termios->c_cflag))
up->ier |= UART_IER_MSI;
--
1.7.1

2010-11-12 21:43:36

by Greg KH

[permalink] [raw]
Subject: [PATCH 10/19] tty_ldisc: Fix BUG() on hangup

From: Philippe Rétornaz <[email protected]>

A kernel BUG when bluetooth rfcomm connection drop while the associated
serial port is open is sometime triggered.

It seems that the line discipline can disappear between the
tty_ldisc_put and tty_ldisc_get. This patch fall back to the N_TTY line
discipline if the previous discipline is not available anymore.

Signed-off-by: Philippe Retornaz <[email protected]>
Acked-by: Alan Cox <[email protected]>
Cc: stable <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/tty/tty_ldisc.c | 20 +++++++++++++-------
1 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 5bbf33a..d8e96b0 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -743,9 +743,12 @@ static void tty_reset_termios(struct tty_struct *tty)
* state closed
*/

-static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
+static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
{
- struct tty_ldisc *ld;
+ struct tty_ldisc *ld = tty_ldisc_get(ldisc);
+
+ if (IS_ERR(ld))
+ return -1;

tty_ldisc_close(tty, tty->ldisc);
tty_ldisc_put(tty->ldisc);
@@ -753,10 +756,10 @@ static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
/*
* Switch the line discipline back
*/
- ld = tty_ldisc_get(ldisc);
- BUG_ON(IS_ERR(ld));
tty_ldisc_assign(tty, ld);
tty_set_termios_ldisc(tty, ldisc);
+
+ return 0;
}

/**
@@ -831,13 +834,16 @@ void tty_ldisc_hangup(struct tty_struct *tty)
a FIXME */
if (tty->ldisc) { /* Not yet closed */
if (reset == 0) {
- tty_ldisc_reinit(tty, tty->termios->c_line);
- err = tty_ldisc_open(tty, tty->ldisc);
+
+ if (!tty_ldisc_reinit(tty, tty->termios->c_line))
+ err = tty_ldisc_open(tty, tty->ldisc);
+ else
+ err = 1;
}
/* If the re-open fails or we reset then go to N_TTY. The
N_TTY open cannot fail */
if (reset || err) {
- tty_ldisc_reinit(tty, N_TTY);
+ BUG_ON(tty_ldisc_reinit(tty, N_TTY));
WARN_ON(tty_ldisc_open(tty, tty->ldisc));
}
tty_ldisc_enable(tty);
--
1.7.1

2010-11-12 21:43:49

by Greg KH

[permalink] [raw]
Subject: [PATCH 08/19] SERIAL: blacklist si3052 chip

From: Maciej Szmigiero <[email protected]>

[SERIAL]blacklist si3052 chip

Si3052-based softmodems aren't serial ports so don't bind serial driver to them.
Allows proper driver to bind to them.

Signed-off-by: Maciej Szmigiero <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/serial/8250_pci.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 2ada93e..842e3b2 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -2285,6 +2285,8 @@ static struct pciserial_board pci_boards[] __devinitdata = {

static const struct pci_device_id softmodem_blacklist[] = {
{ PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */
+ { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */
+ { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */
};

/*
--
1.7.1

2010-11-12 21:43:53

by Greg KH

[permalink] [raw]
Subject: [PATCH 07/19] drivers/serial/bfin_5xx.c: Fix line continuation defects

From: Joe Perches <[email protected]>

Signed-off-by: Joe Perches <[email protected]>
Acked-by: Sonic Zhang <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/serial/bfin_5xx.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index a9eff2b..351cc03 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -734,8 +734,7 @@ static int bfin_serial_startup(struct uart_port *port)
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
IRQF_DISABLED, "BFIN_UART_CTS", uart)) {
uart->cts_pin = -1;
- pr_info("Unable to attach BlackFin UART CTS interrupt.\
- So, disable it.\n");
+ pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n");
}
}
if (uart->rts_pin >= 0) {
@@ -747,8 +746,7 @@ static int bfin_serial_startup(struct uart_port *port)
if (request_irq(uart->status_irq,
bfin_serial_mctrl_cts_int,
IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) {
- pr_info("Unable to attach BlackFin UART Modem \
- Status interrupt.\n");
+ pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n");
}

/* CTS RTS PINs are negative assertive. */
--
1.7.1

2010-11-12 21:44:24

by Greg KH

[permalink] [raw]
Subject: [PATCH 03/19] tty: fix warning in synclink driver

From: Andres Salomon <[email protected]>

During builds I see the following warning -

CC [M] drivers/char/pcmcia/synclink_cs.o
drivers/char/pcmcia/synclink_cs.c:2194: warning: ‘mgslpc_get_icount’ defined but not used

The function is a callback meant to be assigned to get_icount (added during 0587102cf).
Fix accordingly.

Signed-off-by: Andres Salomon <[email protected]>
Acked-by: Alan Cox <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/char/pcmcia/synclink_cs.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index bfc10f8..eaa4199 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -2796,6 +2796,7 @@ static const struct tty_operations mgslpc_ops = {
.hangup = mgslpc_hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .get_icount = mgslpc_get_icount,
.proc_fops = &mgslpc_proc_fops,
};

--
1.7.1

2010-11-12 21:43:55

by Greg KH

[permalink] [raw]
Subject: [PATCH 06/19] tty: prevent DOS in the flush_to_ldisc

From: Jiri Olsa <[email protected]>

There's a small window inside the flush_to_ldisc function,
where the tty is unlocked and calling ldisc's receive_buf
function. If in this window new buffer is added to the tty,
the processing might never leave the flush_to_ldisc function.

This scenario will hog the cpu, causing other tty processing
starving, and making it impossible to interface the computer
via tty.

I was able to exploit this via pty interface by sending only
control characters to the master input, causing the flush_to_ldisc
to be scheduled, but never actually generate any output.

To reproduce, please run multiple instances of following code.

- SNIP
#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
int i, slave, master = getpt();
char buf[8192];

sprintf(buf, "%s", ptsname(master));
grantpt(master);
unlockpt(master);

slave = open(buf, O_RDWR);
if (slave < 0) {
perror("open slave failed");
return 1;
}

for(i = 0; i < sizeof(buf); i++)
buf[i] = rand() % 32;

while(1) {
write(master, buf, sizeof(buf));
}

return 0;
}
- SNIP

The attached patch (based on -next tree) fixes this by checking on the
tty buffer tail. Once it's reached, the current work is rescheduled
and another could run.

Signed-off-by: Jiri Olsa <[email protected]>
Cc: stable <[email protected]>
Acked-by: Alan Cox <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/tty/tty_buffer.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index cc1e985..d8210ca 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -413,7 +413,8 @@ static void flush_to_ldisc(struct work_struct *work)
spin_lock_irqsave(&tty->buf.lock, flags);

if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {
- struct tty_buffer *head;
+ struct tty_buffer *head, *tail = tty->buf.tail;
+ int seen_tail = 0;
while ((head = tty->buf.head) != NULL) {
int count;
char *char_buf;
@@ -423,6 +424,15 @@ static void flush_to_ldisc(struct work_struct *work)
if (!count) {
if (head->next == NULL)
break;
+ /*
+ There's a possibility tty might get new buffer
+ added during the unlock window below. We could
+ end up spinning in here forever hogging the CPU
+ completely. To avoid this let's have a rest each
+ time we processed the tail buffer.
+ */
+ if (tail == head)
+ seen_tail = 1;
tty->buf.head = head->next;
tty_buffer_free(tty, head);
continue;
@@ -432,7 +442,7 @@ static void flush_to_ldisc(struct work_struct *work)
line discipline as we want to empty the queue */
if (test_bit(TTY_FLUSHPENDING, &tty->flags))
break;
- if (!tty->receive_room) {
+ if (!tty->receive_room || seen_tail) {
schedule_delayed_work(&tty->buf.work, 1);
break;
}
--
1.7.1

2010-11-13 04:18:33

by Alexey Zaytsev

[permalink] [raw]
Subject: Re: [PATCH 11/19] 8250: Fix tcsetattr to avoid ioctl(TIOCMIWAIT) hang

Hi.

This one kills the serial console for me. Luckily, in qemu:

(gdb) bt
#0 __const_udelay (xloops=4295000) at arch/x86/lib/delay.c:117
#1 0xc137ab7c in panic (fmt=0xc147f8e1 "Attempted to kill the idle task!")
at kernel/panic.c:151
#2 0xc1020731 in do_exit (code=9) at kernel/exit.c:915
#3 0xc100476a in oops_end (flags=70, regs=<value optimized out>, signr=9)
at arch/x86/kernel/dumpstack.c:265
#4 0xc1014317 in no_context (regs=0xc14ebe68, error_code=<value
optimized out>,
address=192) at arch/x86/mm/fault.c:673
#5 0xc1014411 in __bad_area_nosemaphore (regs=0xc14ebe68,
error_code=<value optimized out>, address=192, si_code=196609)
at arch/x86/mm/fault.c:739
#6 0xc1014426 in bad_area_nosemaphore (regs=0x418958, error_code=81,
address=3238124885) at arch/x86/mm/fault.c:746
#7 0xc101475a in do_page_fault (regs=0xc14ebe68, error_code=0)
at arch/x86/mm/fault.c:1070
#8 0xc137ced9 in ?? () at arch/x86/kernel/entry_32.S:1265
#9 0xc11db236 in list_empty (head=0xc0) at include/linux/list.h:182
#10 0xc11db374 in waitqueue_active (q=0x98) at include/linux/wait.h:115
#11 0xc11dea4e in serial8250_do_set_termios (port=0xc1c31320,
termios=0xc14ebf2c,
old=0xc1c31240) at drivers/serial/8250.c:2349
#12 0xc11decb6 in serial8250_set_termios (port=0xc1c31320, termios=0xc14ebf2c,
old=0xc1c31240) at drivers/serial/8250.c:2424
#13 0xc11da10b in uart_set_options (port=0xc1c31320, co=0xc164f0a0, baud=9600,
parity=110, bits=8, flow=110) at drivers/serial/serial_core.c:1935
#14 0xc1684d30 in serial8250_console_setup (co=0xc164f0a0, options=0x0)
at drivers/serial/8250.c:2864
#15 0xc101e46f in register_console (newcon=0xc164f0a0) at kernel/printk.c:1300
#16 0xc1684d5e in serial8250_console_init () at drivers/serial/8250.c:2889
#17 0xc1683da0 in console_init () at drivers/tty/tty_io.c:3208
#18 0xc166b7ba in start_kernel () at init/main.c:635
#19 0xc166b0b7 in i386_start_kernel () at arch/x86/kernel/head32.c:75
#20 0x00000000 in ?? ()
(gdb) p up->port.state
$13 = (struct uart_state *) 0x0



On Sat, Nov 13, 2010 at 00:40, Greg Kroah-Hartman <[email protected]> wrote:
> From: Lawrence Rust <[email protected]>
>
> Calling tcsetattr prevents any thread(s) currently suspended in ioctl
> TIOCMIWAIT for the same device from ever resuming.
>
> If a thread is suspended inside a call to ioctl TIOCMIWAIT, waiting for
> a modem status change, then the 8250 driver enables modem status
> interrupts (MSI).  The device interrupt service routine resumes the
> suspended thread(s) on the next MSI.
>
> If while the thread(s) are suspended, another thread calls tcsetattr
> then the 8250 driver disables MSI (unless CTS/RTS handshaking is
> enabled) thus preventing the suspended thread(s) from ever being
> resumed.
>
> This patch only disables MSI in tcsetattr handling if there are no
> suspended threads.
>
> Program to demonstrate bug & fix:
>
> /* gcc miwait.c -o miwait -l pthread */
> #include <stdio.h>
> #include <errno.h>
> #include <unistd.h>
> #include <fcntl.h>
> #include <pthread.h>
> #include <termios.h>
> #include <sys/ioctl.h>
> #include <linux/serial.h>
>
> static void* monitor( void* pv);
> static int s_fd;
>
> int main( void)
>  {
>  const char kszDev[] = "/dev/ttyS0";
>  pthread_t t;
>  struct termios tio;
>
>  s_fd = open( kszDev, O_RDWR | O_NONBLOCK);
>  if ( s_fd < 0)
>    return fprintf( stderr, "Error(%d) opening %s: %s\n", errno, kszDev, strerror( errno)), 1;
>
>  pthread_create( &t, NULL, &monitor, NULL);
>
>  /* Modem status changes seen here */
>  puts( "Main: awaiting status changes");
>  sleep( 5);
>
>  tcgetattr( s_fd, &tio);
>  tio.c_cflag ^= CSTOPB;
>
>  /* But not after here */
>  puts( "Main: tcsetattr called");
>  tcsetattr( s_fd, TCSANOW, &tio);
>
>  for (;;)
>    sleep( 1);
>  }
>
> static void* monitor( void* pv)
>  {
>  (void)pv;
>  for(;;)
>    {
>    unsigned uModem;
>    struct serial_icounter_struct cnt;
>
>    if ( ioctl( s_fd, TIOCMGET, &uModem) < 0)
>      fprintf( stderr, "Error(%d) in TIOCMGET: %s\n", errno, strerror( errno));
>    printf( "Modem status:%s%s%s%s%s%s\n",
>      (uModem & TIOCM_RTS) ? " RTS" : "",
>      (uModem & TIOCM_DTR) ? " DTR" : "",
>      (uModem & TIOCM_CTS) ? " CTS" : "",
>      (uModem & TIOCM_DSR) ? " DSR" : "",
>      (uModem & TIOCM_CD) ? " CD" : "",
>      (uModem & TIOCM_RI) ? " RI" : ""
>    );
>
>    if ( ioctl( s_fd, TIOCGICOUNT, &cnt) < 0)
>      fprintf( stderr, "Error(%d) in TIOCGICOUNT: %s\n", errno, strerror( errno));
>    printf( "Irqs: CTS:%d DSR:%d RNG:%d DCD:%d Rx:%d Tx:%d Frame:%d Orun:%d Par:%d Brk:%d Oflow:%d\n",
>      cnt.cts, cnt.dsr, cnt.rng, cnt.dcd,
>      cnt.rx, cnt.tx, cnt.frame, cnt.overrun, cnt.parity,
>      cnt.brk, cnt.buf_overrun
>    );
>
>    fputs( "Waiting...", stdout), fflush( stdout);
>    if ( 0 > ioctl( s_fd, TIOCMIWAIT, (unsigned long)(TIOCM_CAR | TIOCM_RNG | TIOCM_DSR | TIOCM_CTS)))
>      fprintf( stderr, "\nError(%d) in TIOCMIWAIT: %s\n", errno, strerror( errno));
>    fputs( "\n", stdout);
>    }
>  return NULL;
>  }
>
> Signed-off by Lawrence Rust <[email protected]>
>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
> ---
>  drivers/serial/8250.c |    5 ++++-
>  1 files changed, 4 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
> index 4d8e14b..dd5e1ac 100644
> --- a/drivers/serial/8250.c
> +++ b/drivers/serial/8250.c
> @@ -2343,8 +2343,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
>
>        /*
>         * CTS flow control flag and modem status interrupts
> +        * Only disable MSI if no threads are waiting in
> +        * serial_core::uart_wait_modem_status
>         */
> -       up->ier &= ~UART_IER_MSI;
> +       if (!waitqueue_active(&up->port.state->port.delta_msr_wait))
> +               up->ier &= ~UART_IER_MSI;
>        if (!(up->bugs & UART_BUG_NOMSR) &&
>                        UART_ENABLE_MS(&up->port, termios->c_cflag))
>                up->ier |= UART_IER_MSI;
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

2010-11-13 14:49:22

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH 11/19] 8250: Fix tcsetattr to avoid ioctl(TIOCMIWAIT) hang

On Sat, Nov 13, 2010 at 07:18:30AM +0300, Alexey Zaytsev wrote:
> Hi.
>
> This one kills the serial console for me. Luckily, in qemu:
>
> (gdb) bt
> #0 __const_udelay (xloops=4295000) at arch/x86/lib/delay.c:117
> #1 0xc137ab7c in panic (fmt=0xc147f8e1 "Attempted to kill the idle task!")
> at kernel/panic.c:151
> #2 0xc1020731 in do_exit (code=9) at kernel/exit.c:915
> #3 0xc100476a in oops_end (flags=70, regs=<value optimized out>, signr=9)
> at arch/x86/kernel/dumpstack.c:265
> #4 0xc1014317 in no_context (regs=0xc14ebe68, error_code=<value
> optimized out>,
> address=192) at arch/x86/mm/fault.c:673
> #5 0xc1014411 in __bad_area_nosemaphore (regs=0xc14ebe68,
> error_code=<value optimized out>, address=192, si_code=196609)
> at arch/x86/mm/fault.c:739
> #6 0xc1014426 in bad_area_nosemaphore (regs=0x418958, error_code=81,
> address=3238124885) at arch/x86/mm/fault.c:746
> #7 0xc101475a in do_page_fault (regs=0xc14ebe68, error_code=0)
> at arch/x86/mm/fault.c:1070
> #8 0xc137ced9 in ?? () at arch/x86/kernel/entry_32.S:1265
> #9 0xc11db236 in list_empty (head=0xc0) at include/linux/list.h:182
> #10 0xc11db374 in waitqueue_active (q=0x98) at include/linux/wait.h:115
> #11 0xc11dea4e in serial8250_do_set_termios (port=0xc1c31320,
> termios=0xc14ebf2c,
> old=0xc1c31240) at drivers/serial/8250.c:2349
> #12 0xc11decb6 in serial8250_set_termios (port=0xc1c31320, termios=0xc14ebf2c,
> old=0xc1c31240) at drivers/serial/8250.c:2424
> #13 0xc11da10b in uart_set_options (port=0xc1c31320, co=0xc164f0a0, baud=9600,
> parity=110, bits=8, flow=110) at drivers/serial/serial_core.c:1935
> #14 0xc1684d30 in serial8250_console_setup (co=0xc164f0a0, options=0x0)
> at drivers/serial/8250.c:2864
> #15 0xc101e46f in register_console (newcon=0xc164f0a0) at kernel/printk.c:1300
> #16 0xc1684d5e in serial8250_console_init () at drivers/serial/8250.c:2889
> #17 0xc1683da0 in console_init () at drivers/tty/tty_io.c:3208
> #18 0xc166b7ba in start_kernel () at init/main.c:635
> #19 0xc166b0b7 in i386_start_kernel () at arch/x86/kernel/head32.c:75
> #20 0x00000000 in ?? ()
> (gdb) p up->port.state
> $13 = (struct uart_state *) 0x0
>

Ick.

Lawrence, any ideas? If not, I'm going to have to revert this patch
from the tree.

thanks,

greg k-h


>
>
> On Sat, Nov 13, 2010 at 00:40, Greg Kroah-Hartman <[email protected]> wrote:
> > From: Lawrence Rust <[email protected]>
> >
> > Calling tcsetattr prevents any thread(s) currently suspended in ioctl
> > TIOCMIWAIT for the same device from ever resuming.
> >
> > If a thread is suspended inside a call to ioctl TIOCMIWAIT, waiting for
> > a modem status change, then the 8250 driver enables modem status
> > interrupts (MSI). ??The device interrupt service routine resumes the
> > suspended thread(s) on the next MSI.
> >
> > If while the thread(s) are suspended, another thread calls tcsetattr
> > then the 8250 driver disables MSI (unless CTS/RTS handshaking is
> > enabled) thus preventing the suspended thread(s) from ever being
> > resumed.
> >
> > This patch only disables MSI in tcsetattr handling if there are no
> > suspended threads.
> >
> > Program to demonstrate bug & fix:
> >
> > /* gcc miwait.c -o miwait -l pthread */
> > #include <stdio.h>
> > #include <errno.h>
> > #include <unistd.h>
> > #include <fcntl.h>
> > #include <pthread.h>
> > #include <termios.h>
> > #include <sys/ioctl.h>
> > #include <linux/serial.h>
> >
> > static void* monitor( void* pv);
> > static int s_fd;
> >
> > int main( void)
> > ??{
> > ??const char kszDev[] = "/dev/ttyS0";
> > ??pthread_t t;
> > ??struct termios tio;
> >
> > ??s_fd = open( kszDev, O_RDWR | O_NONBLOCK);
> > ??if ( s_fd < 0)
> > ?? ??return fprintf( stderr, "Error(%d) opening %s: %s\n", errno, kszDev, strerror( errno)), 1;
> >
> > ??pthread_create( &t, NULL, &monitor, NULL);
> >
> > ??/* Modem status changes seen here */
> > ??puts( "Main: awaiting status changes");
> > ??sleep( 5);
> >
> > ??tcgetattr( s_fd, &tio);
> > ??tio.c_cflag ^= CSTOPB;
> >
> > ??/* But not after here */
> > ??puts( "Main: tcsetattr called");
> > ??tcsetattr( s_fd, TCSANOW, &tio);
> >
> > ??for (;;)
> > ?? ??sleep( 1);
> > ??}
> >
> > static void* monitor( void* pv)
> > ??{
> > ??(void)pv;
> > ??for(;;)
> > ?? ??{
> > ?? ??unsigned uModem;
> > ?? ??struct serial_icounter_struct cnt;
> >
> > ?? ??if ( ioctl( s_fd, TIOCMGET, &uModem) < 0)
> > ?? ?? ??fprintf( stderr, "Error(%d) in TIOCMGET: %s\n", errno, strerror( errno));
> > ?? ??printf( "Modem status:%s%s%s%s%s%s\n",
> > ?? ?? ??(uModem & TIOCM_RTS) ? " RTS" : "",
> > ?? ?? ??(uModem & TIOCM_DTR) ? " DTR" : "",
> > ?? ?? ??(uModem & TIOCM_CTS) ? " CTS" : "",
> > ?? ?? ??(uModem & TIOCM_DSR) ? " DSR" : "",
> > ?? ?? ??(uModem & TIOCM_CD) ? " CD" : "",
> > ?? ?? ??(uModem & TIOCM_RI) ? " RI" : ""
> > ?? ??);
> >
> > ?? ??if ( ioctl( s_fd, TIOCGICOUNT, &cnt) < 0)
> > ?? ?? ??fprintf( stderr, "Error(%d) in TIOCGICOUNT: %s\n", errno, strerror( errno));
> > ?? ??printf( "Irqs: CTS:%d DSR:%d RNG:%d DCD:%d Rx:%d Tx:%d Frame:%d Orun:%d Par:%d Brk:%d Oflow:%d\n",
> > ?? ?? ??cnt.cts, cnt.dsr, cnt.rng, cnt.dcd,
> > ?? ?? ??cnt.rx, cnt.tx, cnt.frame, cnt.overrun, cnt.parity,
> > ?? ?? ??cnt.brk, cnt.buf_overrun
> > ?? ??);
> >
> > ?? ??fputs( "Waiting...", stdout), fflush( stdout);
> > ?? ??if ( 0 > ioctl( s_fd, TIOCMIWAIT, (unsigned long)(TIOCM_CAR | TIOCM_RNG | TIOCM_DSR | TIOCM_CTS)))
> > ?? ?? ??fprintf( stderr, "\nError(%d) in TIOCMIWAIT: %s\n", errno, strerror( errno));
> > ?? ??fputs( "\n", stdout);
> > ?? ??}
> > ??return NULL;
> > ??}
> >
> > Signed-off by Lawrence Rust <[email protected]>
> >
> > Signed-off-by: Greg Kroah-Hartman <[email protected]>
> > ---
> > ??drivers/serial/8250.c | ?? ??5 ++++-
> > ??1 files changed, 4 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
> > index 4d8e14b..dd5e1ac 100644
> > --- a/drivers/serial/8250.c
> > +++ b/drivers/serial/8250.c
> > @@ -2343,8 +2343,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
> >
> > ?? ?? ?? ??/*
> > ?? ?? ?? ?? * CTS flow control flag and modem status interrupts
> > + ?? ?? ?? ??* Only disable MSI if no threads are waiting in
> > + ?? ?? ?? ??* serial_core::uart_wait_modem_status
> > ?? ?? ?? ?? */
> > - ?? ?? ?? up->ier &= ~UART_IER_MSI;
> > + ?? ?? ?? if (!waitqueue_active(&up->port.state->port.delta_msr_wait))
> > + ?? ?? ?? ?? ?? ?? ?? up->ier &= ~UART_IER_MSI;
> > ?? ?? ?? ??if (!(up->bugs & UART_BUG_NOMSR) &&
> > ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??UART_ENABLE_MS(&up->port, termios->c_cflag))
> > ?? ?? ?? ?? ?? ?? ?? ??up->ier |= UART_IER_MSI;
> > --
> > 1.7.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to [email protected]
> > More majordomo info at ??http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at ??http://www.tux.org/lkml/
> >

2010-11-13 15:10:47

by Ingo Molnar

[permalink] [raw]
Subject: [boot crash] Re: [GIT PATCH] TTY/serial fixes for .37-rc1


* Greg KH <[email protected]> wrote:

> Here are a number of tty and serial fixes for your .37-rc1 tree.
>
> Full details are below, but there's just a range of bug fixes all over
> the place, some of them having lived in the tree for quite some time,
> and it's nice to get them finally resolved.
>
> Please pull from:
> master.kernel.org:/pub/scm/linux/kernel/git/gregkh/tty-2.6.git/ tty-linus
>
> Patches will be sent to the linux-kernel mailing list, if anyone wants
> to see them.
>
> thanks,
>
> greg k-h
>
> ------------
>
> MAINTAINERS | 4 +-
> drivers/char/amiserial.c | 1 -
> drivers/char/nozomi.c | 1 -
> drivers/char/pcmcia/synclink_cs.c | 1 +
> drivers/serial/8250.c | 5 +++-
> drivers/serial/8250_pci.c | 5 ++++
> drivers/serial/bfin_5xx.c | 31 ++++++++++++++++-------
> drivers/tty/n_gsm.c | 5 ++-
> drivers/tty/tty_buffer.c | 14 +++++++++-
> drivers/tty/tty_ldisc.c | 49 +++++++++++++++++++++++++++++++-----
> drivers/tty/vt/vc_screen.c | 6 ++--
> include/linux/tty.h | 2 +-
> 12 files changed, 94 insertions(+), 30 deletions(-)

I think one of these commits is causing the following boot crash in -tip:

Console: colour VGA+ 80x25
BUG: unable to handle kernel NULL pointer dereference at 0000000000000158
IP: [<ffffffff811ebcb4>] serial8250_do_set_termios+0x1d4/0x430
PGD 0
Oops: 0000 [#1] SMP
last sysfs file:
CPU 0
Modules linked in:

Pid: 0, comm: swapper Not tainted 2.6.37-rc1-tip-02017-gba4813e-dirty #62970 /
RIP: 0010:[<ffffffff811ebcb4>] [<ffffffff811ebcb4>] serial8250_do_set_termios+0x1d4/0x430
RSP: 0000:ffffffff8152fd88 EFLAGS: 00010082
RAX: 0000000000000000 RBX: ffffffff8207aa80 RCX: 0000000000002060
RDX: 0000000000000158 RSI: 0000000000000000 RDI: ffffffff8207aa80
RBP: ffffffff8152fdd8 R08: 000000000000000a R09: 000000000001c200
R10: 0000000000000025 R11: ffffffff81cec340 R12: 0000000000000013
R13: ffffffff8152fe08 R14: 0000000000000001 R15: 000000000001c200
FS: 0000000000000000(0000) GS:ffff88003e400000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000158 CR3: 000000000153f000 CR4: 00000000000006b0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process swapper (pid: 0, threadinfo ffffffff8152e000, task ffffffff81547020)
Stack:
ffffffff815567e0 ffffffff8207aa00 0000000000000286 00ffffff8207aa10
000000000000006e 000000000001c200 ffffffff8207aa80 ffffffff815762c0
000000000000006e 000000000000006e ffffffff8152fde8 ffffffff811ebf35
Call Trace:
[<ffffffff811ebf35>] serial8250_set_termios+0x25/0x30
[<ffffffff811e6663>] uart_set_options+0xf3/0x170
[<ffffffff81798f55>] serial8250_console_setup+0xa8/0xaf
[<ffffffff8104ac1a>] register_console+0x22a/0x390
[<ffffffff81799117>] serial8250_console_init+0x28/0x2c
[<ffffffff81797a5c>] console_init+0x19/0x2a
[<ffffffff81778b4d>] start_kernel+0x27d/0x407
[<ffffffff81778347>] x86_64_start_reservations+0x132/0x136
[<ffffffff81778451>] x86_64_start_kernel+0x106/0x115
Code: 98 00 00 00 41 f6 45 00 04 0f 85 a8 01 00 00 41 f6 45 08 80 75 07 83 8b 98 00 00 00 01 48 8b 83 a0 00 00 00 48 8d 90 58 01 00 00 <48> 39 90 58 01 00 00 0f 84 17 02 00 00 0f b6 93 c1 01 00 00 89
RIP [<ffffffff811ebcb4>] serial8250_do_set_termios+0x1d4/0x430
RSP <ffffffff8152fd88>
CR2: 0000000000000158
---[ end trace a7919e7f17c0a725 ]---
Kernel panic - not syncing: Fatal exception
Pid: 0, comm: swapper Tainted: G D 2.6.37-rc1-tip-02017-gba4813e-dirty #62970
Call Trace:
[<ffffffff8139148f>] panic+0x8c/0x19c
[<ffffffff8104b745>] ? kmsg_dump+0x155/0x170
[<ffffffff8100f744>] oops_end+0xd4/0xf0
[<ffffffff81030a50>] no_context+0xf0/0x260
[<ffffffff81063910>] ? __kernel_text_address+0x40/0x70
[<ffffffff81030ce5>] __bad_area_nosemaphore+0x125/0x1e0
[<ffffffff81030dae>] bad_area_nosemaphore+0xe/0x10
[<ffffffff81031841>] do_page_fault+0x3d1/0x4a0
[<ffffffff8101867a>] ? save_stack_trace+0x2a/0x50
[<ffffffff8107810d>] ? __lock_acquire.clone.20+0x6fd/0xab0
[<ffffffff81395ad5>] page_fault+0x25/0x30
[<ffffffff811ebcb4>] ? serial8250_do_set_termios+0x1d4/0x430
[<ffffffff811ebc2d>] ? serial8250_do_set_termios+0x14d/0x430
[<ffffffff811ebf35>] serial8250_set_termios+0x25/0x30
[<ffffffff811e6663>] uart_set_options+0xf3/0x170
[<ffffffff81798f55>] serial8250_console_setup+0xa8/0xaf
[<ffffffff8104ac1a>] register_console+0x22a/0x390
[<ffffffff81799117>] serial8250_console_init+0x28/0x2c
[<ffffffff81797a5c>] console_init+0x19/0x2a
[<ffffffff81778b4d>] start_kernel+0x27d/0x407
[<ffffffff81778347>] x86_64_start_reservations+0x132/0x136
[<ffffffff81778451>] x86_64_start_kernel+0x106/0x115
Rebooting in 1 seconds..Press any key to enter the menu

It crashed almost immediately after i merged Linus's 9457b24a0955 into -tip, we were
on yesterday's f6614b7bb405 before that - so i think the crash is both pretty
generic.

Thanks,

Ingo


Attachments:
(No filename) (4.94 kB)
config (64.06 kB)
Download all attachments

2010-11-13 15:21:45

by Ingo Molnar

[permalink] [raw]
Subject: Re: [boot crash] Re: [GIT PATCH] TTY/serial fixes for .37-rc1


* Ingo Molnar <[email protected]> wrote:

> It crashed almost immediately after i merged Linus's 9457b24a0955 into -tip,
> we were on yesterday's f6614b7bb405 before that - so i think the crash is
> both pretty generic.

Yes, it crashes with an x86 defconfig too. Appears to be caused by:

47d3904fe40d: 8250: Fix tcsetattr to avoid ioctl(TIOCMIWAIT) hang

It crashes any x86 serial console bootup.

Thanks,

Ingo

2010-11-13 15:25:36

by Ingo Molnar

[permalink] [raw]
Subject: Re: [boot crash] Re: [GIT PATCH] TTY/serial fixes for .37-rc1


* Ingo Molnar <[email protected]> wrote:

> * Ingo Molnar <[email protected]> wrote:
>
> > It crashed almost immediately after i merged Linus's 9457b24a0955 into -tip,
> > we were on yesterday's f6614b7bb405 before that - so i think the crash is
> > both pretty generic.
>
> Yes, it crashes with an x86 defconfig too. Appears to be caused by:
>
> 47d3904fe40d: 8250: Fix tcsetattr to avoid ioctl(TIOCMIWAIT) hang
>
> It crashes any x86 serial console bootup.

The revert below makes the system boot up fine.

Thanks,

Ingo

------------------------>
>From a0758e8ea2a19de96d16db231be71f708980b86a Mon Sep 17 00:00:00 2001
From: Ingo Molnar <[email protected]>
Date: Sat, 13 Nov 2010 16:21:58 +0100
Subject: [PATCH] Revert "8250: Fix tcsetattr to avoid ioctl(TIOCMIWAIT) hang"

This reverts commit 47d3904fe40d62deee8cd46e79ca784e7a548acd.

Crashes any x86 serial console bootup:

Console: colour VGA+ 80x25
BUG: unable to handle kernel NULL pointer dereference at 0000000000000158
IP: [<ffffffff811ebcb4>] serial8250_do_set_termios+0x1d4/0x430
PGD 0
Oops: 0000 [#1] SMP
last sysfs file:
CPU 0
Modules linked in:

Pid: 0, comm: swapper Not tainted 2.6.37-rc1-tip-02017-gba4813e-dirty #62970 /
RIP: 0010:[<ffffffff811ebcb4>] [<ffffffff811ebcb4>] serial8250_do_set_termios+0x1d4/0x430
RSP: 0000:ffffffff8152fd88 EFLAGS: 00010082
RAX: 0000000000000000 RBX: ffffffff8207aa80 RCX: 0000000000002060
RDX: 0000000000000158 RSI: 0000000000000000 RDI: ffffffff8207aa80
RBP: ffffffff8152fdd8 R08: 000000000000000a R09: 000000000001c200
R10: 0000000000000025 R11: ffffffff81cec340 R12: 0000000000000013
R13: ffffffff8152fe08 R14: 0000000000000001 R15: 000000000001c200
FS: 0000000000000000(0000) GS:ffff88003e400000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000158 CR3: 000000000153f000 CR4: 00000000000006b0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process swapper (pid: 0, threadinfo ffffffff8152e000, task ffffffff81547020)
Stack:
ffffffff815567e0 ffffffff8207aa00 0000000000000286 00ffffff8207aa10
000000000000006e 000000000001c200 ffffffff8207aa80 ffffffff815762c0
000000000000006e 000000000000006e ffffffff8152fde8 ffffffff811ebf35
Call Trace:
[<ffffffff811ebf35>] serial8250_set_termios+0x25/0x30
[<ffffffff811e6663>] uart_set_options+0xf3/0x170
[<ffffffff81798f55>] serial8250_console_setup+0xa8/0xaf
[<ffffffff8104ac1a>] register_console+0x22a/0x390
[<ffffffff81799117>] serial8250_console_init+0x28/0x2c
[<ffffffff81797a5c>] console_init+0x19/0x2a
[<ffffffff81778b4d>] start_kernel+0x27d/0x407
[<ffffffff81778347>] x86_64_start_reservations+0x132/0x136
[<ffffffff81778451>] x86_64_start_kernel+0x106/0x115
Code: 98 00 00 00 41 f6 45 00 04 0f 85 a8 01 00 00 41 f6 45 08 80 75 07 83 8b 98 00 00 00 01 48 8b 83 a0 00 00 00 48 8d 90 58 01 00 00 <48> 39 90 58 01 00 00 0f 84 17 02 00 00 0f b6 93 c1 01 00 00 89
RIP [<ffffffff811ebcb4>] serial8250_do_set_termios+0x1d4/0x430
RSP <ffffffff8152fd88>
CR2: 0000000000000158
---[ end trace a7919e7f17c0a725 ]---
Kernel panic - not syncing: Fatal exception
Pid: 0, comm: swapper Tainted: G D 2.6.37-rc1-tip-02017-gba4813e-dirty #62970
Call Trace:
[<ffffffff8139148f>] panic+0x8c/0x19c
[<ffffffff8104b745>] ? kmsg_dump+0x155/0x170
[<ffffffff8100f744>] oops_end+0xd4/0xf0
[<ffffffff81030a50>] no_context+0xf0/0x260
[<ffffffff81063910>] ? __kernel_text_address+0x40/0x70
[<ffffffff81030ce5>] __bad_area_nosemaphore+0x125/0x1e0
[<ffffffff81030dae>] bad_area_nosemaphore+0xe/0x10
[<ffffffff81031841>] do_page_fault+0x3d1/0x4a0
[<ffffffff8101867a>] ? save_stack_trace+0x2a/0x50
[<ffffffff8107810d>] ? __lock_acquire.clone.20+0x6fd/0xab0
[<ffffffff81395ad5>] page_fault+0x25/0x30
[<ffffffff811ebcb4>] ? serial8250_do_set_termios+0x1d4/0x430
[<ffffffff811ebc2d>] ? serial8250_do_set_termios+0x14d/0x430
[<ffffffff811ebf35>] serial8250_set_termios+0x25/0x30
[<ffffffff811e6663>] uart_set_options+0xf3/0x170
[<ffffffff81798f55>] serial8250_console_setup+0xa8/0xaf
[<ffffffff8104ac1a>] register_console+0x22a/0x390
[<ffffffff81799117>] serial8250_console_init+0x28/0x2c
[<ffffffff81797a5c>] console_init+0x19/0x2a
[<ffffffff81778b4d>] start_kernel+0x27d/0x407
[<ffffffff81778347>] x86_64_start_reservations+0x132/0x136
[<ffffffff81778451>] x86_64_start_kernel+0x106/0x115

Signed-off-by: Ingo Molnar <[email protected]>
---
drivers/serial/8250.c | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index dd5e1ac..4d8e14b 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2343,11 +2343,8 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,

/*
* CTS flow control flag and modem status interrupts
- * Only disable MSI if no threads are waiting in
- * serial_core::uart_wait_modem_status
*/
- if (!waitqueue_active(&up->port.state->port.delta_msr_wait))
- up->ier &= ~UART_IER_MSI;
+ up->ier &= ~UART_IER_MSI;
if (!(up->bugs & UART_BUG_NOMSR) &&
UART_ENABLE_MS(&up->port, termios->c_cflag))
up->ier |= UART_IER_MSI;

2010-11-13 17:44:00

by Alan

[permalink] [raw]
Subject: Re: [PATCH 11/19] 8250: Fix tcsetattr to avoid ioctl(TIOCMIWAIT) hang

> Lawrence, any ideas? If not, I'm going to have to revert this patch
> from the tree.

Peering into the waitqueues like that isn't going to work.

I'd suggest simply keeping a proper count (locked) of the number of
people sitting in TIOCMIWAIT, and probably do it in serial_core (because
the bug doesn't look 8250 specific)

Alan

2010-11-13 19:22:15

by Lawrence Rust

[permalink] [raw]
Subject: Re: [PATCH 11/19] 8250: Fix tcsetattr to avoid ioctl(TIOCMIWAIT) hang

On Sat, 2010-11-13 at 06:49 -0800, Greg KH wrote:
> On Sat, Nov 13, 2010 at 07:18:30AM +0300, Alexey Zaytsev wrote:
> > Hi.
> >
> > This one kills the serial console for me. Luckily, in qemu:
> >
> > (gdb) bt
> > #0 __const_udelay (xloops=4295000) at arch/x86/lib/delay.c:117
> > #1 0xc137ab7c in panic (fmt=0xc147f8e1 "Attempted to kill the idle task!")
> > at kernel/panic.c:151
> > #2 0xc1020731 in do_exit (code=9) at kernel/exit.c:915
> > #3 0xc100476a in oops_end (flags=70, regs=<value optimized out>, signr=9)
> > at arch/x86/kernel/dumpstack.c:265
> > #4 0xc1014317 in no_context (regs=0xc14ebe68, error_code=<value
> > optimized out>,
> > address=192) at arch/x86/mm/fault.c:673
> > #5 0xc1014411 in __bad_area_nosemaphore (regs=0xc14ebe68,
> > error_code=<value optimized out>, address=192, si_code=196609)
> > at arch/x86/mm/fault.c:739
> > #6 0xc1014426 in bad_area_nosemaphore (regs=0x418958, error_code=81,
> > address=3238124885) at arch/x86/mm/fault.c:746
> > #7 0xc101475a in do_page_fault (regs=0xc14ebe68, error_code=0)
> > at arch/x86/mm/fault.c:1070
> > #8 0xc137ced9 in ?? () at arch/x86/kernel/entry_32.S:1265
> > #9 0xc11db236 in list_empty (head=0xc0) at include/linux/list.h:182
> > #10 0xc11db374 in waitqueue_active (q=0x98) at include/linux/wait.h:115
> > #11 0xc11dea4e in serial8250_do_set_termios (port=0xc1c31320,
> > termios=0xc14ebf2c,
> > old=0xc1c31240) at drivers/serial/8250.c:2349
> > #12 0xc11decb6 in serial8250_set_termios (port=0xc1c31320, termios=0xc14ebf2c,
> > old=0xc1c31240) at drivers/serial/8250.c:2424
> > #13 0xc11da10b in uart_set_options (port=0xc1c31320, co=0xc164f0a0, baud=9600,
> > parity=110, bits=8, flow=110) at drivers/serial/serial_core.c:1935
> > #14 0xc1684d30 in serial8250_console_setup (co=0xc164f0a0, options=0x0)
> > at drivers/serial/8250.c:2864
> > #15 0xc101e46f in register_console (newcon=0xc164f0a0) at kernel/printk.c:1300
> > #16 0xc1684d5e in serial8250_console_init () at drivers/serial/8250.c:2889
> > #17 0xc1683da0 in console_init () at drivers/tty/tty_io.c:3208
> > #18 0xc166b7ba in start_kernel () at init/main.c:635
> > #19 0xc166b0b7 in i386_start_kernel () at arch/x86/kernel/head32.c:75
> > #20 0x00000000 in ?? ()
> > (gdb) p up->port.state
> > $13 = (struct uart_state *) 0x0
> >
>
> Ick.
>
> Lawrence, any ideas? If not, I'm going to have to revert this patch
> from the tree.

Maybe best to pull the patch for now and have a re-think. Shame, it
seemed so easy and the fix works for me with a simple modem input. I'll
re-submit later..

-- Lawrence

> thanks,
>
> greg k-h
>
>
> >
> >
> > On Sat, Nov 13, 2010 at 00:40, Greg Kroah-Hartman <[email protected]> wrote:
> > > From: Lawrence Rust <[email protected]>
> > >
> > > Calling tcsetattr prevents any thread(s) currently suspended in ioctl
> > > TIOCMIWAIT for the same device from ever resuming.
> > >
> > > If a thread is suspended inside a call to ioctl TIOCMIWAIT, waiting for
> > > a modem status change, then the 8250 driver enables modem status
> > > interrupts (MSI). ??The device interrupt service routine resumes the
> > > suspended thread(s) on the next MSI.
> > >
> > > If while the thread(s) are suspended, another thread calls tcsetattr
> > > then the 8250 driver disables MSI (unless CTS/RTS handshaking is
> > > enabled) thus preventing the suspended thread(s) from ever being
> > > resumed.
> > >
> > > This patch only disables MSI in tcsetattr handling if there are no
> > > suspended threads.
> > >
> > > Program to demonstrate bug & fix:
> > >
> > > /* gcc miwait.c -o miwait -l pthread */
> > > #include <stdio.h>
> > > #include <errno.h>
> > > #include <unistd.h>
> > > #include <fcntl.h>
> > > #include <pthread.h>
> > > #include <termios.h>
> > > #include <sys/ioctl.h>
> > > #include <linux/serial.h>
> > >
> > > static void* monitor( void* pv);
> > > static int s_fd;
> > >
> > > int main( void)
> > > ??{
> > > ??const char kszDev[] = "/dev/ttyS0";
> > > ??pthread_t t;
> > > ??struct termios tio;
> > >
> > > ??s_fd = open( kszDev, O_RDWR | O_NONBLOCK);
> > > ??if ( s_fd < 0)
> > > ?? ??return fprintf( stderr, "Error(%d) opening %s: %s\n", errno, kszDev, strerror( errno)), 1;
> > >
> > > ??pthread_create( &t, NULL, &monitor, NULL);
> > >
> > > ??/* Modem status changes seen here */
> > > ??puts( "Main: awaiting status changes");
> > > ??sleep( 5);
> > >
> > > ??tcgetattr( s_fd, &tio);
> > > ??tio.c_cflag ^= CSTOPB;
> > >
> > > ??/* But not after here */
> > > ??puts( "Main: tcsetattr called");
> > > ??tcsetattr( s_fd, TCSANOW, &tio);
> > >
> > > ??for (;;)
> > > ?? ??sleep( 1);
> > > ??}
> > >
> > > static void* monitor( void* pv)
> > > ??{
> > > ??(void)pv;
> > > ??for(;;)
> > > ?? ??{
> > > ?? ??unsigned uModem;
> > > ?? ??struct serial_icounter_struct cnt;
> > >
> > > ?? ??if ( ioctl( s_fd, TIOCMGET, &uModem) < 0)
> > > ?? ?? ??fprintf( stderr, "Error(%d) in TIOCMGET: %s\n", errno, strerror( errno));
> > > ?? ??printf( "Modem status:%s%s%s%s%s%s\n",
> > > ?? ?? ??(uModem & TIOCM_RTS) ? " RTS" : "",
> > > ?? ?? ??(uModem & TIOCM_DTR) ? " DTR" : "",
> > > ?? ?? ??(uModem & TIOCM_CTS) ? " CTS" : "",
> > > ?? ?? ??(uModem & TIOCM_DSR) ? " DSR" : "",
> > > ?? ?? ??(uModem & TIOCM_CD) ? " CD" : "",
> > > ?? ?? ??(uModem & TIOCM_RI) ? " RI" : ""
> > > ?? ??);
> > >
> > > ?? ??if ( ioctl( s_fd, TIOCGICOUNT, &cnt) < 0)
> > > ?? ?? ??fprintf( stderr, "Error(%d) in TIOCGICOUNT: %s\n", errno, strerror( errno));
> > > ?? ??printf( "Irqs: CTS:%d DSR:%d RNG:%d DCD:%d Rx:%d Tx:%d Frame:%d Orun:%d Par:%d Brk:%d Oflow:%d\n",
> > > ?? ?? ??cnt.cts, cnt.dsr, cnt.rng, cnt.dcd,
> > > ?? ?? ??cnt.rx, cnt.tx, cnt.frame, cnt.overrun, cnt.parity,
> > > ?? ?? ??cnt.brk, cnt.buf_overrun
> > > ?? ??);
> > >
> > > ?? ??fputs( "Waiting...", stdout), fflush( stdout);
> > > ?? ??if ( 0 > ioctl( s_fd, TIOCMIWAIT, (unsigned long)(TIOCM_CAR | TIOCM_RNG | TIOCM_DSR | TIOCM_CTS)))
> > > ?? ?? ??fprintf( stderr, "\nError(%d) in TIOCMIWAIT: %s\n", errno, strerror( errno));
> > > ?? ??fputs( "\n", stdout);
> > > ?? ??}
> > > ??return NULL;
> > > ??}
> > >
> > > Signed-off by Lawrence Rust <[email protected]>
> > >
> > > Signed-off-by: Greg Kroah-Hartman <[email protected]>
> > > ---
> > > ??drivers/serial/8250.c | ?? ??5 ++++-
> > > ??1 files changed, 4 insertions(+), 1 deletions(-)
> > >
> > > diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
> > > index 4d8e14b..dd5e1ac 100644
> > > --- a/drivers/serial/8250.c
> > > +++ b/drivers/serial/8250.c
> > > @@ -2343,8 +2343,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
> > >
> > > ?? ?? ?? ??/*
> > > ?? ?? ?? ?? * CTS flow control flag and modem status interrupts
> > > + ?? ?? ?? ??* Only disable MSI if no threads are waiting in
> > > + ?? ?? ?? ??* serial_core::uart_wait_modem_status
> > > ?? ?? ?? ?? */
> > > - ?? ?? ?? up->ier &= ~UART_IER_MSI;
> > > + ?? ?? ?? if (!waitqueue_active(&up->port.state->port.delta_msr_wait))
> > > + ?? ?? ?? ?? ?? ?? ?? up->ier &= ~UART_IER_MSI;
> > > ?? ?? ?? ??if (!(up->bugs & UART_BUG_NOMSR) &&
> > > ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??UART_ENABLE_MS(&up->port, termios->c_cflag))
> > > ?? ?? ?? ?? ?? ?? ?? ??up->ier |= UART_IER_MSI;
> > > --
> > > 1.7.1
> > >
> > > --
> > > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > > the body of a message to [email protected]
> > > More majordomo info at ??http://vger.kernel.org/majordomo-info.html
> > > Please read the FAQ at ??http://www.tux.org/lkml/
> > >


--
Lawrence

2010-11-13 23:50:43

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH 11/19] 8250: Fix tcsetattr to avoid ioctl(TIOCMIWAIT) hang

On Sat, Nov 13, 2010 at 08:22:07PM +0100, Lawrence Rust wrote:
> On Sat, 2010-11-13 at 06:49 -0800, Greg KH wrote:
> > On Sat, Nov 13, 2010 at 07:18:30AM +0300, Alexey Zaytsev wrote:
> > > Hi.
> > >
> > > This one kills the serial console for me. Luckily, in qemu:
> > >
> > > (gdb) bt
> > > #0 __const_udelay (xloops=4295000) at arch/x86/lib/delay.c:117
> > > #1 0xc137ab7c in panic (fmt=0xc147f8e1 "Attempted to kill the idle task!")
> > > at kernel/panic.c:151
> > > #2 0xc1020731 in do_exit (code=9) at kernel/exit.c:915
> > > #3 0xc100476a in oops_end (flags=70, regs=<value optimized out>, signr=9)
> > > at arch/x86/kernel/dumpstack.c:265
> > > #4 0xc1014317 in no_context (regs=0xc14ebe68, error_code=<value
> > > optimized out>,
> > > address=192) at arch/x86/mm/fault.c:673
> > > #5 0xc1014411 in __bad_area_nosemaphore (regs=0xc14ebe68,
> > > error_code=<value optimized out>, address=192, si_code=196609)
> > > at arch/x86/mm/fault.c:739
> > > #6 0xc1014426 in bad_area_nosemaphore (regs=0x418958, error_code=81,
> > > address=3238124885) at arch/x86/mm/fault.c:746
> > > #7 0xc101475a in do_page_fault (regs=0xc14ebe68, error_code=0)
> > > at arch/x86/mm/fault.c:1070
> > > #8 0xc137ced9 in ?? () at arch/x86/kernel/entry_32.S:1265
> > > #9 0xc11db236 in list_empty (head=0xc0) at include/linux/list.h:182
> > > #10 0xc11db374 in waitqueue_active (q=0x98) at include/linux/wait.h:115
> > > #11 0xc11dea4e in serial8250_do_set_termios (port=0xc1c31320,
> > > termios=0xc14ebf2c,
> > > old=0xc1c31240) at drivers/serial/8250.c:2349
> > > #12 0xc11decb6 in serial8250_set_termios (port=0xc1c31320, termios=0xc14ebf2c,
> > > old=0xc1c31240) at drivers/serial/8250.c:2424
> > > #13 0xc11da10b in uart_set_options (port=0xc1c31320, co=0xc164f0a0, baud=9600,
> > > parity=110, bits=8, flow=110) at drivers/serial/serial_core.c:1935
> > > #14 0xc1684d30 in serial8250_console_setup (co=0xc164f0a0, options=0x0)
> > > at drivers/serial/8250.c:2864
> > > #15 0xc101e46f in register_console (newcon=0xc164f0a0) at kernel/printk.c:1300
> > > #16 0xc1684d5e in serial8250_console_init () at drivers/serial/8250.c:2889
> > > #17 0xc1683da0 in console_init () at drivers/tty/tty_io.c:3208
> > > #18 0xc166b7ba in start_kernel () at init/main.c:635
> > > #19 0xc166b0b7 in i386_start_kernel () at arch/x86/kernel/head32.c:75
> > > #20 0x00000000 in ?? ()
> > > (gdb) p up->port.state
> > > $13 = (struct uart_state *) 0x0
> > >
> >
> > Ick.
> >
> > Lawrence, any ideas? If not, I'm going to have to revert this patch
> > from the tree.
>
> Maybe best to pull the patch for now and have a re-think. Shame, it
> seemed so easy and the fix works for me with a simple modem input. I'll
> re-submit later..

Linus has now reverted it in his tree.

thanks,

greg k-h

2010-11-13 23:50:52

by Greg KH

[permalink] [raw]
Subject: Re: [boot crash] Re: [GIT PATCH] TTY/serial fixes for .37-rc1

On Sat, Nov 13, 2010 at 04:25:14PM +0100, Ingo Molnar wrote:
>
> * Ingo Molnar <[email protected]> wrote:
>
> > * Ingo Molnar <[email protected]> wrote:
> >
> > > It crashed almost immediately after i merged Linus's 9457b24a0955 into -tip,
> > > we were on yesterday's f6614b7bb405 before that - so i think the crash is
> > > both pretty generic.
> >
> > Yes, it crashes with an x86 defconfig too. Appears to be caused by:
> >
> > 47d3904fe40d: 8250: Fix tcsetattr to avoid ioctl(TIOCMIWAIT) hang
> >
> > It crashes any x86 serial console bootup.
>
> The revert below makes the system boot up fine.

Thanks for this, Linus took it already.

greg k-h

2010-12-07 21:00:40

by Russ Dill

[permalink] [raw]
Subject: Re: [PATCH 10/19] tty_ldisc: Fix BUG() on hangup

Greg Kroah-Hartman <gregkh <at> suse.de> writes:

>
> From: Philippe Rétornaz <philippe.retornaz <at> epfl.ch>
>
> A kernel BUG when bluetooth rfcomm connection drop while the associated
> serial port is open is sometime triggered.
>
> It seems that the line discipline can disappear between the
> tty_ldisc_put and tty_ldisc_get. This patch fall back to the N_TTY line
> discipline if the previous discipline is not available anymore.
>
> Signed-off-by: Philippe Retornaz <philippe.retornaz <at> epfl.ch>
> Acked-by: Alan Cox <alan <at> linux.intel.com>
> Cc: stable <stable <at> kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh <at> suse.de>

I think I've run into this issue with a pl2303 adapter on device removal
with v2.6.32.15:

[ 134.572454] ------------[ cut here ]------------
[ 134.576038] kernel BUG at drivers/char/tty_ldisc.c:707!
[ 134.576038] invalid opcode: 0000 [#1] SMP
[ 134.576038] last sysfs file:
/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-6/1-6:1.0/host2/target2:0:0/
2:0:0:0/block/sdb/ro
[ 134.576038] Modules linked in: -----
[ 134.576038]
[ 134.576038] Pid: 268, comm: khubd Not tainted (2.6.32.15-1 #1)
Catalyst
[ 134.576038] EIP: 0060:[<c122323e>] EFLAGS: 00010202 CPU: 0
[ 134.576038] EIP is at tty_ldisc_reinit+0x3e/0x50
[ 134.576038] EAX: ffffffea EBX: f660e000 ECX: f6b28210 EDX: 00000001
[ 134.576038] ESI: 0000006e EDI: f660e000 EBP: f7092d6c ESP: f7092d64
[ 134.576038] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
[ 134.576038] Process khubd (pid: 268, ti=f7092000 task=f71330c0
task.ti=f7092000)
[ 134.576038] Stack:
[ 134.576038] f660e014 00000000 f7092d84 c12234be 00000001 f660e188
f660e188 f660e000
[ 134.576038] <0> f7092db0 c121c291 00000296 00000000 00000000 00000001
00000296 f660e000
[ 134.576038] <0> f660e000 f7240800 00000000 f7092db8 c121c4cd f7092de4
c12ee98c 00000002
[ 134.576038] Call Trace:
[ 134.576038] [<c12234be>] ? tty_ldisc_hangup+0x1ae/0x1e0
[ 134.576038] [<c121c291>] ? do_tty_hangup+0x111/0x340
[ 134.576038] [<c121c4cd>] ? tty_vhangup+0xd/0x10
[ 134.576038] [<c12ee98c>] ? usb_serial_disconnect+0x8c/0x170
[ 134.576038] [<c12c6831>] ? usb_unbind_interface+0xf1/0x130
[ 134.576038] [<c125b972>] ? __device_release_driver+0x72/0xd0
[ 134.576038] [<c125ba90>] ? device_release_driver+0x20/0x40
[ 134.576038] [<c125ae6c>] ? bus_remove_device+0x7c/0xe0
[ 134.576038] [<c1258c97>] ? device_remove_attrs+0x37/0xb0
[ 134.576038] [<c1258e14>] ? device_del+0x104/0x1a0
[ 134.576038] [<c12c33bc>] ? usb_disable_device+0xbc/0x1f0
[ 134.576038] [<c12bcfa5>] ? usb_disconnect+0xb5/0x1b0
[ 134.576038] [<c12be91f>] ? hub_thread+0x64f/0x17e0
[ 134.576038] [<c103234e>] ? try_to_wake_up+0xbe/0x380
[ 134.576038] [<c104a8d0>] ? autoremove_wake_function+0x0/0x50
[ 134.576038] [<c12be2d0>] ? hub_thread+0x0/0x17e0
[ 134.576038] [<c104a684>] ? kthread+0x74/0x80
[ 134.576038] [<c104a610>] ? kthread+0x0/0x80
[ 134.576038] [<c10039ff>] ? kernel_thread_helper+0x7/0x18
[ 134.576038] Code: 34 e8 c7 fe ff ff 89 f0 c7 43 34 00 00 00 00 e8 d9
fc ff ff 3d 00 f0 ff ff 77 10 89 43 34 89 f2 89 d8 e8 b6 fd ff
[ 134.576038] EIP: [<c122323e>] tty_ldisc_reinit+0x3e/0x50 SS:ESP
0068:f7092d64
[ 134.813426] ---[ end trace dd3cfdb471d33e40 ]---

I'd like to flag this patch for possible stable inclusion.