summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2019-05-19 23:35:20 +0000
committerDmitry V. Levin <ldv@altlinux.org>2019-05-19 23:35:20 +0000
commitd7e00d657a1f623d5f794827e4bfe6db1abaad34 (patch)
tree38817572854b0844b05ad3e4787934ccaec26005
parentf625d610c7018cef0380f81e513695c66615443c (diff)
downloadstrace-d7e00d657a1f623d5f794827e4bfe6db1abaad34.tar.gz
Implement decoding of io_uring_* syscalls
... introduced by Linux kernel commits v5.1-rc1~99^2~14, v5.1-rc1~99^2~7, and v5.1-rc7~24^2. * configure.ac (AC_CHECK_HEADERS): Add linux/io_uring.h. * io_uring.c: New file. * Makefile.am (strace_SOURCES): Add it. * pathtrace.c (pathtrace_match_set): Add SEN_io_uring_enter, SEN_io_uring_register, and SEN_io_uring_setup. * xlat/uring_enter_flags.in: New file. * xlat/uring_register_opcodes.in: Likewise. * linux/32/syscallent.h [425, 426, 427]: Wire up io_uring_setup, io_uring_enter, and io_uring_register. * linux/64/syscallent.h: Likewise. * linux/arm/syscallent.h: Likewise. * linux/hppa/syscallent.h: Likewise. * linux/i386/syscallent.h: Likewise. * linux/m68k/syscallent.h: Likewise. * linux/microblaze/syscallent.h: Likewise. * linux/powerpc/syscallent.h: Likewise. * linux/powerpc64/syscallent.h: Likewise. * linux/s390/syscallent.h: Likewise. * linux/s390x/syscallent.h: Likewise. * linux/sh/syscallent.h: Likewise. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent.h: Likewise. * linux/sparc64/syscallent.h: Likewise. * linux/x32/syscallent.h: Likewise. * linux/x86_64/syscallent.h: Likewise. * linux/xtensa/syscallent.h: Likewise. * linux/alpha/syscallent.h [535, 536, 537]: Likewise. * linux/ia64/syscallent.h [1024 + 425, 1024 + 426, 1024 + 427]: Likewise. * linux/mips/syscallent-n32.h [6425, 6426, 6427]: Likewise. * linux/mips/syscallent-n64.h [5425, 5426, 5427]: Likewise. * linux/mips/syscallent-o32.h [4425, 4426, 4427]: Likewise. * NEWS: Mention this change. * tests/io_uring_enter.c: New file. * tests/io_uring_register.c: Likewise. * tests/io_uring_setup.c: Likewise. * tests/gen_tests.in (io_uring_enter, io_uring_register, io_uring_setup): New entries. * tests/pure_executables.list: Add io_uring_enter, io_uring_register, and io_uring_setup. * tests/.gitignore: Likewise.
-rw-r--r--Makefile.am1
-rw-r--r--NEWS3
-rw-r--r--configure.ac1
-rw-r--r--io_uring.c135
-rw-r--r--linux/32/syscallent.h3
-rw-r--r--linux/64/syscallent.h3
-rw-r--r--linux/alpha/syscallent.h3
-rw-r--r--linux/arm/syscallent.h3
-rw-r--r--linux/hppa/syscallent.h3
-rw-r--r--linux/i386/syscallent.h3
-rw-r--r--linux/ia64/syscallent.h3
-rw-r--r--linux/m68k/syscallent.h3
-rw-r--r--linux/microblaze/syscallent.h3
-rw-r--r--linux/mips/syscallent-n32.h3
-rw-r--r--linux/mips/syscallent-n64.h3
-rw-r--r--linux/mips/syscallent-o32.h3
-rw-r--r--linux/powerpc/syscallent.h3
-rw-r--r--linux/powerpc64/syscallent.h3
-rw-r--r--linux/s390/syscallent.h3
-rw-r--r--linux/s390x/syscallent.h3
-rw-r--r--linux/sh/syscallent.h3
-rw-r--r--linux/sh64/syscallent.h3
-rw-r--r--linux/sparc/syscallent.h3
-rw-r--r--linux/sparc64/syscallent.h3
-rw-r--r--linux/x32/syscallent.h3
-rw-r--r--linux/x86_64/syscallent.h3
-rw-r--r--linux/xtensa/syscallent.h3
-rw-r--r--pathtrace.c3
-rw-r--r--tests/.gitignore3
-rw-r--r--tests/gen_tests.in3
-rw-r--r--tests/io_uring_enter.c83
-rw-r--r--tests/io_uring_register.c100
-rw-r--r--tests/io_uring_setup.c103
-rwxr-xr-xtests/pure_executables.list3
-rw-r--r--xlat/uring_enter_flags.in2
-rw-r--r--xlat/uring_register_opcodes.in4
-rw-r--r--xlat/uring_setup_flags.in3
37 files changed, 515 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index ef42de72d..a8ace321d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -145,6 +145,7 @@ strace_SOURCES = \
inotify.c \
inotify_ioctl.c \
io.c \
+ io_uring.c \
ioctl.c \
ioperm.c \
iopl.c \
diff --git a/NEWS b/NEWS
index d4d3e9443..22cd69d8e 100644
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,8 @@ Noteworthy changes in release ?.? (????-??-??)
pselect6_time64, ppoll_time64, io_pgetevents_time64, recvmmsg_time64,
mq_timedsend_time64, mq_timedreceive_time64, semtimedop_time64,
rt_sigtimedwait_time64, futex_time64, sched_rr_get_interval_time64,
- and pidfd_send_signal syscalls.
+ pidfd_send_signal, io_uring_setup, io_uring_enter, and io_uring_register
+ syscalls.
* Wired up getegid, geteuid, getppid, io_pgetevents, statfs64, and fstatfs64
syscalls on alpha.
* Wired up kexec_file_load and migrate_pages syscalls on arm.
diff --git a/configure.ac b/configure.ac
index e7df4fe60..621312ac4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -387,6 +387,7 @@ AC_CHECK_HEADERS(m4_normalize([
linux/hiddev.h
linux/if_addr.h
linux/if_link.h
+ linux/io_uring.h
linux/ip_vs.h
linux/ipc.h
linux/kcmp.h
diff --git a/io_uring.c b/io_uring.c
new file mode 100644
index 000000000..0b82a0754
--- /dev/null
+++ b/io_uring.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2019 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+
+#ifdef HAVE_LINUX_IO_URING_H
+# include "print_fields.h"
+# include <linux/io_uring.h>
+#endif
+
+#include "xlat/uring_setup_flags.h"
+#include "xlat/uring_enter_flags.h"
+#include "xlat/uring_register_opcodes.h"
+
+SYS_FUNC(io_uring_setup)
+{
+ const uint32_t nentries = tcp->u_arg[0];
+ const kernel_ulong_t params_addr = tcp->u_arg[1];
+
+#ifdef HAVE_LINUX_IO_URING_H
+ struct io_uring_params params;
+
+ if (entering(tcp)) {
+ tprintf("%u, ", nentries);
+
+ if (umove_or_printaddr(tcp, params_addr, &params))
+ return RVAL_DECODED | RVAL_FD;
+
+ PRINT_FIELD_FLAGS("{", params, flags, uring_setup_flags,
+ "IORING_SETUP_???");
+ PRINT_FIELD_X(", ", params, sq_thread_cpu);
+ PRINT_FIELD_U(", ", params, sq_thread_idle);
+ for (unsigned int i = 0; i < ARRAY_SIZE(params.resv); ++i) {
+ if (params.resv[i]) {
+ for (i = 0; i < ARRAY_SIZE(params.resv); ++i)
+ tprintf("%s%#x",
+ (i ? ", " : ", resv={"),
+ params.resv[i]);
+ tprints("}");
+ break;
+ }
+ }
+ return 0;
+ } else {
+ if (syserror(tcp)) {
+ /* The remaining part of params is irrelevant. */
+ } else if (umove(tcp, params_addr, &params)) {
+ tprints(", ???");
+ } else {
+ PRINT_FIELD_U(", ", params, sq_entries);
+ PRINT_FIELD_U(", ", params, cq_entries);
+ PRINT_FIELD_U(", sq_off={", params.sq_off, head);
+ PRINT_FIELD_U(", ", params.sq_off, tail);
+ PRINT_FIELD_U(", ", params.sq_off, ring_mask);
+ PRINT_FIELD_U(", ", params.sq_off, ring_entries);
+ PRINT_FIELD_U(", ", params.sq_off, flags);
+ PRINT_FIELD_U(", ", params.sq_off, dropped);
+ PRINT_FIELD_U(", ", params.sq_off, array);
+ PRINT_FIELD_U("}, cq_off={", params.cq_off, head);
+ PRINT_FIELD_U(", ", params.cq_off, tail);
+ PRINT_FIELD_U(", ", params.cq_off, ring_mask);
+ PRINT_FIELD_U(", ", params.cq_off, ring_entries);
+ PRINT_FIELD_U(", ", params.cq_off, overflow);
+ PRINT_FIELD_U(", ", params.cq_off, cqes);
+ tprints("}");
+ }
+ tprints("}");
+ }
+#else /* !HAVE_LINUX_IO_URING_H */
+ tprintf("%u, ", nentries);
+ printaddr(params_addr);
+#endif
+
+ return RVAL_DECODED | RVAL_FD;
+}
+
+SYS_FUNC(io_uring_enter)
+{
+ const int fd = tcp->u_arg[0];
+ const uint32_t to_submit = tcp->u_arg[1];
+ const uint32_t min_complete = tcp->u_arg[2];
+ const uint32_t flags = tcp->u_arg[3];
+ const kernel_ulong_t sigset_addr = tcp->u_arg[4];
+ const kernel_ulong_t sigset_size = tcp->u_arg[5];
+
+ printfd(tcp, fd);
+ tprintf(", %u, %u, ", to_submit, min_complete);
+ printflags(uring_enter_flags, flags, "IORING_ENTER_???");
+ tprints(", ");
+ print_sigset_addr_len(tcp, sigset_addr, sigset_size);
+ tprintf(", %" PRI_klu, sigset_size);
+
+ return RVAL_DECODED;
+}
+
+static bool
+print_fd_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size,
+ void *data)
+{
+ printfd(tcp, *(int *) elem_buf);
+ return true;
+}
+
+SYS_FUNC(io_uring_register)
+{
+ const int fd = tcp->u_arg[0];
+ const unsigned int opcode = tcp->u_arg[1];
+ const kernel_ulong_t arg = tcp->u_arg[2];
+ const unsigned int nargs = tcp->u_arg[3];
+ int buf;
+
+ printfd(tcp, fd);
+ tprints(", ");
+ printxval(uring_register_opcodes, opcode, "IORING_REGISTER_???");
+ tprints(", ");
+ switch (opcode) {
+ case IORING_REGISTER_BUFFERS:
+ tprint_iov(tcp, nargs, arg, IOV_DECODE_ADDR);
+ break;
+ case IORING_REGISTER_FILES:
+ print_array(tcp, arg, nargs, &buf, sizeof(buf),
+ tfetch_mem, print_fd_array_member, NULL);
+ break;
+ default:
+ printaddr(arg);
+ break;
+ }
+ tprintf(", %u", nargs);
+
+ return RVAL_DECODED;
+}
diff --git a/linux/32/syscallent.h b/linux/32/syscallent.h
index 0d78f42e9..01a5009df 100644
--- a/linux/32/syscallent.h
+++ b/linux/32/syscallent.h
@@ -313,6 +313,9 @@
[422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#undef sys_ARCH_mmap
#undef ARCH_WANT_SYNC_FILE_RANGE2
diff --git a/linux/64/syscallent.h b/linux/64/syscallent.h
index 7188f73bd..294da6901 100644
--- a/linux/64/syscallent.h
+++ b/linux/64/syscallent.h
@@ -287,3 +287,6 @@
[294] = { 5, TD, SEN(kexec_file_load), "kexec_file_load" },
/* [295 ... 423] - reserved to sync up with other architectures */
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
diff --git a/linux/alpha/syscallent.h b/linux/alpha/syscallent.h
index c78a120a0..7fa8f1469 100644
--- a/linux/alpha/syscallent.h
+++ b/linux/alpha/syscallent.h
@@ -478,3 +478,6 @@
[532] = { 0, PU|NF, SEN(getppid), "getppid" },
/* all other architectures have common numbers for new syscalls, alpha is the exception */
[534] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[535] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[536] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[537] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
diff --git a/linux/arm/syscallent.h b/linux/arm/syscallent.h
index 73d29eff2..8f85a4957 100644
--- a/linux/arm/syscallent.h
+++ b/linux/arm/syscallent.h
@@ -431,6 +431,9 @@
[422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#ifdef __ARM_EABI__
# define ARM_FIRST_SHUFFLED_SYSCALL 500
diff --git a/linux/hppa/syscallent.h b/linux/hppa/syscallent.h
index 56f5682be..1a62ad31e 100644
--- a/linux/hppa/syscallent.h
+++ b/linux/hppa/syscallent.h
@@ -380,3 +380,6 @@
[422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
diff --git a/linux/i386/syscallent.h b/linux/i386/syscallent.h
index fee1cddf8..98866f3da 100644
--- a/linux/i386/syscallent.h
+++ b/linux/i386/syscallent.h
@@ -425,6 +425,9 @@
[422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#define SYS_socket_subcall 500
#include "subcall32.h"
diff --git a/linux/ia64/syscallent.h b/linux/ia64/syscallent.h
index 1e3934be5..3ec6dabd7 100644
--- a/linux/ia64/syscallent.h
+++ b/linux/ia64/syscallent.h
@@ -343,3 +343,6 @@
[1024 + 333] = { 4, 0, SEN(rseq), "rseq" },
/* [1024 + 334 ... 1024 + 423] - reserved to sync up with other architectures */
[1024 + 424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[1024 + 425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[1024 + 426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[1024 + 427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
diff --git a/linux/m68k/syscallent.h b/linux/m68k/syscallent.h
index c35b0765e..f21176975 100644
--- a/linux/m68k/syscallent.h
+++ b/linux/m68k/syscallent.h
@@ -423,6 +423,9 @@
[422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#define SYS_socket_subcall 500
#include "subcall32.h"
diff --git a/linux/microblaze/syscallent.h b/linux/microblaze/syscallent.h
index aeda7b84e..9feefac54 100644
--- a/linux/microblaze/syscallent.h
+++ b/linux/microblaze/syscallent.h
@@ -429,3 +429,6 @@
[422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
diff --git a/linux/mips/syscallent-n32.h b/linux/mips/syscallent-n32.h
index e9c5e5d23..16ec2a1bd 100644
--- a/linux/mips/syscallent-n32.h
+++ b/linux/mips/syscallent-n32.h
@@ -362,6 +362,9 @@
[6422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[6423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[6424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[6425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[6426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[6427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
# define SYS_socket_subcall 6500
# include "subcall32.h"
diff --git a/linux/mips/syscallent-n64.h b/linux/mips/syscallent-n64.h
index f2bb30c52..15db301ee 100644
--- a/linux/mips/syscallent-n64.h
+++ b/linux/mips/syscallent-n64.h
@@ -338,6 +338,9 @@
[5328] = { 6, 0, SEN(io_pgetevents_time64), "io_pgetevents" },
/* [5329 ... 5423] - reserved to sync up with other architectures */
[5424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[5425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[5426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[5427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
# define SYS_socket_subcall 5500
# include "subcall64.h"
diff --git a/linux/mips/syscallent-o32.h b/linux/mips/syscallent-o32.h
index 9cd3b1d0c..7fdc60f67 100644
--- a/linux/mips/syscallent-o32.h
+++ b/linux/mips/syscallent-o32.h
@@ -409,6 +409,9 @@
[4422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[4423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[4424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[4425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[4426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[4427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
# define SYS_socket_subcall 4500
# include "subcall32.h"
diff --git a/linux/powerpc/syscallent.h b/linux/powerpc/syscallent.h
index ecda494c2..4e184646b 100644
--- a/linux/powerpc/syscallent.h
+++ b/linux/powerpc/syscallent.h
@@ -417,6 +417,9 @@
[422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#define SYS_socket_subcall 500
#include "subcall32.h"
diff --git a/linux/powerpc64/syscallent.h b/linux/powerpc64/syscallent.h
index 3352b346e..47a599900 100644
--- a/linux/powerpc64/syscallent.h
+++ b/linux/powerpc64/syscallent.h
@@ -394,6 +394,9 @@
[402] = { 3, TI, SEN(msgctl), "msgctl" },
/* [403 ... 423] - reserved to sync up with other architectures */
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#define SYS_socket_subcall 500
#include "subcall64.h"
diff --git a/linux/s390/syscallent.h b/linux/s390/syscallent.h
index 8eaeae737..24cd190b7 100644
--- a/linux/s390/syscallent.h
+++ b/linux/s390/syscallent.h
@@ -428,6 +428,9 @@
[422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#define SYS_socket_subcall 500
#include "subcall32.h"
diff --git a/linux/s390x/syscallent.h b/linux/s390x/syscallent.h
index 3cf61144c..5b61cdc28 100644
--- a/linux/s390x/syscallent.h
+++ b/linux/s390x/syscallent.h
@@ -394,6 +394,9 @@
[402] = { 3, TI, SEN(msgctl), "msgctl" },
/* [403 ... 423] - reserved to sync up with other architectures */
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#define SYS_socket_subcall 500
#include "subcall64.h"
diff --git a/linux/sh/syscallent.h b/linux/sh/syscallent.h
index b14d7ed1a..44cc9d90c 100644
--- a/linux/sh/syscallent.h
+++ b/linux/sh/syscallent.h
@@ -426,6 +426,9 @@
[422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#define SYS_socket_subcall 500
#include "subcall32.h"
diff --git a/linux/sh64/syscallent.h b/linux/sh64/syscallent.h
index 8a068ce5c..a21b0c47d 100644
--- a/linux/sh64/syscallent.h
+++ b/linux/sh64/syscallent.h
@@ -400,6 +400,9 @@
[393] = { 6, TD, SEN(pwritev2), "pwritev2" },
/* [403 ... 423] - reserved to sync up with other architectures */
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#define SYS_socket_subcall 500
#include "subcall64.h"
diff --git a/linux/sparc/syscallent.h b/linux/sparc/syscallent.h
index 19900af32..706c15e6e 100644
--- a/linux/sparc/syscallent.h
+++ b/linux/sparc/syscallent.h
@@ -403,6 +403,9 @@
[422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#define SYS_socket_subcall 500
#include "subcall32.h"
diff --git a/linux/sparc64/syscallent.h b/linux/sparc64/syscallent.h
index 1ed0dc234..1023b07df 100644
--- a/linux/sparc64/syscallent.h
+++ b/linux/sparc64/syscallent.h
@@ -383,6 +383,9 @@
[402] = { 3, TI, SEN(msgctl), "msgctl" },
/* [403 ... 423] - reserved to sync up with other architectures */
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
#define SYS_socket_subcall 500
#include "subcall64.h"
diff --git a/linux/x32/syscallent.h b/linux/x32/syscallent.h
index d0f8e8db0..6a9303725 100644
--- a/linux/x32/syscallent.h
+++ b/linux/x32/syscallent.h
@@ -382,3 +382,6 @@
[545] = { 5, CST|TD|TF|TP|SE|SI, SEN(execveat), "execveat" },
[546] = { 5, TD, SEN(preadv2), "preadv2" },
[547] = { 5, TD, SEN(pwritev2), "pwritev2" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
diff --git a/linux/x86_64/syscallent.h b/linux/x86_64/syscallent.h
index 2ac8dc6c1..41b7796f0 100644
--- a/linux/x86_64/syscallent.h
+++ b/linux/x86_64/syscallent.h
@@ -342,3 +342,6 @@
[334] = { 4, 0, SEN(rseq), "rseq" },
/* [335 ... 423] - reserved to sync up with other architectures */
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
diff --git a/linux/xtensa/syscallent.h b/linux/xtensa/syscallent.h
index 6d0925710..79fb8d13e 100644
--- a/linux/xtensa/syscallent.h
+++ b/linux/xtensa/syscallent.h
@@ -370,3 +370,6 @@
[422] = { 6, 0, SEN(futex_time64), "futex_time64" },
[423] = { 2, 0, SEN(sched_rr_get_interval_time64), "sched_rr_get_interval_time64" },
[424] = { 4, TD|TS, SEN(pidfd_send_signal), "pidfd_send_signal" },
+[425] = { 2, TD, SEN(io_uring_setup), "io_uring_setup" },
+[426] = { 6, TD|TS, SEN(io_uring_enter), "io_uring_enter" },
+[427] = { 4, TD|TM, SEN(io_uring_register), "io_uring_register" },
diff --git a/pathtrace.c b/pathtrace.c
index a1716caec..142e1b659 100644
--- a/pathtrace.c
+++ b/pathtrace.c
@@ -326,6 +326,9 @@ pathtrace_match_set(struct tcb *tcp, struct path_set *set)
case SEN_fanotify_init:
case SEN_inotify_init:
case SEN_inotify_init1:
+ case SEN_io_uring_enter:
+ case SEN_io_uring_register:
+ case SEN_io_uring_setup:
case SEN_memfd_create:
case SEN_mq_getsetattr:
case SEN_mq_notify:
diff --git a/tests/.gitignore b/tests/.gitignore
index 40380ac6e..fb3fa928f 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -143,6 +143,9 @@ inject-nf
inotify
inotify_init1
int_0x80
+io_uring_enter
+io_uring_register
+io_uring_setup
ioctl
ioctl_block
ioctl_dm
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index b81e67d02..487b9608a 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -118,6 +118,9 @@ inet-cmsg -e trace=recvmsg
init_module -a27
inotify -a23 -e trace=inotify_add_watch,inotify_rm_watch
inotify_init1 -a27
+io_uring_enter -y
+io_uring_register -y
+io_uring_setup -a26 -y
ioctl_block +ioctl.test
ioctl_dm +ioctl.test -s9
ioctl_dm-v +ioctl.test -v -s9
diff --git a/tests/io_uring_enter.c b/tests/io_uring_enter.c
new file mode 100644
index 000000000..3284ebac3
--- /dev/null
+++ b/tests/io_uring_enter.c
@@ -0,0 +1,83 @@
+/*
+ * Check decoding of io_uring_enter syscall.
+ *
+ * Copyright (c) 2019 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <unistd.h>
+#include <asm/unistd.h>
+#include "scno.h"
+
+#ifdef __NR_io_uring_enter
+
+# include <fcntl.h>
+# include <signal.h>
+# include <stdio.h>
+# include <string.h>
+
+static const char *errstr;
+
+static long
+sys_io_uring_enter(unsigned int fd, unsigned int to_submit,
+ unsigned int min_complete, unsigned int flags,
+ const void *sigset_addr, kernel_ulong_t sigset_size)
+
+{
+ kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
+ kernel_ulong_t arg1 = fill | fd;
+ kernel_ulong_t arg2 = fill | to_submit;
+ kernel_ulong_t arg3 = fill | min_complete;
+ kernel_ulong_t arg4 = fill | flags;
+ kernel_ulong_t arg5 = (unsigned long) sigset_addr;
+ kernel_ulong_t arg6 = sigset_size;
+
+ long rc = syscall(__NR_io_uring_enter,
+ arg1, arg2, arg3, arg4, arg5, arg6);
+ errstr = sprintrc(rc);
+ return rc;
+}
+
+int
+main(void)
+{
+ static const char path[] = "/dev/null";
+
+ skip_if_unavailable("/proc/self/fd/");
+
+ int fd = open(path, O_RDONLY);
+ if (fd < 0)
+ perror_msg_and_fail("open: %s", path);
+
+ const unsigned int size = get_sigset_size();
+ void *const sigmask = tail_alloc(size);
+ sigset_t mask;
+
+ memset(&mask, -1, sizeof(mask));
+ sigdelset(&mask, SIGHUP);
+ sigdelset(&mask, SIGKILL);
+ sigdelset(&mask, SIGSTOP);
+ memcpy(sigmask, &mask, size);
+
+ const unsigned int to_submit = 0xdeadbeef;
+ const unsigned int min_complete = 0xcafef00d;
+
+ sys_io_uring_enter(fd, to_submit, min_complete, -1U, sigmask, size);
+ printf("io_uring_enter(%u<%s>, %u, %u"
+ ", IORING_ENTER_GETEVENTS|IORING_ENTER_SQ_WAKEUP|%#x"
+ ", %s, %u) = %s\n",
+ fd, path, to_submit, min_complete, -1U - 3,
+ "~[HUP KILL STOP]", size, errstr);
+
+ puts("+++ exited with 0 +++");
+ return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_io_uring_enter")
+
+#endif
diff --git a/tests/io_uring_register.c b/tests/io_uring_register.c
new file mode 100644
index 000000000..a0327ed85
--- /dev/null
+++ b/tests/io_uring_register.c
@@ -0,0 +1,100 @@
+/*
+ * Check decoding of io_uring_register syscall.
+ *
+ * Copyright (c) 2019 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <unistd.h>
+#include <asm/unistd.h>
+#include "scno.h"
+
+#ifdef __NR_io_uring_register
+
+# include <fcntl.h>
+# include <stdio.h>
+# include <string.h>
+# include <sys/uio.h>
+
+static const char *errstr;
+
+static long
+sys_io_uring_register(unsigned int fd, unsigned int opcode,
+ const void *arg, unsigned int nargs)
+
+{
+ kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
+ kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
+ kernel_ulong_t arg1 = fill | fd;
+ kernel_ulong_t arg2 = fill | opcode;
+ kernel_ulong_t arg3 = (unsigned long) arg;
+ kernel_ulong_t arg4 = fill | nargs;
+
+ long rc = syscall(__NR_io_uring_register,
+ arg1, arg2, arg3, arg4, bad, bad);
+ errstr = sprintrc(rc);
+ return rc;
+}
+
+int
+main(void)
+{
+ static const char path_null[] = "/dev/null";
+ static const char path_full[] = "/dev/full";
+ const struct iovec iov[] = {
+ {
+ .iov_base = (void *) (unsigned long) 0xfacefeedcafef00d,
+ .iov_len = (unsigned long) 0xdeadfacebeefcafe
+ },
+ {
+ .iov_base = (void *) path_null,
+ .iov_len = sizeof(path_null)
+ }
+ };
+ const struct iovec *arg_iov = tail_memdup(iov, sizeof(iov));
+
+ skip_if_unavailable("/proc/self/fd/");
+
+ int fd_null = open(path_null, O_RDONLY);
+ if (fd_null < 0)
+ perror_msg_and_fail("open: %s", path_null);
+
+ int fd_full = open(path_full, O_RDONLY);
+ if (fd_full < 0)
+ perror_msg_and_fail("open: %s", path_null);
+
+ int fds[] = { fd_full, fd_null };
+ const int *arg_fds = tail_memdup(fds, sizeof(fds));
+
+ sys_io_uring_register(fd_null, 0xbadc0ded, path_null, 0xdeadbeef);
+ printf("io_uring_register(%u<%s>, %#x /* IORING_REGISTER_??? */"
+ ", %p, %u) = %s\n",
+ fd_null, path_null, 0xbadc0ded, path_null, 0xdeadbeef, errstr);
+
+ sys_io_uring_register(fd_null, 0, arg_iov, ARRAY_SIZE(iov));
+ printf("io_uring_register(%u<%s>, IORING_REGISTER_BUFFERS"
+ ", [{iov_base=%p, iov_len=%lu}, {iov_base=%p, iov_len=%lu}]"
+ ", %u) = %s\n",
+ fd_null, path_null, iov[0].iov_base,
+ (unsigned long) iov[0].iov_len,
+ iov[1].iov_base, (unsigned long) iov[1].iov_len,
+ (unsigned int) ARRAY_SIZE(iov), errstr);
+
+ sys_io_uring_register(fd_null, 2, arg_fds, ARRAY_SIZE(fds));
+ printf("io_uring_register(%u<%s>, IORING_REGISTER_FILES"
+ ", [%u<%s>, %u<%s>], %u) = %s\n",
+ fd_null, path_null, fd_full, path_full, fd_null, path_null,
+ (unsigned int) ARRAY_SIZE(fds), errstr);
+
+ puts("+++ exited with 0 +++");
+ return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_io_uring_register")
+
+#endif
diff --git a/tests/io_uring_setup.c b/tests/io_uring_setup.c
new file mode 100644
index 000000000..f48095bb3
--- /dev/null
+++ b/tests/io_uring_setup.c
@@ -0,0 +1,103 @@
+/*
+ * Check decoding of io_uring_setup syscall.
+ *
+ * Copyright (c) 2019 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <unistd.h>
+#include <asm/unistd.h>
+#include "scno.h"
+
+#if defined HAVE_LINUX_IO_URING_H && defined __NR_io_uring_setup
+
+# include <stdio.h>
+# include <stdint.h>
+# include <string.h>
+# include <linux/io_uring.h>
+
+# include "print_fields.h"
+
+static const char *errstr;
+
+static long
+sys_io_uring_setup(uint32_t nentries, const void *params)
+{
+ kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
+ kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
+ kernel_ulong_t arg1 = fill | nentries;
+ kernel_ulong_t arg2 = (unsigned long) params;
+
+ long rc = syscall(__NR_io_uring_setup, arg1, arg2, bad, bad, bad, bad);
+ errstr = sprintrc(rc);
+ return rc;
+}
+
+int
+main(void)
+{
+ long rc;
+ TAIL_ALLOC_OBJECT_CONST_PTR(struct io_uring_params, params);
+ const void *efault = (const void *) params + 1;
+
+ skip_if_unavailable("/proc/self/fd/");
+
+ sys_io_uring_setup(-1U, NULL);
+ printf("io_uring_setup(%u, NULL) = %s\n", -1U, errstr);
+
+ sys_io_uring_setup(0, efault);
+ printf("io_uring_setup(%u, %p) = %s\n", 0, efault, errstr);
+
+ fill_memory(params, sizeof(*params));
+ params->flags = -1;
+ sys_io_uring_setup(1, params);
+ printf("io_uring_setup(%u, {flags=IORING_SETUP_IOPOLL"
+ "|IORING_SETUP_SQPOLL|IORING_SETUP_SQ_AFF|%#x"
+ ", sq_thread_cpu=%#x, sq_thread_idle=%u, resv={",
+ 1, -1U - 7, params->sq_thread_cpu, params->sq_thread_idle);
+ for (unsigned int i = 0; i < ARRAY_SIZE(params->resv); ++i)
+ printf("%s%#x", i ? ", " : "", params->resv[i]);
+ printf("}}) = %s\n", errstr);
+
+ memset(params, 0, sizeof(*params));
+ rc = sys_io_uring_setup(2, params);
+ printf("io_uring_setup(%u, {flags=0, sq_thread_cpu=0"
+ ", sq_thread_idle=0", 2);
+ if (rc < 0)
+ printf("}) = %s\n", errstr);
+ else
+ printf(", sq_entries=%u, cq_entries=%u"
+ ", sq_off={head=%u, tail=%u, ring_mask=%u"
+ ", ring_entries=%u, flags=%u, dropped=%u, array=%u}"
+ ", cq_off={head=%u, tail=%u, ring_mask=%u"
+ ", ring_entries=%u, overflow=%u, cqes=%u}"
+ "}) = %ld<anon_inode:[io_uring]>\n",
+ params->sq_entries,
+ params->cq_entries,
+ params->sq_off.head,
+ params->sq_off.tail,
+ params->sq_off.ring_mask,
+ params->sq_off.ring_entries,
+ params->sq_off.flags,
+ params->sq_off.dropped,
+ params->sq_off.array,
+ params->cq_off.head,
+ params->cq_off.tail,
+ params->cq_off.ring_mask,
+ params->cq_off.ring_entries,
+ params->cq_off.overflow,
+ params->cq_off.cqes,
+ rc);
+
+ puts("+++ exited with 0 +++");
+ return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("HAVE_LINUX_IO_URING_H && __NR_io_uring_setup")
+
+#endif
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index 258b8c65f..372252095 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -120,6 +120,9 @@ inet-cmsg
init_module
inotify
inotify_init1
+io_uring_enter
+io_uring_register
+io_uring_setup
ioctl
ioctl_block
ioctl_dm
diff --git a/xlat/uring_enter_flags.in b/xlat/uring_enter_flags.in
new file mode 100644
index 000000000..609727802
--- /dev/null
+++ b/xlat/uring_enter_flags.in
@@ -0,0 +1,2 @@
+IORING_ENTER_GETEVENTS 1U
+IORING_ENTER_SQ_WAKEUP 2U
diff --git a/xlat/uring_register_opcodes.in b/xlat/uring_register_opcodes.in
new file mode 100644
index 000000000..d98df2e72
--- /dev/null
+++ b/xlat/uring_register_opcodes.in
@@ -0,0 +1,4 @@
+IORING_REGISTER_BUFFERS 0U
+IORING_UNREGISTER_BUFFERS 1U
+IORING_REGISTER_FILES 2U
+IORING_UNREGISTER_FILES 3U
diff --git a/xlat/uring_setup_flags.in b/xlat/uring_setup_flags.in
new file mode 100644
index 000000000..d44c7b1bd
--- /dev/null
+++ b/xlat/uring_setup_flags.in
@@ -0,0 +1,3 @@
+IORING_SETUP_IOPOLL 1U
+IORING_SETUP_SQPOLL 2U
+IORING_SETUP_SQ_AFF 4U