summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2022-06-08 10:45:14 +0200
committerEugene Syromyatnikov <evgsyr@gmail.com>2022-08-11 14:34:17 +0200
commit1f8df42d24c9e2bbe1df8448e8eee852934a4c57 (patch)
tree6ad744e385e68eac53d6e71cb27f96e15aa01562
parenta30e5defe41b5b806c223865e92b20d8c9b08f4b (diff)
downloadstrace-1f8df42d24c9e2bbe1df8448e8eee852934a4c57.tar.gz
io_uring: add support for IORING_{,UN}REGISTER_PBUF_RING opcodes
Introduced by Linux commit v5.19-rc1~251^2~10. * src/xlat/uring_register_opcodes.in (IORING_REGISTER_PBUF_RING, IORING_UNREGISTER_PBUF_RING): New constants. * src/io_uring.c (print_io_uring_buf_reg): New function. (SYS_FUNC(io_uring_register)) <case IORING_REGISTER_PBUF_RING, case IORING_UNREGISTER_PBUF_RING>: Call print_io_uring_buf_reg for decoding. * tests/io_uring_register.c: Update expected output, add checks.
-rw-r--r--src/io_uring.c37
-rw-r--r--tests/io_uring_register.c61
2 files changed, 98 insertions, 0 deletions
diff --git a/src/io_uring.c b/src/io_uring.c
index e59ccbe3c..1f3c6bb5d 100644
--- a/src/io_uring.c
+++ b/src/io_uring.c
@@ -560,6 +560,39 @@ print_io_uring_ringfds_unregister(struct tcb *tcp, const kernel_ulong_t arg,
tfetch_mem, print_ringfd_unregister_array_member, NULL);
}
+static void
+print_io_uring_buf_reg(struct tcb *tcp, const kernel_ulong_t addr)
+{
+ struct io_uring_buf_reg arg;
+ CHECK_TYPE_SIZE(arg, 40);
+ CHECK_TYPE_SIZE(arg.pad, sizeof(uint16_t));
+ CHECK_TYPE_SIZE(arg.resv, sizeof(uint64_t) * 3);
+
+ if (umove_or_printaddr(tcp, addr, &arg))
+ return;
+
+ tprint_struct_begin();
+ PRINT_FIELD_ADDR64(arg, ring_addr);
+
+ tprint_struct_next();
+ PRINT_FIELD_U(arg, ring_entries);
+
+ tprint_struct_next();
+ PRINT_FIELD_U(arg, bgid);
+
+ if (arg.pad) {
+ tprint_struct_next();
+ PRINT_FIELD_X(arg, pad);
+ }
+
+ if (!IS_ARRAY_ZERO(arg.resv)) {
+ tprint_struct_next();
+ PRINT_FIELD_ARRAY(arg, resv, tcp, print_xint_array_member);
+ }
+
+ tprint_struct_end();
+}
+
SYS_FUNC(io_uring_register)
{
const int fd = tcp->u_arg[0];
@@ -622,6 +655,10 @@ SYS_FUNC(io_uring_register)
case IORING_UNREGISTER_RING_FDS:
print_io_uring_ringfds_unregister(tcp, arg, nargs);
break;
+ case IORING_REGISTER_PBUF_RING:
+ case IORING_UNREGISTER_PBUF_RING:
+ print_io_uring_buf_reg(tcp, arg);
+ break;
case IORING_UNREGISTER_BUFFERS:
case IORING_UNREGISTER_FILES:
case IORING_UNREGISTER_EVENTFD:
diff --git a/tests/io_uring_register.c b/tests/io_uring_register.c
index b87b3c9bd..3b0d4c16a 100644
--- a/tests/io_uring_register.c
+++ b/tests/io_uring_register.c
@@ -1067,6 +1067,67 @@ main(void)
}
}
+
+ /* IORING_REGISTER_PBUF_RING, IORING_UNREGISTER_PBUF_RING */
+ static const struct {
+ unsigned int op;
+ const char *str;
+ } buf_reg_ops[] = {
+ { 22, "IORING_REGISTER_PBUF_RING" },
+ { 23, "IORING_UNREGISTER_PBUF_RING" },
+ };
+ TAIL_ALLOC_OBJECT_VAR_PTR(struct io_uring_buf_reg, buf_reg);
+
+ for (size_t i = 0; i < ARRAY_SIZE(buf_reg_ops); i++) {
+ sys_io_uring_register(fd_null, buf_reg_ops[i].op, 0,
+ 0xdeadbeef);
+ printf("io_uring_register(%u<%s>, " XLAT_FMT ", NULL, %u)"
+ " = %s\n",
+ fd_null, path_null,
+ XLAT_SEL(buf_reg_ops[i].op, buf_reg_ops[i].str),
+ 0xdeadbeef, errstr);
+
+ sys_io_uring_register(fd_null, buf_reg_ops[i].op,
+ buf_reg + 1, 0);
+ printf("io_uring_register(%u<%s>, " XLAT_FMT ", %p, 0) = %s\n",
+ fd_null, path_null,
+ XLAT_SEL(buf_reg_ops[i].op, buf_reg_ops[i].str),
+ buf_reg + 1, errstr);
+
+ for (size_t j = 0; j < 256; j++) {
+ memset(buf_reg, 0, sizeof(*buf_reg));
+ buf_reg->ring_addr = j & 2 ? (uintptr_t) buf_reg : 0;
+ buf_reg->ring_entries = j & 4 ? 3141592653 : 0;
+ buf_reg->bgid = j & 8 ? 42069 : 0;
+ buf_reg->pad = j & 16 ? 31337 : 0;
+ buf_reg->resv[0] = j & 32 ? 0xbadc0deddeadfaceULL : 0;
+ buf_reg->resv[1] = j & 64 ? 0xdecaffedbeefdeadULL : 0;
+ buf_reg->resv[2] = j & 128 ? 0xbadc0dedfacefeedULL : 0;
+
+ sys_io_uring_register(fd_null, buf_reg_ops[i].op,
+ buf_reg, 0x42);
+ printf("io_uring_register(%u<%s>, " XLAT_FMT
+ ", {ring_addr=",
+ fd_null, path_null,
+ XLAT_SEL(buf_reg_ops[i].op, buf_reg_ops[i].str));
+ if (j & 2)
+ printf("%p", buf_reg);
+ else
+ printf("NULL");
+ printf(", ring_entries=%s, bgid=%s%s",
+ j & 4 ? "3141592653" : "0",
+ j & 8 ? "42069" : "0",
+ j & 16 ? ", pad=0x7a69" : "");
+ if (j & 0xe0) {
+ printf(", resv=[%s, %s, %s]",
+ j & 32 ? "0xbadc0deddeadface" : "0",
+ j & 64 ? "0xdecaffedbeefdead" : "0",
+ j & 128 ? "0xbadc0dedfacefeed" : "0");
+ }
+ printf("}, 66) = %s\n", errstr);
+ }
+ }
+
puts("+++ exited with 0 +++");
return 0;
}