16f52b16cSGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2607ca46eSDavid Howells #ifndef _UAPI_LINUX_FUTEX_H 3607ca46eSDavid Howells #define _UAPI_LINUX_FUTEX_H 4607ca46eSDavid Howells 5607ca46eSDavid Howells #include <linux/compiler.h> 6607ca46eSDavid Howells #include <linux/types.h> 7607ca46eSDavid Howells 8607ca46eSDavid Howells /* Second argument to futex syscall */ 9607ca46eSDavid Howells 10607ca46eSDavid Howells 11607ca46eSDavid Howells #define FUTEX_WAIT 0 12607ca46eSDavid Howells #define FUTEX_WAKE 1 13607ca46eSDavid Howells #define FUTEX_FD 2 14607ca46eSDavid Howells #define FUTEX_REQUEUE 3 15607ca46eSDavid Howells #define FUTEX_CMP_REQUEUE 4 16607ca46eSDavid Howells #define FUTEX_WAKE_OP 5 17607ca46eSDavid Howells #define FUTEX_LOCK_PI 6 18607ca46eSDavid Howells #define FUTEX_UNLOCK_PI 7 19607ca46eSDavid Howells #define FUTEX_TRYLOCK_PI 8 20607ca46eSDavid Howells #define FUTEX_WAIT_BITSET 9 21607ca46eSDavid Howells #define FUTEX_WAKE_BITSET 10 22607ca46eSDavid Howells #define FUTEX_WAIT_REQUEUE_PI 11 23607ca46eSDavid Howells #define FUTEX_CMP_REQUEUE_PI 12 24bf22a697SThomas Gleixner #define FUTEX_LOCK_PI2 13 25607ca46eSDavid Howells 26607ca46eSDavid Howells #define FUTEX_PRIVATE_FLAG 128 27607ca46eSDavid Howells #define FUTEX_CLOCK_REALTIME 256 28607ca46eSDavid Howells #define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) 29607ca46eSDavid Howells 30607ca46eSDavid Howells #define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) 31607ca46eSDavid Howells #define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) 32607ca46eSDavid Howells #define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG) 33607ca46eSDavid Howells #define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG) 34607ca46eSDavid Howells #define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG) 35607ca46eSDavid Howells #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) 36bf22a697SThomas Gleixner #define FUTEX_LOCK_PI2_PRIVATE (FUTEX_LOCK_PI2 | FUTEX_PRIVATE_FLAG) 37607ca46eSDavid Howells #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) 38607ca46eSDavid Howells #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) 39607ca46eSDavid Howells #define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG) 40607ca46eSDavid Howells #define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG) 41607ca46eSDavid Howells #define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | \ 42607ca46eSDavid Howells FUTEX_PRIVATE_FLAG) 43607ca46eSDavid Howells #define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \ 44607ca46eSDavid Howells FUTEX_PRIVATE_FLAG) 45607ca46eSDavid Howells 46607ca46eSDavid Howells /* 474923954bSpeterz@infradead.org * Flags for futex2 syscalls. 48*d6d08d24Speterz@infradead.org * 49*d6d08d24Speterz@infradead.org * NOTE: these are not pure flags, they can also be seen as: 50*d6d08d24Speterz@infradead.org * 51*d6d08d24Speterz@infradead.org * union { 52*d6d08d24Speterz@infradead.org * u32 flags; 53*d6d08d24Speterz@infradead.org * struct { 54*d6d08d24Speterz@infradead.org * u32 size : 2, 55*d6d08d24Speterz@infradead.org * numa : 1, 56*d6d08d24Speterz@infradead.org * : 4, 57*d6d08d24Speterz@infradead.org * private : 1; 58*d6d08d24Speterz@infradead.org * }; 59*d6d08d24Speterz@infradead.org * }; 60bf69bad3SAndré Almeida */ 61*d6d08d24Speterz@infradead.org #define FUTEX2_SIZE_U8 0x00 62*d6d08d24Speterz@infradead.org #define FUTEX2_SIZE_U16 0x01 634923954bSpeterz@infradead.org #define FUTEX2_SIZE_U32 0x02 64*d6d08d24Speterz@infradead.org #define FUTEX2_SIZE_U64 0x03 65*d6d08d24Speterz@infradead.org #define FUTEX2_NUMA 0x04 664923954bSpeterz@infradead.org /* 0x08 */ 674923954bSpeterz@infradead.org /* 0x10 */ 684923954bSpeterz@infradead.org /* 0x20 */ 694923954bSpeterz@infradead.org /* 0x40 */ 704923954bSpeterz@infradead.org #define FUTEX2_PRIVATE FUTEX_PRIVATE_FLAG 714923954bSpeterz@infradead.org 72*d6d08d24Speterz@infradead.org #define FUTEX2_SIZE_MASK 0x03 73*d6d08d24Speterz@infradead.org 744923954bSpeterz@infradead.org /* do not use */ 754923954bSpeterz@infradead.org #define FUTEX_32 FUTEX2_SIZE_U32 /* historical accident :-( */ 76bf69bad3SAndré Almeida 77bf69bad3SAndré Almeida /* 78bf69bad3SAndré Almeida * Max numbers of elements in a futex_waitv array 79bf69bad3SAndré Almeida */ 80bf69bad3SAndré Almeida #define FUTEX_WAITV_MAX 128 81bf69bad3SAndré Almeida 82bf69bad3SAndré Almeida /** 83bf69bad3SAndré Almeida * struct futex_waitv - A waiter for vectorized wait 84bf69bad3SAndré Almeida * @val: Expected value at uaddr 85bf69bad3SAndré Almeida * @uaddr: User address to wait on 86bf69bad3SAndré Almeida * @flags: Flags for this waiter 87bf69bad3SAndré Almeida * @__reserved: Reserved member to preserve data alignment. Should be 0. 88bf69bad3SAndré Almeida */ 89bf69bad3SAndré Almeida struct futex_waitv { 90bf69bad3SAndré Almeida __u64 val; 91bf69bad3SAndré Almeida __u64 uaddr; 92bf69bad3SAndré Almeida __u32 flags; 93bf69bad3SAndré Almeida __u32 __reserved; 94bf69bad3SAndré Almeida }; 95bf69bad3SAndré Almeida 96bf69bad3SAndré Almeida /* 97607ca46eSDavid Howells * Support for robust futexes: the kernel cleans up held futexes at 98607ca46eSDavid Howells * thread exit time. 99607ca46eSDavid Howells */ 100607ca46eSDavid Howells 101607ca46eSDavid Howells /* 102607ca46eSDavid Howells * Per-lock list entry - embedded in user-space locks, somewhere close 103607ca46eSDavid Howells * to the futex field. (Note: user-space uses a double-linked list to 104607ca46eSDavid Howells * achieve O(1) list add and remove, but the kernel only needs to know 105607ca46eSDavid Howells * about the forward link) 106607ca46eSDavid Howells * 107607ca46eSDavid Howells * NOTE: this structure is part of the syscall ABI, and must not be 108607ca46eSDavid Howells * changed. 109607ca46eSDavid Howells */ 110607ca46eSDavid Howells struct robust_list { 111607ca46eSDavid Howells struct robust_list __user *next; 112607ca46eSDavid Howells }; 113607ca46eSDavid Howells 114607ca46eSDavid Howells /* 115607ca46eSDavid Howells * Per-thread list head: 116607ca46eSDavid Howells * 117607ca46eSDavid Howells * NOTE: this structure is part of the syscall ABI, and must only be 118607ca46eSDavid Howells * changed if the change is first communicated with the glibc folks. 119607ca46eSDavid Howells * (When an incompatible change is done, we'll increase the structure 120607ca46eSDavid Howells * size, which glibc will detect) 121607ca46eSDavid Howells */ 122607ca46eSDavid Howells struct robust_list_head { 123607ca46eSDavid Howells /* 124607ca46eSDavid Howells * The head of the list. Points back to itself if empty: 125607ca46eSDavid Howells */ 126607ca46eSDavid Howells struct robust_list list; 127607ca46eSDavid Howells 128607ca46eSDavid Howells /* 129607ca46eSDavid Howells * This relative offset is set by user-space, it gives the kernel 130607ca46eSDavid Howells * the relative position of the futex field to examine. This way 131607ca46eSDavid Howells * we keep userspace flexible, to freely shape its data-structure, 132607ca46eSDavid Howells * without hardcoding any particular offset into the kernel: 133607ca46eSDavid Howells */ 134607ca46eSDavid Howells long futex_offset; 135607ca46eSDavid Howells 136607ca46eSDavid Howells /* 137607ca46eSDavid Howells * The death of the thread may race with userspace setting 138607ca46eSDavid Howells * up a lock's links. So to handle this race, userspace first 139607ca46eSDavid Howells * sets this field to the address of the to-be-taken lock, 140607ca46eSDavid Howells * then does the lock acquire, and then adds itself to the 141607ca46eSDavid Howells * list, and then clears this field. Hence the kernel will 142607ca46eSDavid Howells * always have full knowledge of all locks that the thread 143607ca46eSDavid Howells * _might_ have taken. We check the owner TID in any case, 144607ca46eSDavid Howells * so only truly owned locks will be handled. 145607ca46eSDavid Howells */ 146607ca46eSDavid Howells struct robust_list __user *list_op_pending; 147607ca46eSDavid Howells }; 148607ca46eSDavid Howells 149607ca46eSDavid Howells /* 150607ca46eSDavid Howells * Are there any waiters for this robust futex: 151607ca46eSDavid Howells */ 152607ca46eSDavid Howells #define FUTEX_WAITERS 0x80000000 153607ca46eSDavid Howells 154607ca46eSDavid Howells /* 155607ca46eSDavid Howells * The kernel signals via this bit that a thread holding a futex 156607ca46eSDavid Howells * has exited without unlocking the futex. The kernel also does 157607ca46eSDavid Howells * a FUTEX_WAKE on such futexes, after setting the bit, to wake 158607ca46eSDavid Howells * up any possible waiters: 159607ca46eSDavid Howells */ 160607ca46eSDavid Howells #define FUTEX_OWNER_DIED 0x40000000 161607ca46eSDavid Howells 162607ca46eSDavid Howells /* 163607ca46eSDavid Howells * The rest of the robust-futex field is for the TID: 164607ca46eSDavid Howells */ 165607ca46eSDavid Howells #define FUTEX_TID_MASK 0x3fffffff 166607ca46eSDavid Howells 167607ca46eSDavid Howells /* 168607ca46eSDavid Howells * This limit protects against a deliberately circular list. 169607ca46eSDavid Howells * (Not worth introducing an rlimit for it) 170607ca46eSDavid Howells */ 171607ca46eSDavid Howells #define ROBUST_LIST_LIMIT 2048 172607ca46eSDavid Howells 173607ca46eSDavid Howells /* 174607ca46eSDavid Howells * bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a 175607ca46eSDavid Howells * match of any bit. 176607ca46eSDavid Howells */ 177607ca46eSDavid Howells #define FUTEX_BITSET_MATCH_ANY 0xffffffff 178607ca46eSDavid Howells 179607ca46eSDavid Howells 180607ca46eSDavid Howells #define FUTEX_OP_SET 0 /* *(int *)UADDR2 = OPARG; */ 181607ca46eSDavid Howells #define FUTEX_OP_ADD 1 /* *(int *)UADDR2 += OPARG; */ 182607ca46eSDavid Howells #define FUTEX_OP_OR 2 /* *(int *)UADDR2 |= OPARG; */ 183607ca46eSDavid Howells #define FUTEX_OP_ANDN 3 /* *(int *)UADDR2 &= ~OPARG; */ 184607ca46eSDavid Howells #define FUTEX_OP_XOR 4 /* *(int *)UADDR2 ^= OPARG; */ 185607ca46eSDavid Howells 186607ca46eSDavid Howells #define FUTEX_OP_OPARG_SHIFT 8 /* Use (1 << OPARG) instead of OPARG. */ 187607ca46eSDavid Howells 188607ca46eSDavid Howells #define FUTEX_OP_CMP_EQ 0 /* if (oldval == CMPARG) wake */ 189607ca46eSDavid Howells #define FUTEX_OP_CMP_NE 1 /* if (oldval != CMPARG) wake */ 190607ca46eSDavid Howells #define FUTEX_OP_CMP_LT 2 /* if (oldval < CMPARG) wake */ 191607ca46eSDavid Howells #define FUTEX_OP_CMP_LE 3 /* if (oldval <= CMPARG) wake */ 192607ca46eSDavid Howells #define FUTEX_OP_CMP_GT 4 /* if (oldval > CMPARG) wake */ 193607ca46eSDavid Howells #define FUTEX_OP_CMP_GE 5 /* if (oldval >= CMPARG) wake */ 194607ca46eSDavid Howells 195607ca46eSDavid Howells /* FUTEX_WAKE_OP will perform atomically 196607ca46eSDavid Howells int oldval = *(int *)UADDR2; 197607ca46eSDavid Howells *(int *)UADDR2 = oldval OP OPARG; 198607ca46eSDavid Howells if (oldval CMP CMPARG) 199607ca46eSDavid Howells wake UADDR2; */ 200607ca46eSDavid Howells 201607ca46eSDavid Howells #define FUTEX_OP(op, oparg, cmp, cmparg) \ 202607ca46eSDavid Howells (((op & 0xf) << 28) | ((cmp & 0xf) << 24) \ 203607ca46eSDavid Howells | ((oparg & 0xfff) << 12) | (cmparg & 0xfff)) 204607ca46eSDavid Howells 205607ca46eSDavid Howells #endif /* _UAPI_LINUX_FUTEX_H */ 206