github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/sys/linux/io_uring.txt (about)

     1  # Copyright 2019 syzkaller project authors. All rights reserved.
     2  # Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  # See http://kernel.dk/io_uring.pdf
     5  
     6  include <uapi/linux/io_uring.h>
     7  # For EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL
     8  include <uapi/linux/eventpoll.h>
     9  
    10  resource fd_io_uring[fd]
    11  resource ring_ptr[int64]
    12  resource sqes_ptr[int64]
    13  resource ioring_personality_id[int16]
    14  
    15  # fs/io_uring.c
    16  define IORING_MAX_ENTRIES	32768
    17  define IORING_MAX_CQ_ENTRIES	(2 * IORING_MAX_ENTRIES)
    18  
    19  # First does the setup calling io_uring_setup, than calls mmap to map the ring and
    20  # the sqes. It is hard for the fuzzer to generate correct programs using mmap calls
    21  # with fuzzer-provided mmap length. This wrapper ensures correct length computation.
    22  syz_io_uring_setup(entries int32[1:IORING_MAX_ENTRIES], params ptr[inout, io_uring_params], ring_ptr ptr[out, ring_ptr], sqes_ptr ptr[out, sqes_ptr]) fd_io_uring
    23  
    24  io_uring_setup(entries int32[1:IORING_MAX_ENTRIES], params ptr[inout, io_uring_params]) fd_io_uring
    25  io_uring_enter(fd fd_io_uring, to_submit int32[0:IORING_MAX_ENTRIES], min_complete int32[0:IORING_MAX_CQ_ENTRIES], flags flags[io_uring_enter_flags], sigmask ptr[in, sigset_t], size len[sigmask])
    26  io_uring_register$IORING_REGISTER_BUFFERS(fd fd_io_uring, opcode const[IORING_REGISTER_BUFFERS], arg ptr[in, array[iovec_out]], nr_args len[arg])
    27  io_uring_register$IORING_UNREGISTER_BUFFERS(fd fd_io_uring, opcode const[IORING_UNREGISTER_BUFFERS], arg const[0], nr_args const[0])
    28  io_uring_register$IORING_REGISTER_FILES(fd fd_io_uring, opcode const[IORING_REGISTER_FILES], arg ptr[in, array[fd]], nr_args len[arg])
    29  io_uring_register$IORING_UNREGISTER_FILES(fd fd_io_uring, opcode const[IORING_UNREGISTER_FILES], arg const[0], nr_args const[0])
    30  io_uring_register$IORING_REGISTER_EVENTFD(fd fd_io_uring, opcode const[IORING_REGISTER_EVENTFD], arg ptr[in, fd_event], nr_args const[1])
    31  io_uring_register$IORING_UNREGISTER_EVENTFD(fd fd_io_uring, opcode const[IORING_UNREGISTER_EVENTFD], arg const[0], nr_args const[0])
    32  io_uring_register$IORING_REGISTER_FILES_UPDATE(fd fd_io_uring, opcode const[IORING_REGISTER_FILES_UPDATE], arg ptr[in, io_uring_files_update], nr_args len[arg:fds])
    33  io_uring_register$IORING_REGISTER_EVENTFD_ASYNC(fd fd_io_uring, opcode const[IORING_REGISTER_EVENTFD_ASYNC], arg ptr[in, fd_event], nr_args const[1])
    34  io_uring_register$IORING_REGISTER_PROBE(fd fd_io_uring, opcode const[IORING_REGISTER_PROBE], arg ptr[inout, io_uring_probe], nr_args len[arg:ops])
    35  io_uring_register$IORING_REGISTER_PERSONALITY(fd fd_io_uring, opcode const[IORING_REGISTER_PERSONALITY], arg const[0], nr_args const[0]) ioring_personality_id
    36  io_uring_register$IORING_UNREGISTER_PERSONALITY(fd fd_io_uring, opcode const[IORING_UNREGISTER_PERSONALITY], arg const[0], nr_args ioring_personality_id)
    37  # IORING_REGISTER_EVENTFD, IORING_UNREGISTER_EVENTFD >= 5.2
    38  # IORING_REGISTER_FILES_UPDATE >= 5.5
    39  # IORING_REGISTER_EVENTFD_ASYNC, IORING_REGISTER_PROBE, IORING_REGISTER_PERSONALITY, IORING_UNREGISTER_PERSONALITY>= 5.6
    40  
    41  io_uring_register$IORING_REGISTER_ENABLE_RINGS(fd fd_io_uring, opcode const[IORING_REGISTER_ENABLE_RINGS], arg const[0], nr_args const[0])
    42  io_uring_register$IORING_REGISTER_RESTRICTIONS(fd fd_io_uring, opcode const[IORING_REGISTER_RESTRICTIONS], arg ptr[in, array[io_uring_restriction_st]], nr_args len[arg])
    43  # IORING_REGISTER_ENABLE_RINGS, IORING_REGISTER_RESTRICTIONS >= 5.10
    44  io_uring_register$IORING_REGISTER_BUFFERS2(fd fd_io_uring, opcode const[IORING_REGISTER_BUFFERS2], arg ptr[in, io_uring_rsrc_register], size bytesize[arg])
    45  io_uring_register$IORING_REGISTER_BUFFERS_UPDATE(fd fd_io_uring, opcode const[IORING_REGISTER_BUFFERS_UPDATE], arg ptr[in, io_uring_rsrc_update2], size bytesize[arg])
    46  io_uring_register$IORING_REGISTER_FILES2(fd fd_io_uring, opcode const[IORING_REGISTER_FILES2], arg ptr[in, io_uring_rsrc_register], size bytesize[arg])
    47  io_uring_register$IORING_REGISTER_FILES_UPDATE2(fd fd_io_uring, opcode const[IORING_REGISTER_FILES_UPDATE2], arg ptr[in, io_uring_rsrc_update2], size bytesize[arg])
    48  # IORING_REGISTER_BUFFERS2, IORING_REGISTER_BUFFERS_UPDATE, IORING_REGISTER_FILES2, IORING_REGISTER_FILES_UPDATE2 >= 5.13
    49  io_uring_register$IORING_REGISTER_IOWQ_AFF(fd fd_io_uring, opcode const[IORING_REGISTER_IOWQ_AFF], arg ptr[in, array[int8]], size bytesize[arg])
    50  io_uring_register$IORING_UNREGISTER_IOWQ_AFF(fd fd_io_uring, opcode const[IORING_UNREGISTER_IOWQ_AFF], arg const[0], nr_args const[0])
    51  # IORING_REGISTER_IOWQ_AFF, IORING_UNREGISTER_IOWQ_AFF >= 5.14
    52  io_uring_register$IORING_REGISTER_IOWQ_MAX_WORKERS(fd fd_io_uring, opcode const[IORING_REGISTER_IOWQ_MAX_WORKERS], arg ptr[in, array[int32, 2]], nr_args const[2])
    53  # IORING_REGISTER_IOWQ_MAX_WORKERS >= 5.15
    54  io_uring_register$IORING_REGISTER_RING_FDS(fd fd_io_uring, opcode const[IORING_REGISTER_RING_FDS], arg ptr[in, array[io_uring_rsrc_register]], nr_args len[arg])
    55  io_uring_register$IORING_UNREGISTER_RING_FDS(fd fd_io_uring, opcode const[IORING_UNREGISTER_RING_FDS], arg ptr[in, array[io_uring_rsrc_register]], nr_args len[arg])
    56  # IORING_REGISTER_RING_FDS, IORING_UNREGISTER_RING_FDS >= 5.18
    57  io_uring_register$IORING_REGISTER_PBUF_RING(fd fd_io_uring, opcode const[IORING_REGISTER_PBUF_RING], arg ptr[in, io_uring_buf_reg], nr_args const[1])
    58  io_uring_register$IORING_UNREGISTER_PBUF_RING(fd fd_io_uring, opcode const[IORING_UNREGISTER_PBUF_RING], arg ptr[in, io_uring_buf_reg], nr_args const[1])
    59  # IORING_REGISTER_PBUF_RING, IORING_UNREGISTER_PBUF_RING >= 5.19
    60  io_uring_register$IORING_REGISTER_SYNC_CANCEL(fd fd_io_uring, opcode const[IORING_REGISTER_SYNC_CANCEL], arg ptr[in, io_uring_sync_cancel_reg], nr_args const[1])
    61  io_uring_register$IORING_REGISTER_FILE_ALLOC_RANGE(fd fd_io_uring, opcode const[IORING_REGISTER_FILE_ALLOC_RANGE], arg ptr[in, io_uring_file_index_range], nr_args const[0])
    62  io_uring_register$IORING_REGISTER_PBUF_STATUS(fd fd_io_uring, opcode const[IORING_REGISTER_PBUF_STATUS], arg ptr[in, io_uring_buf_status], nr_args const[1])
    63  io_uring_register$IORING_REGISTER_NAPI(fd fd_io_uring, opcode const[IORING_REGISTER_NAPI], arg ptr[in, io_uring_napi], nr_args const[1])
    64  io_uring_register$IORING_UNREGISTER_NAPI(fd fd_io_uring, opcode const[IORING_UNREGISTER_NAPI], arg ptr[out, io_uring_napi], nr_args const[1])
    65  io_uring_register$IORING_REGISTER_CLOCK(fd fd_io_uring, opcode const[IORING_REGISTER_CLOCK], arg ptr[in, io_uring_clock_register], nr_args const[0])
    66  io_uring_register$IORING_REGISTER_CLONE_BUFFERS(fd fd_io_uring, opcode const[IORING_REGISTER_CLONE_BUFFERS], arg ptr[in, io_uring_clone_buffers], nr_args const[1])
    67  io_uring_register$IORING_REGISTER_RESIZE_RINGS(fd fd_io_uring, opcode const[IORING_REGISTER_RESIZE_RINGS], arg ptr[in, io_uring_params], nr_args const[1])
    68  io_uring_register$IORING_REGISTER_MEM_REGION(fd fd_io_uring, opcode const[IORING_REGISTER_MEM_REGION], arg ptr[in, io_uring_mem_region_reg], nr_args const[1])
    69  
    70  io_uring_register_opcodes = IORING_REGISTER_BUFFERS, IORING_UNREGISTER_BUFFERS, IORING_REGISTER_FILES, IORING_UNREGISTER_FILES, IORING_REGISTER_EVENTFD, IORING_UNREGISTER_EVENTFD, IORING_REGISTER_FILES_UPDATE, IORING_REGISTER_EVENTFD_ASYNC, IORING_REGISTER_PROBE, IORING_REGISTER_PERSONALITY, IORING_UNREGISTER_PERSONALITY, IORING_REGISTER_RESTRICTIONS, IORING_REGISTER_ENABLE_RINGS, IORING_REGISTER_FILES2, IORING_REGISTER_FILES_UPDATE2, IORING_REGISTER_BUFFERS2, IORING_REGISTER_BUFFERS_UPDATE, IORING_REGISTER_IOWQ_AFF, IORING_UNREGISTER_IOWQ_AFF, IORING_REGISTER_IOWQ_MAX_WORKERS, IORING_REGISTER_RING_FDS, IORING_UNREGISTER_RING_FDS, IORING_REGISTER_PBUF_RING, IORING_UNREGISTER_PBUF_RING, IORING_REGISTER_SYNC_CANCEL, IORING_REGISTER_FILE_ALLOC_RANGE, IORING_REGISTER_PBUF_STATUS, IORING_REGISTER_NAPI, IORING_UNREGISTER_NAPI, IORING_REGISTER_CLOCK, IORING_REGISTER_CLONE_BUFFERS, IORING_REGISTER_SEND_MSG_RING, IORING_REGISTER_RESIZE_RINGS, IORING_REGISTER_MEM_REGION
    71  
    72  # The mmap'ed area for SQ and CQ rings are really the same -- the difference is
    73  # accounted for with the usage of offsets.
    74  mmap$IORING_OFF_SQ_RING(addr vma, len len[addr], prot flags[mmap_prot], flags flags[mmap_flags], fd fd_io_uring, offset const[IORING_OFF_SQ_RING]) ring_ptr
    75  mmap$IORING_OFF_CQ_RING(addr vma, len len[addr], prot flags[mmap_prot], flags flags[mmap_flags], fd fd_io_uring, offset const[IORING_OFF_CQ_RING]) ring_ptr
    76  mmap$IORING_OFF_SQES(addr vma, len len[addr], prot flags[mmap_prot], flags flags[mmap_flags], fd fd_io_uring, offset const[IORING_OFF_SQES]) sqes_ptr
    77  
    78  # If no flags are specified(0), the io_uring instance is setup for interrupt driven IO.
    79  io_uring_setup_flags = 0, IORING_SETUP_IOPOLL, IORING_SETUP_SQPOLL, IORING_SETUP_SQ_AFF, IORING_SETUP_CQSIZE, IORING_SETUP_CLAMP, IORING_SETUP_ATTACH_WQ, IORING_FEAT_SINGLE_MMAP, IORING_FEAT_NODROP, IORING_FEAT_SUBMIT_STABLE, IORING_FEAT_RW_CUR_POS, IORING_FEAT_FAST_POLL, IORING_FEAT_POLL_32BITS, IORING_SETUP_R_DISABLED, IORING_FEAT_SQPOLL_NONFIXED, IORING_FEAT_NATIVE_WORKERS, IORING_FEAT_RSRC_TAGS, IORING_FEAT_CQE_SKIP, IORING_FEAT_LINKED_FILE, IORING_FEAT_REG_REG_RING, IORING_FEAT_RECVSEND_BUNDLE, IORING_FEAT_MIN_TIMEOUT, IORING_SETUP_SUBMIT_ALL, IORING_SETUP_COOP_TASKRUN, IORING_SETUP_TASKRUN_FLAG, IORING_SETUP_SQE128, IORING_SETUP_CQE32, IORING_SETUP_SINGLE_ISSUER, IORING_SETUP_DEFER_TASKRUN, IORING_SETUP_NO_MMAP, IORING_SETUP_REGISTERED_FD_ONLY, IORING_SETUP_NO_SQARRAY, IORING_SETUP_HYBRID_IOPOLL
    80  # watch out the being tested kernel version
    81  # IORING_FEAT_SINGLE_MMAP >= 5.4
    82  # IORING_FEAT_NODROP, IORING_FEAT_SUBMIT_STABLE >= 5.5
    83  # IORING_FEAT_RW_CUR_POS >= 5.6
    84  # IORING_FEAT_FAST_POLL >= 5.7
    85  # IORING_FEAT_POLL_32BITS >= 5.9
    86  # IORING_SETUP_R_DISABLED >= 5.10 (this shoule be used with IORING_REGISTER_ENABLE_RINGS)
    87  # IORING_FEAT_SQPOLL_NONFIXED >= 5.11
    88  # IORING_FEAT_NATIVE_WORKERS >= 5.12
    89  # IORING_FEAT_RSRC_TAGS >= 5.13
    90  # IORING_FEAT_CQE_SKIP >= 5.17
    91  # IORING_SETUP_SUBMIT_ALL >= 5.18
    92  # IORING_SETUP_COOP_TASKRUN, IORING_SETUP_TASKRUN_FLAG, IORING_SETUP_SQE128, IORING_SETUP_CQE32 >= 5.19
    93  # IORING_SETUP_SINGLE_ISSUER >= 6.0
    94  # IORING_SETUP_DEFER_TASKRUN >= 6.1
    95  
    96  io_uring_enter_flags = IORING_ENTER_GETEVENTS, IORING_ENTER_SQ_WAKEUP, IORING_ENTER_SQ_WAIT, IORING_ENTER_EXT_ARG, IORING_ENTER_REGISTERED_RING, IORING_ENTER_ABS_TIMER, IORING_ENTER_EXT_ARG_REG
    97  # IORING_ENTER_EXT_ARG >= 5.11
    98  _ = __NR_mmap2
    99  
   100  # Once an io_uring is set up by calling io_uring_setup, the offsets to the member fields
   101  # to be used on the mmap'ed area are set in structs io_sqring_offsets and io_cqring_offsets.
   102  # Except io_sqring_offsets.array, the offsets are static while all depend on how struct io_rings
   103  # is organized in code. The offsets can be marked as resources in syzkaller descriptions but
   104  # this makes it difficult to generate correct programs by the fuzzer. Thus, the offsets are
   105  # hard-coded here (and in the executor).
   106  define SQ_HEAD_OFFSET	0
   107  define SQ_TAIL_OFFSET	64
   108  define SQ_RING_MASK_OFFSET	256
   109  define SQ_RING_ENTRIES_OFFSET	264
   110  define SQ_FLAGS_OFFSET	276
   111  define SQ_DROPPED_OFFSET	272
   112  define CQ_HEAD_OFFSET	128
   113  define CQ_TAIL_OFFSET	192
   114  define CQ_RING_MASK_OFFSET	260
   115  define CQ_RING_ENTRIES_OFFSET	268
   116  define CQ_RING_OVERFLOW_OFFSET	284
   117  define CQ_FLAGS_OFFSET	280
   118  
   119  # Notice all offsets are pointing to uint32 values. This is assumed for the
   120  io_uring_offsets = SQ_HEAD_OFFSET, SQ_TAIL_OFFSET, SQ_RING_MASK_OFFSET, SQ_RING_ENTRIES_OFFSET, SQ_DROPPED_OFFSET, CQ_HEAD_OFFSET, CQ_TAIL_OFFSET, CQ_RING_MASK_OFFSET, CQ_RING_ENTRIES_OFFSET, CQ_RING_OVERFLOW_OFFSET, io_uring_flags_offsets
   121  
   122  # Also, all values are int32, thus, set nbytes to 4.
   123  syz_memcpy_off$IO_URING_METADATA_GENERIC(ring_ptr ring_ptr, off flags[io_uring_offsets], src ptr[in, int32], src_off const[0], nbytes const[4])
   124  
   125  # The flags available are: IORING_SQ_NEED_WAKEUP (1) for sq, IORING_CQ_EVENTFD_DISABLED (1) for cq. Use int32[0:1] to represent possible values.
   126  io_uring_flags_offsets = SQ_FLAGS_OFFSET, CQ_FLAGS_OFFSET
   127  syz_memcpy_off$IO_URING_METADATA_FLAGS(ring_ptr ring_ptr, flag_off flags[io_uring_flags_offsets], src ptr[in, int32[0:1]], src_off const[0], nbytes const[4])
   128  
   129  io_uring_probe {
   130  	last_op	const[0, int8]
   131  	ops_len	const[0, int8]
   132  	resv	const[0, int16]
   133  	resv2	array[const[0, int32], 3]
   134  	ops	array[io_uring_probe_op, 0:IORING_OP_LAST]
   135  }
   136  
   137  io_uring_probe_op {
   138  	op	const[0, int8]
   139  	resv	const[0, int8]
   140  	flags	const[0, int16]
   141  	resv2	const[0, int32]
   142  }
   143  
   144  io_uring_files_update {
   145  	offset	int32
   146  	resv	const[0, int32]
   147  	fds	ptr64[in, array[fd]]
   148  }
   149  
   150  #
   151  # type template for io_uring_restriction
   152  #
   153  
   154  type io_uring_restriction[OPCODE, OPARG] {
   155  	op	const[OPCODE, int16]
   156  	oparg	OPARG
   157  	resv	const[0, int8]
   158  	resv2	array[const[0, int32], 3]
   159  }
   160  
   161  io_uring_restriction_st [
   162  	ioring_restriction_register_op		io_uring_restriction[IORING_RESTRICTION_REGISTER_OP, flags[io_uring_register_opcodes, int8]]
   163  	ioring_restriction_sqe_op		io_uring_restriction[IORING_RESTRICTION_SQE_OP, flags[io_uring_register_opcodes, int8]]
   164  	ioring_restriction_sqe_flags_allowed	io_uring_restriction[IORING_RESTRICTION_SQE_FLAGS_ALLOWED, flags[io_uring_register_opcodes, int8]]
   165  	ioring_restriction_sqe_flags_required	io_uring_restriction[IORING_RESTRICTION_SQE_FLAGS_REQUIRED, flags[io_uring_register_opcodes, int8]]
   166  ]
   167  
   168  io_uring_rsrc_flags = IORING_RSRC_REGISTER_SPARSE
   169  
   170  io_uring_rsrc_register {
   171  	nr	len[data, int32]
   172  	flags	flags[io_uring_rsrc_flags, int32]
   173  	resv2	const[0, int64]
   174  	data	ptr64[in, array[iovec_out]]
   175  	tags	ptr64[in, array[int64]]
   176  }
   177  
   178  io_uring_rsrc_update2 {
   179  	offset	int32
   180  	resv	const[0, int32]
   181  	data	ptr64[in, array[iovec_out]]
   182  	tags	ptr64[in, array[int64]]
   183  	nr	len[data, int32]
   184  	resv2	const[0, int32]
   185  }
   186  
   187  io_uring_buf {
   188  	addr	ptr64[in, array[int8]]
   189  	len	len[addr, int32]
   190  	bid	io_uring_bid[int16]
   191  	resv	const[0, int16]
   192  }
   193  
   194  io_uring_buf_array {
   195  	data	array[io_uring_buf]
   196  } [align[4096]]
   197  
   198  io_uring_buf_reg {
   199  	ring_addr	ptr64[in, io_uring_buf_array]
   200  	ring_entries	len[ring_addr:data, int32]
   201  	bgid		io_uring_bgid[int16]	(in)
   202  # IOU_PBUF_RING_MMAP not supported yet
   203  	flags		const[0, int16]
   204  	resv		array[const[0, int64], 3]
   205  }
   206  
   207  io_uring_params {
   208  	sq_entries	int32	(out)
   209  	cq_entries	int32[0:IORING_MAX_CQ_ENTRIES]	(inout)
   210  	flags		flags[io_uring_setup_flags, int32]	(in)
   211  	sq_thread_cpu	int32[0:3]	(in)
   212  	sq_thread_idle	int32[0:1000]	(in)
   213  	features	int32	(out)
   214  	wq_fd		fd_io_uring[opt]	(in)
   215  	resv		array[const[0, int32], 3]
   216  # We don't really use them (they are hard-coded). Thus, just pass some memory region of their size.
   217  # TODO: Now that per-field directions is supported, can we avoid using hard-coded values for offsets?
   218  	sq_off		array[int32, 10]	(out)
   219  	cq_off		array[int32, 10]	(out)
   220  }
   221  
   222  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   223  # Descriptions for sq_ring and cq_ring manipulation # # # # # # # # # # # # # #
   224  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   225  
   226  # Retrieve the cqe at the head of the cq_ring and advance the head. The only meaningful
   227  # resource contained within a cqe is by the completion of openat or openat2 calls,
   228  # which produce fd. If that is the case, returns the return value of those. Otherwise,
   229  # for other operations, returns an invalid fd (-1).
   230  syz_io_uring_complete(ring_ptr ring_ptr) fd
   231  
   232  # Submit sqe into the sq_ring
   233  syz_io_uring_submit(ring_ptr ring_ptr, sqes_ptr sqes_ptr, sqe ptr[in, io_uring_sqe_u])
   234  
   235  io_uring_sqe_u [
   236  	IORING_OP_NOP			io_uring_sqe$nop
   237  	IORING_OP_READV			io_uring_sqe_readv
   238  	IORING_OP_WRITEV		io_uring_sqe$writev
   239  	IORING_OP_FSYNC			io_uring_sqe$fsync
   240  	IORING_OP_READ_FIXED		io_uring_sqe$read_fixed
   241  	IORING_OP_WRITE_FIXED		io_uring_sqe$write_fixed
   242  	IORING_OP_POLL_ADD		io_uring_sqe$poll_add
   243  	IORING_OP_POLL_REMOVE		io_uring_sqe$poll_remove
   244  	IORING_OP_SYNC_FILE_RANGE	io_uring_sqe$sync_file_range
   245  	IORING_OP_SENDMSG		io_uring_sqe$sendmsg
   246  	IORING_OP_RECVMSG		io_uring_sqe$recvmsg
   247  	IORING_OP_TIMEOUT		io_uring_sqe$timeout
   248  	IORING_OP_TIMEOUT_REMOVE	io_uring_sqe$timeout_remove
   249  	IORING_OP_ACCEPT		io_uring_sqe$accept
   250  	IORING_OP_ASYNC_CANCEL		io_uring_sqe$async_cancel
   251  	IORING_OP_LINK_TIMEOUT		io_uring_sqe$link_timeout
   252  	IORING_OP_CONNECT		io_uring_sqe$connect
   253  	IORING_OP_FALLOCATE		io_uring_sqe$fallocate
   254  	IORING_OP_OPENAT		io_uring_sqe$openat
   255  	IORING_OP_CLOSE			io_uring_sqe$close
   256  	IORING_OP_FILES_UPDATE		io_uring_sqe$files_update
   257  	IORING_OP_STATX			io_uring_sqe$statx
   258  	IORING_OP_READ			io_uring_sqe_read
   259  	IORING_OP_WRITE			io_uring_sqe$write
   260  	IORING_OP_FADVISE		io_uring_sqe$fadvise
   261  	IORING_OP_MADVISE		io_uring_sqe$madvise
   262  	IORING_OP_SEND			io_uring_sqe$send
   263  	IORING_OP_RECV			io_uring_sqe_recv
   264  	IORING_OP_OPENAT2		io_uring_sqe$openat2
   265  	IORING_OP_EPOLL_CTL		io_uring_sqe_epoll_ctl
   266  	IORING_OP_SPLICE		io_uring_sqe$splice
   267  	IORING_OP_PROVIDE_BUFFERS	io_uring_sqe$provide_buffers
   268  	IORING_OP_REMOVE_BUFFERS	io_uring_sqe$remove_buffers
   269  	IORING_OP_TEE			io_uring_sqe$tee
   270  	IORING_OP_SHUTDOWN		io_uring_sqe$shutdown
   271  	IORING_OP_RENAMEAT		io_uring_sqe$renameat
   272  	IORING_OP_UNLINKAT		io_uring_sqe$unlinkat
   273  	IORING_OP_MKDIRAT		io_uring_sqe$mkdirat
   274  	IORING_OP_SYMLINKAT		io_uring_sqe$symlinkat
   275  	IORING_OP_LINKAT		io_uring_sqe$linkat
   276  	IORING_OP_MSG_RING		io_uring_sqe$msg_ring
   277  # 	TODO undocumented 6.0
   278  #	IORING_OP_FSETXATTR		io_uring_sqe$fsetxatt
   279  #	IORING_OP_SETXATTR		io_uring_sqe$setxatt
   280  #	IORING_OP_FGETXATTR		io_uring_sqe$fgetxatt
   281  #	IORING_OP_GETXATTR		io_uring_sqe$etxatt
   282  #	IORING_OP_SOCKET		io_uring_sqe$socket
   283  #	IORING_OP_URING_CMD		io_uring_sqe$uring_cmd
   284  #	IORING_OP_SEND_ZC		io_uring_sqe$send_zc
   285  ]
   286  
   287  # io_uring_enter_opcodes = IORING_OP_NOP, IORING_OP_READV, IORING_OP_WRITEV, IORING_OP_FSYNC, IORING_OP_READ_FIXED, IORING_OP_WRITE_FIXED, IORING_OP_POLL_ADD, IORING_OP_POLL_REMOVE, IORING_OP_SYNC_FILE_RANGE, IORING_OP_SENDMSG, IORING_OP_RECVMSG, IORING_OP_TIMEOUT, IORING_OP_TIMEOUT_REMOVE, IORING_OP_ACCEPT, IORING_OP_ASYNC_CANCEL, IORING_OP_LINK_TIMEOUT, IORING_OP_CONNECT, IORING_OP_FALLOCATE, IORING_OP_OPENAT, IORING_OP_CLOSE, IORING_OP_FILES_UPDATE, IORING_OP_STATX, IORING_OP_READ, IORING_OP_WRITE, IORING_OP_FADVISE, IORING_OP_MADVISE, IORING_OP_SEND, IORING_OP_RECV, IORING_OP_OPENAT2, IORING_OP_EPOLL_CTL, IORING_OP_SPLICE, IORING_OP_PROVIDE_BUFFERS, IORING_OP_REMOVE_BUFFERS, IORING_OP_TEE, IORING_OP_SHUTDOWN, IORING_OP_RENAMEAT, IORING_OP_UNLINKAT, IORING_OP_MKDIRAT, IORING_OP_SYMLINKAT, IORING_OP_LINKAT, IORING_OP_MSG_RING, IORING_OP_FSETXATTR, IORING_OP_SETXATTR, IORING_OP_FGETXATTR, IORING_OP_GETXATTR, IORING_OP_SOCKET, IORING_OP_URING_CMD, IORING_OP_SEND_ZC
   288  
   289  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   290  # io_uring submission queue entry (io_uring_sqe) descriptions # # # # # # # # #
   291  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   292  
   293  #
   294  # sqe type template
   295  #
   296  
   297  type io_uring_sqe[OP, IOPRIO, FD, OFF, ADDR, LEN, MISC_FLAGS, USER_DATA, MISC] {
   298  	opcode		const[OP, int8]
   299  	flags		flags[iosqe_flags, int8]
   300  	ioprio		IOPRIO
   301  	fd		FD
   302  	off		OFF
   303  	addr		ADDR
   304  	len		LEN
   305  	misc_flags	MISC_FLAGS
   306  	user_data	flags[USER_DATA, int64]
   307  # This is a union of different possibilites with a padding at the end.
   308  	misc		MISC
   309  } [size[SIZEOF_IO_URING_SQE]]
   310  
   311  define SIZEOF_IO_URING_SQE	64
   312  
   313  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   314  
   315  #
   316  # Instantiation of sqes for each op
   317  #
   318  
   319  type io_uring_sqe$nop io_uring_sqe[IORING_OP_NOP, const[0, int16], const[0, int32], const[0, int64], const[0, int64], const[0, int32], const[0, int32], zero_flag, array[const[0, int64], 3]]
   320  
   321  io_uring_sqe_readv [
   322  	pass_iovec		io_uring_sqe[IORING_OP_READV, flags[ioprio_priorities, int16], fd_or_fixed_fd_index, fileoff[int64], ptr[in, array[iovec_out]], len[addr, int32], flags[rwf_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   323  	use_registered_buffer	io_uring_sqe[IORING_OP_READV, flags[ioprio_priorities, int16], fd_or_fixed_fd_index, fileoff[int64], const[0, int64], const[0, int32], flags[rwf_flags, int32], sqe_user_data_not_openat, buf_index_personality_misc]
   324  ]
   325  
   326  type io_uring_sqe$writev io_uring_sqe[IORING_OP_WRITEV, flags[ioprio_priorities, int16], fd_or_fixed_fd_index, fileoff[int64], ptr[in, array[iovec_in]], len[addr, int32], flags[rwf_flags, int32], sqe_user_data_not_openat, buf_index_personality_misc]
   327  type io_uring_sqe$fsync io_uring_sqe[IORING_OP_FSYNC, const[0, int16], fd_or_fixed_fd_index, const[0, int64], const[0, int64], const[0, int32], flags[io_uring_fsync_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   328  type io_uring_sqe$read_fixed io_uring_sqe[IORING_OP_READ_FIXED, flags[ioprio_priorities, int16], fd_or_fixed_fd_index, fileoff[int64], int64, int32, flags[rwf_flags, int32], sqe_user_data_not_openat, buf_index_personality_misc]
   329  type io_uring_sqe$write_fixed io_uring_sqe[IORING_OP_WRITE_FIXED, flags[ioprio_priorities, int16], fd_or_fixed_fd_index, fileoff[int64], int64, int32, flags[rwf_flags, int32], sqe_user_data_not_openat, buf_index_personality_misc]
   330  type io_uring_sqe$poll_add io_uring_sqe[IORING_OP_POLL_ADD, const[0, int16], fd_or_fixed_fd_index, const[0, int64], const[0, int64], const[0, int32], io_uring_sqe_poll_add_misc_flags, sqe_user_data_not_openat, personality_only_misc]
   331  type io_uring_sqe$poll_remove io_uring_sqe[IORING_OP_POLL_REMOVE, const[0, int16], const[0, int32], const[0, int64], flags[sqe_user_data, int64], const[0, int32], const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   332  type io_uring_sqe$sync_file_range io_uring_sqe[IORING_OP_SYNC_FILE_RANGE, const[0, int16], fd_or_fixed_fd_index, fileoff[int64], const[0, int64], int32, flags[sync_file_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   333  # IORING_OP_SYNC_FILE_RANGE >= 5.2
   334  type io_uring_sqe$sendmsg io_uring_sqe[IORING_OP_SENDMSG, const[0, int16], sock, const[0, int64], ptr[in, send_msghdr], const[0, int32], flags[send_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   335  type io_uring_sqe$recvmsg io_uring_sqe[IORING_OP_RECVMSG, flags[iouring_recv_ioprio, int16], sock, const[0, int64], ptr[inout, recv_msghdr], const[0, int32], flags[recv_flags, int32], sqe_user_data_not_openat, buf_group_personality_misc]
   336  # IORING_OP_SENDMSG, IORING_OP_RECVMSG >= 5.3
   337  type io_uring_sqe$timeout io_uring_sqe[IORING_OP_TIMEOUT, const[0, int16], const[0, int32], io_uring_timeout_completion_event_count, ptr[in, timespec], const[1, int32], flags[io_uring_timeout_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   338  # IORING_OP_TIMEOUT >= 5.4
   339  type io_uring_sqe$timeout_remove io_uring_sqe[IORING_OP_TIMEOUT_REMOVE, const[0, int16], const[0, int32], const[0, int64], flags[sqe_user_data, int64], const[0, int32], const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   340  type io_uring_sqe$accept io_uring_sqe[IORING_OP_ACCEPT, flags[iouring_accept_flags, int16], sock, ptr[inout, len[addr, int32]], ptr[out, sockaddr_storage, opt], const[0, int32], flags[accept_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   341  type io_uring_sqe$async_cancel io_uring_sqe[IORING_OP_ASYNC_CANCEL, const[0, int16], const[0, int32], const[0, int64], flags[sqe_user_data, int64], const[0, int32], const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   342  type io_uring_sqe$link_timeout io_uring_sqe[IORING_OP_LINK_TIMEOUT, const[0, int16], const[0, int32], const[0, int64], ptr[in, timespec], const[1, int32], flags[io_uring_timeout_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   343  type io_uring_sqe$connect io_uring_sqe[IORING_OP_CONNECT, const[0, int16], sock, len[addr, int32], ptr[in, sockaddr_storage], const[0, int32], const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   344  # IORING_OP_TIMEOUT_REMOVE, IORING_OP_ACCEPT, IORING_OP_ASYNC_CANCEL, IORING_OP_LINK_TIMEOUT, IORING_OP_CONNECT >= 5.5
   345  type io_uring_sqe$fallocate io_uring_sqe[IORING_OP_FALLOCATE, const[0, int16], fd_or_fixed_fd_index, fileoff[int64], const[0, int64], int32, const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   346  type io_uring_sqe$openat io_uring_sqe[IORING_OP_OPENAT, const[0, int16], fd_dir[opt], const[0, int64], ptr64[in, filename], flags[open_mode, int32], flags[open_flags, int32], sqe_user_data_openat, personality_only_misc]
   347  type io_uring_sqe$close io_uring_sqe[IORING_OP_CLOSE, const[0, int16], fd, const[0, int64], const[0, int64], const[0, int32], const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   348  type io_uring_sqe$files_update io_uring_sqe[IORING_OP_FILES_UPDATE, const[0, int16], const[0, int32], fileoff[int64], ptr[in, array[fd]], len[addr, int32], const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   349  type io_uring_sqe$statx io_uring_sqe[IORING_OP_STATX, const[0, int16], fd_dir[opt], ptr[out, statx], ptr64[in, filename], flags[statx_mask, int32], flags[statx_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   350  
   351  iouring_accept_flags = IORING_ACCEPT_MULTISHOT, IORING_ACCEPT_DONTWAIT, IORING_ACCEPT_POLL_FIRST
   352  
   353  io_uring_sqe_read [
   354  	pass_buffer		io_uring_sqe[IORING_OP_READ, flags[ioprio_priorities, int16], fd_or_fixed_fd_index, fileoff[int64], buffer[out], bytesize[addr, int32], flags[rwf_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   355  	use_registered_buffer	io_uring_sqe[IORING_OP_READ, flags[ioprio_priorities, int16], fd_or_fixed_fd_index, fileoff[int64], const[0, int64], const[0, int32], flags[rwf_flags, int32], sqe_user_data_not_openat, buf_index_personality_misc]
   356  ]
   357  
   358  type io_uring_sqe$write io_uring_sqe[IORING_OP_WRITE, flags[ioprio_priorities, int16], fd_or_fixed_fd_index, fileoff[int64], buffer[in], bytesize[addr, int32], flags[rwf_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   359  type io_uring_sqe$fadvise io_uring_sqe[IORING_OP_FADVISE, const[0, int16], fd_or_fixed_fd_index, fileoff[int64], const[0, int64], int32, flags[fadvise_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   360  type io_uring_sqe$madvise io_uring_sqe[IORING_OP_MADVISE, const[0, int16], const[0, int32], const[0, int64], vma, len[addr, int32], flags[madvise_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   361  type io_uring_sqe$send io_uring_sqe[IORING_OP_SEND, const[0, int16], sock, const[0, int64], buffer[in], len[addr, int32], flags[send_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   362  
   363  iouring_recv_ioprio = IORING_RECVSEND_POLL_FIRST, IORING_RECV_MULTISHOT, IORING_RECVSEND_FIXED_BUF, IORING_RECVSEND_BUNDLE
   364  
   365  io_uring_sqe_recv [
   366  	pass_buffer		io_uring_sqe[IORING_OP_RECV, const[0, int16], sock, const[0, int64], buffer[inout], len[addr, int32], flags[recv_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   367  	use_registered_buffer	io_uring_sqe[IORING_OP_RECV, flags[iouring_recv_ioprio, int16], sock, const[0, int64], const[0, int64], const[0, int32], flags[recv_flags, int32], sqe_user_data_not_openat, buf_group_personality_misc]
   368  ]
   369  
   370  type io_uring_sqe$openat2 io_uring_sqe[IORING_OP_OPENAT2, const[0, int16], fd_dir[opt], ptr[in, open_how], ptr64[in, filename], bytesize[off, int32], const[0, int32], sqe_user_data_openat, personality_only_misc]
   371  type io_uring_sqe$epoll_ctl_t[EPOLL_OP, EPOLL_EVENTS] io_uring_sqe[IORING_OP_EPOLL_CTL, const[0, int16], fd_epoll, EPOLL_EVENTS, fd, const[EPOLL_OP, int32], const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   372  
   373  io_uring_sqe_epoll_ctl [
   374  	add	io_uring_sqe$epoll_ctl_t[EPOLL_CTL_ADD, ptr[in, epoll_event]]
   375  	del	io_uring_sqe$epoll_ctl_t[EPOLL_CTL_DEL, const[0, int64]]
   376  	mod	io_uring_sqe$epoll_ctl_t[EPOLL_CTL_MOD, ptr[in, epoll_event]]
   377  ]
   378  
   379  # IORING_OP_EPOLL_CTL, IORING_OP_SEND, IORING_OP_FALLOCATE, IORING_OP_MADVISE, IORING_OP_FADVISE, IORING_OP_RECV
   380  # IORING_OP_OPENAT, IORING_OP_OPENAT2, IORING_OP_CLOSE, IORING_OP_STATX, IORING_OP_READ, IORING_OP_WRITE >= 5.6
   381  
   382  type io_uring_sqe$splice io_uring_sqe[IORING_OP_SPLICE, const[0, int16], fd_or_fixed_fd_index, fileoff[int64], io_uring_sqe_splice_off_in, int32, flags[splice_flags, int32], sqe_user_data_not_openat, io_uring_sqe_splice_misc]
   383  type io_uring_sqe$provide_buffers io_uring_sqe[IORING_OP_PROVIDE_BUFFERS, const[0, int16], int32, io_uring_bid[int64], buffer[in], int32, const[0, int32], sqe_user_data_not_openat, buf_group_personality_misc]
   384  type io_uring_sqe$remove_buffers io_uring_sqe[IORING_OP_PROVIDE_BUFFERS, const[0, int16], int32, const[0, int64], const[0, int64], const[0, int32], const[0, int32], sqe_user_data_not_openat, buf_group_personality_misc]
   385  # IORING_OP_SPLICE, IORING_OP_PROVIDE_BUFFERS >= 5.7
   386  type io_uring_sqe$tee io_uring_sqe[IORING_OP_TEE, const[0, int16], fd_or_fixed_fd_index, const[0, int64], const[0, int64], int32, flags[splice_flags, int32], sqe_user_data_not_openat, io_uring_sqe_tee_misc]
   387  # IORING_OP_TEE >= 5.8
   388  
   389  type io_uring_sqe$shutdown io_uring_sqe[IORING_OP_SHUTDOWN, const[0, int16], sock, const[0, int64], const[0, int64], flags[shutdown_flags, int32], const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   390  type io_uring_sqe$renameat io_uring_sqe[IORING_OP_RENAMEAT, const[0, int16], fd_dir, ptr64[in, filename], ptr64[in, filename], fd_dir, const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   391  type io_uring_sqe$unlinkat io_uring_sqe[IORING_OP_UNLINKAT, const[0, int16], fd_dir, const[0, int64], ptr64[in, filename], const[0, int32], flags[unlinkat_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   392  # IORING_OP_SHUTDOWN, IORING_OP_RENAMEAT, IORING_OP_UNLINKAT >= 5.11
   393  
   394  type io_uring_sqe$mkdirat io_uring_sqe[IORING_OP_MKDIRAT, const[0, int16], fd_dir, const[0, int64], ptr64[in, filename], flags[open_mode, int32], const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   395  type io_uring_sqe$symlinkat io_uring_sqe[IORING_OP_SYMLINKAT, const[0, int16], fd_dir, ptr64[in, filename], ptr64[in, filename], const[0, int32], const[0, int32], sqe_user_data_not_openat, personality_only_misc]
   396  type io_uring_sqe$linkat io_uring_sqe[IORING_OP_LINKAT, const[0, int16], fd_dir, ptr64[in, filename], ptr64[in, filename], fd_dir, flags[linkat_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   397  # IORING_OP_MKDIRAT, IORING_OP_SYMLINKAT, IORING_OP_LINKAT >= 5.15
   398  
   399  iouring_msg_ring_cmd_flags = IORING_MSG_DATA, IORING_MSG_SEND_FD
   400  msg_ring_flags = IORING_MSG_RING_CQE_SKIP, IORING_MSG_RING_FLAGS_PASS
   401  
   402  type io_uring_sqe$msg_ring io_uring_sqe[IORING_OP_MSG_RING, const[0, int16], fd_io_uring, flags[iouring_msg_ring_cmd_flags, int64], buffer[in], len[addr, int32], flags[msg_ring_flags, int32], sqe_user_data_not_openat, personality_only_misc]
   403  # IORING_OP_MSG_RING >= 5.18
   404  
   405  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
   406  
   407  #
   408  # Flags, enumerations, and misc fields of sqe ops
   409  #
   410  
   411  iosqe_flags = IOSQE_IO_DRAIN, IOSQE_IO_LINK, IOSQE_IO_HARDLINK, IOSQE_ASYNC, IOSQE_BUFFER_SELECT, IOSQE_FIXED_FILE, IOSQE_CQE_SKIP_SUCCESS
   412  # should not use BIT as flags
   413  # IOSQE_IO_DRAIN >= 5.2
   414  # IOSQE_IO_LINK >= 5.3
   415  # IOSQE_IO_HARDLINK >= 5.5
   416  # IOSQE_ASYNC >= 5.6
   417  # IOSQE_BUFFER_SELECT >= 5.7
   418  # IOSQE_FIXED_FILE >= 5.1
   419  # IOSQE_CQE_SKIP_SUCCESS >= 5.17
   420  
   421  fd_or_fixed_fd_index [
   422  	fd		fd
   423  # Use the registered files (io_uring_register$IORING_REGISTER_FILES) when IOSQE_FIXED_FILE_BIT is set in sqe.
   424  # To ease collisions, limit the indices.
   425  	fd_index	int32[0:10]
   426  ]
   427  
   428  # 0 for normal file integrity sync, IORING_FSYNC_DATASYNC to provide data sync only semantics
   429  io_uring_fsync_flags = 0, IORING_FSYNC_DATASYNC
   430  
   431  # 0 for relative, IORING_TIMEOUT_ABS for absolute timeout value
   432  io_uring_timeout_flags = 0, IORING_TIMEOUT_ABS, IORING_TIMEOUT_UPDATE, IORING_TIMEOUT_BOOTTIME, IORING_TIMEOUT_REALTIME, IORING_LINK_TIMEOUT_UPDATE, IORING_TIMEOUT_ETIME_SUCCESS, IORING_TIMEOUT_MULTISHOT, IORING_TIMEOUT_CLOCK_MASK, IORING_TIMEOUT_UPDATE_MASK
   433  
   434  # The timeout condition is met when either the specific timeout expries, or the
   435  # specified number of events have completed. If not set, defaults to 1. Use a
   436  # limited range to allow utilization of this value to meet timeout condition besides
   437  # the timeout expiration.
   438  type io_uring_timeout_completion_event_count int64[0:10]
   439  
   440  # An already issued request can be attempted to be cancelled using ASYNC_CANCEL
   441  # operation. This operation identifies the operations using what's passed as
   442  # with user_data in their sqe. To ease collisions of ASYNC_CANCEL operation with
   443  # already submitted ones, use a limited range of values for user_data field.
   444  # Among all operations that can be achieved by submitting to the io_uring, only
   445  # openat and openat2 returns a useful resource (fd) that we can use for other
   446  # systemcalls. The resulting fds are returned within io_uring_cqe.res. The only way
   447  # to identify cqes for those operations is to keep track of their user data. Thus,
   448  # use a separate set of sqe_user_data range for openat and openat2.
   449  sqe_user_data_not_openat = 0, 1
   450  sqe_user_data_openat = 0x12345, 0x23456
   451  sqe_user_data = 0, 1, 0x12345, 0x23456
   452  
   453  # The buffer id (bid) and the buffer group id (bgid) are registered using
   454  # IORING_OP_PROVIDE_BUFFERS. Use the ids in a limited range to ease collisions
   455  # with other operations.
   456  type io_uring_bid[T] T[0:3]
   457  type io_uring_bgid[T] T[0:3]
   458  
   459  zero_flag = 0
   460  
   461  io_uring_sqe_poll_add_misc_flags {
   462  	misc_flags		flags[pollfd_events, int16]
   463  # 2 bytes of padding to fill what is left from the union of flags
   464  	fill_flags_union	const[0, int16]
   465  }
   466  
   467  io_uring_sqe_splice_off_in {
   468  	splice_off_in_unused	const[0, int32]
   469  	splice_off_in		fd
   470  }
   471  
   472  # Descriptions for MISC field of io_uring_sqe. The content for most are common
   473  # while there are a few specials.
   474  
   475  personality_only_misc {
   476  	buf_index_unused	const[0, int16]
   477  	ioring_personality_id	ioring_personality_id[opt]
   478  	pad_unused		array[const[0, int8], 20]
   479  }
   480  
   481  buf_index_personality_misc {
   482  	buf_index		io_uring_bid[int16]
   483  	ioring_personality_id	ioring_personality_id[opt]
   484  	pad_unused		array[const[0, int8], 20]
   485  }
   486  
   487  buf_group_personality_misc {
   488  	buf_group		io_uring_bgid[int16]
   489  	ioring_personality_id	ioring_personality_id[opt]
   490  	pad_unused		array[const[0, int8], 20]
   491  }
   492  
   493  io_uring_sqe_splice_misc {
   494  	buf_unused		const[0, int16]
   495  	ioring_personality_id	ioring_personality_id[opt]
   496  	splice_fd_in		fd
   497  	pad_unused		array[const[0, int64], 2]
   498  }
   499  
   500  io_uring_sqe_tee_misc {
   501  	buf_unused		const[0, int16]
   502  	ioring_personality_id	ioring_personality_id[opt]
   503  	splice_fd_in		fd
   504  	pad_unused		array[const[0, int64], 2]
   505  }
   506  
   507  io_uring_sync_cancel_reg {
   508  	addr	int64
   509  	fd	fd
   510  	flags	flags[iouring_async_cancel_flags, int32]
   511  	timeout	kernel_timespec
   512  	opcode	int8
   513  	pad	array[const[0, int8], 7]
   514  	pad2	array[const[0, int64], 3]
   515  }
   516  
   517  kernel_timespec {
   518  	tv_sec	int64
   519  	tv_nsec	int64
   520  }
   521  
   522  iouring_async_cancel_flags = IORING_ASYNC_CANCEL_ALL, IORING_ASYNC_CANCEL_FD, IORING_ASYNC_CANCEL_ANY, IORING_ASYNC_CANCEL_FD_FIXED, IORING_ASYNC_CANCEL_USERDATA, IORING_ASYNC_CANCEL_OP
   523  
   524  io_uring_file_index_range {
   525  	off	int32
   526  	len	int32
   527  	resv	int64
   528  }
   529  
   530  io_uring_buf_status {
   531  	buf_group	int32	(in)
   532  	head		int32	(out)
   533  	resv		array[const[0, int32], 8]
   534  }
   535  
   536  io_uring_napi {
   537  	busy_poll_to		int32
   538  	prefer_busy_poll	int8
   539  	pad			array[const[0, int8], 3]
   540  	resv			const[0, int64]
   541  }
   542  
   543  io_uring_clock_register {
   544  	clockid	flags[clock_type, int32]
   545  	resv	array[const[0, int32], 3]
   546  }
   547  
   548  io_uring_clone_buffers {
   549  	src_fd	fd
   550  	flags	const[1, int32]
   551  	pad	array[const[0, int32], 6]
   552  }
   553  
   554  io_uring_mem_region_reg {
   555  	region_uptr	ptr64[inout, io_uring_region_desc]
   556  	flags		flags[io_uring_region_flags, int64]
   557  	resv		array[const[0, int64], 2]
   558  }
   559  
   560  io_uring_region_flags = IORING_MEM_REGION_REG_WAIT_ARG
   561  
   562  io_uring_region_desc {
   563  	user_addr	ptr64[inout, array[int8]]
   564  	size		len[user_addr, int64]
   565  	flags		flags[io_uring_region_desc_flags, int32]
   566  	id		int32
   567  	mmap_offset	int64
   568  	resv		array[const[0, int64], 4]
   569  }
   570  
   571  io_uring_region_desc_flags = IORING_MEM_REGION_TYPE_USER