diff options
-rw-r--r-- | kernel/futex.c | 146 |
1 files changed, 70 insertions, 76 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index 38cf606a2d7d..87ad28746e17 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -69,6 +69,14 @@ int __read_mostly futex_cmpxchg_enabled; | |||
69 | #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8) | 69 | #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8) |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * Futex flags used to encode options to functions and preserve them across | ||
73 | * restarts. | ||
74 | */ | ||
75 | #define FLAGS_SHARED 0x01 | ||
76 | #define FLAGS_CLOCKRT 0x02 | ||
77 | #define FLAGS_HAS_TIMEOUT 0x04 | ||
78 | |||
79 | /* | ||
72 | * Priority Inheritance state: | 80 | * Priority Inheritance state: |
73 | */ | 81 | */ |
74 | struct futex_pi_state { | 82 | struct futex_pi_state { |
@@ -869,7 +877,8 @@ double_unlock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2) | |||
869 | /* | 877 | /* |
870 | * Wake up waiters matching bitset queued on this futex (uaddr). | 878 | * Wake up waiters matching bitset queued on this futex (uaddr). |
871 | */ | 879 | */ |
872 | static int futex_wake(u32 __user *uaddr, int fshared, int nr_wake, u32 bitset) | 880 | static int |
881 | futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) | ||
873 | { | 882 | { |
874 | struct futex_hash_bucket *hb; | 883 | struct futex_hash_bucket *hb; |
875 | struct futex_q *this, *next; | 884 | struct futex_q *this, *next; |
@@ -880,7 +889,7 @@ static int futex_wake(u32 __user *uaddr, int fshared, int nr_wake, u32 bitset) | |||
880 | if (!bitset) | 889 | if (!bitset) |
881 | return -EINVAL; | 890 | return -EINVAL; |
882 | 891 | ||
883 | ret = get_futex_key(uaddr, fshared, &key); | 892 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); |
884 | if (unlikely(ret != 0)) | 893 | if (unlikely(ret != 0)) |
885 | goto out; | 894 | goto out; |
886 | 895 | ||
@@ -916,7 +925,7 @@ out: | |||
916 | * to this virtual address: | 925 | * to this virtual address: |
917 | */ | 926 | */ |
918 | static int | 927 | static int |
919 | futex_wake_op(u32 __user *uaddr1, int fshared, u32 __user *uaddr2, | 928 | futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, |
920 | int nr_wake, int nr_wake2, int op) | 929 | int nr_wake, int nr_wake2, int op) |
921 | { | 930 | { |
922 | union futex_key key1 = FUTEX_KEY_INIT, key2 = FUTEX_KEY_INIT; | 931 | union futex_key key1 = FUTEX_KEY_INIT, key2 = FUTEX_KEY_INIT; |
@@ -926,10 +935,10 @@ futex_wake_op(u32 __user *uaddr1, int fshared, u32 __user *uaddr2, | |||
926 | int ret, op_ret; | 935 | int ret, op_ret; |
927 | 936 | ||
928 | retry: | 937 | retry: |
929 | ret = get_futex_key(uaddr1, fshared, &key1); | 938 | ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1); |
930 | if (unlikely(ret != 0)) | 939 | if (unlikely(ret != 0)) |
931 | goto out; | 940 | goto out; |
932 | ret = get_futex_key(uaddr2, fshared, &key2); | 941 | ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); |
933 | if (unlikely(ret != 0)) | 942 | if (unlikely(ret != 0)) |
934 | goto out_put_key1; | 943 | goto out_put_key1; |
935 | 944 | ||
@@ -961,7 +970,7 @@ retry_private: | |||
961 | if (ret) | 970 | if (ret) |
962 | goto out_put_keys; | 971 | goto out_put_keys; |
963 | 972 | ||
964 | if (!fshared) | 973 | if (!(flags & FLAGS_SHARED)) |
965 | goto retry_private; | 974 | goto retry_private; |
966 | 975 | ||
967 | put_futex_key(&key2); | 976 | put_futex_key(&key2); |
@@ -1132,13 +1141,13 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex, | |||
1132 | /** | 1141 | /** |
1133 | * futex_requeue() - Requeue waiters from uaddr1 to uaddr2 | 1142 | * futex_requeue() - Requeue waiters from uaddr1 to uaddr2 |
1134 | * @uaddr1: source futex user address | 1143 | * @uaddr1: source futex user address |
1135 | * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED | 1144 | * @flags: futex flags (FLAGS_SHARED, etc.) |
1136 | * @uaddr2: target futex user address | 1145 | * @uaddr2: target futex user address |
1137 | * @nr_wake: number of waiters to wake (must be 1 for requeue_pi) | 1146 | * @nr_wake: number of waiters to wake (must be 1 for requeue_pi) |
1138 | * @nr_requeue: number of waiters to requeue (0-INT_MAX) | 1147 | * @nr_requeue: number of waiters to requeue (0-INT_MAX) |
1139 | * @cmpval: @uaddr1 expected value (or %NULL) | 1148 | * @cmpval: @uaddr1 expected value (or %NULL) |
1140 | * @requeue_pi: if we are attempting to requeue from a non-pi futex to a | 1149 | * @requeue_pi: if we are attempting to requeue from a non-pi futex to a |
1141 | * pi futex (pi to pi requeue is not supported) | 1150 | * pi futex (pi to pi requeue is not supported) |
1142 | * | 1151 | * |
1143 | * Requeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire | 1152 | * Requeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire |
1144 | * uaddr2 atomically on behalf of the top waiter. | 1153 | * uaddr2 atomically on behalf of the top waiter. |
@@ -1147,9 +1156,9 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex, | |||
1147 | * >=0 - on success, the number of tasks requeued or woken | 1156 | * >=0 - on success, the number of tasks requeued or woken |
1148 | * <0 - on error | 1157 | * <0 - on error |
1149 | */ | 1158 | */ |
1150 | static int futex_requeue(u32 __user *uaddr1, int fshared, u32 __user *uaddr2, | 1159 | static int futex_requeue(u32 __user *uaddr1, unsigned int flags, |
1151 | int nr_wake, int nr_requeue, u32 *cmpval, | 1160 | u32 __user *uaddr2, int nr_wake, int nr_requeue, |
1152 | int requeue_pi) | 1161 | u32 *cmpval, int requeue_pi) |
1153 | { | 1162 | { |
1154 | union futex_key key1 = FUTEX_KEY_INIT, key2 = FUTEX_KEY_INIT; | 1163 | union futex_key key1 = FUTEX_KEY_INIT, key2 = FUTEX_KEY_INIT; |
1155 | int drop_count = 0, task_count = 0, ret; | 1164 | int drop_count = 0, task_count = 0, ret; |
@@ -1190,10 +1199,10 @@ retry: | |||
1190 | pi_state = NULL; | 1199 | pi_state = NULL; |
1191 | } | 1200 | } |
1192 | 1201 | ||
1193 | ret = get_futex_key(uaddr1, fshared, &key1); | 1202 | ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1); |
1194 | if (unlikely(ret != 0)) | 1203 | if (unlikely(ret != 0)) |
1195 | goto out; | 1204 | goto out; |
1196 | ret = get_futex_key(uaddr2, fshared, &key2); | 1205 | ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); |
1197 | if (unlikely(ret != 0)) | 1206 | if (unlikely(ret != 0)) |
1198 | goto out_put_key1; | 1207 | goto out_put_key1; |
1199 | 1208 | ||
@@ -1215,7 +1224,7 @@ retry_private: | |||
1215 | if (ret) | 1224 | if (ret) |
1216 | goto out_put_keys; | 1225 | goto out_put_keys; |
1217 | 1226 | ||
1218 | if (!fshared) | 1227 | if (!(flags & FLAGS_SHARED)) |
1219 | goto retry_private; | 1228 | goto retry_private; |
1220 | 1229 | ||
1221 | put_futex_key(&key2); | 1230 | put_futex_key(&key2); |
@@ -1586,14 +1595,6 @@ handle_fault: | |||
1586 | goto retry; | 1595 | goto retry; |
1587 | } | 1596 | } |
1588 | 1597 | ||
1589 | /* | ||
1590 | * In case we must use restart_block to restart a futex_wait, | ||
1591 | * we encode in the 'flags' shared capability | ||
1592 | */ | ||
1593 | #define FLAGS_SHARED 0x01 | ||
1594 | #define FLAGS_CLOCKRT 0x02 | ||
1595 | #define FLAGS_HAS_TIMEOUT 0x04 | ||
1596 | |||
1597 | static long futex_wait_restart(struct restart_block *restart); | 1598 | static long futex_wait_restart(struct restart_block *restart); |
1598 | 1599 | ||
1599 | /** | 1600 | /** |
@@ -1712,7 +1713,7 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q, | |||
1712 | * futex_wait_setup() - Prepare to wait on a futex | 1713 | * futex_wait_setup() - Prepare to wait on a futex |
1713 | * @uaddr: the futex userspace address | 1714 | * @uaddr: the futex userspace address |
1714 | * @val: the expected value | 1715 | * @val: the expected value |
1715 | * @fshared: whether the futex is shared (1) or not (0) | 1716 | * @flags: futex flags (FLAGS_SHARED, etc.) |
1716 | * @q: the associated futex_q | 1717 | * @q: the associated futex_q |
1717 | * @hb: storage for hash_bucket pointer to be returned to caller | 1718 | * @hb: storage for hash_bucket pointer to be returned to caller |
1718 | * | 1719 | * |
@@ -1725,7 +1726,7 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q, | |||
1725 | * 0 - uaddr contains val and hb has been locked | 1726 | * 0 - uaddr contains val and hb has been locked |
1726 | * <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlcoked | 1727 | * <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlcoked |
1727 | */ | 1728 | */ |
1728 | static int futex_wait_setup(u32 __user *uaddr, u32 val, int fshared, | 1729 | static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, |
1729 | struct futex_q *q, struct futex_hash_bucket **hb) | 1730 | struct futex_q *q, struct futex_hash_bucket **hb) |
1730 | { | 1731 | { |
1731 | u32 uval; | 1732 | u32 uval; |
@@ -1750,7 +1751,7 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, int fshared, | |||
1750 | */ | 1751 | */ |
1751 | retry: | 1752 | retry: |
1752 | q->key = FUTEX_KEY_INIT; | 1753 | q->key = FUTEX_KEY_INIT; |
1753 | ret = get_futex_key(uaddr, fshared, &q->key); | 1754 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key); |
1754 | if (unlikely(ret != 0)) | 1755 | if (unlikely(ret != 0)) |
1755 | return ret; | 1756 | return ret; |
1756 | 1757 | ||
@@ -1766,7 +1767,7 @@ retry_private: | |||
1766 | if (ret) | 1767 | if (ret) |
1767 | goto out; | 1768 | goto out; |
1768 | 1769 | ||
1769 | if (!fshared) | 1770 | if (!(flags & FLAGS_SHARED)) |
1770 | goto retry_private; | 1771 | goto retry_private; |
1771 | 1772 | ||
1772 | put_futex_key(&q->key); | 1773 | put_futex_key(&q->key); |
@@ -1784,8 +1785,8 @@ out: | |||
1784 | return ret; | 1785 | return ret; |
1785 | } | 1786 | } |
1786 | 1787 | ||
1787 | static int futex_wait(u32 __user *uaddr, int fshared, | 1788 | static int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val, |
1788 | u32 val, ktime_t *abs_time, u32 bitset, int clockrt) | 1789 | ktime_t *abs_time, u32 bitset) |
1789 | { | 1790 | { |
1790 | struct hrtimer_sleeper timeout, *to = NULL; | 1791 | struct hrtimer_sleeper timeout, *to = NULL; |
1791 | struct restart_block *restart; | 1792 | struct restart_block *restart; |
@@ -1804,8 +1805,9 @@ static int futex_wait(u32 __user *uaddr, int fshared, | |||
1804 | if (abs_time) { | 1805 | if (abs_time) { |
1805 | to = &timeout; | 1806 | to = &timeout; |
1806 | 1807 | ||
1807 | hrtimer_init_on_stack(&to->timer, clockrt ? CLOCK_REALTIME : | 1808 | hrtimer_init_on_stack(&to->timer, (flags & FLAGS_CLOCKRT) ? |
1808 | CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | 1809 | CLOCK_REALTIME : CLOCK_MONOTONIC, |
1810 | HRTIMER_MODE_ABS); | ||
1809 | hrtimer_init_sleeper(to, current); | 1811 | hrtimer_init_sleeper(to, current); |
1810 | hrtimer_set_expires_range_ns(&to->timer, *abs_time, | 1812 | hrtimer_set_expires_range_ns(&to->timer, *abs_time, |
1811 | current->timer_slack_ns); | 1813 | current->timer_slack_ns); |
@@ -1816,7 +1818,7 @@ retry: | |||
1816 | * Prepare to wait on uaddr. On success, holds hb lock and increments | 1818 | * Prepare to wait on uaddr. On success, holds hb lock and increments |
1817 | * q.key refs. | 1819 | * q.key refs. |
1818 | */ | 1820 | */ |
1819 | ret = futex_wait_setup(uaddr, val, fshared, &q, &hb); | 1821 | ret = futex_wait_setup(uaddr, val, flags, &q, &hb); |
1820 | if (ret) | 1822 | if (ret) |
1821 | goto out; | 1823 | goto out; |
1822 | 1824 | ||
@@ -1849,12 +1851,7 @@ retry: | |||
1849 | restart->futex.val = val; | 1851 | restart->futex.val = val; |
1850 | restart->futex.time = abs_time->tv64; | 1852 | restart->futex.time = abs_time->tv64; |
1851 | restart->futex.bitset = bitset; | 1853 | restart->futex.bitset = bitset; |
1852 | restart->futex.flags = FLAGS_HAS_TIMEOUT; | 1854 | restart->futex.flags = flags; |
1853 | |||
1854 | if (fshared) | ||
1855 | restart->futex.flags |= FLAGS_SHARED; | ||
1856 | if (clockrt) | ||
1857 | restart->futex.flags |= FLAGS_CLOCKRT; | ||
1858 | 1855 | ||
1859 | ret = -ERESTART_RESTARTBLOCK; | 1856 | ret = -ERESTART_RESTARTBLOCK; |
1860 | 1857 | ||
@@ -1870,7 +1867,6 @@ out: | |||
1870 | static long futex_wait_restart(struct restart_block *restart) | 1867 | static long futex_wait_restart(struct restart_block *restart) |
1871 | { | 1868 | { |
1872 | u32 __user *uaddr = restart->futex.uaddr; | 1869 | u32 __user *uaddr = restart->futex.uaddr; |
1873 | int fshared = 0; | ||
1874 | ktime_t t, *tp = NULL; | 1870 | ktime_t t, *tp = NULL; |
1875 | 1871 | ||
1876 | if (restart->futex.flags & FLAGS_HAS_TIMEOUT) { | 1872 | if (restart->futex.flags & FLAGS_HAS_TIMEOUT) { |
@@ -1878,11 +1874,9 @@ static long futex_wait_restart(struct restart_block *restart) | |||
1878 | tp = &t; | 1874 | tp = &t; |
1879 | } | 1875 | } |
1880 | restart->fn = do_no_restart_syscall; | 1876 | restart->fn = do_no_restart_syscall; |
1881 | if (restart->futex.flags & FLAGS_SHARED) | 1877 | |
1882 | fshared = 1; | 1878 | return (long)futex_wait(uaddr, restart->futex.flags, |
1883 | return (long)futex_wait(uaddr, fshared, restart->futex.val, tp, | 1879 | restart->futex.val, tp, restart->futex.bitset); |
1884 | restart->futex.bitset, | ||
1885 | restart->futex.flags & FLAGS_CLOCKRT); | ||
1886 | } | 1880 | } |
1887 | 1881 | ||
1888 | 1882 | ||
@@ -1892,8 +1886,8 @@ static long futex_wait_restart(struct restart_block *restart) | |||
1892 | * if there are waiters then it will block, it does PI, etc. (Due to | 1886 | * if there are waiters then it will block, it does PI, etc. (Due to |
1893 | * races the kernel might see a 0 value of the futex too.) | 1887 | * races the kernel might see a 0 value of the futex too.) |
1894 | */ | 1888 | */ |
1895 | static int futex_lock_pi(u32 __user *uaddr, int fshared, | 1889 | static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, int detect, |
1896 | int detect, ktime_t *time, int trylock) | 1890 | ktime_t *time, int trylock) |
1897 | { | 1891 | { |
1898 | struct hrtimer_sleeper timeout, *to = NULL; | 1892 | struct hrtimer_sleeper timeout, *to = NULL; |
1899 | struct futex_hash_bucket *hb; | 1893 | struct futex_hash_bucket *hb; |
@@ -1916,7 +1910,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared, | |||
1916 | q.requeue_pi_key = NULL; | 1910 | q.requeue_pi_key = NULL; |
1917 | retry: | 1911 | retry: |
1918 | q.key = FUTEX_KEY_INIT; | 1912 | q.key = FUTEX_KEY_INIT; |
1919 | ret = get_futex_key(uaddr, fshared, &q.key); | 1913 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key); |
1920 | if (unlikely(ret != 0)) | 1914 | if (unlikely(ret != 0)) |
1921 | goto out; | 1915 | goto out; |
1922 | 1916 | ||
@@ -2005,7 +1999,7 @@ uaddr_faulted: | |||
2005 | if (ret) | 1999 | if (ret) |
2006 | goto out_put_key; | 2000 | goto out_put_key; |
2007 | 2001 | ||
2008 | if (!fshared) | 2002 | if (!(flags & FLAGS_SHARED)) |
2009 | goto retry_private; | 2003 | goto retry_private; |
2010 | 2004 | ||
2011 | put_futex_key(&q.key); | 2005 | put_futex_key(&q.key); |
@@ -2017,7 +2011,7 @@ uaddr_faulted: | |||
2017 | * This is the in-kernel slowpath: we look up the PI state (if any), | 2011 | * This is the in-kernel slowpath: we look up the PI state (if any), |
2018 | * and do the rt-mutex unlock. | 2012 | * and do the rt-mutex unlock. |
2019 | */ | 2013 | */ |
2020 | static int futex_unlock_pi(u32 __user *uaddr, int fshared) | 2014 | static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags) |
2021 | { | 2015 | { |
2022 | struct futex_hash_bucket *hb; | 2016 | struct futex_hash_bucket *hb; |
2023 | struct futex_q *this, *next; | 2017 | struct futex_q *this, *next; |
@@ -2035,7 +2029,7 @@ retry: | |||
2035 | if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current)) | 2029 | if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current)) |
2036 | return -EPERM; | 2030 | return -EPERM; |
2037 | 2031 | ||
2038 | ret = get_futex_key(uaddr, fshared, &key); | 2032 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); |
2039 | if (unlikely(ret != 0)) | 2033 | if (unlikely(ret != 0)) |
2040 | goto out; | 2034 | goto out; |
2041 | 2035 | ||
@@ -2157,7 +2151,7 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, | |||
2157 | /** | 2151 | /** |
2158 | * futex_wait_requeue_pi() - Wait on uaddr and take uaddr2 | 2152 | * futex_wait_requeue_pi() - Wait on uaddr and take uaddr2 |
2159 | * @uaddr: the futex we initially wait on (non-pi) | 2153 | * @uaddr: the futex we initially wait on (non-pi) |
2160 | * @fshared: whether the futexes are shared (1) or not (0). They must be | 2154 | * @flags: futex flags (FLAGS_SHARED, FLAGS_CLOCKRT, etc.), they must be |
2161 | * the same type, no requeueing from private to shared, etc. | 2155 | * the same type, no requeueing from private to shared, etc. |
2162 | * @val: the expected value of uaddr | 2156 | * @val: the expected value of uaddr |
2163 | * @abs_time: absolute timeout | 2157 | * @abs_time: absolute timeout |
@@ -2195,9 +2189,9 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, | |||
2195 | * 0 - On success | 2189 | * 0 - On success |
2196 | * <0 - On error | 2190 | * <0 - On error |
2197 | */ | 2191 | */ |
2198 | static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared, | 2192 | static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, |
2199 | u32 val, ktime_t *abs_time, u32 bitset, | 2193 | u32 val, ktime_t *abs_time, u32 bitset, |
2200 | int clockrt, u32 __user *uaddr2) | 2194 | u32 __user *uaddr2) |
2201 | { | 2195 | { |
2202 | struct hrtimer_sleeper timeout, *to = NULL; | 2196 | struct hrtimer_sleeper timeout, *to = NULL; |
2203 | struct rt_mutex_waiter rt_waiter; | 2197 | struct rt_mutex_waiter rt_waiter; |
@@ -2212,8 +2206,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared, | |||
2212 | 2206 | ||
2213 | if (abs_time) { | 2207 | if (abs_time) { |
2214 | to = &timeout; | 2208 | to = &timeout; |
2215 | hrtimer_init_on_stack(&to->timer, clockrt ? CLOCK_REALTIME : | 2209 | hrtimer_init_on_stack(&to->timer, (flags & FLAGS_CLOCKRT) ? |
2216 | CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | 2210 | CLOCK_REALTIME : CLOCK_MONOTONIC, |
2211 | HRTIMER_MODE_ABS); | ||
2217 | hrtimer_init_sleeper(to, current); | 2212 | hrtimer_init_sleeper(to, current); |
2218 | hrtimer_set_expires_range_ns(&to->timer, *abs_time, | 2213 | hrtimer_set_expires_range_ns(&to->timer, *abs_time, |
2219 | current->timer_slack_ns); | 2214 | current->timer_slack_ns); |
@@ -2227,7 +2222,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared, | |||
2227 | rt_waiter.task = NULL; | 2222 | rt_waiter.task = NULL; |
2228 | 2223 | ||
2229 | key2 = FUTEX_KEY_INIT; | 2224 | key2 = FUTEX_KEY_INIT; |
2230 | ret = get_futex_key(uaddr2, fshared, &key2); | 2225 | ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); |
2231 | if (unlikely(ret != 0)) | 2226 | if (unlikely(ret != 0)) |
2232 | goto out; | 2227 | goto out; |
2233 | 2228 | ||
@@ -2240,7 +2235,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared, | |||
2240 | * Prepare to wait on uaddr. On success, increments q.key (key1) ref | 2235 | * Prepare to wait on uaddr. On success, increments q.key (key1) ref |
2241 | * count. | 2236 | * count. |
2242 | */ | 2237 | */ |
2243 | ret = futex_wait_setup(uaddr, val, fshared, &q, &hb); | 2238 | ret = futex_wait_setup(uaddr, val, flags, &q, &hb); |
2244 | if (ret) | 2239 | if (ret) |
2245 | goto out_key2; | 2240 | goto out_key2; |
2246 | 2241 | ||
@@ -2547,58 +2542,57 @@ void exit_robust_list(struct task_struct *curr) | |||
2547 | long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, | 2542 | long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, |
2548 | u32 __user *uaddr2, u32 val2, u32 val3) | 2543 | u32 __user *uaddr2, u32 val2, u32 val3) |
2549 | { | 2544 | { |
2550 | int clockrt, ret = -ENOSYS; | 2545 | int ret = -ENOSYS, cmd = op & FUTEX_CMD_MASK; |
2551 | int cmd = op & FUTEX_CMD_MASK; | 2546 | unsigned int flags = 0; |
2552 | int fshared = 0; | ||
2553 | 2547 | ||
2554 | if (!(op & FUTEX_PRIVATE_FLAG)) | 2548 | if (!(op & FUTEX_PRIVATE_FLAG)) |
2555 | fshared = 1; | 2549 | flags |= FLAGS_SHARED; |
2556 | 2550 | ||
2557 | clockrt = op & FUTEX_CLOCK_REALTIME; | 2551 | if (op & FUTEX_CLOCK_REALTIME) { |
2558 | if (clockrt && cmd != FUTEX_WAIT_BITSET && cmd != FUTEX_WAIT_REQUEUE_PI) | 2552 | flags |= FLAGS_CLOCKRT; |
2559 | return -ENOSYS; | 2553 | if (cmd != FUTEX_WAIT_BITSET && cmd != FUTEX_WAIT_REQUEUE_PI) |
2554 | return -ENOSYS; | ||
2555 | } | ||
2560 | 2556 | ||
2561 | switch (cmd) { | 2557 | switch (cmd) { |
2562 | case FUTEX_WAIT: | 2558 | case FUTEX_WAIT: |
2563 | val3 = FUTEX_BITSET_MATCH_ANY; | 2559 | val3 = FUTEX_BITSET_MATCH_ANY; |
2564 | case FUTEX_WAIT_BITSET: | 2560 | case FUTEX_WAIT_BITSET: |
2565 | ret = futex_wait(uaddr, fshared, val, timeout, val3, clockrt); | 2561 | ret = futex_wait(uaddr, flags, val, timeout, val3); |
2566 | break; | 2562 | break; |
2567 | case FUTEX_WAKE: | 2563 | case FUTEX_WAKE: |
2568 | val3 = FUTEX_BITSET_MATCH_ANY; | 2564 | val3 = FUTEX_BITSET_MATCH_ANY; |
2569 | case FUTEX_WAKE_BITSET: | 2565 | case FUTEX_WAKE_BITSET: |
2570 | ret = futex_wake(uaddr, fshared, val, val3); | 2566 | ret = futex_wake(uaddr, flags, val, val3); |
2571 | break; | 2567 | break; |
2572 | case FUTEX_REQUEUE: | 2568 | case FUTEX_REQUEUE: |
2573 | ret = futex_requeue(uaddr, fshared, uaddr2, val, val2, NULL, 0); | 2569 | ret = futex_requeue(uaddr, flags, uaddr2, val, val2, NULL, 0); |
2574 | break; | 2570 | break; |
2575 | case FUTEX_CMP_REQUEUE: | 2571 | case FUTEX_CMP_REQUEUE: |
2576 | ret = futex_requeue(uaddr, fshared, uaddr2, val, val2, &val3, | 2572 | ret = futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 0); |
2577 | 0); | ||
2578 | break; | 2573 | break; |
2579 | case FUTEX_WAKE_OP: | 2574 | case FUTEX_WAKE_OP: |
2580 | ret = futex_wake_op(uaddr, fshared, uaddr2, val, val2, val3); | 2575 | ret = futex_wake_op(uaddr, flags, uaddr2, val, val2, val3); |
2581 | break; | 2576 | break; |
2582 | case FUTEX_LOCK_PI: | 2577 | case FUTEX_LOCK_PI: |
2583 | if (futex_cmpxchg_enabled) | 2578 | if (futex_cmpxchg_enabled) |
2584 | ret = futex_lock_pi(uaddr, fshared, val, timeout, 0); | 2579 | ret = futex_lock_pi(uaddr, flags, val, timeout, 0); |
2585 | break; | 2580 | break; |
2586 | case FUTEX_UNLOCK_PI: | 2581 | case FUTEX_UNLOCK_PI: |
2587 | if (futex_cmpxchg_enabled) | 2582 | if (futex_cmpxchg_enabled) |
2588 | ret = futex_unlock_pi(uaddr, fshared); | 2583 | ret = futex_unlock_pi(uaddr, flags); |
2589 | break; | 2584 | break; |
2590 | case FUTEX_TRYLOCK_PI: | 2585 | case FUTEX_TRYLOCK_PI: |
2591 | if (futex_cmpxchg_enabled) | 2586 | if (futex_cmpxchg_enabled) |
2592 | ret = futex_lock_pi(uaddr, fshared, 0, timeout, 1); | 2587 | ret = futex_lock_pi(uaddr, flags, 0, timeout, 1); |
2593 | break; | 2588 | break; |
2594 | case FUTEX_WAIT_REQUEUE_PI: | 2589 | case FUTEX_WAIT_REQUEUE_PI: |
2595 | val3 = FUTEX_BITSET_MATCH_ANY; | 2590 | val3 = FUTEX_BITSET_MATCH_ANY; |
2596 | ret = futex_wait_requeue_pi(uaddr, fshared, val, timeout, val3, | 2591 | ret = futex_wait_requeue_pi(uaddr, flags, val, timeout, val3, |
2597 | clockrt, uaddr2); | 2592 | uaddr2); |
2598 | break; | 2593 | break; |
2599 | case FUTEX_CMP_REQUEUE_PI: | 2594 | case FUTEX_CMP_REQUEUE_PI: |
2600 | ret = futex_requeue(uaddr, fshared, uaddr2, val, val2, &val3, | 2595 | ret = futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 1); |
2601 | 1); | ||
2602 | break; | 2596 | break; |
2603 | default: | 2597 | default: |
2604 | ret = -ENOSYS; | 2598 | ret = -ENOSYS; |