diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/futex.c | 48 |
1 files changed, 19 insertions, 29 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index facf17d1a705..60b47bb9e3dd 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -200,8 +200,7 @@ static void drop_futex_key_refs(union futex_key *key) | |||
200 | * For other futexes, it points to ¤t->mm->mmap_sem and | 200 | * For other futexes, it points to ¤t->mm->mmap_sem and |
201 | * caller must have taken the reader lock. but NOT any spinlocks. | 201 | * caller must have taken the reader lock. but NOT any spinlocks. |
202 | */ | 202 | */ |
203 | static int get_futex_key(u32 __user *uaddr, struct rw_semaphore *fshared, | 203 | static int get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) |
204 | union futex_key *key) | ||
205 | { | 204 | { |
206 | unsigned long address = (unsigned long)uaddr; | 205 | unsigned long address = (unsigned long)uaddr; |
207 | struct mm_struct *mm = current->mm; | 206 | struct mm_struct *mm = current->mm; |
@@ -268,7 +267,7 @@ again: | |||
268 | } | 267 | } |
269 | 268 | ||
270 | static inline | 269 | static inline |
271 | void put_futex_key(struct rw_semaphore *fshared, union futex_key *key) | 270 | void put_futex_key(int fshared, union futex_key *key) |
272 | { | 271 | { |
273 | drop_futex_key_refs(key); | 272 | drop_futex_key_refs(key); |
274 | } | 273 | } |
@@ -297,10 +296,8 @@ static int get_futex_value_locked(u32 *dest, u32 __user *from) | |||
297 | 296 | ||
298 | /* | 297 | /* |
299 | * Fault handling. | 298 | * Fault handling. |
300 | * if fshared is non NULL, current->mm->mmap_sem is already held | ||
301 | */ | 299 | */ |
302 | static int futex_handle_fault(unsigned long address, | 300 | static int futex_handle_fault(unsigned long address, int attempt) |
303 | struct rw_semaphore *fshared, int attempt) | ||
304 | { | 301 | { |
305 | struct vm_area_struct * vma; | 302 | struct vm_area_struct * vma; |
306 | struct mm_struct *mm = current->mm; | 303 | struct mm_struct *mm = current->mm; |
@@ -687,8 +684,7 @@ double_lock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2) | |||
687 | * Wake up all waiters hashed on the physical page that is mapped | 684 | * Wake up all waiters hashed on the physical page that is mapped |
688 | * to this virtual address: | 685 | * to this virtual address: |
689 | */ | 686 | */ |
690 | static int futex_wake(u32 __user *uaddr, struct rw_semaphore *fshared, | 687 | static int futex_wake(u32 __user *uaddr, int fshared, int nr_wake, u32 bitset) |
691 | int nr_wake, u32 bitset) | ||
692 | { | 688 | { |
693 | struct futex_hash_bucket *hb; | 689 | struct futex_hash_bucket *hb; |
694 | struct futex_q *this, *next; | 690 | struct futex_q *this, *next; |
@@ -735,8 +731,7 @@ out: | |||
735 | * to this virtual address: | 731 | * to this virtual address: |
736 | */ | 732 | */ |
737 | static int | 733 | static int |
738 | futex_wake_op(u32 __user *uaddr1, struct rw_semaphore *fshared, | 734 | futex_wake_op(u32 __user *uaddr1, int fshared, u32 __user *uaddr2, |
739 | u32 __user *uaddr2, | ||
740 | int nr_wake, int nr_wake2, int op) | 735 | int nr_wake, int nr_wake2, int op) |
741 | { | 736 | { |
742 | union futex_key key1 = FUTEX_KEY_INIT, key2 = FUTEX_KEY_INIT; | 737 | union futex_key key1 = FUTEX_KEY_INIT, key2 = FUTEX_KEY_INIT; |
@@ -790,7 +785,7 @@ retry: | |||
790 | */ | 785 | */ |
791 | if (attempt++) { | 786 | if (attempt++) { |
792 | ret = futex_handle_fault((unsigned long)uaddr2, | 787 | ret = futex_handle_fault((unsigned long)uaddr2, |
793 | fshared, attempt); | 788 | attempt); |
794 | if (ret) | 789 | if (ret) |
795 | goto out; | 790 | goto out; |
796 | goto retry; | 791 | goto retry; |
@@ -841,8 +836,7 @@ out: | |||
841 | * Requeue all waiters hashed on one physical page to another | 836 | * Requeue all waiters hashed on one physical page to another |
842 | * physical page. | 837 | * physical page. |
843 | */ | 838 | */ |
844 | static int futex_requeue(u32 __user *uaddr1, struct rw_semaphore *fshared, | 839 | static int futex_requeue(u32 __user *uaddr1, int fshared, u32 __user *uaddr2, |
845 | u32 __user *uaddr2, | ||
846 | int nr_wake, int nr_requeue, u32 *cmpval) | 840 | int nr_wake, int nr_requeue, u32 *cmpval) |
847 | { | 841 | { |
848 | union futex_key key1 = FUTEX_KEY_INIT, key2 = FUTEX_KEY_INIT; | 842 | union futex_key key1 = FUTEX_KEY_INIT, key2 = FUTEX_KEY_INIT; |
@@ -1048,8 +1042,7 @@ static void unqueue_me_pi(struct futex_q *q) | |||
1048 | * private futexes. | 1042 | * private futexes. |
1049 | */ | 1043 | */ |
1050 | static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, | 1044 | static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, |
1051 | struct task_struct *newowner, | 1045 | struct task_struct *newowner, int fshared) |
1052 | struct rw_semaphore *fshared) | ||
1053 | { | 1046 | { |
1054 | u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS; | 1047 | u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS; |
1055 | struct futex_pi_state *pi_state = q->pi_state; | 1048 | struct futex_pi_state *pi_state = q->pi_state; |
@@ -1128,7 +1121,7 @@ retry: | |||
1128 | handle_fault: | 1121 | handle_fault: |
1129 | spin_unlock(q->lock_ptr); | 1122 | spin_unlock(q->lock_ptr); |
1130 | 1123 | ||
1131 | ret = futex_handle_fault((unsigned long)uaddr, fshared, attempt++); | 1124 | ret = futex_handle_fault((unsigned long)uaddr, attempt++); |
1132 | 1125 | ||
1133 | spin_lock(q->lock_ptr); | 1126 | spin_lock(q->lock_ptr); |
1134 | 1127 | ||
@@ -1152,7 +1145,7 @@ handle_fault: | |||
1152 | 1145 | ||
1153 | static long futex_wait_restart(struct restart_block *restart); | 1146 | static long futex_wait_restart(struct restart_block *restart); |
1154 | 1147 | ||
1155 | static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, | 1148 | static int futex_wait(u32 __user *uaddr, int fshared, |
1156 | u32 val, ktime_t *abs_time, u32 bitset) | 1149 | u32 val, ktime_t *abs_time, u32 bitset) |
1157 | { | 1150 | { |
1158 | struct task_struct *curr = current; | 1151 | struct task_struct *curr = current; |
@@ -1307,13 +1300,13 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1307 | static long futex_wait_restart(struct restart_block *restart) | 1300 | static long futex_wait_restart(struct restart_block *restart) |
1308 | { | 1301 | { |
1309 | u32 __user *uaddr = (u32 __user *)restart->futex.uaddr; | 1302 | u32 __user *uaddr = (u32 __user *)restart->futex.uaddr; |
1310 | struct rw_semaphore *fshared = NULL; | 1303 | int fshared = 0; |
1311 | ktime_t t; | 1304 | ktime_t t; |
1312 | 1305 | ||
1313 | t.tv64 = restart->futex.time; | 1306 | t.tv64 = restart->futex.time; |
1314 | restart->fn = do_no_restart_syscall; | 1307 | restart->fn = do_no_restart_syscall; |
1315 | if (restart->futex.flags & FLAGS_SHARED) | 1308 | if (restart->futex.flags & FLAGS_SHARED) |
1316 | fshared = ¤t->mm->mmap_sem; | 1309 | fshared = 1; |
1317 | return (long)futex_wait(uaddr, fshared, restart->futex.val, &t, | 1310 | return (long)futex_wait(uaddr, fshared, restart->futex.val, &t, |
1318 | restart->futex.bitset); | 1311 | restart->futex.bitset); |
1319 | } | 1312 | } |
@@ -1325,7 +1318,7 @@ static long futex_wait_restart(struct restart_block *restart) | |||
1325 | * if there are waiters then it will block, it does PI, etc. (Due to | 1318 | * if there are waiters then it will block, it does PI, etc. (Due to |
1326 | * races the kernel might see a 0 value of the futex too.) | 1319 | * races the kernel might see a 0 value of the futex too.) |
1327 | */ | 1320 | */ |
1328 | static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, | 1321 | static int futex_lock_pi(u32 __user *uaddr, int fshared, |
1329 | int detect, ktime_t *time, int trylock) | 1322 | int detect, ktime_t *time, int trylock) |
1330 | { | 1323 | { |
1331 | struct hrtimer_sleeper timeout, *to = NULL; | 1324 | struct hrtimer_sleeper timeout, *to = NULL; |
@@ -1571,8 +1564,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1571 | queue_unlock(&q, hb); | 1564 | queue_unlock(&q, hb); |
1572 | 1565 | ||
1573 | if (attempt++) { | 1566 | if (attempt++) { |
1574 | ret = futex_handle_fault((unsigned long)uaddr, fshared, | 1567 | ret = futex_handle_fault((unsigned long)uaddr, attempt); |
1575 | attempt); | ||
1576 | if (ret) | 1568 | if (ret) |
1577 | goto out_release_sem; | 1569 | goto out_release_sem; |
1578 | goto retry_unlocked; | 1570 | goto retry_unlocked; |
@@ -1592,7 +1584,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1592 | * This is the in-kernel slowpath: we look up the PI state (if any), | 1584 | * This is the in-kernel slowpath: we look up the PI state (if any), |
1593 | * and do the rt-mutex unlock. | 1585 | * and do the rt-mutex unlock. |
1594 | */ | 1586 | */ |
1595 | static int futex_unlock_pi(u32 __user *uaddr, struct rw_semaphore *fshared) | 1587 | static int futex_unlock_pi(u32 __user *uaddr, int fshared) |
1596 | { | 1588 | { |
1597 | struct futex_hash_bucket *hb; | 1589 | struct futex_hash_bucket *hb; |
1598 | struct futex_q *this, *next; | 1590 | struct futex_q *this, *next; |
@@ -1683,8 +1675,7 @@ pi_faulted: | |||
1683 | spin_unlock(&hb->lock); | 1675 | spin_unlock(&hb->lock); |
1684 | 1676 | ||
1685 | if (attempt++) { | 1677 | if (attempt++) { |
1686 | ret = futex_handle_fault((unsigned long)uaddr, fshared, | 1678 | ret = futex_handle_fault((unsigned long)uaddr, attempt); |
1687 | attempt); | ||
1688 | if (ret) | 1679 | if (ret) |
1689 | goto out; | 1680 | goto out; |
1690 | uval = 0; | 1681 | uval = 0; |
@@ -1816,8 +1807,7 @@ retry: | |||
1816 | * PI futexes happens in exit_pi_state(): | 1807 | * PI futexes happens in exit_pi_state(): |
1817 | */ | 1808 | */ |
1818 | if (!pi && (uval & FUTEX_WAITERS)) | 1809 | if (!pi && (uval & FUTEX_WAITERS)) |
1819 | futex_wake(uaddr, &curr->mm->mmap_sem, 1, | 1810 | futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY); |
1820 | FUTEX_BITSET_MATCH_ANY); | ||
1821 | } | 1811 | } |
1822 | return 0; | 1812 | return 0; |
1823 | } | 1813 | } |
@@ -1913,10 +1903,10 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, | |||
1913 | { | 1903 | { |
1914 | int ret = -ENOSYS; | 1904 | int ret = -ENOSYS; |
1915 | int cmd = op & FUTEX_CMD_MASK; | 1905 | int cmd = op & FUTEX_CMD_MASK; |
1916 | struct rw_semaphore *fshared = NULL; | 1906 | int fshared = 0; |
1917 | 1907 | ||
1918 | if (!(op & FUTEX_PRIVATE_FLAG)) | 1908 | if (!(op & FUTEX_PRIVATE_FLAG)) |
1919 | fshared = ¤t->mm->mmap_sem; | 1909 | fshared = 1; |
1920 | 1910 | ||
1921 | switch (cmd) { | 1911 | switch (cmd) { |
1922 | case FUTEX_WAIT: | 1912 | case FUTEX_WAIT: |