--- /dev/null
+From paulkf@microgate.com Wed Jul 26 12:11:54 2006
+Subject: tty serialize flush_to_ldisc
+From: Paul Fulghum <paulkf@microgate.com>
+To: Greg KH <greg@kroah.com>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>,
+ Chuck Ebbert <76306.1226@compuserve.com>,
+ linux-stable <stable@kernel.org>
+Date: Wed, 26 Jul 2006 14:10:29 -0500
+Message-Id: <1153941029.6903.5.camel@amdx2.microgate.com>
+
+From: Paul Fulghum <paulkf@microgate.com>
+
+Serialize processing of tty buffers in flush_to_ldisc
+to fix (very rare) corruption of tty buffer free list
+on SMP systems.
+
+Signed-off-by: Paul Fulghum <paulkf@microgate.com>
+Acked-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/char/tty_io.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- linux-2.6.17.7.orig/drivers/char/tty_io.c
++++ linux-2.6.17.7/drivers/char/tty_io.c
+@@ -2776,7 +2776,7 @@ static void flush_to_ldisc(void *private
+ struct tty_struct *tty = (struct tty_struct *) private_;
+ unsigned long flags;
+ struct tty_ldisc *disc;
+- struct tty_buffer *tbuf;
++ struct tty_buffer *tbuf, *head;
+ int count;
+ char *char_buf;
+ unsigned char *flag_buf;
+@@ -2793,7 +2793,9 @@ static void flush_to_ldisc(void *private
+ goto out;
+ }
+ spin_lock_irqsave(&tty->buf.lock, flags);
+- while((tbuf = tty->buf.head) != NULL) {
++ head = tty->buf.head;
++ tty->buf.head = NULL;
++ while((tbuf = head) != NULL) {
+ while ((count = tbuf->commit - tbuf->read) != 0) {
+ char_buf = tbuf->char_buf_ptr + tbuf->read;
+ flag_buf = tbuf->flag_buf_ptr + tbuf->read;
+@@ -2802,10 +2804,12 @@ static void flush_to_ldisc(void *private
+ disc->receive_buf(tty, char_buf, flag_buf, count);
+ spin_lock_irqsave(&tty->buf.lock, flags);
+ }
+- if (tbuf->active)
++ if (tbuf->active) {
++ tty->buf.head = head;
+ break;
+- tty->buf.head = tbuf->next;
+- if (tty->buf.head == NULL)
++ }
++ head = tbuf->next;
++ if (head == NULL)
+ tty->buf.tail = NULL;
+ tty_buffer_free(tty, tbuf);
+ }