diff options
Diffstat (limited to 'kernel/futex.c')
-rw-r--r-- | kernel/futex.c | 209 |
1 files changed, 124 insertions, 85 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index 3019b92e6917..bda415715382 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -233,7 +233,7 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) | |||
233 | { | 233 | { |
234 | unsigned long address = (unsigned long)uaddr; | 234 | unsigned long address = (unsigned long)uaddr; |
235 | struct mm_struct *mm = current->mm; | 235 | struct mm_struct *mm = current->mm; |
236 | struct page *page; | 236 | struct page *page, *page_head; |
237 | int err; | 237 | int err; |
238 | 238 | ||
239 | /* | 239 | /* |
@@ -265,11 +265,46 @@ again: | |||
265 | if (err < 0) | 265 | if (err < 0) |
266 | return err; | 266 | return err; |
267 | 267 | ||
268 | page = compound_head(page); | 268 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
269 | lock_page(page); | 269 | page_head = page; |
270 | if (!page->mapping) { | 270 | if (unlikely(PageTail(page))) { |
271 | unlock_page(page); | ||
272 | put_page(page); | 271 | put_page(page); |
272 | /* serialize against __split_huge_page_splitting() */ | ||
273 | local_irq_disable(); | ||
274 | if (likely(__get_user_pages_fast(address, 1, 1, &page) == 1)) { | ||
275 | page_head = compound_head(page); | ||
276 | /* | ||
277 | * page_head is valid pointer but we must pin | ||
278 | * it before taking the PG_lock and/or | ||
279 | * PG_compound_lock. The moment we re-enable | ||
280 | * irqs __split_huge_page_splitting() can | ||
281 | * return and the head page can be freed from | ||
282 | * under us. We can't take the PG_lock and/or | ||
283 | * PG_compound_lock on a page that could be | ||
284 | * freed from under us. | ||
285 | */ | ||
286 | if (page != page_head) { | ||
287 | get_page(page_head); | ||
288 | put_page(page); | ||
289 | } | ||
290 | local_irq_enable(); | ||
291 | } else { | ||
292 | local_irq_enable(); | ||
293 | goto again; | ||
294 | } | ||
295 | } | ||
296 | #else | ||
297 | page_head = compound_head(page); | ||
298 | if (page != page_head) { | ||
299 | get_page(page_head); | ||
300 | put_page(page); | ||
301 | } | ||
302 | #endif | ||
303 | |||
304 | lock_page(page_head); | ||
305 | if (!page_head->mapping) { | ||
306 | unlock_page(page_head); | ||
307 | put_page(page_head); | ||
273 | goto again; | 308 | goto again; |
274 | } | 309 | } |
275 | 310 | ||
@@ -280,20 +315,20 @@ again: | |||
280 | * it's a read-only handle, it's expected that futexes attach to | 315 | * it's a read-only handle, it's expected that futexes attach to |
281 | * the object not the particular process. | 316 | * the object not the particular process. |
282 | */ | 317 | */ |
283 | if (PageAnon(page)) { | 318 | if (PageAnon(page_head)) { |
284 | key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */ | 319 | key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */ |
285 | key->private.mm = mm; | 320 | key->private.mm = mm; |
286 | key->private.address = address; | 321 | key->private.address = address; |
287 | } else { | 322 | } else { |
288 | key->both.offset |= FUT_OFF_INODE; /* inode-based key */ | 323 | key->both.offset |= FUT_OFF_INODE; /* inode-based key */ |
289 | key->shared.inode = page->mapping->host; | 324 | key->shared.inode = page_head->mapping->host; |
290 | key->shared.pgoff = page->index; | 325 | key->shared.pgoff = page_head->index; |
291 | } | 326 | } |
292 | 327 | ||
293 | get_futex_key_refs(key); | 328 | get_futex_key_refs(key); |
294 | 329 | ||
295 | unlock_page(page); | 330 | unlock_page(page_head); |
296 | put_page(page); | 331 | put_page(page_head); |
297 | return 0; | 332 | return 0; |
298 | } | 333 | } |
299 | 334 | ||
@@ -346,15 +381,16 @@ static struct futex_q *futex_top_waiter(struct futex_hash_bucket *hb, | |||
346 | return NULL; | 381 | return NULL; |
347 | } | 382 | } |
348 | 383 | ||
349 | static u32 cmpxchg_futex_value_locked(u32 __user *uaddr, u32 uval, u32 newval) | 384 | static int cmpxchg_futex_value_locked(u32 *curval, u32 __user *uaddr, |
385 | u32 uval, u32 newval) | ||
350 | { | 386 | { |
351 | u32 curval; | 387 | int ret; |
352 | 388 | ||
353 | pagefault_disable(); | 389 | pagefault_disable(); |
354 | curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); | 390 | ret = futex_atomic_cmpxchg_inatomic(curval, uaddr, uval, newval); |
355 | pagefault_enable(); | 391 | pagefault_enable(); |
356 | 392 | ||
357 | return curval; | 393 | return ret; |
358 | } | 394 | } |
359 | 395 | ||
360 | static int get_futex_value_locked(u32 *dest, u32 __user *from) | 396 | static int get_futex_value_locked(u32 *dest, u32 __user *from) |
@@ -639,7 +675,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, | |||
639 | struct task_struct *task, int set_waiters) | 675 | struct task_struct *task, int set_waiters) |
640 | { | 676 | { |
641 | int lock_taken, ret, ownerdied = 0; | 677 | int lock_taken, ret, ownerdied = 0; |
642 | u32 uval, newval, curval; | 678 | u32 uval, newval, curval, vpid = task_pid_vnr(task); |
643 | 679 | ||
644 | retry: | 680 | retry: |
645 | ret = lock_taken = 0; | 681 | ret = lock_taken = 0; |
@@ -649,19 +685,17 @@ retry: | |||
649 | * (by doing a 0 -> TID atomic cmpxchg), while holding all | 685 | * (by doing a 0 -> TID atomic cmpxchg), while holding all |
650 | * the locks. It will most likely not succeed. | 686 | * the locks. It will most likely not succeed. |
651 | */ | 687 | */ |
652 | newval = task_pid_vnr(task); | 688 | newval = vpid; |
653 | if (set_waiters) | 689 | if (set_waiters) |
654 | newval |= FUTEX_WAITERS; | 690 | newval |= FUTEX_WAITERS; |
655 | 691 | ||
656 | curval = cmpxchg_futex_value_locked(uaddr, 0, newval); | 692 | if (unlikely(cmpxchg_futex_value_locked(&curval, uaddr, 0, newval))) |
657 | |||
658 | if (unlikely(curval == -EFAULT)) | ||
659 | return -EFAULT; | 693 | return -EFAULT; |
660 | 694 | ||
661 | /* | 695 | /* |
662 | * Detect deadlocks. | 696 | * Detect deadlocks. |
663 | */ | 697 | */ |
664 | if ((unlikely((curval & FUTEX_TID_MASK) == task_pid_vnr(task)))) | 698 | if ((unlikely((curval & FUTEX_TID_MASK) == vpid))) |
665 | return -EDEADLK; | 699 | return -EDEADLK; |
666 | 700 | ||
667 | /* | 701 | /* |
@@ -688,14 +722,12 @@ retry: | |||
688 | */ | 722 | */ |
689 | if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { | 723 | if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { |
690 | /* Keep the OWNER_DIED bit */ | 724 | /* Keep the OWNER_DIED bit */ |
691 | newval = (curval & ~FUTEX_TID_MASK) | task_pid_vnr(task); | 725 | newval = (curval & ~FUTEX_TID_MASK) | vpid; |
692 | ownerdied = 0; | 726 | ownerdied = 0; |
693 | lock_taken = 1; | 727 | lock_taken = 1; |
694 | } | 728 | } |
695 | 729 | ||
696 | curval = cmpxchg_futex_value_locked(uaddr, uval, newval); | 730 | if (unlikely(cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))) |
697 | |||
698 | if (unlikely(curval == -EFAULT)) | ||
699 | return -EFAULT; | 731 | return -EFAULT; |
700 | if (unlikely(curval != uval)) | 732 | if (unlikely(curval != uval)) |
701 | goto retry; | 733 | goto retry; |
@@ -740,6 +772,24 @@ retry: | |||
740 | return ret; | 772 | return ret; |
741 | } | 773 | } |
742 | 774 | ||
775 | /** | ||
776 | * __unqueue_futex() - Remove the futex_q from its futex_hash_bucket | ||
777 | * @q: The futex_q to unqueue | ||
778 | * | ||
779 | * The q->lock_ptr must not be NULL and must be held by the caller. | ||
780 | */ | ||
781 | static void __unqueue_futex(struct futex_q *q) | ||
782 | { | ||
783 | struct futex_hash_bucket *hb; | ||
784 | |||
785 | if (WARN_ON(!q->lock_ptr || !spin_is_locked(q->lock_ptr) | ||
786 | || plist_node_empty(&q->list))) | ||
787 | return; | ||
788 | |||
789 | hb = container_of(q->lock_ptr, struct futex_hash_bucket, lock); | ||
790 | plist_del(&q->list, &hb->chain); | ||
791 | } | ||
792 | |||
743 | /* | 793 | /* |
744 | * The hash bucket lock must be held when this is called. | 794 | * The hash bucket lock must be held when this is called. |
745 | * Afterwards, the futex_q must not be accessed. | 795 | * Afterwards, the futex_q must not be accessed. |
@@ -757,7 +807,7 @@ static void wake_futex(struct futex_q *q) | |||
757 | */ | 807 | */ |
758 | get_task_struct(p); | 808 | get_task_struct(p); |
759 | 809 | ||
760 | plist_del(&q->list, &q->list.plist); | 810 | __unqueue_futex(q); |
761 | /* | 811 | /* |
762 | * The waiting task can free the futex_q as soon as | 812 | * The waiting task can free the futex_q as soon as |
763 | * q->lock_ptr = NULL is written, without taking any locks. A | 813 | * q->lock_ptr = NULL is written, without taking any locks. A |
@@ -791,10 +841,9 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) | |||
791 | new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); | 841 | new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); |
792 | 842 | ||
793 | /* | 843 | /* |
794 | * This happens when we have stolen the lock and the original | 844 | * It is possible that the next waiter (the one that brought |
795 | * pending owner did not enqueue itself back on the rt_mutex. | 845 | * this owner to the kernel) timed out and is no longer |
796 | * Thats not a tragedy. We know that way, that a lock waiter | 846 | * waiting on the lock. |
797 | * is on the fly. We make the futex_q waiter the pending owner. | ||
798 | */ | 847 | */ |
799 | if (!new_owner) | 848 | if (!new_owner) |
800 | new_owner = this->task; | 849 | new_owner = this->task; |
@@ -809,9 +858,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) | |||
809 | 858 | ||
810 | newval = FUTEX_WAITERS | task_pid_vnr(new_owner); | 859 | newval = FUTEX_WAITERS | task_pid_vnr(new_owner); |
811 | 860 | ||
812 | curval = cmpxchg_futex_value_locked(uaddr, uval, newval); | 861 | if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) |
813 | |||
814 | if (curval == -EFAULT) | ||
815 | ret = -EFAULT; | 862 | ret = -EFAULT; |
816 | else if (curval != uval) | 863 | else if (curval != uval) |
817 | ret = -EINVAL; | 864 | ret = -EINVAL; |
@@ -846,10 +893,8 @@ static int unlock_futex_pi(u32 __user *uaddr, u32 uval) | |||
846 | * There is no waiter, so we unlock the futex. The owner died | 893 | * There is no waiter, so we unlock the futex. The owner died |
847 | * bit has not to be preserved here. We are the owner: | 894 | * bit has not to be preserved here. We are the owner: |
848 | */ | 895 | */ |
849 | oldval = cmpxchg_futex_value_locked(uaddr, uval, 0); | 896 | if (cmpxchg_futex_value_locked(&oldval, uaddr, uval, 0)) |
850 | 897 | return -EFAULT; | |
851 | if (oldval == -EFAULT) | ||
852 | return oldval; | ||
853 | if (oldval != uval) | 898 | if (oldval != uval) |
854 | return -EAGAIN; | 899 | return -EAGAIN; |
855 | 900 | ||
@@ -1037,9 +1082,6 @@ void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1, | |||
1037 | plist_del(&q->list, &hb1->chain); | 1082 | plist_del(&q->list, &hb1->chain); |
1038 | plist_add(&q->list, &hb2->chain); | 1083 | plist_add(&q->list, &hb2->chain); |
1039 | q->lock_ptr = &hb2->lock; | 1084 | q->lock_ptr = &hb2->lock; |
1040 | #ifdef CONFIG_DEBUG_PI_LIST | ||
1041 | q->list.plist.spinlock = &hb2->lock; | ||
1042 | #endif | ||
1043 | } | 1085 | } |
1044 | get_futex_key_refs(key2); | 1086 | get_futex_key_refs(key2); |
1045 | q->key = *key2; | 1087 | q->key = *key2; |
@@ -1066,16 +1108,12 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key, | |||
1066 | get_futex_key_refs(key); | 1108 | get_futex_key_refs(key); |
1067 | q->key = *key; | 1109 | q->key = *key; |
1068 | 1110 | ||
1069 | WARN_ON(plist_node_empty(&q->list)); | 1111 | __unqueue_futex(q); |
1070 | plist_del(&q->list, &q->list.plist); | ||
1071 | 1112 | ||
1072 | WARN_ON(!q->rt_waiter); | 1113 | WARN_ON(!q->rt_waiter); |
1073 | q->rt_waiter = NULL; | 1114 | q->rt_waiter = NULL; |
1074 | 1115 | ||
1075 | q->lock_ptr = &hb->lock; | 1116 | q->lock_ptr = &hb->lock; |
1076 | #ifdef CONFIG_DEBUG_PI_LIST | ||
1077 | q->list.plist.spinlock = &hb->lock; | ||
1078 | #endif | ||
1079 | 1117 | ||
1080 | wake_up_state(q->task, TASK_NORMAL); | 1118 | wake_up_state(q->task, TASK_NORMAL); |
1081 | } | 1119 | } |
@@ -1423,9 +1461,6 @@ static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb) | |||
1423 | prio = min(current->normal_prio, MAX_RT_PRIO); | 1461 | prio = min(current->normal_prio, MAX_RT_PRIO); |
1424 | 1462 | ||
1425 | plist_node_init(&q->list, prio); | 1463 | plist_node_init(&q->list, prio); |
1426 | #ifdef CONFIG_DEBUG_PI_LIST | ||
1427 | q->list.plist.spinlock = &hb->lock; | ||
1428 | #endif | ||
1429 | plist_add(&q->list, &hb->chain); | 1464 | plist_add(&q->list, &hb->chain); |
1430 | q->task = current; | 1465 | q->task = current; |
1431 | spin_unlock(&hb->lock); | 1466 | spin_unlock(&hb->lock); |
@@ -1470,8 +1505,7 @@ retry: | |||
1470 | spin_unlock(lock_ptr); | 1505 | spin_unlock(lock_ptr); |
1471 | goto retry; | 1506 | goto retry; |
1472 | } | 1507 | } |
1473 | WARN_ON(plist_node_empty(&q->list)); | 1508 | __unqueue_futex(q); |
1474 | plist_del(&q->list, &q->list.plist); | ||
1475 | 1509 | ||
1476 | BUG_ON(q->pi_state); | 1510 | BUG_ON(q->pi_state); |
1477 | 1511 | ||
@@ -1491,8 +1525,7 @@ retry: | |||
1491 | static void unqueue_me_pi(struct futex_q *q) | 1525 | static void unqueue_me_pi(struct futex_q *q) |
1492 | __releases(q->lock_ptr) | 1526 | __releases(q->lock_ptr) |
1493 | { | 1527 | { |
1494 | WARN_ON(plist_node_empty(&q->list)); | 1528 | __unqueue_futex(q); |
1495 | plist_del(&q->list, &q->list.plist); | ||
1496 | 1529 | ||
1497 | BUG_ON(!q->pi_state); | 1530 | BUG_ON(!q->pi_state); |
1498 | free_pi_state(q->pi_state); | 1531 | free_pi_state(q->pi_state); |
@@ -1522,10 +1555,10 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, | |||
1522 | 1555 | ||
1523 | /* | 1556 | /* |
1524 | * We are here either because we stole the rtmutex from the | 1557 | * We are here either because we stole the rtmutex from the |
1525 | * pending owner or we are the pending owner which failed to | 1558 | * previous highest priority waiter or we are the highest priority |
1526 | * get the rtmutex. We have to replace the pending owner TID | 1559 | * waiter but failed to get the rtmutex the first time. |
1527 | * in the user space variable. This must be atomic as we have | 1560 | * We have to replace the newowner TID in the user space variable. |
1528 | * to preserve the owner died bit here. | 1561 | * This must be atomic as we have to preserve the owner died bit here. |
1529 | * | 1562 | * |
1530 | * Note: We write the user space value _before_ changing the pi_state | 1563 | * Note: We write the user space value _before_ changing the pi_state |
1531 | * because we can fault here. Imagine swapped out pages or a fork | 1564 | * because we can fault here. Imagine swapped out pages or a fork |
@@ -1544,9 +1577,7 @@ retry: | |||
1544 | while (1) { | 1577 | while (1) { |
1545 | newval = (uval & FUTEX_OWNER_DIED) | newtid; | 1578 | newval = (uval & FUTEX_OWNER_DIED) | newtid; |
1546 | 1579 | ||
1547 | curval = cmpxchg_futex_value_locked(uaddr, uval, newval); | 1580 | if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) |
1548 | |||
1549 | if (curval == -EFAULT) | ||
1550 | goto handle_fault; | 1581 | goto handle_fault; |
1551 | if (curval == uval) | 1582 | if (curval == uval) |
1552 | break; | 1583 | break; |
@@ -1574,8 +1605,8 @@ retry: | |||
1574 | 1605 | ||
1575 | /* | 1606 | /* |
1576 | * To handle the page fault we need to drop the hash bucket | 1607 | * To handle the page fault we need to drop the hash bucket |
1577 | * lock here. That gives the other task (either the pending | 1608 | * lock here. That gives the other task (either the highest priority |
1578 | * owner itself or the task which stole the rtmutex) the | 1609 | * waiter itself or the task which stole the rtmutex) the |
1579 | * chance to try the fixup of the pi_state. So once we are | 1610 | * chance to try the fixup of the pi_state. So once we are |
1580 | * back from handling the fault we need to check the pi_state | 1611 | * back from handling the fault we need to check the pi_state |
1581 | * after reacquiring the hash bucket lock and before trying to | 1612 | * after reacquiring the hash bucket lock and before trying to |
@@ -1651,18 +1682,20 @@ static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked) | |||
1651 | /* | 1682 | /* |
1652 | * pi_state is incorrect, some other task did a lock steal and | 1683 | * pi_state is incorrect, some other task did a lock steal and |
1653 | * we returned due to timeout or signal without taking the | 1684 | * we returned due to timeout or signal without taking the |
1654 | * rt_mutex. Too late. We can access the rt_mutex_owner without | 1685 | * rt_mutex. Too late. |
1655 | * locking, as the other task is now blocked on the hash bucket | ||
1656 | * lock. Fix the state up. | ||
1657 | */ | 1686 | */ |
1687 | raw_spin_lock(&q->pi_state->pi_mutex.wait_lock); | ||
1658 | owner = rt_mutex_owner(&q->pi_state->pi_mutex); | 1688 | owner = rt_mutex_owner(&q->pi_state->pi_mutex); |
1689 | if (!owner) | ||
1690 | owner = rt_mutex_next_owner(&q->pi_state->pi_mutex); | ||
1691 | raw_spin_unlock(&q->pi_state->pi_mutex.wait_lock); | ||
1659 | ret = fixup_pi_state_owner(uaddr, q, owner); | 1692 | ret = fixup_pi_state_owner(uaddr, q, owner); |
1660 | goto out; | 1693 | goto out; |
1661 | } | 1694 | } |
1662 | 1695 | ||
1663 | /* | 1696 | /* |
1664 | * Paranoia check. If we did not take the lock, then we should not be | 1697 | * Paranoia check. If we did not take the lock, then we should not be |
1665 | * the owner, nor the pending owner, of the rt_mutex. | 1698 | * the owner of the rt_mutex. |
1666 | */ | 1699 | */ |
1667 | if (rt_mutex_owner(&q->pi_state->pi_mutex) == current) | 1700 | if (rt_mutex_owner(&q->pi_state->pi_mutex) == current) |
1668 | printk(KERN_ERR "fixup_owner: ret = %d pi-mutex: %p " | 1701 | printk(KERN_ERR "fixup_owner: ret = %d pi-mutex: %p " |
@@ -1747,13 +1780,14 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, | |||
1747 | * | 1780 | * |
1748 | * The basic logical guarantee of a futex is that it blocks ONLY | 1781 | * The basic logical guarantee of a futex is that it blocks ONLY |
1749 | * if cond(var) is known to be true at the time of blocking, for | 1782 | * if cond(var) is known to be true at the time of blocking, for |
1750 | * any cond. If we queued after testing *uaddr, that would open | 1783 | * any cond. If we locked the hash-bucket after testing *uaddr, that |
1751 | * a race condition where we could block indefinitely with | 1784 | * would open a race condition where we could block indefinitely with |
1752 | * cond(var) false, which would violate the guarantee. | 1785 | * cond(var) false, which would violate the guarantee. |
1753 | * | 1786 | * |
1754 | * A consequence is that futex_wait() can return zero and absorb | 1787 | * On the other hand, we insert q and release the hash-bucket only |
1755 | * a wakeup when *uaddr != val on entry to the syscall. This is | 1788 | * after testing *uaddr. This guarantees that futex_wait() will NOT |
1756 | * rare, but normal. | 1789 | * absorb a wakeup if *uaddr does not match the desired values |
1790 | * while the syscall executes. | ||
1757 | */ | 1791 | */ |
1758 | retry: | 1792 | retry: |
1759 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key); | 1793 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key); |
@@ -2012,9 +2046,9 @@ static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags) | |||
2012 | { | 2046 | { |
2013 | struct futex_hash_bucket *hb; | 2047 | struct futex_hash_bucket *hb; |
2014 | struct futex_q *this, *next; | 2048 | struct futex_q *this, *next; |
2015 | u32 uval; | ||
2016 | struct plist_head *head; | 2049 | struct plist_head *head; |
2017 | union futex_key key = FUTEX_KEY_INIT; | 2050 | union futex_key key = FUTEX_KEY_INIT; |
2051 | u32 uval, vpid = task_pid_vnr(current); | ||
2018 | int ret; | 2052 | int ret; |
2019 | 2053 | ||
2020 | retry: | 2054 | retry: |
@@ -2023,7 +2057,7 @@ retry: | |||
2023 | /* | 2057 | /* |
2024 | * We release only a lock we actually own: | 2058 | * We release only a lock we actually own: |
2025 | */ | 2059 | */ |
2026 | if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current)) | 2060 | if ((uval & FUTEX_TID_MASK) != vpid) |
2027 | return -EPERM; | 2061 | return -EPERM; |
2028 | 2062 | ||
2029 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); | 2063 | ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); |
@@ -2038,17 +2072,14 @@ retry: | |||
2038 | * again. If it succeeds then we can return without waking | 2072 | * again. If it succeeds then we can return without waking |
2039 | * anyone else up: | 2073 | * anyone else up: |
2040 | */ | 2074 | */ |
2041 | if (!(uval & FUTEX_OWNER_DIED)) | 2075 | if (!(uval & FUTEX_OWNER_DIED) && |
2042 | uval = cmpxchg_futex_value_locked(uaddr, task_pid_vnr(current), 0); | 2076 | cmpxchg_futex_value_locked(&uval, uaddr, vpid, 0)) |
2043 | |||
2044 | |||
2045 | if (unlikely(uval == -EFAULT)) | ||
2046 | goto pi_faulted; | 2077 | goto pi_faulted; |
2047 | /* | 2078 | /* |
2048 | * Rare case: we managed to release the lock atomically, | 2079 | * Rare case: we managed to release the lock atomically, |
2049 | * no need to wake anyone else up: | 2080 | * no need to wake anyone else up: |
2050 | */ | 2081 | */ |
2051 | if (unlikely(uval == task_pid_vnr(current))) | 2082 | if (unlikely(uval == vpid)) |
2052 | goto out_unlock; | 2083 | goto out_unlock; |
2053 | 2084 | ||
2054 | /* | 2085 | /* |
@@ -2133,7 +2164,7 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, | |||
2133 | * We were woken prior to requeue by a timeout or a signal. | 2164 | * We were woken prior to requeue by a timeout or a signal. |
2134 | * Unqueue the futex_q and determine which it was. | 2165 | * Unqueue the futex_q and determine which it was. |
2135 | */ | 2166 | */ |
2136 | plist_del(&q->list, &q->list.plist); | 2167 | plist_del(&q->list, &hb->chain); |
2137 | 2168 | ||
2138 | /* Handle spurious wakeups gracefully */ | 2169 | /* Handle spurious wakeups gracefully */ |
2139 | ret = -EWOULDBLOCK; | 2170 | ret = -EWOULDBLOCK; |
@@ -2429,11 +2460,20 @@ retry: | |||
2429 | * userspace. | 2460 | * userspace. |
2430 | */ | 2461 | */ |
2431 | mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED; | 2462 | mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED; |
2432 | nval = futex_atomic_cmpxchg_inatomic(uaddr, uval, mval); | 2463 | /* |
2433 | 2464 | * We are not holding a lock here, but we want to have | |
2434 | if (nval == -EFAULT) | 2465 | * the pagefault_disable/enable() protection because |
2435 | return -1; | 2466 | * we want to handle the fault gracefully. If the |
2436 | 2467 | * access fails we try to fault in the futex with R/W | |
2468 | * verification via get_user_pages. get_user() above | ||
2469 | * does not guarantee R/W access. If that fails we | ||
2470 | * give up and leave the futex locked. | ||
2471 | */ | ||
2472 | if (cmpxchg_futex_value_locked(&nval, uaddr, uval, mval)) { | ||
2473 | if (fault_in_user_writeable(uaddr)) | ||
2474 | return -1; | ||
2475 | goto retry; | ||
2476 | } | ||
2437 | if (nval != uval) | 2477 | if (nval != uval) |
2438 | goto retry; | 2478 | goto retry; |
2439 | 2479 | ||
@@ -2644,8 +2684,7 @@ static int __init futex_init(void) | |||
2644 | * implementation, the non-functional ones will return | 2684 | * implementation, the non-functional ones will return |
2645 | * -ENOSYS. | 2685 | * -ENOSYS. |
2646 | */ | 2686 | */ |
2647 | curval = cmpxchg_futex_value_locked(NULL, 0, 0); | 2687 | if (cmpxchg_futex_value_locked(&curval, NULL, 0, 0) == -EFAULT) |
2648 | if (curval == -EFAULT) | ||
2649 | futex_cmpxchg_enabled = 1; | 2688 | futex_cmpxchg_enabled = 1; |
2650 | 2689 | ||
2651 | for (i = 0; i < ARRAY_SIZE(futex_queues); i++) { | 2690 | for (i = 0; i < ARRAY_SIZE(futex_queues); i++) { |