>!DOATGvE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> LXR linux/kernel/futex_compat.c
linux/kernel/futex_compat.c
<<
0" /spaion /formon a 0" href="../linux+v3v2.9/kernel/futex_compat.c">0" img src="../.static/gfx/right.png" alt=">>">0" /spaion0" spai class="lxr_search">0" 0" input typluehidden" namluenavtarget" n value">0" input typluetext" namluesearch" iduesearch">0" butttiotypluesubmit">Search0" Prefsn /a>0" /spaion /divon form acopti="ajax+*" method="post" onsubmit="return false;">0" input typluehidden" namlueajax_lookup" idueajax_lookup" n value">0 /formon0 div class="headingbotttm">n div iduefile_contents"o
 
1 /a> spai class="comment">/* /spaion
 
2 /a> spai class="comment"> * linux/kernel/futex_compat.c /spaion
 
3 /a> spai class="comment"> * /spaion
 
4 /a> spai class="comment"> * Futex compatibililty routines. /spaion
 
5 /a> spai class="comment"> * /spaion
 
6 /a> spai class="comment"> * Copyright 2006, Red Hat, Inc., Ingo Molnar /spaion
 
7 /a> spai class="comment"> */ /spaion
 
8 /a>0
 
9 /a>#include <linux/linkage.h /a>>0
 7.10a>#include <linux/compat.h /a>>0
 1110a>#include <linux/nsproxy.h /a>>0
 1210a>#include <linux/futex.h /a>>0
 1310a>#include <linux/ptrace.h /a>>0
 14 /a>0
 1510a>#include <asm/uaccess.h /a>>0
 16 /a>0
 17 /a>0
 18 /a> spai class="comment">/* /spaion
 19 /a> spai class="comment"> * Fetch a robust-list pointer. Bit 0 signals PI futexes: /spaion
 20 /a> spai class="comment"> */ /spaion
 2110a>static
 a href="+code=inline" class="sref">inline10a> intn
 22 /a> a href="+code=fetch_robust_entry" class="sref">fetch_robust_entry /a>( a href="+code=compat_uptr_t" class="sref">compat_uptr_t10a> * a href="+code=uentry" class="sref">uentry /a>, struct
 a href="+code=robust_list" class="sref">robust_list10a>  a href="+code=__user" class="sref">__user10a> ** a href="+code=entry" class="sref">entry /a>,n
 2310a>                    a href="+code=compat_uptr_t" class="sref">compat_uptr_t10a>  a href="+code=__user" class="sref">__user10a> * a href="+code=head" class="sref">head /a>, unsigned int * a href="+code=pi" class="sref">pi /a>)n
 24 /a>{n
 2510a>        if ( a href="+code=get_user" class="sref">get_user /a>(* a href="+code=uentry" class="sref">uentry /a>,  a href="+code=head" class="sref">head /a>))n
 2610a>                return - a href="+code=EFAULT" class="sref">EFAULT10a>;0
 27 /a>0
 2810a>        * a href="+code=entry" class="sref">entry /a> =  a href="+code=compat_ptr" class="sref">compat_ptr /a>((* a href="+code=uentry" class="sref">uentry /a>) & ~1);0
 2910a>        * a href="+code=pi" class="sref">pi /a> = (unsigned int)(* a href="+code=uentry" class="sref">uentry /a>) & 1;0
 30 /a>0
 3110a>        return 0;0
 32 /a>}0
 33 /a>0
 3410a>static
void  a href="+code=__user" class="sref">__user10a> * a href="+code=futex_uaddr" class="sref">futex_uaddr /a>(struct
 a href="+code=robust_list" class="sref">robust_list10a>  a href="+code=__user" class="sref">__user10a> * a href="+code=entry" class="sref">entry /a>,n
 3510a>                                 a href="+code=compat_long_t" class="sref">compat_long_t10a>  a href="+code=futex_offset" class="sref">futex_offset /a>)n
 36 /a>{n
 3710a>         a href="+code=compat_uptr_t" class="sref">compat_uptr_t10a>  a href="+code=base" class="sref">base /a> =  a href="+code=ptr_to_compat" class="sref">ptr_to_compat /a>( a href="+code=entry" class="sref">entry /a>);0
 3810a>        void  a href="+code=__user" class="sref">__user10a> * a href="+code=uaddr" class="sref">uaddr /a> =  a href="+code=compat_ptr" class="sref">compat_ptr /a>( a href="+code=base" class="sref">base /a> +  a href="+code=futex_offset" class="sref">futex_offset /a>);0
 39 /a>0
 4010a>        return  a href="+code=uaddr" class="sref">uaddr /a>;0
 41 /a>}0
 42 /a>0
 43 /a> spai class="comment">/* /spaion
 44 /a> spai class="comment"> * Walk curr->robust_list (very carefully, it's a userspace list!) /spaion
 45 /a> spai class="comment"> * and mark any locks found there dead, and notify any waiters. /spaion
 46 /a> spai class="comment"> * /spaion
 47 /a> spai class="comment"> * We silently return on any sign of list-walking problem. /spaion
 48 /a> spai class="comment"> */ /spaion
 49 /a>void  a href="+code=compat_exit_robust_list" class="sref">compat_exit_robust_list /a>(struct
 a href="+code=task_struct" class="sref">task_struct10a> * a href="+code=curr" class="sref">curr /a>)n
 50 /a>{n
 5110a>        struct
 a href="+code=compat_robust_list_head" class="sref">compat_robust_list_head10a>  a href="+code=__user" class="sref">__user10a> * a href="+code=head" class="sref">head /a> =  a href="+code=curr" class="sref">curr /a>-> a href="+code=compat_robust_list" class="sref">compat_robust_list /a>;0
 5210a>        struct
 a href="+code=robust_list" class="sref">robust_list10a>  a href="+code=__user" class="sref">__user10a> * a href="+code=entry" class="sref">entry /a>, * a href="+code=next_entry" class="sref">next_entry /a>, * a href="+code=pending" class="sref">pending /a>;0
 5310a>        unsigned int  a href="+code=limit" class="sref">limit /a> =  a href="+code=ROBUST_LIST_LIMIT" class="sref">ROBUST_LIST_LIMIT /a>,  a href="+code=pi" class="sref">pi /a>,  a href="+code=pip" class="sref">pip /a>;0
 5410a>        unsigned int  a href="+code=uninitialized_var" class="sref">uninitialized_var /a>( a href="+code=next_pi" class="sref">next_pi /a>);0
 5510a>         a href="+code=compat_uptr_t" class="sref">compat_uptr_t10a>  a href="+code=uentry" class="sref">uentry /a>,  a href="+code=next_uentry" class="sref">next_uentry /a>,  a href="+code=upending" class="sref">upending /a>;0
 5610a>         a href="+code=compat_long_t" class="sref">compat_long_t10a>  a href="+code=futex_offset" class="sref">futex_offset /a>;0
 5710a>        int  a href="+code=rc" class="sref">rc /a>;0
 58 /a>0
 5910a>        if (! a href="+code=futex_cmpxchg_enabled" class="sref">futex_cmpxchg_enabled /a>)n
 6010a>                return;0
 61 /a>0
 6210a>         spai class="comment">/* /spaion
 63 /a> spai class="comment">         * Fetch the list head (which was registered earlier, via /spaion
 64 /a> spai class="comment">         * sys_set_robust_list()): /spaion
 65 /a> spai class="comment">         */ /spaion
 6610a>        if ( a href="+code=fetch_robust_entry" class="sref">fetch_robust_entry /a>(& a href="+code=uentry" class="sref">uentry /a>, & a href="+code=entry" class="sref">entry /a>, & a href="+code=head" class="sref">head /a>-> a href="+code=list" class="sref">list10a>. a href="+code=next" class="sref">next /a>, & a href="+code=pi" class="sref">pi /a>))n
 6710a>                return;0
 6810a>         spai class="comment">/* /spaion
 69 /a> spai class="comment">         * Fetch the relative futex offset: /spaion
 70 /a> spai class="comment">         */ /spaion
 7110a>        if ( a href="+code=get_user" class="sref">get_user /a>( a href="+code=futex_offset" class="sref">futex_offset /a>, & a href="+code=head" class="sref">head /a>-> a href="+code=futex_offset" class="sref">futex_offset /a>))n
 7210a>                return;0
 7310a>         spai class="comment">/* /spaion
 74 /a> spai class="comment">         * Fetch any possibly pending lock-add first, and handle it /spaion
 75 /a> spai class="comment">         * if it exists: /spaion
 76 /a> spai class="comment">         */ /spaion
 7710a>        if ( a href="+code=fetch_robust_entry" class="sref">fetch_robust_entry /a>(& a href="+code=upending" class="sref">upending /a>, & a href="+code=pending" class="sref">pending /a>,n
 7810a>                               & a href="+code=head" class="sref">head /a>-> a href="+code=list_op_pending" class="sref">list_op_pending /a>, & a href="+code=pip" class="sref">pip /a>))n
 7910a>                return;0
 80 /a>0
 8110a>         a href="+code=next_entry" class="sref">next_entry /a> =  a href="+code=NULL" class="sref">NULL /a>;       spai class="comment">/* avoid warning with gcc */ /spaion
 8210a>        while ( a href="+code=entry" class="sref">entry /a> != (struct
 a href="+code=robust_list" class="sref">robust_list10a>  a href="+code=__user" class="sref">__user10a> *) & a href="+code=head" class="sref">head /a>-> a href="+code=list" class="sref">list10a>) {n
 8310a>                 spai class="comment">/* /spaion
 84 /a> spai class="comment">                 * Fetch the next entry in the list before calling /spaion
 85 /a> spai class="comment">                 * handle_futex_death: /spaion
 86 /a> spai class="comment">                 */ /spaion
 8710a>                 a href="+code=rc" class="sref">rc /a> =  a href="+code=fetch_robust_entry" class="sref">fetch_robust_entry /a>(& a href="+code=next_uentry" class="sref">next_uentry /a>, & a href="+code=next_entry" class="sref">next_entry /a>,n
 8810a>                        ( a href="+code=compat_uptr_t" class="sref">compat_uptr_t10a>  a href="+code=__user" class="sref">__user10a> *)& a href="+code=entry" class="sref">entry /a>-> a href="+code=next" class="sref">next /a>, & a href="+code=next_pi" class="sref">next_pi /a>);0
 8910a>                 spai class="comment">/* /spaion
 90 /a> spai class="comment">                 * A pending lock might already be on the list, so /spaion
 91 /a> spai class="comment">                 * dont process it twice: /spaion
 92 /a> spai class="comment">                 */ /spaion
 9310a>                if ( a href="+code=entry" class="sref">entry /a> !=  a href="+code=pending" class="sref">pending /a>) {n
 9410a>                        void  a href="+code=__user" class="sref">__user10a> * a href="+code=uaddr" class="sref">uaddr /a> =  a href="+code=futex_uaddr" class="sref">futex_uaddr /a>( a href="+code=entry" class="sref">entry /a>,  a href="+code=futex_offset" class="sref">futex_offset /a>);0
 95 /a>0
 9610a>                        if ( a href="+code=handle_futex_death" class="sref">handle_futex_death /a>( a href="+code=uaddr" class="sref">uaddr /a>,  a href="+code=curr" class="sref">curr /a>,  a href="+code=pi" class="sref">pi /a>))n
 9710a>                                return;0
 9810a>                }0
 9910a>                if ( a href="+code=rc" class="sref">rc /a>)n
10010a>                        return;0
10110a>                 a href="+code=uentry" class="sref">uentry /a> =  a href="+code=next_uentry" class="sref">next_uentry /a>;0
10210a>                 a href="+code=entry" class="sref">entry /a> =  a href="+code=next_entry" class="sref">next_entry /a>;0
10310a>                 a href="+code=pi" class="sref">pi /a> =  a href="+code=next_pi" class="sref">next_pi /a>;0
10410a>                 spai class="comment">/* /spaion
105 /a> spai class="comment">                 * Avoid excessively long or circular lists: /spaion
106 /a> spai class="comment">                 */ /spaion
10710a>                if (!-- a href="+code=limit" class="sref">limit /a>)n
10810a>                        break;0
109 /a>0
11010a>                 a href="+code=cond_resched" class="sref">cond_resched /a>();0
11110a>        }0
11210a>        if ( a href="+code=pending" class="sref">pending /a>) {n
11310a>                void  a href="+code=__user" class="sref">__user10a> * a href="+code=uaddr" class="sref">uaddr /a> =  a href="+code=futex_uaddr" class="sref">futex_uaddr /a>( a href="+code=pending" class="sref">pending /a>,  a href="+code=futex_offset" class="sref">futex_offset /a>);0
114 /a>0
11510a>                 a href="+code=handle_futex_death" class="sref">handle_futex_death /a>( a href="+code=uaddr" class="sref">uaddr /a>,  a href="+code=curr" class="sref">curr /a>,  a href="+code=pip" class="sref">pip /a>);0
11610a>        }0
117 /a>}0
118 /a>0
119 /a> a href="+code=asmlinkage" class="sref">asmlinkage10a> long0
120 /a> a href="+code=compat_sys_set_robust_list" class="sref">compat_sys_set_robust_list /a>(struct
 a href="+code=compat_robust_list_head" class="sref">compat_robust_list_head10a>  a href="+code=__user" class="sref">__user10a> * a href="+code=head" class="sref">head /a>,n
12110a>                            a href="+code=compat_size_t" class="sref">compat_size_t10a>  a href="+code=len" class="sref">len /a>)n
122 /a>{n
12310a>        if (! a href="+code=futex_cmpxchg_enabled" class="sref">futex_cmpxchg_enabled /a>)n
12410a>                return - a href="+code=ENOSYS" class="sref">ENOSYS /a>;0
125 /a>0
12610a>        if ( a href="+code=unlikely" class="sref">unlikely /a>( a href="+code=len" class="sref">len /a> != sizeof(* a href="+code=head" class="sref">head /a>)))n
12710a>                return - a href="+code=EINVAL" class="sref">EINVAL /a>;0
128 /a>0
12910a>         a href="+code=current" class="sref">current /a>-> a href="+code=compat_robust_list" class="sref">compat_robust_list /a> =  a href="+code=head" class="sref">head /a>;0
130 /a>0
13110a>        return 0;0
132 /a>}0
133 /a>0
13410a> a href="+code=asmlinkage" class="sref">asmlinkage10a> long0
13510a> a href="+code=compat_sys_get_robust_list" class="sref">compat_sys_get_robust_list /a>(int  a href="+code=pid" class="sref">pid /a>,  a href="+code=compat_uptr_t" class="sref">compat_uptr_t10a>  a href="+code=__user" class="sref">__user10a> * a href="+code=head_ptr" class="sref">head_ptr /a>,n
13610a>                            a href="+code=compat_size_t" class="sref">compat_size_t10a>  a href="+code=__user" class="sref">__user10a> * a href="+code=len_ptr" class="sref">len_ptr /a>)n
13710a>{n
13810a>        struct
 a href="+code=compat_robust_list_head" class="sref">compat_robust_list_head10a>  a href="+code=__user" class="sref">__user10a> * a href="+code=head" class="sref">head /a>;0
13910a>        unsigned long  a href="+code=ret" class="sref">ret /a>;0
14010a>        struct
 a href="+code=task_struct" class="sref">task_struct10a> * a href="+code=p" class="sref">p /a>;0
141 /a>0
14210a>        if (! a href="+code=futex_cmpxchg_enabled" class="sref">futex_cmpxchg_enabled /a>)n
14310a>                return - a href="+code=ENOSYS" class="sref">ENOSYS /a>;0
144 /a>0
14510a>         a href="+code=WARN_ONCE" class="sref">WARN_ONCE /a>(1,  spai class="string">"deprecated: get_robust_list will be deleted in 2013.\n" /spaio);0
146 /a>0
14710a>         a href="+code=rcu_read_lock" class="sref">rcu_read_lock /a>();0
148 /a>0
14910a>         a href="+code=ret" class="sref">ret /a> = - a href="+code=ESRCH" class="sref">ESRCH /a>;0
15010a>        if (! a href="+code=pid" class="sref">pid /a>)n
15110a>                 a href="+code=p" class="sref">p /a> =  a href="+code=current" class="sref">current /a>;0
15210a>        else {n
15310a>                 a href="+code=p" class="sref">p /a> =  a href="+code=find_task_by_vpid" class="sref">find_task_by_vpid /a>( a href="+code=pid" class="sref">pid /a>);0
15410a>                if (! a href="+code=p" class="sref">p /a>)n
15510a>                        goto  a href="+code=err_unlock" class="sref">err_unlock /a>;0
15610a>        }0
157 /a>0
15810a>         a href="+code=ret" class="sref">ret /a> = - a href="+code=EPERM" class="sref">EPERM /a>;0
15910a>        if (! a href="+code=ptrace_may_access" class="sref">ptrace_may_access /a>( a href="+code=p" class="sref">p /a>,  a href="+code=PTRACE_MODE_READ" class="sref">PTRACE_MODE_READ /a>))0
16010a>                goto  a href="+code=err_unlock" class="sref">err_unlock /a>;0
161 /a>0
16210a>         a href="+code=head" class="sref">head /a> =  a href="+code=p" class="sref">p /a>-> a href="+code=compat_robust_list" class="sref">compat_robust_list /a>;0
16310a>         a href="+code=rcu_read_unlock" class="sref">rcu_read_unlock /a>();0
164 /a>0
16510a>        if ( a href="+code=put_user" class="sref">put_user /a>(sizeof(* a href="+code=head" class="sref">head /a>),  a href="+code=len_ptr" class="sref">len_ptr /a>))0
16610a>                return - a href="+code=EFAULT" class="sref">EFAULT10a>;0
16710a>        return  a href="+code=put_user" class="sref">put_user /a>( a href="+code=ptr_to_compat" class="sref">ptr_to_compat /a>( a href="+code=head" class="sref">head /a>),  a href="+code=head_ptr" class="sref">head_ptr /a>);0
168 /a>0
169 /a> a href="+code=err_unlock" class="sref">err_unlock /a>:0
17010a>         a href="+code=rcu_read_unlock" class="sref">rcu_read_unlock /a>();0
171 /a>0
17210a>        return  a href="+code=ret" class="sref">ret /a>;0
17310a>}0
174 /a>0
17510a> a href="+code=asmlinkage" class="sref">asmlinkage10a> long  a href="+code=compat_sys_futex" class="sref">compat_sys_futex /a>( a href="+code=u32" class="sref">u32 /a>  a href="+code=__user" class="sref">__user10a> * a href="+code=uaddr" class="sref">uaddr /a>, int  a href="+code=op" class="sref">op /a>,  a href="+code=u32" class="sref">u32 /a>  a href="+code=val" class="sref">val /a>,n
17610a>                struct
 a href="+code=compat_timespec" class="sref">compat_timespec /a>  a href="+code=__user" class="sref">__user10a> * a href="+code=utime" class="sref">utime /a>,  a href="+code=u32" class="sref">u32 /a>  a href="+code=__user" class="sref">__user10a> * a href="+code=uaddr2" class="sref">uaddr2 /a>,n
17710a>                 a href="+code=u32" class="sref">u32 /a>  a href="+code=val3" class="sref">val3 /a>)n
17810a>{n
17910a>        struct
 a href="+code=timespec" class="sref">timespec /a>  a href="+code=ts" class="sref">ts /a>;0
18010a>         a href="+code=ktime_t" class="sref">ktime_t /a>  a href="+code=t" class="sref">t /a>, * a href="+code=tp" class="sref">tp /a> =  a href="+code=NULL" class="sref">NULL /a>;0
18110a>        int  a href="+code=val2" class="sref">val2 /a> = 0;0
18210a>        int  a href="+code=cmd" class="sref">cmd /a> =  a href="+code=op" class="sref">op /a> &  a href="+code=FUTEX_CMD_MASK" class="sref">FUTEX_CMD_MASK /a>;0
183 /a>0
18410a>        if ( a href="+code=utime" class="sref">utime /a> && ( a href="+code=cmd" class="sref">cmd /a> ==  a href="+code=FUTEX_WAIT" class="sref">FUTEX_WAIT /a> ||  a href="+code=cmd" class="sref">cmd /a> ==  a href="+code=FUTEX_LOCK_PI" class="sref">FUTEX_LOCK_PI /a> ||0
18510a>                       a href="+code=cmd" class="sref">cmd /a> ==  a href="+code=FUTEX_WAIT_BITSET" class="sref">FUTEX_WAIT_BITSET /a> ||0
18610a>                       a href="+code=cmd" class="sref">cmd /a> ==  a href="+code=FUTEX_WAIT_REQUEUE_PI" class="sref">FUTEX_WAIT_REQUEUE_PI /a>)) {n
18710a>                if ( a href="+code=get_compat_timespec" class="sref">get_compat_timespec /a>(& a href="+code=ts" class="sref">ts /a>,  a href="+code=utime" class="sref">utime /a>))0
18810a>                        return - a href="+code=EFAULT" class="sref">EFAULT10a>;0
18910a>                if (! a href="+code=timespec_valid" class="sref">timespec_valid /a>(& a href="+code=ts" class="sref">ts /a>))0
19010a>                        return - a href="+code=EINVAL" class="sref">EINVAL /a>;0
191 /a>0
19210a>                 a href="+code=t" class="sref">t /a> =  a href="+code=timespec_to_ktime" class="sref">timespec_to_ktime /a>( a href="+code=ts" class="sref">ts /a>);0
19310a>                if ( a href="+code=cmd" class="sref">cmd /a> ==  a href="+code=FUTEX_WAIT" class="sref">FUTEX_WAIT /a>)0
19410a>                         a href="+code=t" class="sref">t /a> =  a href="+code=ktime_add_safe" class="sref">ktime_add_safe /a>( a href="+code=ktime_get" class="sref">ktime_get /a>(),  a href="+code=t" class="sref">t /a>);0
19510a>                 a href="+code=tp" class="sref">tp /a> = & a href="+code=t" class="sref">t /a>;0
19610a>        }0
19710a>        if ( a href="+code=cmd" class="sref">cmd /a> ==  a href="+code=FUTEX_REQUEUE" class="sref">FUTEX_REQUEUE /a> ||  a href="+code=cmd" class="sref">cmd /a> ==  a href="+code=FUTEX_CMP_REQUEUE" class="sref">FUTEX_CMP_REQUEUE /a> ||0
19810a>             a href="+code=cmd" class="sref">cmd /a> ==  a href="+code=FUTEX_CMP_REQUEUE_PI" class="sref">FUTEX_CMP_REQUEUE_PI /a> ||  a href="+code=cmd" class="sref">cmd /a> ==  a href="+code=FUTEX_WAKE_OP" class="sref">FUTEX_WAKE_OP /a>)0
19910a>                 a href="+code=val2" class="sref">val2 /a> = (int) (unsigned long)  a href="+code=utime" class="sref">utime /a>;0
200 /a>0
20110a>        return  a href="+code=do_futex" class="sref">do_futex /a>( a href="+code=uaddr" class="sref">uaddr /a>,  a href="+code=op" class="sref">op /a>,  a href="+code=val" class="sref">val /a>,  a href="+code=tp" class="sref">tp /a>,  a href="+code=uaddr2" class="sref">uaddr2 /a>,  a href="+code=val2" class="sref">val2 /a>,  a href="+code=val3" class="sref">val3 /a>);0
202 /a>}0
20310a>
lxe."liux.no kindly hoseted by ts="sref"1ls:'/www.redpill-"li/po.no">Redpill Lli/po ASy /a>,/povidern ofLliuxR"cnsultding andoperations services since> 195.
/bodyv> /htmlv>