xref: /openbmc/linux/include/linux/futex.h (revision 8019ad13)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds #ifndef _LINUX_FUTEX_H
31da177e4SLinus Torvalds #define _LINUX_FUTEX_H
41da177e4SLinus Torvalds 
5ba31c1a4SThomas Gleixner #include <linux/sched.h>
62456e855SThomas Gleixner #include <linux/ktime.h>
7ba31c1a4SThomas Gleixner 
8607ca46eSDavid Howells #include <uapi/linux/futex.h>
90771dfefSIngo Molnar 
109064a678SMike Frysinger struct inode;
119064a678SMike Frysinger struct mm_struct;
129064a678SMike Frysinger struct task_struct;
139064a678SMike Frysinger 
149adef58bSRusty Russell /*
159adef58bSRusty Russell  * Futexes are matched on equal values of this key.
169adef58bSRusty Russell  * The key type depends on whether it's a shared or private mapping.
179adef58bSRusty Russell  * Don't rearrange members without looking at hash_futex().
189adef58bSRusty Russell  *
199adef58bSRusty Russell  * offset is aligned to a multiple of sizeof(u32) (== 4) by definition.
2034f01cc1SEric Dumazet  * We use the two low order bits of offset to tell what is the kind of key :
2134f01cc1SEric Dumazet  *  00 : Private process futex (PTHREAD_PROCESS_PRIVATE)
2234f01cc1SEric Dumazet  *       (no reference on an inode or mm)
2334f01cc1SEric Dumazet  *  01 : Shared futex (PTHREAD_PROCESS_SHARED)
2434f01cc1SEric Dumazet  *	mapped on a file (reference on the underlying inode)
2534f01cc1SEric Dumazet  *  10 : Shared futex (PTHREAD_PROCESS_SHARED)
2634f01cc1SEric Dumazet  *       (but private mapping on an mm, and reference taken on it)
279adef58bSRusty Russell */
2834f01cc1SEric Dumazet 
2934f01cc1SEric Dumazet #define FUT_OFF_INODE    1 /* We set bit 0 if key has a reference on inode */
3034f01cc1SEric Dumazet #define FUT_OFF_MMSHARED 2 /* We set bit 1 if key has a reference on mm */
3134f01cc1SEric Dumazet 
329adef58bSRusty Russell union futex_key {
339adef58bSRusty Russell 	struct {
348019ad13SPeter Zijlstra 		u64 i_seq;
359adef58bSRusty Russell 		unsigned long pgoff;
368019ad13SPeter Zijlstra 		unsigned int offset;
379adef58bSRusty Russell 	} shared;
389adef58bSRusty Russell 	struct {
398019ad13SPeter Zijlstra 		union {
409adef58bSRusty Russell 			struct mm_struct *mm;
418019ad13SPeter Zijlstra 			u64 __tmp;
428019ad13SPeter Zijlstra 		};
438019ad13SPeter Zijlstra 		unsigned long address;
448019ad13SPeter Zijlstra 		unsigned int offset;
459adef58bSRusty Russell 	} private;
469adef58bSRusty Russell 	struct {
478019ad13SPeter Zijlstra 		u64 ptr;
489adef58bSRusty Russell 		unsigned long word;
498019ad13SPeter Zijlstra 		unsigned int offset;
509adef58bSRusty Russell 	} both;
519adef58bSRusty Russell };
529adef58bSRusty Russell 
538019ad13SPeter Zijlstra #define FUTEX_KEY_INIT (union futex_key) { .both = { .ptr = 0ULL } }
5438d47c1bSPeter Zijlstra 
550771dfefSIngo Molnar #ifdef CONFIG_FUTEX
563d4775dfSThomas Gleixner enum {
573d4775dfSThomas Gleixner 	FUTEX_STATE_OK,
5818f69438SThomas Gleixner 	FUTEX_STATE_EXITING,
593d4775dfSThomas Gleixner 	FUTEX_STATE_DEAD,
603d4775dfSThomas Gleixner };
61ba31c1a4SThomas Gleixner 
futex_init_task(struct task_struct * tsk)62ba31c1a4SThomas Gleixner static inline void futex_init_task(struct task_struct *tsk)
63ba31c1a4SThomas Gleixner {
64ba31c1a4SThomas Gleixner 	tsk->robust_list = NULL;
65ba31c1a4SThomas Gleixner #ifdef CONFIG_COMPAT
66ba31c1a4SThomas Gleixner 	tsk->compat_robust_list = NULL;
67ba31c1a4SThomas Gleixner #endif
68ba31c1a4SThomas Gleixner 	INIT_LIST_HEAD(&tsk->pi_state_list);
69ba31c1a4SThomas Gleixner 	tsk->pi_state_cache = NULL;
703d4775dfSThomas Gleixner 	tsk->futex_state = FUTEX_STATE_OK;
713f186d97SThomas Gleixner 	mutex_init(&tsk->futex_exit_mutex);
723d4775dfSThomas Gleixner }
733d4775dfSThomas Gleixner 
7418f69438SThomas Gleixner void futex_exit_recursive(struct task_struct *tsk);
75150d7158SThomas Gleixner void futex_exit_release(struct task_struct *tsk);
76150d7158SThomas Gleixner void futex_exec_release(struct task_struct *tsk);
772de0db99SDominik Brodowski 
782de0db99SDominik Brodowski long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
792de0db99SDominik Brodowski 	      u32 __user *uaddr2, u32 val2, u32 val3);
800771dfefSIngo Molnar #else
futex_init_task(struct task_struct * tsk)81ba31c1a4SThomas Gleixner static inline void futex_init_task(struct task_struct *tsk) { }
futex_exit_recursive(struct task_struct * tsk)8218f69438SThomas Gleixner static inline void futex_exit_recursive(struct task_struct *tsk) { }
futex_exit_release(struct task_struct * tsk)83150d7158SThomas Gleixner static inline void futex_exit_release(struct task_struct *tsk) { }
futex_exec_release(struct task_struct * tsk)84150d7158SThomas Gleixner static inline void futex_exec_release(struct task_struct *tsk) { }
do_futex(u32 __user * uaddr,int op,u32 val,ktime_t * timeout,u32 __user * uaddr2,u32 val2,u32 val3)852de0db99SDominik Brodowski static inline long do_futex(u32 __user *uaddr, int op, u32 val,
862de0db99SDominik Brodowski 			    ktime_t *timeout, u32 __user *uaddr2,
872de0db99SDominik Brodowski 			    u32 val2, u32 val3)
882de0db99SDominik Brodowski {
892de0db99SDominik Brodowski 	return -EINVAL;
902de0db99SDominik Brodowski }
91bc2eecd7SNicolas Pitre #endif
92bc2eecd7SNicolas Pitre 
931da177e4SLinus Torvalds #endif
94