diff options
author | Alan Cox <alan@linux.intel.com> | 2012-07-14 10:31:27 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-07-16 15:58:12 -0400 |
commit | 6d31a88cb2e01d46c0cb74aa5da529e1f92ae3db (patch) | |
tree | 09ce3b070a845395f942b0ddeb8149514c0a7446 /drivers/tty/tty_io.c | |
parent | 467a3ca5cab64a16b5ec46ebb1895c84c280dcfe (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/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 67 |
1 files changed, 27 insertions, 40 deletions
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 | ||
1426 | err_deinit_tty: | 1423 | err_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); |
1430 | err_module_put: | 1426 | err_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 */ |
1435 | err_release_tty: | 1431 | err_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 | ||
1912 | static int tty_open(struct inode *inode, struct file *filp) | 1901 | static 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(¤t->sighand->siglock); | 2006 | spin_lock_irq(¤t->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(¤t->sighand->siglock); | 2012 | spin_unlock_irq(¤t->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; |
2026 | err_unlock: | 2016 | err_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 | ||
2107 | static int tty_fasync(int fd, struct file *filp, int on) | 2098 | static 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); |