Commit 487ad7ef authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

tty: fix BKL related leak and crash

Enabling the BKL to be lockdep tracked uncovered the following
upstream kernel bug in the tty code, which caused a BKL
reference leak:

  ================================================
  [ BUG: lock held when returning to user space! ]
  ------------------------------------------------
  dmesg/3121 is leaving the kernel with locks still held!
  1 lock held by dmesg/3121:
   #0:  (kernel_mutex){--..}, at: [<c02f34d9>] opost+0x24/0x194

this might explain some of the atomicity warnings and crashes
that -tip tree testing has been experiencing since the BKL
was converted back to a spinlock.
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8568dae2
...@@ -282,16 +282,20 @@ static int opost(unsigned char c, struct tty_struct *tty) ...@@ -282,16 +282,20 @@ static int opost(unsigned char c, struct tty_struct *tty)
if (O_ONLRET(tty)) if (O_ONLRET(tty))
tty->column = 0; tty->column = 0;
if (O_ONLCR(tty)) { if (O_ONLCR(tty)) {
if (space < 2) if (space < 2) {
unlock_kernel();
return -1; return -1;
}
tty_put_char(tty, '\r'); tty_put_char(tty, '\r');
tty->column = 0; tty->column = 0;
} }
tty->canon_column = tty->column; tty->canon_column = tty->column;
break; break;
case '\r': case '\r':
if (O_ONOCR(tty) && tty->column == 0) if (O_ONOCR(tty) && tty->column == 0) {
unlock_kernel();
return 0; return 0;
}
if (O_OCRNL(tty)) { if (O_OCRNL(tty)) {
c = '\n'; c = '\n';
if (O_ONLRET(tty)) if (O_ONLRET(tty))
...@@ -303,10 +307,13 @@ static int opost(unsigned char c, struct tty_struct *tty) ...@@ -303,10 +307,13 @@ static int opost(unsigned char c, struct tty_struct *tty)
case '\t': case '\t':
spaces = 8 - (tty->column & 7); spaces = 8 - (tty->column & 7);
if (O_TABDLY(tty) == XTABS) { if (O_TABDLY(tty) == XTABS) {
if (space < spaces) if (space < spaces) {
unlock_kernel();
return -1; return -1;
}
tty->column += spaces; tty->column += spaces;
tty->ops->write(tty, " ", spaces); tty->ops->write(tty, " ", spaces);
unlock_kernel();
return 0; return 0;
} }
tty->column += spaces; tty->column += spaces;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment