aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/futex.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2014-06-11 16:45:39 -0400
committerThomas Gleixner <tglx@linutronix.de>2014-06-21 16:26:23 -0400
commitbd1dbcc67cd2c1181e2c01daac51eabf1b964dd8 (patch)
tree96e16729f5e2247dd80cc9a3721dc8602a72bac6 /kernel/futex.c
parentccf9e6a80d9e1b9df69c98e6b9745cf49869ee15 (diff)
futex: Use futex_top_waiter() in lookup_pi_state()
No point in open coding the same function again. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Darren Hart <darren@dvhart.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Davidlohr Bueso <davidlohr@hp.com> Cc: Kees Cook <kees@outflux.net> Cc: wad@chromium.org Link: http://lkml.kernel.org/r/20140611204237.092947239@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/futex.c')
-rw-r--r--kernel/futex.c124
1 files changed, 61 insertions, 63 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 346d5c280545..fff1ed9b1c43 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -796,87 +796,85 @@ static int
796lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, 796lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
797 union futex_key *key, struct futex_pi_state **ps) 797 union futex_key *key, struct futex_pi_state **ps)
798{ 798{
799 struct futex_q *match = futex_top_waiter(hb, key);
799 struct futex_pi_state *pi_state = NULL; 800 struct futex_pi_state *pi_state = NULL;
800 struct futex_q *this, *next;
801 struct task_struct *p; 801 struct task_struct *p;
802 pid_t pid = uval & FUTEX_TID_MASK; 802 pid_t pid = uval & FUTEX_TID_MASK;
803 803
804 plist_for_each_entry_safe(this, next, &hb->chain, list) { 804 if (match) {
805 if (match_futex(&this->key, key)) { 805 /*
806 /* 806 * Sanity check the waiter before increasing the
807 * Sanity check the waiter before increasing 807 * refcount and attaching to it.
808 * the refcount and attaching to it. 808 */
809 */ 809 pi_state = match->pi_state;
810 pi_state = this->pi_state; 810 /*
811 /* 811 * Userspace might have messed up non-PI and PI
812 * Userspace might have messed up non-PI and 812 * futexes [3]
813 * PI futexes [3] 813 */
814 */ 814 if (unlikely(!pi_state))
815 if (unlikely(!pi_state)) 815 return -EINVAL;
816 return -EINVAL;
817 816
818 WARN_ON(!atomic_read(&pi_state->refcount)); 817 WARN_ON(!atomic_read(&pi_state->refcount));
819 818
819 /*
820 * Handle the owner died case:
821 */
822 if (uval & FUTEX_OWNER_DIED) {
820 /* 823 /*
821 * Handle the owner died case: 824 * exit_pi_state_list sets owner to NULL and
825 * wakes the topmost waiter. The task which
826 * acquires the pi_state->rt_mutex will fixup
827 * owner.
822 */ 828 */
823 if (uval & FUTEX_OWNER_DIED) { 829 if (!pi_state->owner) {
824 /* 830 /*
825 * exit_pi_state_list sets owner to NULL and 831 * No pi state owner, but the user
826 * wakes the topmost waiter. The task which 832 * space TID is not 0. Inconsistent
827 * acquires the pi_state->rt_mutex will fixup 833 * state. [5]
828 * owner.
829 */ 834 */
830 if (!pi_state->owner) { 835 if (pid)
831 /* 836 return -EINVAL;
832 * No pi state owner, but the user
833 * space TID is not 0. Inconsistent
834 * state. [5]
835 */
836 if (pid)
837 return -EINVAL;
838 /*
839 * Take a ref on the state and
840 * return. [4]
841 */
842 goto out_state;
843 }
844
845 /*
846 * If TID is 0, then either the dying owner
847 * has not yet executed exit_pi_state_list()
848 * or some waiter acquired the rtmutex in the
849 * pi state, but did not yet fixup the TID in
850 * user space.
851 *
852 * Take a ref on the state and return. [6]
853 */
854 if (!pid)
855 goto out_state;
856 } else {
857 /* 837 /*
858 * If the owner died bit is not set, 838 * Take a ref on the state and
859 * then the pi_state must have an 839 * return. [4]
860 * owner. [7]
861 */ 840 */
862 if (!pi_state->owner) 841 goto out_state;
863 return -EINVAL;
864 } 842 }
865 843
866 /* 844 /*
867 * Bail out if user space manipulated the 845 * If TID is 0, then either the dying owner
868 * futex value. If pi state exists then the 846 * has not yet executed exit_pi_state_list()
869 * owner TID must be the same as the user 847 * or some waiter acquired the rtmutex in the
870 * space TID. [9/10] 848 * pi state, but did not yet fixup the TID in
849 * user space.
850 *
851 * Take a ref on the state and return. [6]
852 */
853 if (!pid)
854 goto out_state;
855 } else {
856 /*
857 * If the owner died bit is not set,
858 * then the pi_state must have an
859 * owner. [7]
871 */ 860 */
872 if (pid != task_pid_vnr(pi_state->owner)) 861 if (!pi_state->owner)
873 return -EINVAL; 862 return -EINVAL;
874
875 out_state:
876 atomic_inc(&pi_state->refcount);
877 *ps = pi_state;
878 return 0;
879 } 863 }
864
865 /*
866 * Bail out if user space manipulated the
867 * futex value. If pi state exists then the
868 * owner TID must be the same as the user
869 * space TID. [9/10]
870 */
871 if (pid != task_pid_vnr(pi_state->owner))
872 return -EINVAL;
873
874 out_state:
875 atomic_inc(&pi_state->refcount);
876 *ps = pi_state;
877 return 0;
880 } 878 }
881 879
882 /* 880 /*