Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

io_uring/mock: add cmd using vectored regbufs

There is a command api allowing to import vectored registered buffers,
add a new mock command that uses the feature and simply copies the
specified registered buffer into user space or vice versa.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/229a113fd7de6b27dbef9567f7c0bf4475c9017d.1750599274.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Pavel Begunkov and committed by
Jens Axboe
4aac001f 3a0ae385

+83 -1
+14
include/uapi/linux/io_uring/mock_file.h
··· 3 3 4 4 #include <linux/types.h> 5 5 6 + enum { 7 + IORING_MOCK_FEAT_CMD_COPY, 8 + 9 + IORING_MOCK_FEAT_END, 10 + }; 11 + 6 12 struct io_uring_mock_probe { 7 13 __u64 features; 8 14 __u64 __resv[9]; ··· 23 17 enum { 24 18 IORING_MOCK_MGR_CMD_PROBE, 25 19 IORING_MOCK_MGR_CMD_CREATE, 20 + }; 21 + 22 + enum { 23 + IORING_MOCK_CMD_COPY_REGBUF, 24 + }; 25 + 26 + enum { 27 + IORING_MOCK_COPY_FROM = 1, 26 28 }; 27 29 28 30 #endif
+69 -1
io_uring/mock_file.c
··· 9 9 #include <linux/io_uring_types.h> 10 10 #include <uapi/linux/io_uring/mock_file.h> 11 11 12 + #define IO_VALID_COPY_CMD_FLAGS IORING_MOCK_COPY_FROM 13 + 14 + static int io_copy_regbuf(struct iov_iter *reg_iter, void __user *ubuf) 15 + { 16 + size_t ret, copied = 0; 17 + size_t buflen = PAGE_SIZE; 18 + void *tmp_buf; 19 + 20 + tmp_buf = kzalloc(buflen, GFP_KERNEL); 21 + if (!tmp_buf) 22 + return -ENOMEM; 23 + 24 + while (iov_iter_count(reg_iter)) { 25 + size_t len = min(iov_iter_count(reg_iter), buflen); 26 + 27 + if (iov_iter_rw(reg_iter) == ITER_SOURCE) { 28 + ret = copy_from_iter(tmp_buf, len, reg_iter); 29 + if (ret <= 0) 30 + break; 31 + if (copy_to_user(ubuf, tmp_buf, ret)) 32 + break; 33 + } else { 34 + if (copy_from_user(tmp_buf, ubuf, len)) 35 + break; 36 + ret = copy_to_iter(tmp_buf, len, reg_iter); 37 + if (ret <= 0) 38 + break; 39 + } 40 + ubuf += ret; 41 + copied += ret; 42 + } 43 + 44 + kfree(tmp_buf); 45 + return copied; 46 + } 47 + 48 + static int io_cmd_copy_regbuf(struct io_uring_cmd *cmd, unsigned int issue_flags) 49 + { 50 + const struct io_uring_sqe *sqe = cmd->sqe; 51 + const struct iovec __user *iovec; 52 + unsigned flags, iovec_len; 53 + struct iov_iter iter; 54 + void __user *ubuf; 55 + int dir, ret; 56 + 57 + ubuf = u64_to_user_ptr(READ_ONCE(sqe->addr3)); 58 + iovec = u64_to_user_ptr(READ_ONCE(sqe->addr)); 59 + iovec_len = READ_ONCE(sqe->len); 60 + flags = READ_ONCE(sqe->file_index); 61 + 62 + if (unlikely(sqe->ioprio || sqe->__pad1)) 63 + return -EINVAL; 64 + if (flags & ~IO_VALID_COPY_CMD_FLAGS) 65 + return -EINVAL; 66 + 67 + dir = (flags & IORING_MOCK_COPY_FROM) ? ITER_SOURCE : ITER_DEST; 68 + ret = io_uring_cmd_import_fixed_vec(cmd, iovec, iovec_len, dir, &iter, 69 + issue_flags); 70 + if (ret) 71 + return ret; 72 + ret = io_copy_regbuf(&iter, ubuf); 73 + return ret ? ret : -EFAULT; 74 + } 75 + 12 76 static int io_mock_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) 13 77 { 78 + switch (cmd->cmd_op) { 79 + case IORING_MOCK_CMD_COPY_REGBUF: 80 + return io_cmd_copy_regbuf(cmd, issue_flags); 81 + } 14 82 return -ENOTSUPP; 15 83 } 16 84 ··· 159 91 if (!mem_is_zero(&mp, sizeof(mp))) 160 92 return -EINVAL; 161 93 162 - mp.features = 0; 94 + mp.features = IORING_MOCK_FEAT_END; 163 95 164 96 if (copy_to_user(uarg, &mp, uarg_size)) 165 97 return -EFAULT;