diff options
Diffstat (limited to 'kernel/futex.c')
| -rw-r--r-- | kernel/futex.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index e2b0fb9a0b3b..3717e7b306e0 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
| @@ -2231,11 +2231,11 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, | |||
| 2231 | * @uaddr2: the pi futex we will take prior to returning to user-space | 2231 | * @uaddr2: the pi futex we will take prior to returning to user-space |
| 2232 | * | 2232 | * |
| 2233 | * The caller will wait on uaddr and will be requeued by futex_requeue() to | 2233 | * The caller will wait on uaddr and will be requeued by futex_requeue() to |
| 2234 | * uaddr2 which must be PI aware. Normal wakeup will wake on uaddr2 and | 2234 | * uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake |
| 2235 | * complete the acquisition of the rt_mutex prior to returning to userspace. | 2235 | * on uaddr2 and complete the acquisition of the rt_mutex prior to returning to |
| 2236 | * This ensures the rt_mutex maintains an owner when it has waiters; without | 2236 | * userspace. This ensures the rt_mutex maintains an owner when it has waiters; |
| 2237 | * one, the pi logic wouldn't know which task to boost/deboost, if there was a | 2237 | * without one, the pi logic would not know which task to boost/deboost, if |
| 2238 | * need to. | 2238 | * there was a need to. |
| 2239 | * | 2239 | * |
| 2240 | * We call schedule in futex_wait_queue_me() when we enqueue and return there | 2240 | * We call schedule in futex_wait_queue_me() when we enqueue and return there |
| 2241 | * via the following: | 2241 | * via the following: |
| @@ -2272,6 +2272,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
| 2272 | struct futex_q q = futex_q_init; | 2272 | struct futex_q q = futex_q_init; |
| 2273 | int res, ret; | 2273 | int res, ret; |
| 2274 | 2274 | ||
| 2275 | if (uaddr == uaddr2) | ||
| 2276 | return -EINVAL; | ||
| 2277 | |||
| 2275 | if (!bitset) | 2278 | if (!bitset) |
| 2276 | return -EINVAL; | 2279 | return -EINVAL; |
| 2277 | 2280 | ||
| @@ -2343,7 +2346,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
| 2343 | * signal. futex_unlock_pi() will not destroy the lock_ptr nor | 2346 | * signal. futex_unlock_pi() will not destroy the lock_ptr nor |
| 2344 | * the pi_state. | 2347 | * the pi_state. |
| 2345 | */ | 2348 | */ |
| 2346 | WARN_ON(!&q.pi_state); | 2349 | WARN_ON(!q.pi_state); |
| 2347 | pi_mutex = &q.pi_state->pi_mutex; | 2350 | pi_mutex = &q.pi_state->pi_mutex; |
| 2348 | ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1); | 2351 | ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1); |
| 2349 | debug_rt_mutex_free_waiter(&rt_waiter); | 2352 | debug_rt_mutex_free_waiter(&rt_waiter); |
| @@ -2370,7 +2373,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
| 2370 | * fault, unlock the rt_mutex and return the fault to userspace. | 2373 | * fault, unlock the rt_mutex and return the fault to userspace. |
| 2371 | */ | 2374 | */ |
| 2372 | if (ret == -EFAULT) { | 2375 | if (ret == -EFAULT) { |
| 2373 | if (rt_mutex_owner(pi_mutex) == current) | 2376 | if (pi_mutex && rt_mutex_owner(pi_mutex) == current) |
| 2374 | rt_mutex_unlock(pi_mutex); | 2377 | rt_mutex_unlock(pi_mutex); |
| 2375 | } else if (ret == -EINTR) { | 2378 | } else if (ret == -EINTR) { |
| 2376 | /* | 2379 | /* |
