Some io_uring operations' SQEs store user_data values in the addr2 field. These don't need to be modified as they're not dereferenced by the kernel.
Reported-by: Kevin Brodsky kevin.brodsky@arm.com Signed-off-by: Tudor Cretu tudor.cretu@arm.com --- v2: - Updated the comment that it's only propagated, not matched.
Review branch: https://git.morello-project.org/tudcre01/linux/-/commits/morello/addr2_fix_v... --- io_uring/io_uring.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h index 5b4f0f298ad9..26cfe280b049 100644 --- a/io_uring/io_uring.h +++ b/io_uring/io_uring.h @@ -132,9 +132,22 @@ static inline void convert_compat64_io_uring_sqe(struct io_ring_ctx *ctx, sqe->ioprio = READ_ONCE(compat_sqe->ioprio); sqe->fd = READ_ONCE(compat_sqe->fd); BUILD_BUG_COMPAT_SQE_UNION_ELEM(addr2, addr); - sqe->addr2 = (__kernel_uintptr_t)compat_ptr(READ_ONCE(compat_sqe->addr2)); - BUILD_BUG_COMPAT_SQE_UNION_ELEM(addr, len); + /* + * Some opcodes set a user_data value in the addr2 field to propagate + * it as-is to the user_data field of a CQE. It's not dereferenced + * by the kernel, so don't modify it. + */ + switch (sqe->opcode) { + case IORING_OP_POLL_REMOVE: + case IORING_OP_MSG_RING: + sqe->addr2 = (__kernel_uintptr_t)READ_ONCE(compat_sqe->addr2); + break; + default: + sqe->addr2 = (__kernel_uintptr_t)compat_ptr(READ_ONCE(compat_sqe->addr2)); + break; + }
+ BUILD_BUG_COMPAT_SQE_UNION_ELEM(addr, len); /* * Some opcodes set a user_data value in the addr field to be matched * with a pre-existing IO event's user_data. It's not dereferenced by