1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later 2*49cdfc7eSAndroid Build Coastguard Worker /* 3*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2015 Linux Test Project 4*49cdfc7eSAndroid Build Coastguard Worker * Copyright (C) 2021 SUSE LLC Andrea Cervesato <[email protected]> 5*49cdfc7eSAndroid Build Coastguard Worker */ 6*49cdfc7eSAndroid Build Coastguard Worker 7*49cdfc7eSAndroid Build Coastguard Worker #ifndef LAPI_FUTEX_H__ 8*49cdfc7eSAndroid Build Coastguard Worker #define LAPI_FUTEX_H__ 9*49cdfc7eSAndroid Build Coastguard Worker 10*49cdfc7eSAndroid Build Coastguard Worker #include <stdint.h> 11*49cdfc7eSAndroid Build Coastguard Worker #include "config.h" 12*49cdfc7eSAndroid Build Coastguard Worker 13*49cdfc7eSAndroid Build Coastguard Worker typedef volatile uint32_t futex_t; 14*49cdfc7eSAndroid Build Coastguard Worker 15*49cdfc7eSAndroid Build Coastguard Worker #if !defined(SYS_futex) && defined(SYS_futex_time64) 16*49cdfc7eSAndroid Build Coastguard Worker #define SYS_futex SYS_futex_time64 17*49cdfc7eSAndroid Build Coastguard Worker #endif 18*49cdfc7eSAndroid Build Coastguard Worker 19*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_FUTEX_H 20*49cdfc7eSAndroid Build Coastguard Worker # include <linux/futex.h> 21*49cdfc7eSAndroid Build Coastguard Worker #else 22*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h> 23*49cdfc7eSAndroid Build Coastguard Worker 24*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAIT 0 25*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAKE 1 26*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_FD 2 27*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_REQUEUE 3 28*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_CMP_REQUEUE 4 29*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAKE_OP 5 30*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_LOCK_PI 6 31*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_UNLOCK_PI 7 32*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_TRYLOCK_PI 8 33*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAIT_BITSET 9 34*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAKE_BITSET 10 35*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAIT_REQUEUE_PI 11 36*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_CMP_REQUEUE_PI 12 37*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_LOCK_PI2 13 38*49cdfc7eSAndroid Build Coastguard Worker 39*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_PRIVATE_FLAG 128 40*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_CLOCK_REALTIME 256 41*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) 42*49cdfc7eSAndroid Build Coastguard Worker 43*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) 44*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) 45*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG) 46*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG) 47*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG) 48*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) 49*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_LOCK_PI2_PRIVATE (FUTEX_LOCK_PI2 | FUTEX_PRIVATE_FLAG) 50*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) 51*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) 52*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG) 53*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG) 54*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | \ 55*49cdfc7eSAndroid Build Coastguard Worker FUTEX_PRIVATE_FLAG) 56*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \ 57*49cdfc7eSAndroid Build Coastguard Worker FUTEX_PRIVATE_FLAG) 58*49cdfc7eSAndroid Build Coastguard Worker 59*49cdfc7eSAndroid Build Coastguard Worker /* 60*49cdfc7eSAndroid Build Coastguard Worker * Support for robust futexes: the kernel cleans up held futexes at 61*49cdfc7eSAndroid Build Coastguard Worker * thread exit time. 62*49cdfc7eSAndroid Build Coastguard Worker */ 63*49cdfc7eSAndroid Build Coastguard Worker 64*49cdfc7eSAndroid Build Coastguard Worker /* 65*49cdfc7eSAndroid Build Coastguard Worker * Per-lock list entry - embedded in user-space locks, somewhere close 66*49cdfc7eSAndroid Build Coastguard Worker * to the futex field. (Note: user-space uses a double-linked list to 67*49cdfc7eSAndroid Build Coastguard Worker * achieve O(1) list add and remove, but the kernel only needs to know 68*49cdfc7eSAndroid Build Coastguard Worker * about the forward link) 69*49cdfc7eSAndroid Build Coastguard Worker * 70*49cdfc7eSAndroid Build Coastguard Worker * NOTE: this structure is part of the syscall ABI, and must not be 71*49cdfc7eSAndroid Build Coastguard Worker * changed. 72*49cdfc7eSAndroid Build Coastguard Worker */ 73*49cdfc7eSAndroid Build Coastguard Worker struct robust_list { 74*49cdfc7eSAndroid Build Coastguard Worker struct robust_list *next; 75*49cdfc7eSAndroid Build Coastguard Worker }; 76*49cdfc7eSAndroid Build Coastguard Worker 77*49cdfc7eSAndroid Build Coastguard Worker /* 78*49cdfc7eSAndroid Build Coastguard Worker * Per-thread list head: 79*49cdfc7eSAndroid Build Coastguard Worker * 80*49cdfc7eSAndroid Build Coastguard Worker * NOTE: this structure is part of the syscall ABI, and must only be 81*49cdfc7eSAndroid Build Coastguard Worker * changed if the change is first communicated with the glibc folks. 82*49cdfc7eSAndroid Build Coastguard Worker * (When an incompatible change is done, we'll increase the structure 83*49cdfc7eSAndroid Build Coastguard Worker * size, which glibc will detect) 84*49cdfc7eSAndroid Build Coastguard Worker */ 85*49cdfc7eSAndroid Build Coastguard Worker struct robust_list_head { 86*49cdfc7eSAndroid Build Coastguard Worker /* 87*49cdfc7eSAndroid Build Coastguard Worker * The head of the list. Points back to itself if empty: 88*49cdfc7eSAndroid Build Coastguard Worker */ 89*49cdfc7eSAndroid Build Coastguard Worker struct robust_list list; 90*49cdfc7eSAndroid Build Coastguard Worker 91*49cdfc7eSAndroid Build Coastguard Worker /* 92*49cdfc7eSAndroid Build Coastguard Worker * This relative offset is set by user-space, it gives the kernel 93*49cdfc7eSAndroid Build Coastguard Worker * the relative position of the futex field to examine. This way 94*49cdfc7eSAndroid Build Coastguard Worker * we keep userspace flexible, to freely shape its data-structure, 95*49cdfc7eSAndroid Build Coastguard Worker * without hardcoding any particular offset into the kernel: 96*49cdfc7eSAndroid Build Coastguard Worker */ 97*49cdfc7eSAndroid Build Coastguard Worker long futex_offset; 98*49cdfc7eSAndroid Build Coastguard Worker 99*49cdfc7eSAndroid Build Coastguard Worker /* 100*49cdfc7eSAndroid Build Coastguard Worker * The death of the thread may race with userspace setting 101*49cdfc7eSAndroid Build Coastguard Worker * up a lock's links. So to handle this race, userspace first 102*49cdfc7eSAndroid Build Coastguard Worker * sets this field to the address of the to-be-taken lock, 103*49cdfc7eSAndroid Build Coastguard Worker * then does the lock acquire, and then adds itself to the 104*49cdfc7eSAndroid Build Coastguard Worker * list, and then clears this field. Hence the kernel will 105*49cdfc7eSAndroid Build Coastguard Worker * always have full knowledge of all locks that the thread 106*49cdfc7eSAndroid Build Coastguard Worker * _might_ have taken. We check the owner TID in any case, 107*49cdfc7eSAndroid Build Coastguard Worker * so only truly owned locks will be handled. 108*49cdfc7eSAndroid Build Coastguard Worker */ 109*49cdfc7eSAndroid Build Coastguard Worker struct robust_list *list_op_pending; 110*49cdfc7eSAndroid Build Coastguard Worker }; 111*49cdfc7eSAndroid Build Coastguard Worker 112*49cdfc7eSAndroid Build Coastguard Worker /* 113*49cdfc7eSAndroid Build Coastguard Worker * Are there any waiters for this robust futex: 114*49cdfc7eSAndroid Build Coastguard Worker */ 115*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAITERS 0x80000000 116*49cdfc7eSAndroid Build Coastguard Worker 117*49cdfc7eSAndroid Build Coastguard Worker /* 118*49cdfc7eSAndroid Build Coastguard Worker * The kernel signals via this bit that a thread holding a futex 119*49cdfc7eSAndroid Build Coastguard Worker * has exited without unlocking the futex. The kernel also does 120*49cdfc7eSAndroid Build Coastguard Worker * a FUTEX_WAKE on such futexes, after setting the bit, to wake 121*49cdfc7eSAndroid Build Coastguard Worker * up any possible waiters: 122*49cdfc7eSAndroid Build Coastguard Worker */ 123*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OWNER_DIED 0x40000000 124*49cdfc7eSAndroid Build Coastguard Worker 125*49cdfc7eSAndroid Build Coastguard Worker /* 126*49cdfc7eSAndroid Build Coastguard Worker * The rest of the robust-futex field is for the TID: 127*49cdfc7eSAndroid Build Coastguard Worker */ 128*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_TID_MASK 0x3fffffff 129*49cdfc7eSAndroid Build Coastguard Worker 130*49cdfc7eSAndroid Build Coastguard Worker /* 131*49cdfc7eSAndroid Build Coastguard Worker * This limit protects against a deliberately circular list. 132*49cdfc7eSAndroid Build Coastguard Worker * (Not worth introducing an rlimit for it) 133*49cdfc7eSAndroid Build Coastguard Worker */ 134*49cdfc7eSAndroid Build Coastguard Worker #define ROBUST_LIST_LIMIT 2048 135*49cdfc7eSAndroid Build Coastguard Worker 136*49cdfc7eSAndroid Build Coastguard Worker /* 137*49cdfc7eSAndroid Build Coastguard Worker * bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a 138*49cdfc7eSAndroid Build Coastguard Worker * match of any bit. 139*49cdfc7eSAndroid Build Coastguard Worker */ 140*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_BITSET_MATCH_ANY 0xffffffff 141*49cdfc7eSAndroid Build Coastguard Worker 142*49cdfc7eSAndroid Build Coastguard Worker 143*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_SET 0 /* *(int *)UADDR2 = OPARG; */ 144*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_ADD 1 /* *(int *)UADDR2 += OPARG; */ 145*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_OR 2 /* *(int *)UADDR2 |= OPARG; */ 146*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_ANDN 3 /* *(int *)UADDR2 &= ~OPARG; */ 147*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_XOR 4 /* *(int *)UADDR2 ^= OPARG; */ 148*49cdfc7eSAndroid Build Coastguard Worker 149*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_OPARG_SHIFT 8 /* Use (1 << OPARG) instead of OPARG. */ 150*49cdfc7eSAndroid Build Coastguard Worker 151*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_CMP_EQ 0 /* if (oldval == CMPARG) wake */ 152*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_CMP_NE 1 /* if (oldval != CMPARG) wake */ 153*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_CMP_LT 2 /* if (oldval < CMPARG) wake */ 154*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_CMP_LE 3 /* if (oldval <= CMPARG) wake */ 155*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_CMP_GT 4 /* if (oldval > CMPARG) wake */ 156*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP_CMP_GE 5 /* if (oldval >= CMPARG) wake */ 157*49cdfc7eSAndroid Build Coastguard Worker 158*49cdfc7eSAndroid Build Coastguard Worker /* FUTEX_WAKE_OP will perform atomically 159*49cdfc7eSAndroid Build Coastguard Worker int oldval = *(int *)UADDR2; 160*49cdfc7eSAndroid Build Coastguard Worker *(int *)UADDR2 = oldval OP OPARG; 161*49cdfc7eSAndroid Build Coastguard Worker if (oldval CMP CMPARG) 162*49cdfc7eSAndroid Build Coastguard Worker wake UADDR2; */ 163*49cdfc7eSAndroid Build Coastguard Worker 164*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_OP(op, oparg, cmp, cmparg) \ 165*49cdfc7eSAndroid Build Coastguard Worker (((op & 0xf) << 28) | ((cmp & 0xf) << 24) \ 166*49cdfc7eSAndroid Build Coastguard Worker | ((oparg & 0xfff) << 12) | (cmparg & 0xfff)) 167*49cdfc7eSAndroid Build Coastguard Worker 168*49cdfc7eSAndroid Build Coastguard Worker #endif /* HAVE_LINUX_FUTEX_H */ 169*49cdfc7eSAndroid Build Coastguard Worker 170*49cdfc7eSAndroid Build Coastguard Worker #ifndef HAVE_STRUCT_FUTEX_WAITV 171*49cdfc7eSAndroid Build Coastguard Worker /* 172*49cdfc7eSAndroid Build Coastguard Worker * Flags to specify the bit length of the futex word for futex2 syscalls. 173*49cdfc7eSAndroid Build Coastguard Worker * Currently, only 32 is supported. 174*49cdfc7eSAndroid Build Coastguard Worker */ 175*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_32 2 176*49cdfc7eSAndroid Build Coastguard Worker 177*49cdfc7eSAndroid Build Coastguard Worker /* 178*49cdfc7eSAndroid Build Coastguard Worker * Max numbers of elements in a futex_waitv array 179*49cdfc7eSAndroid Build Coastguard Worker */ 180*49cdfc7eSAndroid Build Coastguard Worker #define FUTEX_WAITV_MAX 128 181*49cdfc7eSAndroid Build Coastguard Worker 182*49cdfc7eSAndroid Build Coastguard Worker /** 183*49cdfc7eSAndroid Build Coastguard Worker * struct futex_waitv - A waiter for vectorized wait 184*49cdfc7eSAndroid Build Coastguard Worker * @val: Expected value at uaddr 185*49cdfc7eSAndroid Build Coastguard Worker * @uaddr: User address to wait on 186*49cdfc7eSAndroid Build Coastguard Worker * @flags: Flags for this waiter 187*49cdfc7eSAndroid Build Coastguard Worker * @__reserved: Reserved member to preserve data alignment. Should be 0. 188*49cdfc7eSAndroid Build Coastguard Worker */ 189*49cdfc7eSAndroid Build Coastguard Worker struct futex_waitv { 190*49cdfc7eSAndroid Build Coastguard Worker uint64_t val; 191*49cdfc7eSAndroid Build Coastguard Worker uint64_t uaddr; 192*49cdfc7eSAndroid Build Coastguard Worker uint32_t flags; 193*49cdfc7eSAndroid Build Coastguard Worker uint32_t __reserved; 194*49cdfc7eSAndroid Build Coastguard Worker }; 195*49cdfc7eSAndroid Build Coastguard Worker #endif /* HAVE_STRUCT_FUTEX_WAITV */ 196*49cdfc7eSAndroid Build Coastguard Worker 197*49cdfc7eSAndroid Build Coastguard Worker #endif /* LAPI_FUTEX_H__ */ 198