1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2#ifndef _LINUX_FUTEX_H
3#define _LINUX_FUTEX_H
4
5
6#include <linux/types.h>
7
8/* Second argument to futex syscall */
9
10
11#define FUTEX_WAIT 0
12#define FUTEX_WAKE 1
13#define FUTEX_FD 2
14#define FUTEX_REQUEUE 3
15#define FUTEX_CMP_REQUEUE 4
16#define FUTEX_WAKE_OP 5
17#define FUTEX_LOCK_PI 6
18#define FUTEX_UNLOCK_PI 7
19#define FUTEX_TRYLOCK_PI 8
20#define FUTEX_WAIT_BITSET 9
21#define FUTEX_WAKE_BITSET 10
22#define FUTEX_WAIT_REQUEUE_PI 11
23#define FUTEX_CMP_REQUEUE_PI 12
24#define FUTEX_LOCK_PI2 13
25
26#define FUTEX_PRIVATE_FLAG 128
27#define FUTEX_CLOCK_REALTIME 256
28#define FUTEX_ROBUST_UNLOCK 512
29#define FUTEX_ROBUST_LIST32 1024
30
31#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME | \
32 FUTEX_ROBUST_UNLOCK | FUTEX_ROBUST_LIST32)
33
34#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
35#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
36#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
37#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
38#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
39#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
40#define FUTEX_LOCK_PI2_PRIVATE (FUTEX_LOCK_PI2 | FUTEX_PRIVATE_FLAG)
41#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
42#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
43#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG)
44#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)
45#define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | FUTEX_PRIVATE_FLAG)
46#define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | FUTEX_PRIVATE_FLAG)
47
48/*
49 * Operations to unlock a futex, clear the robust list pending op pointer and
50 * wake waiters.
51 */
52#define FUTEX_UNLOCK_PI_LIST64 (FUTEX_UNLOCK_PI | FUTEX_ROBUST_UNLOCK)
53#define FUTEX_UNLOCK_PI_LIST64_PRIVATE (FUTEX_UNLOCK_PI_LIST64 | FUTEX_PRIVATE_FLAG)
54#define FUTEX_UNLOCK_PI_LIST32 (FUTEX_UNLOCK_PI | FUTEX_ROBUST_UNLOCK | \
55 FUTEX_ROBUST_LIST32)
56#define FUTEX_UNLOCK_PI_LIST32_PRIVATE (FUTEX_UNLOCK_PI_LIST32 | FUTEX_PRIVATE_FLAG)
57
58#define FUTEX_UNLOCK_WAKE_LIST64 (FUTEX_WAKE | FUTEX_ROBUST_UNLOCK)
59#define FUTEX_UNLOCK_WAKE_LIST64_PRIVATE (FUTEX_UNLOCK_WAKE_LIST64 | FUTEX_PRIVATE_FLAG)
60
61#define FUTEX_UNLOCK_WAKE_LIST32 (FUTEX_WAKE | FUTEX_ROBUST_UNLOCK | \
62 FUTEX_ROBUST_LIST32)
63#define FUTEX_UNLOCK_WAKE_LIST32_PRIVATE (FUTEX_UNLOCK_WAKE_LIST32 | FUTEX_PRIVATE_FLAG)
64
65#define FUTEX_UNLOCK_BITSET_LIST64 (FUTEX_WAKE_BITSET | FUTEX_ROBUST_UNLOCK)
66#define FUTEX_UNLOCK_BITSET_LIST64_PRIVATE (FUTEX_UNLOCK_BITSET_LIST64 | FUTEX_PRIVATE_FLAG)
67
68#define FUTEX_UNLOCK_BITSET_LIST32 (FUTEX_WAKE_BITSET | FUTEX_ROBUST_UNLOCK | \
69 FUTEX_ROBUST_LIST32)
70#define FUTEX_UNLOCK_BITSET_LIST32_PRIVATE (FUTEX_UNLOCK_BITSET_LIST32 | FUTEX_PRIVATE_FLAG)
71
72/*
73 * Flags for futex2 syscalls.
74 *
75 * NOTE: these are not pure flags, they can also be seen as:
76 *
77 * union {
78 * u32 flags;
79 * struct {
80 * u32 size : 2,
81 * numa : 1,
82 * : 4,
83 * private : 1;
84 * };
85 * };
86 */
87#define FUTEX2_SIZE_U8 0x00
88#define FUTEX2_SIZE_U16 0x01
89#define FUTEX2_SIZE_U32 0x02
90#define FUTEX2_SIZE_U64 0x03
91#define FUTEX2_NUMA 0x04
92#define FUTEX2_MPOL 0x08
93 /* 0x10 */
94 /* 0x20 */
95 /* 0x40 */
96#define FUTEX2_PRIVATE FUTEX_PRIVATE_FLAG
97
98#define FUTEX2_SIZE_MASK 0x03
99
100/* do not use */
101#define FUTEX_32 FUTEX2_SIZE_U32 /* historical accident :-( */
102
103/*
104 * When FUTEX2_NUMA doubles the futex word, the second word is a node value.
105 * The special value -1 indicates no-node. This is the same value as
106 * NUMA_NO_NODE, except that value is not ABI, this is.
107 */
108#define FUTEX_NO_NODE (-1)
109
110/*
111 * Max numbers of elements in a futex_waitv array
112 */
113#define FUTEX_WAITV_MAX 128
114
115/**
116 * struct futex_waitv - A waiter for vectorized wait
117 * @val: Expected value at uaddr
118 * @uaddr: User address to wait on
119 * @flags: Flags for this waiter
120 * @__reserved: Reserved member to preserve data alignment. Should be 0.
121 */
122struct futex_waitv {
123 __u64 val;
124 __u64 uaddr;
125 __u32 flags;
126 __u32 __reserved;
127};
128
129/*
130 * Support for robust futexes: the kernel cleans up held futexes at
131 * thread exit time.
132 */
133
134/*
135 * Per-lock list entry - embedded in user-space locks, somewhere close
136 * to the futex field. (Note: user-space uses a double-linked list to
137 * achieve O(1) list add and remove, but the kernel only needs to know
138 * about the forward link)
139 *
140 * NOTE: this structure is part of the syscall ABI, and must not be
141 * changed.
142 */
143struct robust_list {
144 struct robust_list *next;
145};
146
147/*
148 * Per-thread list head:
149 *
150 * NOTE: this structure is part of the syscall ABI, and must only be
151 * changed if the change is first communicated with the glibc folks.
152 * (When an incompatible change is done, we'll increase the structure
153 * size, which glibc will detect)
154 */
155struct robust_list_head {
156 /*
157 * The head of the list. Points back to itself if empty:
158 */
159 struct robust_list list;
160
161 /*
162 * This relative offset is set by user-space, it gives the kernel
163 * the relative position of the futex field to examine. This way
164 * we keep userspace flexible, to freely shape its data-structure,
165 * without hardcoding any particular offset into the kernel:
166 */
167 long futex_offset;
168
169 /*
170 * The death of the thread may race with userspace setting
171 * up a lock's links. So to handle this race, userspace first
172 * sets this field to the address of the to-be-taken lock,
173 * then does the lock acquire, and then adds itself to the
174 * list, and then clears this field. Hence the kernel will
175 * always have full knowledge of all locks that the thread
176 * _might_ have taken. We check the owner TID in any case,
177 * so only truly owned locks will be handled.
178 */
179 struct robust_list *list_op_pending;
180};
181
182/*
183 * Are there any waiters for this robust futex:
184 */
185#define FUTEX_WAITERS 0x80000000
186
187/*
188 * The kernel signals via this bit that a thread holding a futex
189 * has exited without unlocking the futex. The kernel also does
190 * a FUTEX_WAKE on such futexes, after setting the bit, to wake
191 * up any possible waiters:
192 */
193#define FUTEX_OWNER_DIED 0x40000000
194
195/*
196 * The rest of the robust-futex field is for the TID:
197 */
198#define FUTEX_TID_MASK 0x3fffffff
199
200/*
201 * This limit protects against a deliberately circular list.
202 * (Not worth introducing an rlimit for it)
203 */
204#define ROBUST_LIST_LIMIT 2048
205
206/* Modifiers for robust_list_head::list_op_pending */
207#define FUTEX_ROBUST_MOD_PI (0x1UL)
208#define FUTEX_ROBUST_MOD_MASK (FUTEX_ROBUST_MOD_PI)
209
210/*
211 * bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a
212 * match of any bit.
213 */
214#define FUTEX_BITSET_MATCH_ANY 0xffffffff
215
216
217#define FUTEX_OP_SET 0 /* *(int *)UADDR2 = OPARG; */
218#define FUTEX_OP_ADD 1 /* *(int *)UADDR2 += OPARG; */
219#define FUTEX_OP_OR 2 /* *(int *)UADDR2 |= OPARG; */
220#define FUTEX_OP_ANDN 3 /* *(int *)UADDR2 &= ~OPARG; */
221#define FUTEX_OP_XOR 4 /* *(int *)UADDR2 ^= OPARG; */
222
223#define FUTEX_OP_OPARG_SHIFT 8 /* Use (1 << OPARG) instead of OPARG. */
224
225#define FUTEX_OP_CMP_EQ 0 /* if (oldval == CMPARG) wake */
226#define FUTEX_OP_CMP_NE 1 /* if (oldval != CMPARG) wake */
227#define FUTEX_OP_CMP_LT 2 /* if (oldval < CMPARG) wake */
228#define FUTEX_OP_CMP_LE 3 /* if (oldval <= CMPARG) wake */
229#define FUTEX_OP_CMP_GT 4 /* if (oldval > CMPARG) wake */
230#define FUTEX_OP_CMP_GE 5 /* if (oldval >= CMPARG) wake */
231
232/* FUTEX_WAKE_OP will perform atomically
233 int oldval = *(int *)UADDR2;
234 *(int *)UADDR2 = oldval OP OPARG;
235 if (oldval CMP CMPARG)
236 wake UADDR2; */
237
238#define FUTEX_OP(op, oparg, cmp, cmparg) \
239 (((op & 0xf) << 28) | ((cmp & 0xf) << 24) \
240 | ((oparg & 0xfff) << 12) | (cmparg & 0xfff))
241
242#endif /* _LINUX_FUTEX_H */