diff options
author | Eugene Syromyatnikov <evgsyr@gmail.com> | 2022-06-08 10:45:14 +0200 |
---|---|---|
committer | Eugene Syromyatnikov <evgsyr@gmail.com> | 2022-08-11 14:34:17 +0200 |
commit | 1f8df42d24c9e2bbe1df8448e8eee852934a4c57 (patch) | |
tree | 6ad744e385e68eac53d6e71cb27f96e15aa01562 | |
parent | a30e5defe41b5b806c223865e92b20d8c9b08f4b (diff) | |
download | strace-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.c | 37 | ||||
-rw-r--r-- | tests/io_uring_register.c | 61 |
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; } |