diff options
| -rw-r--r-- | kernel/futex.c | 40 |
1 files changed, 18 insertions, 22 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index 520e7b23bf3c..e1cb1baa23fb 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
| @@ -1052,6 +1052,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) | |||
| 1052 | struct task_struct *new_owner; | 1052 | struct task_struct *new_owner; |
| 1053 | struct futex_pi_state *pi_state = this->pi_state; | 1053 | struct futex_pi_state *pi_state = this->pi_state; |
| 1054 | u32 uninitialized_var(curval), newval; | 1054 | u32 uninitialized_var(curval), newval; |
| 1055 | int ret = 0; | ||
| 1055 | 1056 | ||
| 1056 | if (!pi_state) | 1057 | if (!pi_state) |
| 1057 | return -EINVAL; | 1058 | return -EINVAL; |
| @@ -1075,23 +1076,19 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) | |||
| 1075 | new_owner = this->task; | 1076 | new_owner = this->task; |
| 1076 | 1077 | ||
| 1077 | /* | 1078 | /* |
| 1078 | * We pass it to the next owner. (The WAITERS bit is always | 1079 | * We pass it to the next owner. The WAITERS bit is always |
| 1079 | * kept enabled while there is PI state around. We must also | 1080 | * kept enabled while there is PI state around. We cleanup the |
| 1080 | * preserve the owner died bit.) | 1081 | * owner died bit, because we are the owner. |
| 1081 | */ | 1082 | */ |
| 1082 | if (!(uval & FUTEX_OWNER_DIED)) { | 1083 | newval = FUTEX_WAITERS | task_pid_vnr(new_owner); |
| 1083 | int ret = 0; | ||
| 1084 | |||
| 1085 | newval = FUTEX_WAITERS | task_pid_vnr(new_owner); | ||
| 1086 | 1084 | ||
| 1087 | if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) | 1085 | if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) |
| 1088 | ret = -EFAULT; | 1086 | ret = -EFAULT; |
| 1089 | else if (curval != uval) | 1087 | else if (curval != uval) |
| 1090 | ret = -EINVAL; | 1088 | ret = -EINVAL; |
| 1091 | if (ret) { | 1089 | if (ret) { |
| 1092 | raw_spin_unlock(&pi_state->pi_mutex.wait_lock); | 1090 | raw_spin_unlock(&pi_state->pi_mutex.wait_lock); |
| 1093 | return ret; | 1091 | return ret; |
| 1094 | } | ||
| 1095 | } | 1092 | } |
| 1096 | 1093 | ||
| 1097 | raw_spin_lock_irq(&pi_state->owner->pi_lock); | 1094 | raw_spin_lock_irq(&pi_state->owner->pi_lock); |
| @@ -2351,9 +2348,10 @@ retry: | |||
| 2351 | /* | 2348 | /* |
| 2352 | * To avoid races, try to do the TID -> 0 atomic transition | 2349 | * To avoid races, try to do the TID -> 0 atomic transition |
| 2353 | * again. If it succeeds then we can return without waking | 2350 | * again. If it succeeds then we can return without waking |
| 2354 | * anyone else up: | 2351 | * anyone else up. We only try this if neither the waiters nor |
| 2352 | * the owner died bit are set. | ||
| 2355 | */ | 2353 | */ |
| 2356 | if (!(uval & FUTEX_OWNER_DIED) && | 2354 | if (!(uval & ~FUTEX_TID_MASK) && |
| 2357 | cmpxchg_futex_value_locked(&uval, uaddr, vpid, 0)) | 2355 | cmpxchg_futex_value_locked(&uval, uaddr, vpid, 0)) |
| 2358 | goto pi_faulted; | 2356 | goto pi_faulted; |
| 2359 | /* | 2357 | /* |
| @@ -2383,11 +2381,9 @@ retry: | |||
| 2383 | /* | 2381 | /* |
| 2384 | * No waiters - kernel unlocks the futex: | 2382 | * No waiters - kernel unlocks the futex: |
| 2385 | */ | 2383 | */ |
| 2386 | if (!(uval & FUTEX_OWNER_DIED)) { | 2384 | ret = unlock_futex_pi(uaddr, uval); |
| 2387 | ret = unlock_futex_pi(uaddr, uval); | 2385 | if (ret == -EFAULT) |
| 2388 | if (ret == -EFAULT) | 2386 | goto pi_faulted; |
| 2389 | goto pi_faulted; | ||
| 2390 | } | ||
| 2391 | 2387 | ||
| 2392 | out_unlock: | 2388 | out_unlock: |
| 2393 | spin_unlock(&hb->lock); | 2389 | spin_unlock(&hb->lock); |
