1 /*
2  * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
3  * Copyright (c) 2016-2018 The strace developers.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "tests.h"
30 
31 #include <asm/unistd.h>
32 
33 #ifdef __NR_futex
34 
35 # include <errno.h>
36 # include <stdarg.h>
37 # include <stdio.h>
38 # include <stdint.h>
39 # include <unistd.h>
40 
41 # include <sys/time.h>
42 
43 # ifndef FUTEX_PRIVATE_FLAG
44 #  define FUTEX_PRIVATE_FLAG 128
45 # endif
46 # ifndef FUTEX_CLOCK_REALTIME
47 #  define FUTEX_CLOCK_REALTIME 256
48 # endif
49 # ifndef FUTEX_CMD_MASK
50 #  define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
51 # endif
52 
53 # include "xlat.h"
54 # include "xlat/futexops.h"
55 # include "xlat/futexwakeops.h"
56 # include "xlat/futexwakecmps.h"
57 
futex_error(int * uaddr,int op,unsigned long val,unsigned long timeout,int * uaddr2,unsigned long val3,int rc,const char * func,int line)58 void futex_error(int *uaddr, int op, unsigned long val, unsigned long timeout,
59 	int *uaddr2, unsigned long val3, int rc, const char *func, int line)
60 {
61 	perror_msg_and_fail("%s:%d: futex(%p, %#x, %#x, %#lx, %p, %#x) = %d",
62 		func, line, uaddr, op, (unsigned) val, timeout, uaddr,
63 		(unsigned) val3, rc);
64 }
65 
66 # define CHECK_FUTEX_GENERIC(uaddr, op, val, timeout, uaddr2, val3, check, \
67 	enosys) \
68 	do { \
69 		errno = 0; \
70 		rc = syscall(__NR_futex, (uaddr), (op), (val), (timeout), \
71 			(uaddr2), (val3)); \
72 		/* It is here due to EPERM on WAKE_OP on AArch64 */ \
73 		if ((rc == -1) && (errno == EPERM)) \
74 			break; \
75 		if (enosys && (rc == -1) && (errno == ENOSYS)) \
76 			break; \
77 		if (!(check)) \
78 			futex_error((uaddr), (op), (val), \
79 				(unsigned long) (timeout), (int *) (uaddr2), \
80 				(val3), rc, __func__, __LINE__); \
81 	} while (0)
82 
83 # define CHECK_FUTEX_ENOSYS(uaddr, op, val, timeout, uaddr2, val3, check) \
84 	CHECK_FUTEX_GENERIC(uaddr, op, val, timeout, uaddr2, val3, check, 1)
85 
86 # define CHECK_FUTEX(uaddr, op, val, timeout, uaddr2, val3, check) \
87 	CHECK_FUTEX_GENERIC(uaddr, op, val, timeout, uaddr2, val3, check, 0)
88 
89 enum argmask {
90 	ARG3 = 1 << 0,
91 	ARG4 = 1 << 1,
92 	ARG5 = 1 << 2,
93 	ARG6 = 1 << 3,
94 };
95 
invalid_op(int * val,int op,uint32_t argmask,...)96 void invalid_op(int *val, int op, uint32_t argmask, ...)
97 {
98 	static const unsigned long args[] = {
99 		(unsigned long) 0xface1e55deadbee1ULL,
100 		(unsigned long) 0xface1e56deadbee2ULL,
101 		(unsigned long) 0xface1e57deadbee3ULL,
102 		(unsigned long) 0xface1e58deadbee4ULL,
103 	};
104 	/* Since timeout value is copied before full op check, we should provide
105 	 * some valid timeout address or NULL */
106 	int cmd = op & FUTEX_CMD_MASK;
107 	bool valid_timeout = (cmd == FUTEX_WAIT) || (cmd == FUTEX_LOCK_PI) ||
108 		(cmd == FUTEX_WAIT_BITSET) || (cmd == FUTEX_WAIT_REQUEUE_PI);
109 	bool timeout_is_val2 = (cmd == FUTEX_REQUEUE) ||
110 		(cmd == FUTEX_CMP_REQUEUE) || (cmd == FUTEX_WAKE_OP) ||
111 		(cmd == FUTEX_CMP_REQUEUE_PI);
112 	const char *fmt;
113 	int saved_errno;
114 	int rc;
115 	int i;
116 	va_list ap;
117 
118 
119 	CHECK_FUTEX(val, op, args[0], valid_timeout ? 0 : args[1], args[2],
120 		args[3], (rc == -1) && (errno == ENOSYS));
121 	saved_errno = errno;
122 	printf("futex(%p, %#x /* FUTEX_??? */", val, op);
123 
124 	va_start(ap, argmask);
125 
126 	for (i = 0; i < 4; i++) {
127 		if (argmask & (1 << i)) {
128 			fmt = va_arg(ap, const char *);
129 
130 			printf(", ");
131 
132 			if (((1 << i) == ARG3) || ((1 << i) == ARG6) ||
133 			    (((1 << i) == ARG4) && timeout_is_val2))
134 				printf(fmt, (unsigned) args[i]);
135 			else
136 				printf(fmt, args[i]);
137 		}
138 	}
139 
140 	va_end(ap);
141 
142 	errno = saved_errno;
143 	printf(") = -1 ENOSYS (%m)\n");
144 }
145 
146 # define CHECK_INVALID_CLOCKRT(op, ...) \
147 	do { \
148 		invalid_op(uaddr, FUTEX_CLOCK_REALTIME | (op), __VA_ARGS__); \
149 		invalid_op(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG | \
150 			(op), __VA_ARGS__); \
151 	} while (0)
152 
153 /* Value which differs from one stored in int *val */
154 # define VAL      ((unsigned long) 0xbadda7a0facefeedLLU)
155 # define VAL_PR   ((unsigned) VAL)
156 
157 # define VALP     ((unsigned long) 0xbadda7a01acefeedLLU)
158 # define VALP_PR  ((unsigned) VALP)
159 
160 # define VAL2     ((unsigned long) 0xbadda7a0ca7b100dLLU)
161 # define VAL2_PR  ((unsigned) VAL2)
162 
163 # define VAL2P    ((unsigned long) 0xbadda7a07a7b100dLLU)
164 # define VAL2P_PR ((unsigned) VAL2P)
165 
166 # define VAL3     ((unsigned long) 0xbadda7a09caffee1LLU)
167 # define VAL3_PR  ((unsigned) VAL3)
168 
169 # define VAL3A    ((unsigned long) 0xbadda7a0ffffffffLLU)
170 # define VAL3A_PR "FUTEX_BITSET_MATCH_ANY"
171 
172 int
main(int argc,char * argv[])173 main(int argc, char *argv[])
174 {
175 	TAIL_ALLOC_OBJECT_CONST_PTR(int, uaddr);
176 	TAIL_ALLOC_OBJECT_CONST_PTR(int, uaddr2);
177 	int rc;
178 	unsigned i;
179 	unsigned j;
180 
181 	uaddr[0] = 0x1deadead;
182 	uaddr2[0] = 0xbadf00d;
183 
184 	TAIL_ALLOC_OBJECT_CONST_PTR(struct timespec, tmout);
185 	tmout->tv_sec = 123;
186 	tmout->tv_nsec = 0xbadc0de;
187 
188 	/* FUTEX_WAIT - check whether uaddr == val and sleep
189 	 * Possible flags: PRIVATE, CLOCK_RT (since 4.5)
190 	 * 1. uaddr   - futex address
191 	 * 2. op      - FUTEX_WAIT
192 	 * 3. val     - expected value
193 	 * 4. timeout - address to timespec with timeout
194 	 * 5. uaddr2  - not used
195 	 * 6. val3    - not used
196 	 */
197 
198 	/* uaddr is NULL */
199 	CHECK_FUTEX(NULL, FUTEX_WAIT, VAL, tmout, uaddr2, VAL3,
200 		(rc == -1) && (errno == EFAULT));
201 	printf("futex(NULL, FUTEX_WAIT, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
202 	       VAL_PR, (long long) tmout->tv_sec,
203 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
204 
205 	/* uaddr is faulty */
206 	CHECK_FUTEX(uaddr + 1, FUTEX_WAIT, VAL, tmout, uaddr2, VAL3,
207 		(rc == -1) && (errno == EFAULT));
208 	printf("futex(%p, FUTEX_WAIT, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
209 	       uaddr + 1, VAL_PR, (long long) tmout->tv_sec,
210 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
211 
212 	/* timeout is faulty */
213 	CHECK_FUTEX(uaddr, FUTEX_WAIT, VAL, tmout + 1, uaddr2, VAL3,
214 		(rc == -1) && (errno == EFAULT));
215 	printf("futex(%p, FUTEX_WAIT, %u, %p) = %s\n",
216 	       uaddr, 0xfacefeed, tmout + 1, sprintrc(rc));
217 
218 	/* timeout is invalid */
219 	tmout->tv_sec = 0xdeadbeefU;
220 	tmout->tv_nsec = 0xfacefeedU;
221 
222 	CHECK_FUTEX(uaddr, FUTEX_WAIT, VAL, tmout, uaddr2, VAL3,
223 		(rc == -1) && (errno == EINVAL));
224 	printf("futex(%p, FUTEX_WAIT, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
225 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
226 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
227 
228 	tmout->tv_sec = (time_t) 0xcafef00ddeadbeefLL;
229 	tmout->tv_nsec = (long) 0xbadc0dedfacefeedLL;
230 
231 	CHECK_FUTEX(uaddr, FUTEX_WAIT, VAL, tmout, uaddr2, VAL3,
232 		(rc == -1) && (errno == EINVAL));
233 	printf("futex(%p, FUTEX_WAIT, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
234 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
235 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
236 
237 	tmout->tv_sec = 123;
238 	tmout->tv_nsec = 0xbadc0de;
239 
240 	/* uaddr is not as provided; uaddr2 is faulty but ignored */
241 	CHECK_FUTEX(uaddr, FUTEX_WAIT, VAL, tmout, uaddr2 + 1, VAL3,
242 		(rc == -1) && (errno == EAGAIN));
243 	printf("futex(%p, FUTEX_WAIT, %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
244 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
245 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
246 
247 	/* uaddr is not as provided; uaddr2 is faulty but ignored */
248 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAIT, VAL, tmout,
249 		uaddr2 + 1, VAL3, (rc == -1) && (errno == EAGAIN));
250 	printf("futex(%p, FUTEX_WAIT_PRIVATE, %u, {tv_sec=%lld, tv_nsec=%llu})"
251 	       " = %s\n",
252 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
253 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
254 
255 	/* Next 2 tests are with CLOCKRT bit set */
256 
257 	/* Valid after v4.4-rc2-27-g337f130 */
258 	CHECK_FUTEX_ENOSYS(uaddr,
259 		FUTEX_CLOCK_REALTIME | FUTEX_WAIT,
260 		VAL, tmout, uaddr2, VAL3, (rc == -1) && (errno == EAGAIN));
261 	printf("futex(%p, FUTEX_WAIT|FUTEX_CLOCK_REALTIME, %u"
262 	       ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
263 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
264 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
265 
266 	CHECK_FUTEX_ENOSYS(uaddr,
267 		FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG | FUTEX_WAIT,
268 		VAL, tmout, uaddr2, 0, (rc == -1) && (errno == EAGAIN));
269 	printf("futex(%p, FUTEX_WAIT_PRIVATE|FUTEX_CLOCK_REALTIME, %u"
270 	       ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
271 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
272 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
273 
274 	/* FUTEX_WAIT_BITSET - FUTEX_WAIT which provides additional bitmask
275 	 *                     which should be matched at least in one bit with
276 	 *                     wake mask in order to wake.
277 	 * Possible flags: PRIVATE, CLOCKRT
278 	 * 1. uaddr   - futex address
279 	 * 2. op      - FUTEX_TRYLOCK_PI
280 	 * 3. val     - expected value stored in uaddr
281 	 * 4. timeout - timeout
282 	 * 5. uaddr2  - not used
283 	 * 6. val3    - bitmask
284 	 */
285 
286 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAIT_BITSET, VAL, tmout, uaddr2 + 1,
287 		VAL3, (rc == -1) && (errno == EAGAIN));
288 	printf("futex(%p, FUTEX_WAIT_BITSET, %u, {tv_sec=%lld, tv_nsec=%llu}"
289 	       ", %#x) = %s\n",
290 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
291 	       zero_extend_signed_to_ull(tmout->tv_nsec), VAL3_PR,
292 	       sprintrc(rc));
293 
294 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAIT_BITSET, VAL, tmout, uaddr2 + 1,
295 		VAL3A, (rc == -1) && (errno == EAGAIN));
296 	printf("futex(%p, FUTEX_WAIT_BITSET, %u, {tv_sec=%lld, tv_nsec=%llu}"
297 	       ", %s) = %s\n",
298 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
299 	       zero_extend_signed_to_ull(tmout->tv_nsec), VAL3A_PR,
300 	       sprintrc(rc));
301 
302 	/* val3 of 0 is invalid  */
303 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAIT_BITSET, VAL, tmout, uaddr2 + 1, 0,
304 		(rc == -1) && (errno == EINVAL));
305 	printf("futex(%p, FUTEX_WAIT_BITSET, %u, {tv_sec=%lld, tv_nsec=%llu}"
306 	       ", %#x) = %s\n",
307 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
308 	       zero_extend_signed_to_ull(tmout->tv_nsec), 0, sprintrc(rc));
309 
310 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAIT_BITSET, VAL,
311 		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EAGAIN));
312 	printf("futex(%p, FUTEX_WAIT_BITSET_PRIVATE, %u"
313 	       ", {tv_sec=%lld, tv_nsec=%llu}, %#x) = %s\n",
314 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
315 	       zero_extend_signed_to_ull(tmout->tv_nsec), VAL3_PR,
316 	       sprintrc(rc));
317 
318 	/* Next 3 tests are with CLOCKRT bit set */
319 
320 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_WAIT_BITSET, VAL,
321 		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EAGAIN));
322 	printf("futex(%p, FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %u"
323 	       ", {tv_sec=%lld, tv_nsec=%llu}, %#x) = %s\n",
324 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
325 	       zero_extend_signed_to_ull(tmout->tv_nsec), VAL3_PR,
326 	       sprintrc(rc));
327 
328 	/* val3 of 0 is invalid  */
329 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_WAIT_BITSET, VAL,
330 		tmout, uaddr2 + 1, 0, (rc == -1) && (errno == EINVAL));
331 	printf("futex(%p, FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %u"
332 	       ", {tv_sec=%lld, tv_nsec=%llu}, %#x) = %s\n",
333 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
334 	       zero_extend_signed_to_ull(tmout->tv_nsec), 0, sprintrc(rc));
335 
336 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG |
337 		FUTEX_WAIT_BITSET, VAL, tmout, uaddr2 + 1, VAL3,
338 		(rc == -1) && (errno == EAGAIN));
339 	printf("futex(%p, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, %u"
340 	       ", {tv_sec=%lld, tv_nsec=%llu}, %#x) = %s\n",
341 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
342 	       zero_extend_signed_to_ull(tmout->tv_nsec), VAL3_PR,
343 	       sprintrc(rc));
344 
345 	/* FUTEX_WAKE - wake val processes waiting for uaddr
346 	 * Possible flags: PRIVATE
347 	 * 1. uaddr   - futex address
348 	 * 2. op      - FUTEX_WAKE
349 	 * 3. val     - how many processes to wake
350 	 * 4. timeout - not used
351 	 * 5. uaddr2  - not used
352 	 * 6. val3    - not used
353 	 */
354 
355 	/* Zero processes to wake is not a good idea, but it should return 0 */
356 	CHECK_FUTEX(uaddr, FUTEX_WAKE, 0, NULL, NULL, 0, (rc == 0));
357 	printf("futex(%p, FUTEX_WAKE, %u) = %s\n", uaddr, 0, sprintrc(rc));
358 
359 	/* Trying to wake some processes, but there's nothing to wake */
360 	CHECK_FUTEX(uaddr, FUTEX_WAKE, 10, NULL, NULL, 0, (rc == 0));
361 	printf("futex(%p, FUTEX_WAKE, %u) = %s\n", uaddr, 10, sprintrc(rc));
362 
363 	/* Trying to wake some processes, but there's nothing to wake */
364 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAKE, 10, NULL,
365 		NULL, 0, (rc == 0));
366 	printf("futex(%p, FUTEX_WAKE_PRIVATE, %u) = %s\n", uaddr, 10,
367 		sprintrc(rc));
368 
369 	CHECK_INVALID_CLOCKRT(FUTEX_WAKE, ARG3, "%u");
370 
371 	/* FUTEX_WAKE_BITSET - wake val processes waiting for uaddr which has at
372 	 *                     least one common bit with bitset provided in
373 	 *                     val3.
374 	 * Possible flags: PRIVATE
375 	 * 1. uaddr   - futex address
376 	 * 2. op      - FUTEX_WAKE
377 	 * 3. val     - how many processes to wake
378 	 * 4. timeout - not used
379 	 * 5. uaddr2  - not used
380 	 * 6. val3    - bitmask
381 	 */
382 
383 	/* Trying to wake some processes, but there's nothing to wake */
384 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAKE_BITSET, 10, NULL, NULL,
385 		VAL3, (rc == 0));
386 	printf("futex(%p, FUTEX_WAKE_BITSET, %u, %#x) = %s\n", uaddr, 10,
387 		VAL3_PR, sprintrc(rc));
388 
389 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAKE_BITSET, 10, NULL, NULL,
390 		VAL3A, (rc == 0));
391 	printf("futex(%p, FUTEX_WAKE_BITSET, %u, %s) = %s\n", uaddr, 10,
392 		VAL3A_PR, sprintrc(rc));
393 
394 	/* bitset 0 is invalid */
395 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAKE_BITSET, 10, NULL, NULL, 0,
396 		(rc == -1) && (errno == EINVAL));
397 	printf("futex(%p, FUTEX_WAKE_BITSET, %u, %#x) = %s\n", uaddr, 10, 0,
398 		sprintrc(rc));
399 
400 	/* Trying to wake some processes, but there's nothing to wake */
401 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAKE_BITSET, 10,
402 		NULL, NULL, VAL3, (rc == 0));
403 	printf("futex(%p, FUTEX_WAKE_BITSET_PRIVATE, %u, %#x) = %s\n", uaddr,
404 		10, VAL3_PR, sprintrc(rc));
405 
406 	CHECK_INVALID_CLOCKRT(FUTEX_WAKE_BITSET, ARG3 | ARG6, "%u", "%#x");
407 
408 	/* FUTEX_FD - deprecated
409 	 * Possible flags: PRIVATE
410 	 * 1. uaddr   - futex address
411 	 * 2. op      - FUTEX_FD
412 	 * 3. val     - signal number
413 	 * 4. timeout - not used
414 	 * 5. uaddr2  - not used
415 	 * 6. val3    - not used
416 	 */
417 
418 	/* FUTEX_FD is not implemented since 2.6.26 */
419 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_FD, VAL, NULL, NULL, VAL3,
420 		(rc == -1) && (errno == EINVAL));
421 	printf("futex(%p, FUTEX_FD, %u) = %s\n", uaddr, VAL_PR, sprintrc(rc));
422 
423 	/* FUTEX_FD is not implemented since 2.6.26 */
424 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_FD, VAL, NULL,
425 		NULL, VAL3, (rc == -1) && (errno == EINVAL));
426 	printf("futex(%p, FUTEX_FD|FUTEX_PRIVATE_FLAG, %u) = %s\n", uaddr,
427 		VAL_PR, sprintrc(rc));
428 
429 	CHECK_INVALID_CLOCKRT(FUTEX_FD, ARG3, "%u");
430 
431 	/* FUTEX_REQUEUE - wake val processes and re-queue rest on uaddr2
432 	 * Possible flags: PRIVATE
433 	 * 1. uaddr   - futex address
434 	 * 2. op      - FUTEX_REQUEUE
435 	 * 3. val     - how many processes to wake
436 	 * 4. val2    - amount of processes to re-queue on uadr2
437 	 * 5. uaddr2  - another futex address, to re-queue waiting processes on
438 	 * 6. val3    - not used
439 	 */
440 
441 	/* Trying to re-queue some processes but there's nothing to re-queue */
442 	CHECK_FUTEX(uaddr, FUTEX_REQUEUE, VAL, VAL2, uaddr2, VAL3,
443 		(rc == 0) || ((rc == -1) && (errno == EINVAL)));
444 	printf("futex(%p, FUTEX_REQUEUE, %u, %u, %p) = %s\n",
445 		uaddr, VAL_PR, VAL2_PR, uaddr2, sprintrc(rc));
446 
447 	CHECK_FUTEX(uaddr, FUTEX_REQUEUE, VALP, VAL2P, uaddr2, VAL3,
448 		(rc == 0));
449 	printf("futex(%p, FUTEX_REQUEUE, %u, %u, %p) = %s\n",
450 		uaddr, VALP_PR, VAL2P_PR, uaddr2, sprintrc(rc));
451 
452 	/* Trying to re-queue some processes but there's nothing to re-queue */
453 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_REQUEUE, VAL, VAL2,
454 		uaddr2, VAL3, (rc == 0) || ((rc == -1) && (errno == EINVAL)));
455 	printf("futex(%p, FUTEX_REQUEUE_PRIVATE, %u, %u, %p) = %s\n",
456 		uaddr, VAL_PR, VAL2_PR, uaddr2, sprintrc(rc));
457 
458 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_REQUEUE, VALP,
459 		VAL2P, uaddr2, VAL3, (rc == 0));
460 	printf("futex(%p, FUTEX_REQUEUE_PRIVATE, %u, %u, %p) = %s\n",
461 		uaddr, VALP_PR, VAL2P_PR, uaddr2, sprintrc(rc));
462 
463 	CHECK_INVALID_CLOCKRT(FUTEX_REQUEUE, ARG3 | ARG4 | ARG5, "%u", "%u",
464 		"%#lx");
465 
466 	/* FUTEX_CMP_REQUEUE - wake val processes and re-queue rest on uaddr2
467 	 *                     if uaddr has value val3
468 	 * Possible flags: PRIVATE
469 	 * 1. uaddr   - futex address
470 	 * 2. op      - FUTEX_CMP_REQUEUE
471 	 * 3. val     - how many processes to wake
472 	 * 4. val2    - amount of processes to re-queue on uadr2
473 	 * 5. uaddr2  - another futex address, to re-queue waiting processes on
474 	 * 6. val3    - expected value stored in uaddr
475 	 */
476 
477 	/* Comparison re-queue with wrong val value */
478 	CHECK_FUTEX(uaddr, FUTEX_CMP_REQUEUE, VAL, VAL2, uaddr2, VAL3,
479 		(rc == -1) && (errno == EAGAIN || errno == EINVAL));
480 	printf("futex(%p, FUTEX_CMP_REQUEUE, %u, %u, %p, %u) = %s\n",
481 		uaddr, VAL_PR, VAL2_PR, uaddr2, VAL3_PR, sprintrc(rc));
482 
483 	CHECK_FUTEX(uaddr, FUTEX_CMP_REQUEUE, VALP, VAL2P, uaddr2, VAL3,
484 		(rc == -1) && (errno == EAGAIN));
485 	printf("futex(%p, FUTEX_CMP_REQUEUE, %u, %u, %p, %u) = %s\n",
486 		uaddr, VALP_PR, VAL2P_PR, uaddr2, VAL3_PR, sprintrc(rc));
487 
488 	/* Successful comparison re-queue */
489 	CHECK_FUTEX(uaddr, FUTEX_CMP_REQUEUE, VAL, VAL2, uaddr2, *uaddr,
490 		(rc == 0) || ((rc == -1) && (errno == EINVAL)));
491 	printf("futex(%p, FUTEX_CMP_REQUEUE, %u, %u, %p, %u) = %s\n",
492 		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
493 
494 	CHECK_FUTEX(uaddr, FUTEX_CMP_REQUEUE, VALP, VAL2P, uaddr2, *uaddr,
495 		(rc == 0));
496 	printf("futex(%p, FUTEX_CMP_REQUEUE, %u, %u, %p, %u) = %s\n",
497 		uaddr, VALP_PR, VAL2P_PR, uaddr2, *uaddr, sprintrc(rc));
498 
499 	/* Successful comparison re-queue */
500 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_CMP_REQUEUE, VAL,
501 		VAL2, uaddr2, *uaddr,
502 		(rc == 0) || ((rc == -1) && (errno == EINVAL)));
503 	printf("futex(%p, FUTEX_CMP_REQUEUE_PRIVATE, %u, %u, %p, %u) = %s\n",
504 		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
505 
506 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_CMP_REQUEUE, VALP,
507 		VAL2P, uaddr2, *uaddr, (rc == 0));
508 	printf("futex(%p, FUTEX_CMP_REQUEUE_PRIVATE, %u, %u, %p, %u) = %s\n",
509 		uaddr, VALP_PR, VAL2P_PR, uaddr2, *uaddr, sprintrc(rc));
510 
511 	CHECK_INVALID_CLOCKRT(FUTEX_CMP_REQUEUE, ARG3 | ARG4 | ARG5 | ARG6,
512 		"%u", "%u", "%#lx", "%u");
513 
514 	/* FUTEX_WAKE_OP - wake val processes waiting for uaddr, additionally
515 	 *                 wake val2 processes waiting for uaddr2 in case
516 	 *                 operation encoded in val3 (change of value at uaddr2
517 	 *                 and comparison of previous value against provided
518 	 *                 constant) succeedes with value at uaddr2. Operation
519 	 *                 result is written to value of uaddr2 (in any case).
520 	 * 1. uaddr   - futex address
521 	 * 2. op      - FUTEX_WAKE_OP
522 	 * 3. val     - how many processes to wake
523 	 * 4. val2    - amount of processes to wake in case operation encoded in
524 	 *              val3 returns true
525 	 * 5. uaddr2  - another futex address, for conditional wake of
526 	 *              additional processes
527 	 * 6. val3    - encoded operation:
528 	 *                1. bit 31 - if 1 then value stored in field field 4
529 	 *                            should be interpreted as power of 2.
530 	 *                2. 28..30 - arithmetic operation which should be
531 	 *                            applied to previous value stored in
532 	 *                            uaddr2. Values available (from 2005 up to
533 	 *                            2016): SET. ADD, OR, ANDN, XOR.
534 	 *                3. 24..29 - comparison operation which should be
535 	 *                            applied to the old value stored in uaddr2
536 	 *                            (before arithmetic operation is applied).
537 	 *                            Possible values: EQ, NE, LT, LE, GT, GE.
538 	 *                4. 12..23 - Second operand for arithmetic operation.
539 	 *                            If bit 31 is set, it is interpreted as
540 	 *                            power of 2.
541 	 *                5. 00..11 - Value against which old value stored in
542 	 *                            uaddr2 is compared.
543 	 */
544 
545 	static const struct {
546 		uint32_t val;
547 		const char *str;
548 
549 		/*
550 		 * Peculiar semantics:
551 		 *  * err == 0 and err2 != 0 => expect both either the absence
552 		 *    of error or presence of err2
553 		 *  * err != 0 and err2 == 0 => expect err only, no success
554 		 *    expected.
555 		 */
556 		int err;
557 		int err2;
558 	} wake_ops[] = {
559 		{ 0x00000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_EQ<<24|0" },
560 		{ 0x00fff000, "FUTEX_OP_SET<<28|0xfff<<12|FUTEX_OP_CMP_EQ<<24|"
561 			"0" },
562 		{ 0x00000fff, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_EQ<<24|"
563 			"0xfff" },
564 		{ 0x00ffffff, "FUTEX_OP_SET<<28|0xfff<<12|FUTEX_OP_CMP_EQ<<24|"
565 			"0xfff" },
566 		{ 0x10000000, "FUTEX_OP_ADD<<28|0<<12|FUTEX_OP_CMP_EQ<<24|0" },
567 		{ 0x20000000, "FUTEX_OP_OR<<28|0<<12|FUTEX_OP_CMP_EQ<<24|0" },
568 		{ 0x30000000, "FUTEX_OP_ANDN<<28|0<<12|FUTEX_OP_CMP_EQ<<24|0" },
569 		{ 0x40000000, "FUTEX_OP_XOR<<28|0<<12|FUTEX_OP_CMP_EQ<<24|0" },
570 		{ 0x50000000, "0x5<<28 /* FUTEX_OP_??? */|0<<12|"
571 			"FUTEX_OP_CMP_EQ<<24|0", ENOSYS },
572 		{ 0x70000000, "0x7<<28 /* FUTEX_OP_??? */|0<<12|"
573 			"FUTEX_OP_CMP_EQ<<24|0", ENOSYS },
574 		{ 0x80000000, "FUTEX_OP_OPARG_SHIFT<<28|FUTEX_OP_SET<<28|0<<12|"
575 			"FUTEX_OP_CMP_EQ<<24|0" },
576 		{ 0xa0caffee, "FUTEX_OP_OPARG_SHIFT<<28|FUTEX_OP_OR<<28|"
577 			"0xcaf<<12|FUTEX_OP_CMP_EQ<<24|0xfee", 0, EINVAL },
578 		{ 0x01000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_NE<<24|0" },
579 		{ 0x01234567, "FUTEX_OP_SET<<28|0x234<<12|FUTEX_OP_CMP_NE<<24|"
580 			"0x567" },
581 		{ 0x02000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_LT<<24|0" },
582 		{ 0x03000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_LE<<24|0" },
583 		{ 0x04000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_GT<<24|0" },
584 		{ 0x05000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_GE<<24|0" },
585 		{ 0x06000000, "FUTEX_OP_SET<<28|0<<12|"
586 			"0x6<<24 /* FUTEX_OP_CMP_??? */|0", ENOSYS },
587 		{ 0x07000000, "FUTEX_OP_SET<<28|0<<12|"
588 			"0x7<<24 /* FUTEX_OP_CMP_??? */|0", ENOSYS },
589 		{ 0x08000000, "FUTEX_OP_SET<<28|0<<12|"
590 			"0x8<<24 /* FUTEX_OP_CMP_??? */|0", ENOSYS },
591 		{ 0x0f000000, "FUTEX_OP_SET<<28|0<<12|"
592 			"0xf<<24 /* FUTEX_OP_CMP_??? */|0", ENOSYS },
593 		{ 0xbadfaced, "FUTEX_OP_OPARG_SHIFT<<28|FUTEX_OP_ANDN<<28|"
594 			"0xdfa<<12|0xa<<24 /* FUTEX_OP_CMP_??? */|0xced",
595 			ENOSYS, EINVAL },
596 		{ 0xffffffff, "FUTEX_OP_OPARG_SHIFT<<28|"
597 			"0x7<<28 /* FUTEX_OP_??? */|0xfff<<12|"
598 			"0xf<<24 /* FUTEX_OP_CMP_??? */|0xfff",
599 			ENOSYS, EINVAL },
600 	};
601 
602 	for (i = 0; i < ARRAY_SIZE(wake_ops); i++) {
603 		for (j = 0; j < 2; j++) {
604 			CHECK_FUTEX_ENOSYS(uaddr,
605 				j ? FUTEX_WAKE_OP_PRIVATE : FUTEX_WAKE_OP,
606 				VAL, i, uaddr2, wake_ops[i].val,
607 				/*
608 				 * Either one of errs is 0 or rc == 0 is not
609 				 * allowed.
610 				 */
611 				((!wake_ops[i].err || !wake_ops[i].err2 ||
612 					(rc != 0)) &&
613 				((!wake_ops[i].err && (rc == 0)) ||
614 				(wake_ops[i].err  && (rc == -1) &&
615 					(errno == wake_ops[i].err)) ||
616 				(wake_ops[i].err2 && (rc == -1) &&
617 					(errno == wake_ops[i].err2)))));
618 			printf("futex(%p, FUTEX_WAKE_OP%s, %u, %u, %p, %s)"
619 			       " = %s\n", uaddr, j ? "_PRIVATE" : "", VAL_PR,
620 			       i, uaddr2, wake_ops[i].str, sprintrc(rc));
621 		}
622 	}
623 
624 	CHECK_INVALID_CLOCKRT(FUTEX_WAKE_OP, ARG3 | ARG4 | ARG5 | ARG6,
625 		"%u", "%u", "%#lx",
626 		/* Decoding of the 0xdeadbee4 value */
627 		"FUTEX_OP_OPARG_SHIFT<<28|0x5<<28 /* FUTEX_OP_??? */|0xadb<<12|"
628 		"0xe<<24 /* FUTEX_OP_CMP_??? */|0xee4");
629 
630 	/* FUTEX_LOCK_PI - slow path for mutex lock with process inheritance
631 	 *                 support. Expect that futex has 0 in unlocked case and
632 	 *                 TID of owning process in locked case. Value can also
633 	 *                 contain FUTEX_WAITERS bit signalling the presence of
634 	 *                 waiters queue.
635 	 * Possible flags: PRIVATE
636 	 * 1. uaddr   - futex address
637 	 * 2. op      - FUTEX_LOCK_PI
638 	 * 3. val     - not used
639 	 * 4. timeout - timeout
640 	 * 5. uaddr2  - not used
641 	 * 6. val3    - not used
642 	 */
643 
644 	*uaddr = getpid();
645 
646 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_LOCK_PI, VAL, tmout, uaddr2 + 1,
647 		VAL3, (rc == -1) && (errno == EFAULT));
648 	printf("futex(%p, FUTEX_LOCK_PI, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
649 	       uaddr + 1, (long long) tmout->tv_sec,
650 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
651 
652 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_PRIVATE_FLAG | FUTEX_LOCK_PI, VAL,
653 		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EFAULT));
654 	printf("futex(%p, FUTEX_LOCK_PI_PRIVATE, {tv_sec=%lld, tv_nsec=%llu})"
655 	       " = %s\n",
656 	       uaddr + 1, (long long) tmout->tv_sec,
657 	       zero_extend_signed_to_ull(tmout->tv_nsec), sprintrc(rc));
658 
659 	/* NULL is passed by invalid_op() in cases valid timeout address is
660 	 * needed */
661 	CHECK_INVALID_CLOCKRT(FUTEX_LOCK_PI, ARG4, "NULL");
662 
663 	/* FUTEX_UNLOCK_PI - slow path for mutex unlock with process inheritance
664 	 *                   support. Expected to be called by process in case
665 	 *                   it failed to execute fast path (it usually means
666 	 *                   that FUTEX_WAITERS flag had been set while the lock
667 	 *                   has been held).
668 	 * Possible flags: PRIVATE
669 	 * 1. uaddr   - futex address
670 	 * 2. op      - FUTEX_UNLOCK_PI
671 	 * 3. val     - not used
672 	 * 4. timeout - not used
673 	 * 5. uaddr2  - not used
674 	 * 6. val3    - not used
675 	 */
676 
677 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_UNLOCK_PI, VAL, tmout, uaddr2 + 1,
678 		VAL3, (rc == -1) && (errno == EFAULT));
679 	printf("futex(%p, FUTEX_UNLOCK_PI) = %s\n", uaddr + 1, sprintrc(rc));
680 
681 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_PRIVATE_FLAG | FUTEX_UNLOCK_PI, VAL,
682 		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EFAULT));
683 	printf("futex(%p, FUTEX_UNLOCK_PI_PRIVATE) = %s\n", uaddr + 1,
684 		sprintrc(rc));
685 
686 	CHECK_INVALID_CLOCKRT(FUTEX_UNLOCK_PI, 0);
687 
688 	/* FUTEX_TRYLOCK_PI - slow path for mutex trylock with process
689 	 *                 inheritance support.
690 	 * Possible flags: PRIVATE
691 	 * 1. uaddr   - futex address
692 	 * 2. op      - FUTEX_TRYLOCK_PI
693 	 * 3. val     - not used
694 	 * 4. timeout - not used
695 	 * 5. uaddr2  - not used
696 	 * 6. val3    - not used
697 	 */
698 
699 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_TRYLOCK_PI, VAL, tmout, uaddr2 + 1,
700 		VAL3, (rc == -1) && (errno == EFAULT));
701 	printf("futex(%p, FUTEX_TRYLOCK_PI) = %s\n", uaddr + 1, sprintrc(rc));
702 
703 	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_PRIVATE_FLAG | FUTEX_TRYLOCK_PI,
704 		VAL, tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EFAULT));
705 	printf("futex(%p, FUTEX_TRYLOCK_PI_PRIVATE) = %s\n", uaddr + 1,
706 		sprintrc(rc));
707 
708 	CHECK_INVALID_CLOCKRT(FUTEX_TRYLOCK_PI, 0);
709 
710 	/* FUTEX_WAIT_REQUEUE_PI - kernel-side handling of special case when
711 	 *                         processes should be re-queued on PI-aware
712 	 *                         futexes. This is so special since PI futexes
713 	 *                         utilize rt_mutex and it should be at no time
714 	 *                         left free with a wait queue, so this should
715 	 *                         be performed atomically in-kernel.
716 	 * Possible flags: PRIVATE, CLOCKRT
717 	 * 1. uaddr   - futex address
718 	 * 2. op      - FUTEX_WAIT_REQUEUE_PI
719 	 * 3. val     - expected value stored in uaddr
720 	 * 4. timeout - timeout
721 	 * 5. uaddr2  - (PI-aware) futex address to requeue process on
722 	 * 6. val3    - not used (in kernel, it always initialized to
723 	 *              FUTEX_BITSET_MATCH_ANY and passed to
724 	 *              futex_wait_requeue_pi())
725 	 */
726 
727 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAIT_REQUEUE_PI, VAL, tmout, uaddr2,
728 		VAL3, (rc == -1) && (errno == EAGAIN));
729 	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI, %u"
730 	       ", {tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
731 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
732 	       zero_extend_signed_to_ull(tmout->tv_nsec), uaddr2, sprintrc(rc));
733 
734 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAIT_REQUEUE_PI,
735 		VAL, tmout, uaddr2, VAL3, (rc == -1) && (errno == EAGAIN));
736 	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI_PRIVATE, %u"
737 	       ", {tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
738 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
739 	       zero_extend_signed_to_ull(tmout->tv_nsec), uaddr2, sprintrc(rc));
740 
741 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_WAIT_REQUEUE_PI,
742 		VAL, tmout, uaddr2, VAL3, (rc == -1) && (errno == EAGAIN));
743 	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, %u"
744 	       ", {tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
745 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
746 	       zero_extend_signed_to_ull(tmout->tv_nsec), uaddr2, sprintrc(rc));
747 
748 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG |
749 		FUTEX_WAIT_REQUEUE_PI, VAL, tmout, uaddr2, VAL3,
750 		(rc == -1) && (errno == EAGAIN));
751 	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME"
752 	       ", %u, {tv_sec=%lld, tv_nsec=%llu}, %p) = %s\n",
753 	       uaddr, VAL_PR, (long long) tmout->tv_sec,
754 	       zero_extend_signed_to_ull(tmout->tv_nsec), uaddr2, sprintrc(rc));
755 
756 	/* FUTEX_CMP_REQUEUE_PI - version of FUTEX_CMP_REQUEUE which re-queues
757 	 *                        on PI-aware futex.
758 	 * Possible flags: PRIVATE
759 	 * 1. uaddr   - futex address
760 	 * 2. op      - FUTEX_CMP_REQUEUE
761 	 * 3. val     - how many processes to wake
762 	 * 4. val2    - amount of processes to re-queue on uadr2
763 	 * 5. uaddr2  - (PI-aware) futex address, to re-queue waiting processes
764 	 *              on
765 	 * 6. val3    - expected value stored in uaddr
766 	 */
767 
768 	/* All these should fail with EINVAL since we try to re-queue to  non-PI
769 	 * futex.
770 	 */
771 
772 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CMP_REQUEUE_PI, VAL, VAL2, uaddr2, VAL3,
773 		(rc == -1) && (errno == EINVAL));
774 	printf("futex(%p, FUTEX_CMP_REQUEUE_PI, %u, %u, %p, %u) = %s\n",
775 		uaddr, VAL_PR, VAL2_PR, uaddr2, VAL3_PR, sprintrc(rc));
776 
777 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CMP_REQUEUE_PI, VAL, VAL2, uaddr2,
778 		*uaddr, (rc == -1) && (errno == EINVAL));
779 	printf("futex(%p, FUTEX_CMP_REQUEUE_PI, %u, %u, %p, %u) = %s\n",
780 		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
781 
782 	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_CMP_REQUEUE_PI,
783 		VAL, VAL2, uaddr2, *uaddr, (rc == -1) && (errno == EINVAL));
784 	printf("futex(%p, FUTEX_CMP_REQUEUE_PI_PRIVATE, %u, %u, %p, %u) = %s\n",
785 		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
786 
787 	CHECK_INVALID_CLOCKRT(FUTEX_CMP_REQUEUE_PI, ARG3 | ARG4 | ARG5 | ARG6,
788 		"%u", "%u", "%#lx", "%u");
789 
790 	/*
791 	 * Unknown commands
792 	 */
793 
794 	CHECK_FUTEX(uaddr, 0xd, VAL, tmout + 1, uaddr2 + 1, VAL3,
795 		(rc == -1) && (errno == ENOSYS));
796 	printf("futex(%p, 0xd /* FUTEX_??? */, %u, %p, %p, %#x) = %s\n",
797 		uaddr, VAL_PR, tmout + 1, uaddr2 + 1, VAL3_PR, sprintrc(rc));
798 
799 	CHECK_FUTEX(uaddr, 0xbefeeded, VAL, tmout + 1, uaddr2, VAL3,
800 		(rc == -1) && (errno == ENOSYS));
801 	printf("futex(%p, 0xbefeeded /* FUTEX_??? */, %u, %p, %p, %#x) = %s\n",
802 		uaddr, VAL_PR, tmout + 1, uaddr2, VAL3_PR, sprintrc(rc));
803 
804 	puts("+++ exited with 0 +++");
805 
806 	return 0;
807 }
808 
809 #else
810 
811 SKIP_MAIN_UNDEFINED("__NR_futex")
812 
813 #endif
814