aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_ldisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tty_ldisc.c')
-rw-r--r--drivers/char/tty_ldisc.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index feb55075819b..d914e77f7f01 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -34,6 +34,8 @@
34#include <linux/vt_kern.h> 34#include <linux/vt_kern.h>
35#include <linux/selection.h> 35#include <linux/selection.h>
36 36
37#include <linux/smp_lock.h> /* For the moment */
38
37#include <linux/kmod.h> 39#include <linux/kmod.h>
38#include <linux/nsproxy.h> 40#include <linux/nsproxy.h>
39 41
@@ -545,6 +547,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
545 if (IS_ERR(new_ldisc)) 547 if (IS_ERR(new_ldisc))
546 return PTR_ERR(new_ldisc); 548 return PTR_ERR(new_ldisc);
547 549
550 lock_kernel();
548 /* 551 /*
549 * We need to look at the tty locking here for pty/tty pairs 552 * We need to look at the tty locking here for pty/tty pairs
550 * when both sides try to change in parallel. 553 * when both sides try to change in parallel.
@@ -558,6 +561,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
558 */ 561 */
559 562
560 if (tty->ldisc->ops->num == ldisc) { 563 if (tty->ldisc->ops->num == ldisc) {
564 unlock_kernel();
561 tty_ldisc_put(new_ldisc); 565 tty_ldisc_put(new_ldisc);
562 return 0; 566 return 0;
563 } 567 }
@@ -569,6 +573,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
569 573
570 tty_wait_until_sent(tty, 0); 574 tty_wait_until_sent(tty, 0);
571 575
576 unlock_kernel();
572 mutex_lock(&tty->ldisc_mutex); 577 mutex_lock(&tty->ldisc_mutex);
573 578
574 /* 579 /*
@@ -582,6 +587,9 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
582 test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); 587 test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
583 mutex_lock(&tty->ldisc_mutex); 588 mutex_lock(&tty->ldisc_mutex);
584 } 589 }
590
591 lock_kernel();
592
585 set_bit(TTY_LDISC_CHANGING, &tty->flags); 593 set_bit(TTY_LDISC_CHANGING, &tty->flags);
586 594
587 /* 595 /*
@@ -592,6 +600,8 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
592 tty->receive_room = 0; 600 tty->receive_room = 0;
593 601
594 o_ldisc = tty->ldisc; 602 o_ldisc = tty->ldisc;
603
604 unlock_kernel();
595 /* 605 /*
596 * Make sure we don't change while someone holds a 606 * Make sure we don't change while someone holds a
597 * reference to the line discipline. The TTY_LDISC bit 607 * reference to the line discipline. The TTY_LDISC bit
@@ -617,12 +627,14 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
617 flush_scheduled_work(); 627 flush_scheduled_work();
618 628
619 mutex_lock(&tty->ldisc_mutex); 629 mutex_lock(&tty->ldisc_mutex);
630 lock_kernel();
620 if (test_bit(TTY_HUPPED, &tty->flags)) { 631 if (test_bit(TTY_HUPPED, &tty->flags)) {
621 /* We were raced by the hangup method. It will have stomped 632 /* We were raced by the hangup method. It will have stomped
622 the ldisc data and closed the ldisc down */ 633 the ldisc data and closed the ldisc down */
623 clear_bit(TTY_LDISC_CHANGING, &tty->flags); 634 clear_bit(TTY_LDISC_CHANGING, &tty->flags);
624 mutex_unlock(&tty->ldisc_mutex); 635 mutex_unlock(&tty->ldisc_mutex);
625 tty_ldisc_put(new_ldisc); 636 tty_ldisc_put(new_ldisc);
637 unlock_kernel();
626 return -EIO; 638 return -EIO;
627 } 639 }
628 640
@@ -664,6 +676,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
664 if (o_work) 676 if (o_work)
665 schedule_delayed_work(&o_tty->buf.work, 1); 677 schedule_delayed_work(&o_tty->buf.work, 1);
666 mutex_unlock(&tty->ldisc_mutex); 678 mutex_unlock(&tty->ldisc_mutex);
679 unlock_kernel();
667 return retval; 680 return retval;
668} 681}
669 682