diff options
-rw-r--r-- | kernel/futex.c | 49 |
1 files changed, 9 insertions, 40 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index 2aa216e5b594..80b5ce716596 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -1507,7 +1507,6 @@ handle_fault: | |||
1507 | #define FLAGS_HAS_TIMEOUT 0x04 | 1507 | #define FLAGS_HAS_TIMEOUT 0x04 |
1508 | 1508 | ||
1509 | static long futex_wait_restart(struct restart_block *restart); | 1509 | static long futex_wait_restart(struct restart_block *restart); |
1510 | static long futex_lock_pi_restart(struct restart_block *restart); | ||
1511 | 1510 | ||
1512 | /** | 1511 | /** |
1513 | * fixup_owner() - Post lock pi_state and corner case management | 1512 | * fixup_owner() - Post lock pi_state and corner case management |
@@ -1930,21 +1929,6 @@ uaddr_faulted: | |||
1930 | goto retry; | 1929 | goto retry; |
1931 | } | 1930 | } |
1932 | 1931 | ||
1933 | static long futex_lock_pi_restart(struct restart_block *restart) | ||
1934 | { | ||
1935 | u32 __user *uaddr = (u32 __user *)restart->futex.uaddr; | ||
1936 | ktime_t t, *tp = NULL; | ||
1937 | int fshared = restart->futex.flags & FLAGS_SHARED; | ||
1938 | |||
1939 | if (restart->futex.flags & FLAGS_HAS_TIMEOUT) { | ||
1940 | t.tv64 = restart->futex.time; | ||
1941 | tp = &t; | ||
1942 | } | ||
1943 | restart->fn = do_no_restart_syscall; | ||
1944 | |||
1945 | return (long)futex_lock_pi(uaddr, fshared, restart->futex.val, tp, 0); | ||
1946 | } | ||
1947 | |||
1948 | /* | 1932 | /* |
1949 | * Userspace attempted a TID -> 0 atomic transition, and failed. | 1933 | * Userspace attempted a TID -> 0 atomic transition, and failed. |
1950 | * This is the in-kernel slowpath: we look up the PI state (if any), | 1934 | * This is the in-kernel slowpath: we look up the PI state (if any), |
@@ -2141,12 +2125,10 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared, | |||
2141 | struct hrtimer_sleeper timeout, *to = NULL; | 2125 | struct hrtimer_sleeper timeout, *to = NULL; |
2142 | struct rt_mutex_waiter rt_waiter; | 2126 | struct rt_mutex_waiter rt_waiter; |
2143 | struct rt_mutex *pi_mutex = NULL; | 2127 | struct rt_mutex *pi_mutex = NULL; |
2144 | struct restart_block *restart; | ||
2145 | struct futex_hash_bucket *hb; | 2128 | struct futex_hash_bucket *hb; |
2146 | union futex_key key2; | 2129 | union futex_key key2; |
2147 | struct futex_q q; | 2130 | struct futex_q q; |
2148 | int res, ret; | 2131 | int res, ret; |
2149 | u32 uval; | ||
2150 | 2132 | ||
2151 | if (!bitset) | 2133 | if (!bitset) |
2152 | return -EINVAL; | 2134 | return -EINVAL; |
@@ -2245,30 +2227,17 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared, | |||
2245 | if (rt_mutex_owner(pi_mutex) == current) | 2227 | if (rt_mutex_owner(pi_mutex) == current) |
2246 | rt_mutex_unlock(pi_mutex); | 2228 | rt_mutex_unlock(pi_mutex); |
2247 | } else if (ret == -EINTR) { | 2229 | } else if (ret == -EINTR) { |
2248 | ret = -EFAULT; | ||
2249 | if (get_user(uval, uaddr2)) | ||
2250 | goto out_put_keys; | ||
2251 | |||
2252 | /* | 2230 | /* |
2253 | * We've already been requeued, so restart by calling | 2231 | * We've already been requeued, but we have no way to |
2254 | * futex_lock_pi() directly, rather then returning to this | 2232 | * restart by calling futex_lock_pi() directly. We |
2255 | * function. | 2233 | * could restart the syscall, but that will look at |
2234 | * the user space value and return right away. So we | ||
2235 | * drop back with EWOULDBLOCK to tell user space that | ||
2236 | * "val" has been changed. That's the same what the | ||
2237 | * restart of the syscall would do in | ||
2238 | * futex_wait_setup(). | ||
2256 | */ | 2239 | */ |
2257 | ret = -ERESTART_RESTARTBLOCK; | 2240 | ret = -EWOULDBLOCK; |
2258 | restart = ¤t_thread_info()->restart_block; | ||
2259 | restart->fn = futex_lock_pi_restart; | ||
2260 | restart->futex.uaddr = (u32 *)uaddr2; | ||
2261 | restart->futex.val = uval; | ||
2262 | restart->futex.flags = 0; | ||
2263 | if (abs_time) { | ||
2264 | restart->futex.flags |= FLAGS_HAS_TIMEOUT; | ||
2265 | restart->futex.time = abs_time->tv64; | ||
2266 | } | ||
2267 | |||
2268 | if (fshared) | ||
2269 | restart->futex.flags |= FLAGS_SHARED; | ||
2270 | if (clockrt) | ||
2271 | restart->futex.flags |= FLAGS_CLOCKRT; | ||
2272 | } | 2241 | } |
2273 | 2242 | ||
2274 | out_put_keys: | 2243 | out_put_keys: |