aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2012-08-08 11:30:13 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-10 15:55:47 -0400
commit89c8d91e31f267703e365593f6bfebb9f6d2ad01 (patch)
treeb115c7738762abe4a8a6374debb4991382b2f785 /drivers/tty
parentdc6802a771e91050fb686dfeeb9de4c6c9cadb79 (diff)
tty: localise the lock
The termios and other changes mean the other protections needed on the driver tty arrays should be adequate. Turn it all back on. This contains pieces folded in from the fixes made to the original patches | From: Geert Uytterhoeven <geert@linux-m68k.org> (fix m68k) | From: Paul Gortmaker <paul.gortmaker@windriver.com> (fix cris) | From: Jiri Kosina <jkosina@suze.cz> (lockdep) | From: Eric Dumazet <eric.dumazet@gmail.com> (lockdep) Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-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.c25
-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.c66
-rw-r--r--drivers/tty/tty_ldisc.c69
-rw-r--r--drivers/tty/tty_mutex.c71
-rw-r--r--drivers/tty/tty_port.c6
12 files changed, 174 insertions, 109 deletions
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 0e8441e73ee0..998731f01d62 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(); 1036 tty_lock(tty);
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(); 1045 tty_unlock(tty);
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(); 1062 tty_lock(tty);
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(); 1067 tty_unlock(tty);
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(); 1077 tty_unlock(tty);
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(); 1087 tty_unlock(tty);
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(); 1119 tty_unlock(tty);
1120 return retval; 1120 return retval;
1121} 1121}
1122 1122
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c
index e77db714ab26..c8850ea832af 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(info->port.close_wait, 1602 wait_event_interruptible_tty(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 5c6c31459a2f..1e6405070ce6 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(); 1068 tty_lock(tty);
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(pInfo->read_wait, 1080 wait_event_interruptible_tty(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(); 1110 tty_unlock(tty);
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(); 1159 tty_lock(tty);
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(); 1178 tty_unlock(tty);
1179 1179
1180 return 0; 1180 return 0;
1181} 1181}
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index d6579a9064c4..4399f1dbd131 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -47,6 +47,7 @@ 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 ?? */
50 if (!tty->link) 51 if (!tty->link)
51 return; 52 return;
52 tty->link->packet = 0; 53 tty->link->packet = 0;
@@ -62,9 +63,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
62 mutex_unlock(&devpts_mutex); 63 mutex_unlock(&devpts_mutex);
63 } 64 }
64#endif 65#endif
65 tty_unlock(); 66 tty_unlock(tty);
66 tty_vhangup(tty->link); 67 tty_vhangup(tty->link);
67 tty_lock(); 68 tty_lock(tty);
68 } 69 }
69} 70}
70 71
@@ -617,26 +618,27 @@ static int ptmx_open(struct inode *inode, struct file *filp)
617 return retval; 618 return retval;
618 619
619 /* find a device that is not in use. */ 620 /* find a device that is not in use. */
620 tty_lock(); 621 mutex_lock(&devpts_mutex);
621 index = devpts_new_index(inode); 622 index = devpts_new_index(inode);
622 tty_unlock();
623 if (index < 0) { 623 if (index < 0) {
624 retval = index; 624 retval = index;
625 goto err_file; 625 goto err_file;
626 } 626 }
627 627
628 mutex_unlock(&devpts_mutex);
629
628 mutex_lock(&tty_mutex); 630 mutex_lock(&tty_mutex);
629 mutex_lock(&devpts_mutex);
630 tty = tty_init_dev(ptm_driver, index); 631 tty = tty_init_dev(ptm_driver, index);
631 mutex_unlock(&devpts_mutex);
632 tty_lock();
633 mutex_unlock(&tty_mutex);
634 632
635 if (IS_ERR(tty)) { 633 if (IS_ERR(tty)) {
636 retval = PTR_ERR(tty); 634 retval = PTR_ERR(tty);
637 goto out; 635 goto out;
638 } 636 }
639 637
638 /* The tty returned here is locked so we can safely
639 drop the mutex */
640 mutex_unlock(&tty_mutex);
641
640 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ 642 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
641 643
642 tty_add_file(tty, filp); 644 tty_add_file(tty, filp);
@@ -649,16 +651,17 @@ static int ptmx_open(struct inode *inode, struct file *filp)
649 if (retval) 651 if (retval)
650 goto err_release; 652 goto err_release;
651 653
652 tty_unlock(); 654 tty_unlock(tty);
653 return 0; 655 return 0;
654err_release: 656err_release:
655 tty_unlock(); 657 tty_unlock(tty);
656 tty_release(inode, filp); 658 tty_release(inode, filp);
657 return retval; 659 return retval;
658out: 660out:
661 mutex_unlock(&tty_mutex);
659 devpts_kill_index(inode, index); 662 devpts_kill_index(inode, index);
660 tty_unlock();
661err_file: 663err_file:
664 mutex_unlock(&devpts_mutex);
662 tty_free_file(filp); 665 tty_free_file(filp);
663 return retval; 666 return retval;
664} 667}
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c
index 6b705b243522..a770b1012962 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(info->close_wait, 3979 wait_event_interruptible_tty(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(); 4055 tty_unlock(tty);
4056 schedule(); 4056 schedule();
4057 tty_lock(); 4057 tty_lock(tty);
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(info->close_wait, 4118 wait_event_interruptible_tty(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 bdeeb3133f62..991bae821232 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(); 3341 tty_unlock(tty);
3342 schedule(); 3342 schedule();
3343 tty_lock(); 3343 tty_lock(tty);
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 f02d18a391e5..913025369fe7 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(); 3339 tty_unlock(tty);
3340 schedule(); 3340 schedule();
3341 tty_lock(); 3341 tty_lock(tty);
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 ae75a3c21fd3..95fd4e20b963 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(); 3360 tty_unlock(tty);
3361 schedule(); 3361 schedule();
3362 tty_lock(); 3362 tty_lock(tty);
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 6784aae210e3..690224483fab 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -187,6 +187,7 @@ void free_tty_struct(struct tty_struct *tty)
187 put_device(tty->dev); 187 put_device(tty->dev);
188 kfree(tty->write_buf); 188 kfree(tty->write_buf);
189 tty_buffer_free_all(tty); 189 tty_buffer_free_all(tty);
190 tty->magic = 0xDEADDEAD;
190 kfree(tty); 191 kfree(tty);
191} 192}
192 193
@@ -575,7 +576,7 @@ void __tty_hangup(struct tty_struct *tty)
575 } 576 }
576 spin_unlock(&redirect_lock); 577 spin_unlock(&redirect_lock);
577 578
578 tty_lock(); 579 tty_lock(tty);
579 580
580 /* some functions below drop BTM, so we need this bit */ 581 /* some functions below drop BTM, so we need this bit */
581 set_bit(TTY_HUPPING, &tty->flags); 582 set_bit(TTY_HUPPING, &tty->flags);
@@ -668,7 +669,7 @@ void __tty_hangup(struct tty_struct *tty)
668 clear_bit(TTY_HUPPING, &tty->flags); 669 clear_bit(TTY_HUPPING, &tty->flags);
669 tty_ldisc_enable(tty); 670 tty_ldisc_enable(tty);
670 671
671 tty_unlock(); 672 tty_unlock(tty);
672 673
673 if (f) 674 if (f)
674 fput(f); 675 fput(f);
@@ -1105,12 +1106,12 @@ void tty_write_message(struct tty_struct *tty, char *msg)
1105{ 1106{
1106 if (tty) { 1107 if (tty) {
1107 mutex_lock(&tty->atomic_write_lock); 1108 mutex_lock(&tty->atomic_write_lock);
1108 tty_lock(); 1109 tty_lock(tty);
1109 if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { 1110 if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
1110 tty_unlock(); 1111 tty_unlock(tty);
1111 tty->ops->write(tty, msg, strlen(msg)); 1112 tty->ops->write(tty, msg, strlen(msg));
1112 } else 1113 } else
1113 tty_unlock(); 1114 tty_unlock(tty);
1114 tty_write_unlock(tty); 1115 tty_write_unlock(tty);
1115 } 1116 }
1116 return; 1117 return;
@@ -1403,6 +1404,7 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
1403 } 1404 }
1404 initialize_tty_struct(tty, driver, idx); 1405 initialize_tty_struct(tty, driver, idx);
1405 1406
1407 tty_lock(tty);
1406 retval = tty_driver_install_tty(driver, tty); 1408 retval = tty_driver_install_tty(driver, tty);
1407 if (retval < 0) 1409 if (retval < 0)
1408 goto err_deinit_tty; 1410 goto err_deinit_tty;
@@ -1418,9 +1420,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
1418 retval = tty_ldisc_setup(tty, tty->link); 1420 retval = tty_ldisc_setup(tty, tty->link);
1419 if (retval) 1421 if (retval)
1420 goto err_release_tty; 1422 goto err_release_tty;
1423 /* Return the tty locked so that it cannot vanish under the caller */
1421 return tty; 1424 return tty;
1422 1425
1423err_deinit_tty: 1426err_deinit_tty:
1427 tty_unlock(tty);
1424 deinitialize_tty_struct(tty); 1428 deinitialize_tty_struct(tty);
1425 free_tty_struct(tty); 1429 free_tty_struct(tty);
1426err_module_put: 1430err_module_put:
@@ -1429,6 +1433,7 @@ err_module_put:
1429 1433
1430 /* call the tty release_tty routine to clean out this slot */ 1434 /* call the tty release_tty routine to clean out this slot */
1431err_release_tty: 1435err_release_tty:
1436 tty_unlock(tty);
1432 printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " 1437 printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, "
1433 "clearing slot %d\n", idx); 1438 "clearing slot %d\n", idx);
1434 release_tty(tty, idx); 1439 release_tty(tty, idx);
@@ -1622,7 +1627,7 @@ int tty_release(struct inode *inode, struct file *filp)
1622 if (tty_paranoia_check(tty, inode, __func__)) 1627 if (tty_paranoia_check(tty, inode, __func__))
1623 return 0; 1628 return 0;
1624 1629
1625 tty_lock(); 1630 tty_lock(tty);
1626 check_tty_count(tty, __func__); 1631 check_tty_count(tty, __func__);
1627 1632
1628 __tty_fasync(-1, filp, 0); 1633 __tty_fasync(-1, filp, 0);
@@ -1631,10 +1636,11 @@ int tty_release(struct inode *inode, struct file *filp)
1631 pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && 1636 pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1632 tty->driver->subtype == PTY_TYPE_MASTER); 1637 tty->driver->subtype == PTY_TYPE_MASTER);
1633 devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; 1638 devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0;
1639 /* Review: parallel close */
1634 o_tty = tty->link; 1640 o_tty = tty->link;
1635 1641
1636 if (tty_release_checks(tty, o_tty, idx)) { 1642 if (tty_release_checks(tty, o_tty, idx)) {
1637 tty_unlock(); 1643 tty_unlock(tty);
1638 return 0; 1644 return 0;
1639 } 1645 }
1640 1646
@@ -1646,7 +1652,7 @@ int tty_release(struct inode *inode, struct file *filp)
1646 if (tty->ops->close) 1652 if (tty->ops->close)
1647 tty->ops->close(tty, filp); 1653 tty->ops->close(tty, filp);
1648 1654
1649 tty_unlock(); 1655 tty_unlock(tty);
1650 /* 1656 /*
1651 * Sanity check: if tty->count is going to zero, there shouldn't be 1657 * Sanity check: if tty->count is going to zero, there shouldn't be
1652 * any waiters on tty->read_wait or tty->write_wait. We test the 1658 * any waiters on tty->read_wait or tty->write_wait. We test the
@@ -1669,7 +1675,7 @@ int tty_release(struct inode *inode, struct file *filp)
1669 opens on /dev/tty */ 1675 opens on /dev/tty */
1670 1676
1671 mutex_lock(&tty_mutex); 1677 mutex_lock(&tty_mutex);
1672 tty_lock(); 1678 tty_lock_pair(tty, o_tty);
1673 tty_closing = tty->count <= 1; 1679 tty_closing = tty->count <= 1;
1674 o_tty_closing = o_tty && 1680 o_tty_closing = o_tty &&
1675 (o_tty->count <= (pty_master ? 1 : 0)); 1681 (o_tty->count <= (pty_master ? 1 : 0));
@@ -1700,7 +1706,7 @@ int tty_release(struct inode *inode, struct file *filp)
1700 1706
1701 printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", 1707 printk(KERN_WARNING "%s: %s: read/write wait queue active!\n",
1702 __func__, tty_name(tty, buf)); 1708 __func__, tty_name(tty, buf));
1703 tty_unlock(); 1709 tty_unlock_pair(tty, o_tty);
1704 mutex_unlock(&tty_mutex); 1710 mutex_unlock(&tty_mutex);
1705 schedule(); 1711 schedule();
1706 } 1712 }
@@ -1763,7 +1769,7 @@ int tty_release(struct inode *inode, struct file *filp)
1763 } 1769 }
1764 1770
1765 mutex_unlock(&tty_mutex); 1771 mutex_unlock(&tty_mutex);
1766 tty_unlock(); 1772 tty_unlock_pair(tty, o_tty);
1767 /* At this point the TTY_CLOSING flag should ensure a dead tty 1773 /* At this point the TTY_CLOSING flag should ensure a dead tty
1768 cannot be re-opened by a racing opener */ 1774 cannot be re-opened by a racing opener */
1769 1775
@@ -1780,7 +1786,9 @@ int tty_release(struct inode *inode, struct file *filp)
1780 tty_ldisc_release(tty, o_tty); 1786 tty_ldisc_release(tty, o_tty);
1781 /* 1787 /*
1782 * The release_tty function takes care of the details of clearing 1788 * The release_tty function takes care of the details of clearing
1783 * the slots and preserving the termios structure. 1789 * the slots and preserving the termios structure. The tty_unlock_pair
1790 * should be safe as we keep a kref while the tty is locked (so the
1791 * unlock never unlocks a freed tty).
1784 */ 1792 */
1785 mutex_lock(&tty_mutex); 1793 mutex_lock(&tty_mutex);
1786 release_tty(tty, idx); 1794 release_tty(tty, idx);
@@ -1789,7 +1797,6 @@ int tty_release(struct inode *inode, struct file *filp)
1789 /* Make this pty number available for reallocation */ 1797 /* Make this pty number available for reallocation */
1790 if (devpts) 1798 if (devpts)
1791 devpts_kill_index(inode, idx); 1799 devpts_kill_index(inode, idx);
1792
1793 return 0; 1800 return 0;
1794} 1801}
1795 1802
@@ -1893,6 +1900,9 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
1893 * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. 1900 * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev.
1894 * tty->count should protect the rest. 1901 * tty->count should protect the rest.
1895 * ->siglock protects ->signal/->sighand 1902 * ->siglock protects ->signal/->sighand
1903 *
1904 * Note: the tty_unlock/lock cases without a ref are only safe due to
1905 * tty_mutex
1896 */ 1906 */
1897 1907
1898static int tty_open(struct inode *inode, struct file *filp) 1908static int tty_open(struct inode *inode, struct file *filp)
@@ -1916,8 +1926,7 @@ retry_open:
1916 retval = 0; 1926 retval = 0;
1917 1927
1918 mutex_lock(&tty_mutex); 1928 mutex_lock(&tty_mutex);
1919 tty_lock(); 1929 /* This is protected by the tty_mutex */
1920
1921 tty = tty_open_current_tty(device, filp); 1930 tty = tty_open_current_tty(device, filp);
1922 if (IS_ERR(tty)) { 1931 if (IS_ERR(tty)) {
1923 retval = PTR_ERR(tty); 1932 retval = PTR_ERR(tty);
@@ -1938,17 +1947,19 @@ retry_open:
1938 } 1947 }
1939 1948
1940 if (tty) { 1949 if (tty) {
1950 tty_lock(tty);
1941 retval = tty_reopen(tty); 1951 retval = tty_reopen(tty);
1942 if (retval) 1952 if (retval < 0) {
1953 tty_unlock(tty);
1943 tty = ERR_PTR(retval); 1954 tty = ERR_PTR(retval);
1944 } else 1955 }
1956 } else /* Returns with the tty_lock held for now */
1945 tty = tty_init_dev(driver, index); 1957 tty = tty_init_dev(driver, index);
1946 1958
1947 mutex_unlock(&tty_mutex); 1959 mutex_unlock(&tty_mutex);
1948 if (driver) 1960 if (driver)
1949 tty_driver_kref_put(driver); 1961 tty_driver_kref_put(driver);
1950 if (IS_ERR(tty)) { 1962 if (IS_ERR(tty)) {
1951 tty_unlock();
1952 retval = PTR_ERR(tty); 1963 retval = PTR_ERR(tty);
1953 goto err_file; 1964 goto err_file;
1954 } 1965 }
@@ -1977,7 +1988,7 @@ retry_open:
1977 printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, 1988 printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__,
1978 retval, tty->name); 1989 retval, tty->name);
1979#endif 1990#endif
1980 tty_unlock(); /* need to call tty_release without BTM */ 1991 tty_unlock(tty); /* need to call tty_release without BTM */
1981 tty_release(inode, filp); 1992 tty_release(inode, filp);
1982 if (retval != -ERESTARTSYS) 1993 if (retval != -ERESTARTSYS)
1983 return retval; 1994 return retval;
@@ -1989,17 +2000,15 @@ retry_open:
1989 /* 2000 /*
1990 * Need to reset f_op in case a hangup happened. 2001 * Need to reset f_op in case a hangup happened.
1991 */ 2002 */
1992 tty_lock();
1993 if (filp->f_op == &hung_up_tty_fops) 2003 if (filp->f_op == &hung_up_tty_fops)
1994 filp->f_op = &tty_fops; 2004 filp->f_op = &tty_fops;
1995 tty_unlock();
1996 goto retry_open; 2005 goto retry_open;
1997 } 2006 }
1998 tty_unlock(); 2007 tty_unlock(tty);
1999 2008
2000 2009
2001 mutex_lock(&tty_mutex); 2010 mutex_lock(&tty_mutex);
2002 tty_lock(); 2011 tty_lock(tty);
2003 spin_lock_irq(&current->sighand->siglock); 2012 spin_lock_irq(&current->sighand->siglock);
2004 if (!noctty && 2013 if (!noctty &&
2005 current->signal->leader && 2014 current->signal->leader &&
@@ -2007,11 +2016,10 @@ retry_open:
2007 tty->session == NULL) 2016 tty->session == NULL)
2008 __proc_set_tty(current, tty); 2017 __proc_set_tty(current, tty);
2009 spin_unlock_irq(&current->sighand->siglock); 2018 spin_unlock_irq(&current->sighand->siglock);
2010 tty_unlock(); 2019 tty_unlock(tty);
2011 mutex_unlock(&tty_mutex); 2020 mutex_unlock(&tty_mutex);
2012 return 0; 2021 return 0;
2013err_unlock: 2022err_unlock:
2014 tty_unlock();
2015 mutex_unlock(&tty_mutex); 2023 mutex_unlock(&tty_mutex);
2016 /* after locks to avoid deadlock */ 2024 /* after locks to avoid deadlock */
2017 if (!IS_ERR_OR_NULL(driver)) 2025 if (!IS_ERR_OR_NULL(driver))
@@ -2094,10 +2102,13 @@ out:
2094 2102
2095static int tty_fasync(int fd, struct file *filp, int on) 2103static int tty_fasync(int fd, struct file *filp, int on)
2096{ 2104{
2105 struct tty_struct *tty = file_tty(filp);
2097 int retval; 2106 int retval;
2098 tty_lock(); 2107
2108 tty_lock(tty);
2099 retval = __tty_fasync(fd, filp, on); 2109 retval = __tty_fasync(fd, filp, on);
2100 tty_unlock(); 2110 tty_unlock(tty);
2111
2101 return retval; 2112 return retval;
2102} 2113}
2103 2114
@@ -2934,6 +2945,7 @@ void initialize_tty_struct(struct tty_struct *tty,
2934 tty->pgrp = NULL; 2945 tty->pgrp = NULL;
2935 tty->overrun_time = jiffies; 2946 tty->overrun_time = jiffies;
2936 tty_buffer_init(tty); 2947 tty_buffer_init(tty);
2948 mutex_init(&tty->legacy_mutex);
2937 mutex_init(&tty->termios_mutex); 2949 mutex_init(&tty->termios_mutex);
2938 mutex_init(&tty->ldisc_mutex); 2950 mutex_init(&tty->ldisc_mutex);
2939 init_waitqueue_head(&tty->write_wait); 2951 init_waitqueue_head(&tty->write_wait);
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 3d0687197d09..4d7b56268c79 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(); 571 tty_lock(tty);
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(); 585 tty_unlock(tty);
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(); 590 tty_unlock(tty);
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(); 598 tty_lock(tty);
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(); 608 tty_unlock(tty);
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(); 611 tty_lock(tty);
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(); 626 tty_unlock(tty);
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(); 653 tty_lock(tty);
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(); 668 tty_unlock(tty);
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(); 711 tty_unlock(tty);
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(); 819 tty_unlock(tty);
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(); 823 tty_lock(tty);
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(); 834 tty_unlock(tty);
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,6 +894,23 @@ 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
897/** 914/**
898 * tty_ldisc_release - release line discipline 915 * tty_ldisc_release - release line discipline
899 * @tty: tty being shut down 916 * @tty: tty being shut down
@@ -912,29 +929,21 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
912 * race with the set_ldisc code path. 929 * race with the set_ldisc code path.
913 */ 930 */
914 931
932 tty_lock_pair(tty, o_tty);
915 tty_ldisc_halt(tty); 933 tty_ldisc_halt(tty);
916 tty_ldisc_flush_works(tty); 934 tty_ldisc_flush_works(tty);
917 tty_lock(); 935 if (o_tty) {
918 936 tty_ldisc_halt(o_tty);
919 mutex_lock(&tty->ldisc_mutex); 937 tty_ldisc_flush_works(o_tty);
920 /* 938 }
921 * Now kill off the ldisc
922 */
923 tty_ldisc_close(tty, tty->ldisc);
924 tty_ldisc_put(tty->ldisc);
925 /* Force an oops if we mess this up */
926 tty->ldisc = NULL;
927
928 /* Ensure the next open requests the N_TTY ldisc */
929 tty_set_termios_ldisc(tty, N_TTY);
930 mutex_unlock(&tty->ldisc_mutex);
931
932 tty_unlock();
933 939
934 /* This will need doing differently if we need to lock */ 940 /* This will need doing differently if we need to lock */
941 tty_ldisc_kill(tty);
942
935 if (o_tty) 943 if (o_tty)
936 tty_ldisc_release(o_tty, NULL); 944 tty_ldisc_kill(o_tty);
937 945
946 tty_unlock_pair(tty, o_tty);
938 /* And the memory resources remaining (buffers, termios) will be 947 /* And the memory resources remaining (buffers, termios) will be
939 disposed of when the kref hits zero */ 948 disposed of when the kref hits zero */
940} 949}
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c
index 9ff986c32a21..67feac9e6ebb 100644
--- a/drivers/tty/tty_mutex.c
+++ b/drivers/tty/tty_mutex.c
@@ -4,29 +4,70 @@
4#include <linux/semaphore.h> 4#include <linux/semaphore.h>
5#include <linux/sched.h> 5#include <linux/sched.h>
6 6
7/* 7/* Legacy tty mutex glue */
8 * The 'big tty mutex' 8
9 * 9enum {
10 * This mutex is taken and released by tty_lock() and tty_unlock(), 10 TTY_MUTEX_NORMAL,
11 * replacing the older big kernel lock. 11 TTY_MUTEX_NESTED,
12 * It can no longer be taken recursively, and does not get 12};
13 * released implicitly while sleeping.
14 *
15 * Don't use in new code.
16 */
17static DEFINE_MUTEX(big_tty_mutex);
18 13
19/* 14/*
20 * Getting the big tty mutex. 15 * Getting the big tty mutex.
21 */ 16 */
22void __lockfunc tty_lock(void) 17
18static void __lockfunc tty_lock_nested(struct tty_struct *tty,
19 unsigned int subclass)
23{ 20{
24 mutex_lock(&big_tty_mutex); 21 if (tty->magic != TTY_MAGIC) {
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);
25} 33}
26EXPORT_SYMBOL(tty_lock); 34EXPORT_SYMBOL(tty_lock);
27 35
28void __lockfunc tty_unlock(void) 36void __lockfunc tty_unlock(struct tty_struct *tty)
29{ 37{
30 mutex_unlock(&big_tty_mutex); 38 if (tty->magic != TTY_MAGIC) {
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);
31} 45}
32EXPORT_SYMBOL(tty_unlock); 46EXPORT_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 edcb827c1286..5246763cff0c 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(port->close_wait, 242 wait_event_interruptible_tty(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(); 308 tty_unlock(tty);
309 schedule(); 309 schedule();
310 tty_lock(); 310 tty_lock(tty);
311 } 311 }
312 finish_wait(&port->open_wait, &wait); 312 finish_wait(&port->open_wait, &wait);
313 313