aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2012-07-14 10:31:27 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-16 15:58:12 -0400
commit6d31a88cb2e01d46c0cb74aa5da529e1f92ae3db (patch)
tree09ce3b070a845395f942b0ddeb8149514c0a7446 /drivers
parent467a3ca5cab64a16b5ec46ebb1895c84c280dcfe (diff)
tty: revert incorrectly applied lock patch
I sent GregKH this after the pre-requisites. He dropped the pre-requesites for good reason and unfortunately then applied this patch. Without this reverted you get random kernel memory corruption which will make bisecting anything between it and the properly applied patches a complete sod. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/tty/amiserial.c14
-rw-r--r--drivers/tty/cyclades.c2
-rw-r--r--drivers/tty/n_r3964.c10
-rw-r--r--drivers/tty/pty.c23
-rw-r--r--drivers/tty/serial/crisv10.c8
-rw-r--r--drivers/tty/synclink.c4
-rw-r--r--drivers/tty/synclink_gt.c4
-rw-r--r--drivers/tty/synclinkmp.c4
-rw-r--r--drivers/tty/tty_io.c67
-rw-r--r--drivers/tty/tty_ldisc.c67
-rw-r--r--drivers/tty/tty_mutex.c71
-rw-r--r--drivers/tty/tty_port.c6
12 files changed, 108 insertions, 172 deletions
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 35819e312624..6cc4358f68c1 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1033,7 +1033,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
1033 if (!retinfo) 1033 if (!retinfo)
1034 return -EFAULT; 1034 return -EFAULT;
1035 memset(&tmp, 0, sizeof(tmp)); 1035 memset(&tmp, 0, sizeof(tmp));
1036 tty_lock(tty); 1036 tty_lock();
1037 tmp.line = tty->index; 1037 tmp.line = tty->index;
1038 tmp.port = state->port; 1038 tmp.port = state->port;
1039 tmp.flags = state->tport.flags; 1039 tmp.flags = state->tport.flags;
@@ -1042,7 +1042,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
1042 tmp.close_delay = state->tport.close_delay; 1042 tmp.close_delay = state->tport.close_delay;
1043 tmp.closing_wait = state->tport.closing_wait; 1043 tmp.closing_wait = state->tport.closing_wait;
1044 tmp.custom_divisor = state->custom_divisor; 1044 tmp.custom_divisor = state->custom_divisor;
1045 tty_unlock(tty); 1045 tty_unlock();
1046 if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) 1046 if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
1047 return -EFAULT; 1047 return -EFAULT;
1048 return 0; 1048 return 0;
@@ -1059,12 +1059,12 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
1059 if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) 1059 if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
1060 return -EFAULT; 1060 return -EFAULT;
1061 1061
1062 tty_lock(tty); 1062 tty_lock();
1063 change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) || 1063 change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) ||
1064 new_serial.custom_divisor != state->custom_divisor; 1064 new_serial.custom_divisor != state->custom_divisor;
1065 if (new_serial.irq || new_serial.port != state->port || 1065 if (new_serial.irq || new_serial.port != state->port ||
1066 new_serial.xmit_fifo_size != state->xmit_fifo_size) { 1066 new_serial.xmit_fifo_size != state->xmit_fifo_size) {
1067 tty_unlock(tty); 1067 tty_unlock();
1068 return -EINVAL; 1068 return -EINVAL;
1069 } 1069 }
1070 1070
@@ -1074,7 +1074,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
1074 (new_serial.xmit_fifo_size != state->xmit_fifo_size) || 1074 (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
1075 ((new_serial.flags & ~ASYNC_USR_MASK) != 1075 ((new_serial.flags & ~ASYNC_USR_MASK) !=
1076 (port->flags & ~ASYNC_USR_MASK))) { 1076 (port->flags & ~ASYNC_USR_MASK))) {
1077 tty_unlock(tty); 1077 tty_unlock();
1078 return -EPERM; 1078 return -EPERM;
1079 } 1079 }
1080 port->flags = ((port->flags & ~ASYNC_USR_MASK) | 1080 port->flags = ((port->flags & ~ASYNC_USR_MASK) |
@@ -1084,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
1084 } 1084 }
1085 1085
1086 if (new_serial.baud_base < 9600) { 1086 if (new_serial.baud_base < 9600) {
1087 tty_unlock(tty); 1087 tty_unlock();
1088 return -EINVAL; 1088 return -EINVAL;
1089 } 1089 }
1090 1090
@@ -1116,7 +1116,7 @@ check_and_exit:
1116 } 1116 }
1117 } else 1117 } else
1118 retval = startup(tty, state); 1118 retval = startup(tty, state);
1119 tty_unlock(tty); 1119 tty_unlock();
1120 return retval; 1120 return retval;
1121} 1121}
1122 1122
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c
index 69e9ca2dd4b3..cff546839db9 100644
--- a/drivers/tty/cyclades.c
+++ b/drivers/tty/cyclades.c
@@ -1599,7 +1599,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
1599 * If the port is the middle of closing, bail out now 1599 * If the port is the middle of closing, bail out now
1600 */ 1600 */
1601 if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { 1601 if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
1602 wait_event_interruptible_tty(tty, info->port.close_wait, 1602 wait_event_interruptible_tty(info->port.close_wait,
1603 !(info->port.flags & ASYNC_CLOSING)); 1603 !(info->port.flags & ASYNC_CLOSING));
1604 return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; 1604 return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
1605 } 1605 }
diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c
index 1e6405070ce6..5c6c31459a2f 100644
--- a/drivers/tty/n_r3964.c
+++ b/drivers/tty/n_r3964.c
@@ -1065,7 +1065,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1065 1065
1066 TRACE_L("read()"); 1066 TRACE_L("read()");
1067 1067
1068 tty_lock(tty); 1068 tty_lock();
1069 1069
1070 pClient = findClient(pInfo, task_pid(current)); 1070 pClient = findClient(pInfo, task_pid(current));
1071 if (pClient) { 1071 if (pClient) {
@@ -1077,7 +1077,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1077 goto unlock; 1077 goto unlock;
1078 } 1078 }
1079 /* block until there is a message: */ 1079 /* block until there is a message: */
1080 wait_event_interruptible_tty(tty, pInfo->read_wait, 1080 wait_event_interruptible_tty(pInfo->read_wait,
1081 (pMsg = remove_msg(pInfo, pClient))); 1081 (pMsg = remove_msg(pInfo, pClient)));
1082 } 1082 }
1083 1083
@@ -1107,7 +1107,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1107 } 1107 }
1108 ret = -EPERM; 1108 ret = -EPERM;
1109unlock: 1109unlock:
1110 tty_unlock(tty); 1110 tty_unlock();
1111 return ret; 1111 return ret;
1112} 1112}
1113 1113
@@ -1156,7 +1156,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
1156 pHeader->locks = 0; 1156 pHeader->locks = 0;
1157 pHeader->owner = NULL; 1157 pHeader->owner = NULL;
1158 1158
1159 tty_lock(tty); 1159 tty_lock();
1160 1160
1161 pClient = findClient(pInfo, task_pid(current)); 1161 pClient = findClient(pInfo, task_pid(current));
1162 if (pClient) { 1162 if (pClient) {
@@ -1175,7 +1175,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
1175 add_tx_queue(pInfo, pHeader); 1175 add_tx_queue(pInfo, pHeader);
1176 trigger_transmit(pInfo); 1176 trigger_transmit(pInfo);
1177 1177
1178 tty_unlock(tty); 1178 tty_unlock();
1179 1179
1180 return 0; 1180 return 0;
1181} 1181}
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index a0ca0830cbcf..b50fc1c01415 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -47,7 +47,6 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
47 wake_up_interruptible(&tty->read_wait); 47 wake_up_interruptible(&tty->read_wait);
48 wake_up_interruptible(&tty->write_wait); 48 wake_up_interruptible(&tty->write_wait);
49 tty->packet = 0; 49 tty->packet = 0;
50 /* Review - krefs on tty_link ?? */
51 if (!tty->link) 50 if (!tty->link)
52 return; 51 return;
53 tty->link->packet = 0; 52 tty->link->packet = 0;
@@ -63,9 +62,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
63 mutex_unlock(&devpts_mutex); 62 mutex_unlock(&devpts_mutex);
64 } 63 }
65#endif 64#endif
66 tty_unlock(tty); 65 tty_unlock();
67 tty_vhangup(tty->link); 66 tty_vhangup(tty->link);
68 tty_lock(tty); 67 tty_lock();
69 } 68 }
70} 69}
71 70
@@ -616,26 +615,26 @@ static int ptmx_open(struct inode *inode, struct file *filp)
616 return retval; 615 return retval;
617 616
618 /* find a device that is not in use. */ 617 /* find a device that is not in use. */
619 mutex_lock(&devpts_mutex); 618 tty_lock();
620 index = devpts_new_index(inode); 619 index = devpts_new_index(inode);
621 mutex_unlock(&devpts_mutex); 620 tty_unlock();
622 if (index < 0) { 621 if (index < 0) {
623 retval = index; 622 retval = index;
624 goto err_file; 623 goto err_file;
625 } 624 }
626 625
627 mutex_lock(&tty_mutex); 626 mutex_lock(&tty_mutex);
627 mutex_lock(&devpts_mutex);
628 tty = tty_init_dev(ptm_driver, index); 628 tty = tty_init_dev(ptm_driver, index);
629 mutex_unlock(&devpts_mutex);
630 tty_lock();
631 mutex_unlock(&tty_mutex);
629 632
630 if (IS_ERR(tty)) { 633 if (IS_ERR(tty)) {
631 retval = PTR_ERR(tty); 634 retval = PTR_ERR(tty);
632 goto out; 635 goto out;
633 } 636 }
634 637
635 /* The tty returned here is locked so we can safely
636 drop the mutex */
637 mutex_unlock(&tty_mutex);
638
639 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ 638 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
640 639
641 tty_add_file(tty, filp); 640 tty_add_file(tty, filp);
@@ -648,15 +647,15 @@ static int ptmx_open(struct inode *inode, struct file *filp)
648 if (retval) 647 if (retval)
649 goto err_release; 648 goto err_release;
650 649
651 tty_unlock(tty); 650 tty_unlock();
652 return 0; 651 return 0;
653err_release: 652err_release:
654 tty_unlock(tty); 653 tty_unlock();
655 tty_release(inode, filp); 654 tty_release(inode, filp);
656 return retval; 655 return retval;
657out: 656out:
658 mutex_unlock(&tty_mutex);
659 devpts_kill_index(inode, index); 657 devpts_kill_index(inode, index);
658 tty_unlock();
660err_file: 659err_file:
661 tty_free_file(filp); 660 tty_free_file(filp);
662 return retval; 661 return retval;
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c
index 7264d4d26717..80b6b1b1f725 100644
--- a/drivers/tty/serial/crisv10.c
+++ b/drivers/tty/serial/crisv10.c
@@ -3976,7 +3976,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
3976 */ 3976 */
3977 if (tty_hung_up_p(filp) || 3977 if (tty_hung_up_p(filp) ||
3978 (info->flags & ASYNC_CLOSING)) { 3978 (info->flags & ASYNC_CLOSING)) {
3979 wait_event_interruptible_tty(tty, info->close_wait, 3979 wait_event_interruptible_tty(info->close_wait,
3980 !(info->flags & ASYNC_CLOSING)); 3980 !(info->flags & ASYNC_CLOSING));
3981#ifdef SERIAL_DO_RESTART 3981#ifdef SERIAL_DO_RESTART
3982 if (info->flags & ASYNC_HUP_NOTIFY) 3982 if (info->flags & ASYNC_HUP_NOTIFY)
@@ -4052,9 +4052,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
4052 printk("block_til_ready blocking: ttyS%d, count = %d\n", 4052 printk("block_til_ready blocking: ttyS%d, count = %d\n",
4053 info->line, info->count); 4053 info->line, info->count);
4054#endif 4054#endif
4055 tty_unlock(tty); 4055 tty_unlock();
4056 schedule(); 4056 schedule();
4057 tty_lock(tty); 4057 tty_lock();
4058 } 4058 }
4059 set_current_state(TASK_RUNNING); 4059 set_current_state(TASK_RUNNING);
4060 remove_wait_queue(&info->open_wait, &wait); 4060 remove_wait_queue(&info->open_wait, &wait);
@@ -4115,7 +4115,7 @@ rs_open(struct tty_struct *tty, struct file * filp)
4115 */ 4115 */
4116 if (tty_hung_up_p(filp) || 4116 if (tty_hung_up_p(filp) ||
4117 (info->flags & ASYNC_CLOSING)) { 4117 (info->flags & ASYNC_CLOSING)) {
4118 wait_event_interruptible_tty(tty, info->close_wait, 4118 wait_event_interruptible_tty(info->close_wait,
4119 !(info->flags & ASYNC_CLOSING)); 4119 !(info->flags & ASYNC_CLOSING));
4120#ifdef SERIAL_DO_RESTART 4120#ifdef SERIAL_DO_RESTART
4121 return ((info->flags & ASYNC_HUP_NOTIFY) ? 4121 return ((info->flags & ASYNC_HUP_NOTIFY) ?
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c
index 5ed0daae6564..593d40ad0a6b 100644
--- a/drivers/tty/synclink.c
+++ b/drivers/tty/synclink.c
@@ -3338,9 +3338,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
3338 printk("%s(%d):block_til_ready blocking on %s count=%d\n", 3338 printk("%s(%d):block_til_ready blocking on %s count=%d\n",
3339 __FILE__,__LINE__, tty->driver->name, port->count ); 3339 __FILE__,__LINE__, tty->driver->name, port->count );
3340 3340
3341 tty_unlock(tty); 3341 tty_unlock();
3342 schedule(); 3342 schedule();
3343 tty_lock(tty); 3343 tty_lock();
3344 } 3344 }
3345 3345
3346 set_current_state(TASK_RUNNING); 3346 set_current_state(TASK_RUNNING);
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index 45b43f11ca39..aa1debf97cc7 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -3336,9 +3336,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3336 } 3336 }
3337 3337
3338 DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); 3338 DBGINFO(("%s block_til_ready wait\n", tty->driver->name));
3339 tty_unlock(tty); 3339 tty_unlock();
3340 schedule(); 3340 schedule();
3341 tty_lock(tty); 3341 tty_lock();
3342 } 3342 }
3343 3343
3344 set_current_state(TASK_RUNNING); 3344 set_current_state(TASK_RUNNING);
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c
index 4a1e4f07765b..a3dddc12d2fe 100644
--- a/drivers/tty/synclinkmp.c
+++ b/drivers/tty/synclinkmp.c
@@ -3357,9 +3357,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3357 printk("%s(%d):%s block_til_ready() count=%d\n", 3357 printk("%s(%d):%s block_til_ready() count=%d\n",
3358 __FILE__,__LINE__, tty->driver->name, port->count ); 3358 __FILE__,__LINE__, tty->driver->name, port->count );
3359 3359
3360 tty_unlock(tty); 3360 tty_unlock();
3361 schedule(); 3361 schedule();
3362 tty_lock(tty); 3362 tty_lock();
3363 } 3363 }
3364 3364
3365 set_current_state(TASK_RUNNING); 3365 set_current_state(TASK_RUNNING);
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index ca7c25d9f6d5..ac96f74573d0 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -185,7 +185,6 @@ void free_tty_struct(struct tty_struct *tty)
185 put_device(tty->dev); 185 put_device(tty->dev);
186 kfree(tty->write_buf); 186 kfree(tty->write_buf);
187 tty_buffer_free_all(tty); 187 tty_buffer_free_all(tty);
188 tty->magic = 0xDEADDEAD;
189 kfree(tty); 188 kfree(tty);
190} 189}
191 190
@@ -574,7 +573,7 @@ void __tty_hangup(struct tty_struct *tty)
574 } 573 }
575 spin_unlock(&redirect_lock); 574 spin_unlock(&redirect_lock);
576 575
577 tty_lock(tty); 576 tty_lock();
578 577
579 /* some functions below drop BTM, so we need this bit */ 578 /* some functions below drop BTM, so we need this bit */
580 set_bit(TTY_HUPPING, &tty->flags); 579 set_bit(TTY_HUPPING, &tty->flags);
@@ -667,7 +666,7 @@ void __tty_hangup(struct tty_struct *tty)
667 clear_bit(TTY_HUPPING, &tty->flags); 666 clear_bit(TTY_HUPPING, &tty->flags);
668 tty_ldisc_enable(tty); 667 tty_ldisc_enable(tty);
669 668
670 tty_unlock(tty); 669 tty_unlock();
671 670
672 if (f) 671 if (f)
673 fput(f); 672 fput(f);
@@ -1104,12 +1103,12 @@ void tty_write_message(struct tty_struct *tty, char *msg)
1104{ 1103{
1105 if (tty) { 1104 if (tty) {
1106 mutex_lock(&tty->atomic_write_lock); 1105 mutex_lock(&tty->atomic_write_lock);
1107 tty_lock(tty); 1106 tty_lock();
1108 if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { 1107 if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
1109 tty_unlock(tty); 1108 tty_unlock();
1110 tty->ops->write(tty, msg, strlen(msg)); 1109 tty->ops->write(tty, msg, strlen(msg));
1111 } else 1110 } else
1112 tty_unlock(tty); 1111 tty_unlock();
1113 tty_write_unlock(tty); 1112 tty_write_unlock(tty);
1114 } 1113 }
1115 return; 1114 return;
@@ -1404,7 +1403,6 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
1404 } 1403 }
1405 initialize_tty_struct(tty, driver, idx); 1404 initialize_tty_struct(tty, driver, idx);
1406 1405
1407 tty_lock(tty);
1408 retval = tty_driver_install_tty(driver, tty); 1406 retval = tty_driver_install_tty(driver, tty);
1409 if (retval < 0) 1407 if (retval < 0)
1410 goto err_deinit_tty; 1408 goto err_deinit_tty;
@@ -1420,11 +1418,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
1420 retval = tty_ldisc_setup(tty, tty->link); 1418 retval = tty_ldisc_setup(tty, tty->link);
1421 if (retval) 1419 if (retval)
1422 goto err_release_tty; 1420 goto err_release_tty;
1423 /* Return the tty locked so that it cannot vanish under the caller */
1424 return tty; 1421 return tty;
1425 1422
1426err_deinit_tty: 1423err_deinit_tty:
1427 tty_unlock(tty);
1428 deinitialize_tty_struct(tty); 1424 deinitialize_tty_struct(tty);
1429 free_tty_struct(tty); 1425 free_tty_struct(tty);
1430err_module_put: 1426err_module_put:
@@ -1433,7 +1429,6 @@ err_module_put:
1433 1429
1434 /* call the tty release_tty routine to clean out this slot */ 1430 /* call the tty release_tty routine to clean out this slot */
1435err_release_tty: 1431err_release_tty:
1436 tty_unlock(tty);
1437 printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " 1432 printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, "
1438 "clearing slot %d\n", idx); 1433 "clearing slot %d\n", idx);
1439 release_tty(tty, idx); 1434 release_tty(tty, idx);
@@ -1636,7 +1631,7 @@ int tty_release(struct inode *inode, struct file *filp)
1636 if (tty_paranoia_check(tty, inode, __func__)) 1631 if (tty_paranoia_check(tty, inode, __func__))
1637 return 0; 1632 return 0;
1638 1633
1639 tty_lock(tty); 1634 tty_lock();
1640 check_tty_count(tty, __func__); 1635 check_tty_count(tty, __func__);
1641 1636
1642 __tty_fasync(-1, filp, 0); 1637 __tty_fasync(-1, filp, 0);
@@ -1645,11 +1640,10 @@ int tty_release(struct inode *inode, struct file *filp)
1645 pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && 1640 pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1646 tty->driver->subtype == PTY_TYPE_MASTER); 1641 tty->driver->subtype == PTY_TYPE_MASTER);
1647 devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; 1642 devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0;
1648 /* Review: parallel close */
1649 o_tty = tty->link; 1643 o_tty = tty->link;
1650 1644
1651 if (tty_release_checks(tty, o_tty, idx)) { 1645 if (tty_release_checks(tty, o_tty, idx)) {
1652 tty_unlock(tty); 1646 tty_unlock();
1653 return 0; 1647 return 0;
1654 } 1648 }
1655 1649
@@ -1661,7 +1655,7 @@ int tty_release(struct inode *inode, struct file *filp)
1661 if (tty->ops->close) 1655 if (tty->ops->close)
1662 tty->ops->close(tty, filp); 1656 tty->ops->close(tty, filp);
1663 1657
1664 tty_unlock(tty); 1658 tty_unlock();
1665 /* 1659 /*
1666 * Sanity check: if tty->count is going to zero, there shouldn't be 1660 * Sanity check: if tty->count is going to zero, there shouldn't be
1667 * any waiters on tty->read_wait or tty->write_wait. We test the 1661 * any waiters on tty->read_wait or tty->write_wait. We test the
@@ -1684,7 +1678,7 @@ int tty_release(struct inode *inode, struct file *filp)
1684 opens on /dev/tty */ 1678 opens on /dev/tty */
1685 1679
1686 mutex_lock(&tty_mutex); 1680 mutex_lock(&tty_mutex);
1687 tty_lock_pair(tty, o_tty); 1681 tty_lock();
1688 tty_closing = tty->count <= 1; 1682 tty_closing = tty->count <= 1;
1689 o_tty_closing = o_tty && 1683 o_tty_closing = o_tty &&
1690 (o_tty->count <= (pty_master ? 1 : 0)); 1684 (o_tty->count <= (pty_master ? 1 : 0));
@@ -1715,7 +1709,7 @@ int tty_release(struct inode *inode, struct file *filp)
1715 1709
1716 printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", 1710 printk(KERN_WARNING "%s: %s: read/write wait queue active!\n",
1717 __func__, tty_name(tty, buf)); 1711 __func__, tty_name(tty, buf));
1718 tty_unlock_pair(tty, o_tty); 1712 tty_unlock();
1719 mutex_unlock(&tty_mutex); 1713 mutex_unlock(&tty_mutex);
1720 schedule(); 1714 schedule();
1721 } 1715 }
@@ -1778,7 +1772,7 @@ int tty_release(struct inode *inode, struct file *filp)
1778 1772
1779 /* check whether both sides are closing ... */ 1773 /* check whether both sides are closing ... */
1780 if (!tty_closing || (o_tty && !o_tty_closing)) { 1774 if (!tty_closing || (o_tty && !o_tty_closing)) {
1781 tty_unlock_pair(tty, o_tty); 1775 tty_unlock();
1782 return 0; 1776 return 0;
1783 } 1777 }
1784 1778
@@ -1791,16 +1785,14 @@ int tty_release(struct inode *inode, struct file *filp)
1791 tty_ldisc_release(tty, o_tty); 1785 tty_ldisc_release(tty, o_tty);
1792 /* 1786 /*
1793 * The release_tty function takes care of the details of clearing 1787 * The release_tty function takes care of the details of clearing
1794 * the slots and preserving the termios structure. The tty_unlock_pair 1788 * the slots and preserving the termios structure.
1795 * should be safe as we keep a kref while the tty is locked (so the
1796 * unlock never unlocks a freed tty).
1797 */ 1789 */
1798 release_tty(tty, idx); 1790 release_tty(tty, idx);
1799 tty_unlock_pair(tty, o_tty);
1800 1791
1801 /* Make this pty number available for reallocation */ 1792 /* Make this pty number available for reallocation */
1802 if (devpts) 1793 if (devpts)
1803 devpts_kill_index(inode, idx); 1794 devpts_kill_index(inode, idx);
1795 tty_unlock();
1804 return 0; 1796 return 0;
1805} 1797}
1806 1798
@@ -1904,9 +1896,6 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
1904 * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. 1896 * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev.
1905 * tty->count should protect the rest. 1897 * tty->count should protect the rest.
1906 * ->siglock protects ->signal/->sighand 1898 * ->siglock protects ->signal/->sighand
1907 *
1908 * Note: the tty_unlock/lock cases without a ref are only safe due to
1909 * tty_mutex
1910 */ 1899 */
1911 1900
1912static int tty_open(struct inode *inode, struct file *filp) 1901static int tty_open(struct inode *inode, struct file *filp)
@@ -1930,7 +1919,8 @@ retry_open:
1930 retval = 0; 1919 retval = 0;
1931 1920
1932 mutex_lock(&tty_mutex); 1921 mutex_lock(&tty_mutex);
1933 /* This is protected by the tty_mutex */ 1922 tty_lock();
1923
1934 tty = tty_open_current_tty(device, filp); 1924 tty = tty_open_current_tty(device, filp);
1935 if (IS_ERR(tty)) { 1925 if (IS_ERR(tty)) {
1936 retval = PTR_ERR(tty); 1926 retval = PTR_ERR(tty);
@@ -1951,19 +1941,17 @@ retry_open:
1951 } 1941 }
1952 1942
1953 if (tty) { 1943 if (tty) {
1954 tty_lock(tty);
1955 retval = tty_reopen(tty); 1944 retval = tty_reopen(tty);
1956 if (retval < 0) { 1945 if (retval)
1957 tty_unlock(tty);
1958 tty = ERR_PTR(retval); 1946 tty = ERR_PTR(retval);
1959 } 1947 } else
1960 } else /* Returns with the tty_lock held for now */
1961 tty = tty_init_dev(driver, index); 1948 tty = tty_init_dev(driver, index);
1962 1949
1963 mutex_unlock(&tty_mutex); 1950 mutex_unlock(&tty_mutex);
1964 if (driver) 1951 if (driver)
1965 tty_driver_kref_put(driver); 1952 tty_driver_kref_put(driver);
1966 if (IS_ERR(tty)) { 1953 if (IS_ERR(tty)) {
1954 tty_unlock();
1967 retval = PTR_ERR(tty); 1955 retval = PTR_ERR(tty);
1968 goto err_file; 1956 goto err_file;
1969 } 1957 }
@@ -1992,7 +1980,7 @@ retry_open:
1992 printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, 1980 printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__,
1993 retval, tty->name); 1981 retval, tty->name);
1994#endif 1982#endif
1995 tty_unlock(tty); /* need to call tty_release without BTM */ 1983 tty_unlock(); /* need to call tty_release without BTM */
1996 tty_release(inode, filp); 1984 tty_release(inode, filp);
1997 if (retval != -ERESTARTSYS) 1985 if (retval != -ERESTARTSYS)
1998 return retval; 1986 return retval;
@@ -2004,15 +1992,17 @@ retry_open:
2004 /* 1992 /*
2005 * Need to reset f_op in case a hangup happened. 1993 * Need to reset f_op in case a hangup happened.
2006 */ 1994 */
1995 tty_lock();
2007 if (filp->f_op == &hung_up_tty_fops) 1996 if (filp->f_op == &hung_up_tty_fops)
2008 filp->f_op = &tty_fops; 1997 filp->f_op = &tty_fops;
1998 tty_unlock();
2009 goto retry_open; 1999 goto retry_open;
2010 } 2000 }
2011 tty_unlock(tty); 2001 tty_unlock();
2012 2002
2013 2003
2014 mutex_lock(&tty_mutex); 2004 mutex_lock(&tty_mutex);
2015 tty_lock(tty); 2005 tty_lock();
2016 spin_lock_irq(&current->sighand->siglock); 2006 spin_lock_irq(&current->sighand->siglock);
2017 if (!noctty && 2007 if (!noctty &&
2018 current->signal->leader && 2008 current->signal->leader &&
@@ -2020,10 +2010,11 @@ retry_open:
2020 tty->session == NULL) 2010 tty->session == NULL)
2021 __proc_set_tty(current, tty); 2011 __proc_set_tty(current, tty);
2022 spin_unlock_irq(&current->sighand->siglock); 2012 spin_unlock_irq(&current->sighand->siglock);
2023 tty_unlock(tty); 2013 tty_unlock();
2024 mutex_unlock(&tty_mutex); 2014 mutex_unlock(&tty_mutex);
2025 return 0; 2015 return 0;
2026err_unlock: 2016err_unlock:
2017 tty_unlock();
2027 mutex_unlock(&tty_mutex); 2018 mutex_unlock(&tty_mutex);
2028 /* after locks to avoid deadlock */ 2019 /* after locks to avoid deadlock */
2029 if (!IS_ERR_OR_NULL(driver)) 2020 if (!IS_ERR_OR_NULL(driver))
@@ -2106,13 +2097,10 @@ out:
2106 2097
2107static int tty_fasync(int fd, struct file *filp, int on) 2098static int tty_fasync(int fd, struct file *filp, int on)
2108{ 2099{
2109 struct tty_struct *tty = file_tty(filp);
2110 int retval; 2100 int retval;
2111 2101 tty_lock();
2112 tty_lock(tty);
2113 retval = __tty_fasync(fd, filp, on); 2102 retval = __tty_fasync(fd, filp, on);
2114 tty_unlock(tty); 2103 tty_unlock();
2115
2116 return retval; 2104 return retval;
2117} 2105}
2118 2106
@@ -2949,7 +2937,6 @@ void initialize_tty_struct(struct tty_struct *tty,
2949 tty->pgrp = NULL; 2937 tty->pgrp = NULL;
2950 tty->overrun_time = jiffies; 2938 tty->overrun_time = jiffies;
2951 tty_buffer_init(tty); 2939 tty_buffer_init(tty);
2952 mutex_init(&tty->legacy_mutex);
2953 mutex_init(&tty->termios_mutex); 2940 mutex_init(&tty->termios_mutex);
2954 mutex_init(&tty->ldisc_mutex); 2941 mutex_init(&tty->ldisc_mutex);
2955 init_waitqueue_head(&tty->write_wait); 2942 init_waitqueue_head(&tty->write_wait);
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 847f7ed7a3ed..6f99c9959f0c 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -568,7 +568,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
568 if (IS_ERR(new_ldisc)) 568 if (IS_ERR(new_ldisc))
569 return PTR_ERR(new_ldisc); 569 return PTR_ERR(new_ldisc);
570 570
571 tty_lock(tty); 571 tty_lock();
572 /* 572 /*
573 * We need to look at the tty locking here for pty/tty pairs 573 * We need to look at the tty locking here for pty/tty pairs
574 * when both sides try to change in parallel. 574 * when both sides try to change in parallel.
@@ -582,12 +582,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
582 */ 582 */
583 583
584 if (tty->ldisc->ops->num == ldisc) { 584 if (tty->ldisc->ops->num == ldisc) {
585 tty_unlock(tty); 585 tty_unlock();
586 tty_ldisc_put(new_ldisc); 586 tty_ldisc_put(new_ldisc);
587 return 0; 587 return 0;
588 } 588 }
589 589
590 tty_unlock(tty); 590 tty_unlock();
591 /* 591 /*
592 * Problem: What do we do if this blocks ? 592 * Problem: What do we do if this blocks ?
593 * We could deadlock here 593 * We could deadlock here
@@ -595,7 +595,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
595 595
596 tty_wait_until_sent(tty, 0); 596 tty_wait_until_sent(tty, 0);
597 597
598 tty_lock(tty); 598 tty_lock();
599 mutex_lock(&tty->ldisc_mutex); 599 mutex_lock(&tty->ldisc_mutex);
600 600
601 /* 601 /*
@@ -605,10 +605,10 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
605 605
606 while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { 606 while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) {
607 mutex_unlock(&tty->ldisc_mutex); 607 mutex_unlock(&tty->ldisc_mutex);
608 tty_unlock(tty); 608 tty_unlock();
609 wait_event(tty_ldisc_wait, 609 wait_event(tty_ldisc_wait,
610 test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); 610 test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
611 tty_lock(tty); 611 tty_lock();
612 mutex_lock(&tty->ldisc_mutex); 612 mutex_lock(&tty->ldisc_mutex);
613 } 613 }
614 614
@@ -623,7 +623,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
623 623
624 o_ldisc = tty->ldisc; 624 o_ldisc = tty->ldisc;
625 625
626 tty_unlock(tty); 626 tty_unlock();
627 /* 627 /*
628 * Make sure we don't change while someone holds a 628 * Make sure we don't change while someone holds a
629 * reference to the line discipline. The TTY_LDISC bit 629 * reference to the line discipline. The TTY_LDISC bit
@@ -650,7 +650,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
650 650
651 retval = tty_ldisc_wait_idle(tty, 5 * HZ); 651 retval = tty_ldisc_wait_idle(tty, 5 * HZ);
652 652
653 tty_lock(tty); 653 tty_lock();
654 mutex_lock(&tty->ldisc_mutex); 654 mutex_lock(&tty->ldisc_mutex);
655 655
656 /* handle wait idle failure locked */ 656 /* handle wait idle failure locked */
@@ -665,7 +665,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
665 clear_bit(TTY_LDISC_CHANGING, &tty->flags); 665 clear_bit(TTY_LDISC_CHANGING, &tty->flags);
666 mutex_unlock(&tty->ldisc_mutex); 666 mutex_unlock(&tty->ldisc_mutex);
667 tty_ldisc_put(new_ldisc); 667 tty_ldisc_put(new_ldisc);
668 tty_unlock(tty); 668 tty_unlock();
669 return -EIO; 669 return -EIO;
670 } 670 }
671 671
@@ -708,7 +708,7 @@ enable:
708 if (o_work) 708 if (o_work)
709 schedule_work(&o_tty->buf.work); 709 schedule_work(&o_tty->buf.work);
710 mutex_unlock(&tty->ldisc_mutex); 710 mutex_unlock(&tty->ldisc_mutex);
711 tty_unlock(tty); 711 tty_unlock();
712 return retval; 712 return retval;
713} 713}
714 714
@@ -816,11 +816,11 @@ void tty_ldisc_hangup(struct tty_struct *tty)
816 * need to wait for another function taking the BTM 816 * need to wait for another function taking the BTM
817 */ 817 */
818 clear_bit(TTY_LDISC, &tty->flags); 818 clear_bit(TTY_LDISC, &tty->flags);
819 tty_unlock(tty); 819 tty_unlock();
820 cancel_work_sync(&tty->buf.work); 820 cancel_work_sync(&tty->buf.work);
821 mutex_unlock(&tty->ldisc_mutex); 821 mutex_unlock(&tty->ldisc_mutex);
822retry: 822retry:
823 tty_lock(tty); 823 tty_lock();
824 mutex_lock(&tty->ldisc_mutex); 824 mutex_lock(&tty->ldisc_mutex);
825 825
826 /* At this point we have a closed ldisc and we want to 826 /* At this point we have a closed ldisc and we want to
@@ -831,7 +831,7 @@ retry:
831 if (atomic_read(&tty->ldisc->users) != 1) { 831 if (atomic_read(&tty->ldisc->users) != 1) {
832 char cur_n[TASK_COMM_LEN], tty_n[64]; 832 char cur_n[TASK_COMM_LEN], tty_n[64];
833 long timeout = 3 * HZ; 833 long timeout = 3 * HZ;
834 tty_unlock(tty); 834 tty_unlock();
835 835
836 while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { 836 while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
837 timeout = MAX_SCHEDULE_TIMEOUT; 837 timeout = MAX_SCHEDULE_TIMEOUT;
@@ -894,23 +894,6 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
894 tty_ldisc_enable(tty); 894 tty_ldisc_enable(tty);
895 return 0; 895 return 0;
896} 896}
897
898static void tty_ldisc_kill(struct tty_struct *tty)
899{
900 mutex_lock(&tty->ldisc_mutex);
901 /*
902 * Now kill off the ldisc
903 */
904 tty_ldisc_close(tty, tty->ldisc);
905 tty_ldisc_put(tty->ldisc);
906 /* Force an oops if we mess this up */
907 tty->ldisc = NULL;
908
909 /* Ensure the next open requests the N_TTY ldisc */
910 tty_set_termios_ldisc(tty, N_TTY);
911 mutex_unlock(&tty->ldisc_mutex);
912}
913
914/** 897/**
915 * tty_ldisc_release - release line discipline 898 * tty_ldisc_release - release line discipline
916 * @tty: tty being shut down 899 * @tty: tty being shut down
@@ -929,19 +912,27 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
929 * race with the set_ldisc code path. 912 * race with the set_ldisc code path.
930 */ 913 */
931 914
932 tty_unlock_pair(tty, o_tty); 915 tty_unlock();
933 tty_ldisc_halt(tty); 916 tty_ldisc_halt(tty);
934 tty_ldisc_flush_works(tty); 917 tty_ldisc_flush_works(tty);
935 if (o_tty) { 918 tty_lock();
936 tty_ldisc_halt(o_tty);
937 tty_ldisc_flush_works(o_tty);
938 }
939 tty_lock_pair(tty, o_tty);
940 919
920 mutex_lock(&tty->ldisc_mutex);
921 /*
922 * Now kill off the ldisc
923 */
924 tty_ldisc_close(tty, tty->ldisc);
925 tty_ldisc_put(tty->ldisc);
926 /* Force an oops if we mess this up */
927 tty->ldisc = NULL;
928
929 /* Ensure the next open requests the N_TTY ldisc */
930 tty_set_termios_ldisc(tty, N_TTY);
931 mutex_unlock(&tty->ldisc_mutex);
941 932
942 tty_ldisc_kill(tty); 933 /* This will need doing differently if we need to lock */
943 if (o_tty) 934 if (o_tty)
944 tty_ldisc_kill(o_tty); 935 tty_ldisc_release(o_tty, NULL);
945 936
946 /* And the memory resources remaining (buffers, termios) will be 937 /* And the memory resources remaining (buffers, termios) will be
947 disposed of when the kref hits zero */ 938 disposed of when the kref hits zero */
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c
index 67feac9e6ebb..9ff986c32a21 100644
--- a/drivers/tty/tty_mutex.c
+++ b/drivers/tty/tty_mutex.c
@@ -4,70 +4,29 @@
4#include <linux/semaphore.h> 4#include <linux/semaphore.h>
5#include <linux/sched.h> 5#include <linux/sched.h>
6 6
7/* Legacy tty mutex glue */ 7/*
8 8 * The 'big tty mutex'
9enum { 9 *
10 TTY_MUTEX_NORMAL, 10 * This mutex is taken and released by tty_lock() and tty_unlock(),
11 TTY_MUTEX_NESTED, 11 * replacing the older big kernel lock.
12}; 12 * It can no longer be taken recursively, and does not get
13 * released implicitly while sleeping.
14 *
15 * Don't use in new code.
16 */
17static DEFINE_MUTEX(big_tty_mutex);
13 18
14/* 19/*
15 * Getting the big tty mutex. 20 * Getting the big tty mutex.
16 */ 21 */
17 22void __lockfunc tty_lock(void)
18static void __lockfunc tty_lock_nested(struct tty_struct *tty,
19 unsigned int subclass)
20{ 23{
21 if (tty->magic != TTY_MAGIC) { 24 mutex_lock(&big_tty_mutex);
22 printk(KERN_ERR "L Bad %p\n", tty);
23 WARN_ON(1);
24 return;
25 }
26 tty_kref_get(tty);
27 mutex_lock_nested(&tty->legacy_mutex, subclass);
28}
29
30void __lockfunc tty_lock(struct tty_struct *tty)
31{
32 return tty_lock_nested(tty, TTY_MUTEX_NORMAL);
33} 25}
34EXPORT_SYMBOL(tty_lock); 26EXPORT_SYMBOL(tty_lock);
35 27
36void __lockfunc tty_unlock(struct tty_struct *tty) 28void __lockfunc tty_unlock(void)
37{ 29{
38 if (tty->magic != TTY_MAGIC) { 30 mutex_unlock(&big_tty_mutex);
39 printk(KERN_ERR "U Bad %p\n", tty);
40 WARN_ON(1);
41 return;
42 }
43 mutex_unlock(&tty->legacy_mutex);
44 tty_kref_put(tty);
45} 31}
46EXPORT_SYMBOL(tty_unlock); 32EXPORT_SYMBOL(tty_unlock);
47
48/*
49 * Getting the big tty mutex for a pair of ttys with lock ordering
50 * On a non pty/tty pair tty2 can be NULL which is just fine.
51 */
52void __lockfunc tty_lock_pair(struct tty_struct *tty,
53 struct tty_struct *tty2)
54{
55 if (tty < tty2) {
56 tty_lock(tty);
57 tty_lock_nested(tty2, TTY_MUTEX_NESTED);
58 } else {
59 if (tty2 && tty2 != tty)
60 tty_lock(tty2);
61 tty_lock_nested(tty, TTY_MUTEX_NESTED);
62 }
63}
64EXPORT_SYMBOL(tty_lock_pair);
65
66void __lockfunc tty_unlock_pair(struct tty_struct *tty,
67 struct tty_struct *tty2)
68{
69 tty_unlock(tty);
70 if (tty2 && tty2 != tty)
71 tty_unlock(tty2);
72}
73EXPORT_SYMBOL(tty_unlock_pair);
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index a3ba776c574c..4e9d2b291f4a 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -239,7 +239,7 @@ int tty_port_block_til_ready(struct tty_port *port,
239 239
240 /* block if port is in the process of being closed */ 240 /* block if port is in the process of being closed */
241 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { 241 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
242 wait_event_interruptible_tty(tty, port->close_wait, 242 wait_event_interruptible_tty(port->close_wait,
243 !(port->flags & ASYNC_CLOSING)); 243 !(port->flags & ASYNC_CLOSING));
244 if (port->flags & ASYNC_HUP_NOTIFY) 244 if (port->flags & ASYNC_HUP_NOTIFY)
245 return -EAGAIN; 245 return -EAGAIN;
@@ -305,9 +305,9 @@ int tty_port_block_til_ready(struct tty_port *port,
305 retval = -ERESTARTSYS; 305 retval = -ERESTARTSYS;
306 break; 306 break;
307 } 307 }
308 tty_unlock(tty); 308 tty_unlock();
309 schedule(); 309 schedule();
310 tty_lock(tty); 310 tty_lock();
311 } 311 }
312 finish_wait(&port->open_wait, &wait); 312 finish_wait(&port->open_wait, &wait);
313 313