if (tty->icanon && !L_EXTPROC(tty)) {
                        /* N.B. avoid overrun if nr == 0 */
+                       spin_lock_irqsave(&tty->read_lock, flags);
                        while (nr && tty->read_cnt) {
                                int eol;
 
                                eol = test_and_clear_bit(tty->read_tail,
                                                tty->read_flags);
                                c = tty->read_buf[tty->read_tail];
-                               spin_lock_irqsave(&tty->read_lock, flags);
                                tty->read_tail = ((tty->read_tail+1) &
                                                  (N_TTY_BUF_SIZE-1));
                                tty->read_cnt--;
                                        if (tty_put_user(tty, c, b++)) {
                                                retval = -EFAULT;
                                                b--;
+                                               spin_lock_irqsave(&tty->read_lock, flags);
                                                break;
                                        }
                                        nr--;
                                }
                                if (eol) {
                                        tty_audit_push(tty);
+                                       spin_lock_irqsave(&tty->read_lock, flags);
                                        break;
                                }
+                               spin_lock_irqsave(&tty->read_lock, flags);
                        }
+                       spin_unlock_irqrestore(&tty->read_lock, flags);
                        if (retval)
                                break;
                } else {