| @@ -7118,7 +7118,8 @@ static int io_run_task_work_sig(void) · 7117 unmodified lines |
| 7118 | * application must reap them itself, as they reside on the shared cq ring. | 7118 | * application must reap them itself, as they reside on the shared cq ring. |
| 7119 | */ | 7119 | */ |
| 7120 | static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, | 7120 | static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, |
| 7121 | const sigset_t __user *sig, size_t sigsz) | 7121 | const sigset_t __user *sig, size_t sigsz, |
| | 7122 | struct __kernel_timespec __user *uts) |
| 7122 | { | 7123 | { |
| 7123 | struct io_wait_queue iowq = { | 7124 | struct io_wait_queue iowq = { |
| 7124 | .wq = { | 7125 | .wq = { |
| @@ -7130,6 +7131,8 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, · 5 unmodified lines |
| 7130 | .to_wait = min_events, | 7131 | .to_wait = min_events, |
| 7131 | }; | 7132 | }; |
| 7132 | struct io_rings *rings = ctx->rings; | 7133 | struct io_rings *rings = ctx->rings; |
| | 7134 | struct timespec64 ts; |
| | 7135 | signed long timeout = 0; |
| 7133 | int ret = 0; | 7136 | int ret = 0; |
| 7134 | | 7137 | |
| 7135 | do { | 7138 | do { |
| @@ -7152,6 +7155,12 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, · 16 unmodified lines |
| 7152 | return ret; | 7155 | return ret; |
| 7153 | } | 7156 | } |
| 7154 | | 7157 | |
| | 7158 | if (uts) { |
| | 7159 | if (get_timespec64(&ts, uts)) |
| | 7160 | return -EFAULT; |
| | 7161 | timeout = timespec64_to_jiffies(&ts); |
| | 7162 | } |
| | 7163 | |
| 7155 | iowq.nr_timeouts = atomic_read(&ctx->cq_timeouts); | 7164 | iowq.nr_timeouts = atomic_read(&ctx->cq_timeouts); |
| 7156 | trace_io_uring_cqring_wait(ctx, min_events); | 7165 | trace_io_uring_cqring_wait(ctx, min_events); |
| 7157 | do { | 7166 | do { |
| @@ -7165,7 +7174,15 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, · 7 unmodified lines |
| 7165 | break; | 7174 | break; |
| 7166 | if (io_should_wake(&iowq, false)) | 7175 | if (io_should_wake(&iowq, false)) |
| 7167 | break; | 7176 | break; |
| 7168 | schedule(); | 7177 | if (uts) { |
| | 7178 | timeout = schedule_timeout(timeout); |
| | 7179 | if (timeout == 0) { |
| | 7180 | ret = -ETIME; |
| | 7181 | break; |
| | 7182 | } |
| | 7183 | } else { |
| | 7184 | schedule(); |
| | 7185 | } |
| 7169 | } while (1); | 7186 | } while (1); |
| 7170 | finish_wait(&ctx->wait, &iowq.wq); | 7187 | finish_wait(&ctx->wait, &iowq.wq); |
| 7171 | | 7188 | |
| @@ -9167,9 +9184,39 @@ static void io_sqpoll_wait_sq(struct io_ring_ctx *ctx) · 1995 unmodified lines |
| 9167 | finish_wait(&ctx->sqo_sq_wait, &wait); | 9184 | finish_wait(&ctx->sqo_sq_wait, &wait); |
| 9168 | } | 9185 | } |
| 9169 | | 9186 | |
| | 9187 | static int io_get_ext_arg(unsigned flags, const void __user *argp, size_t *argsz, |
| | 9188 | struct __kernel_timespec __user **ts, |
| | 9189 | const sigset_t __user **sig) |
| | 9190 | { |
| | 9191 | struct io_uring_getevents_arg arg; |
| | 9192 | |
| | 9193 | /* |
| | 9194 | * If EXT_ARG isn't set, then we have no timespec and the argp pointer |
| | 9195 | * is just a pointer to the sigset_t. |
| | 9196 | */ |
| | 9197 | if (!(flags & IORING_ENTER_EXT_ARG)) { |
| | 9198 | *sig = (const sigset_t __user *) argp; |
| | 9199 | *ts = NULL; |
| | 9200 | return 0; |
| | 9201 | } |
| | 9202 | |
| | 9203 | /* |
| | 9204 | * EXT_ARG is set - ensure we agree on the size of it and copy in our |
| | 9205 | * timespec and sigset_t pointers if good. |
| | 9206 | */ |
| | 9207 | if (*argsz != sizeof(arg)) |
| | 9208 | return -EINVAL; |
| | 9209 | if (copy_from_user(&arg, argp, sizeof(arg))) |
| | 9210 | return -EFAULT; |
| | 9211 | *sig = u64_to_user_ptr(arg.sigmask); |
| | 9212 | *argsz = arg.sigmask_sz; |
| | 9213 | *ts = u64_to_user_ptr(arg.ts); |
| | 9214 | return 0; |
| | 9215 | } |
| | 9216 | |
| 9170 | SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit, | 9217 | SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit, |
| 9171 | u32, min_complete, u32, flags, const sigset_t __user *, sig, | 9218 | u32, min_complete, u32, flags, const void __user *, argp, |
| 9172 | size_t, sigsz) | 9219 | size_t, argsz) |
| 9173 | { | 9220 | { |
| 9174 | struct io_ring_ctx *ctx; | 9221 | struct io_ring_ctx *ctx; |
| 9175 | long ret = -EBADF; | 9222 | long ret = -EBADF; |
| @@ -9179,7 +9226,7 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit, · 3 unmodified lines |
| 9179 | io_run_task_work(); | 9226 | io_run_task_work(); |
| 9180 | | 9227 | |
| 9181 | if (flags & ~(IORING_ENTER_GETEVENTS | IORING_ENTER_SQ_WAKEUP | | 9228 | if (flags & ~(IORING_ENTER_GETEVENTS | IORING_ENTER_SQ_WAKEUP | |
| 9182 | IORING_ENTER_SQ_WAIT)) | 9229 | IORING_ENTER_SQ_WAIT | IORING_ENTER_EXT_ARG)) |
| 9183 | return -EINVAL; | 9230 | return -EINVAL; |
| 9184 | | 9231 | |
| 9185 | f = fdget(fd); | 9232 | f = fdget(fd); |
| @@ -9225,6 +9272,13 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit, · 39 unmodified lines |
| 9225 | goto out; | 9272 | goto out; |
| 9226 | } | 9273 | } |
| 9227 | if (flags & IORING_ENTER_GETEVENTS) { | 9274 | if (flags & IORING_ENTER_GETEVENTS) { |
| | 9275 | const sigset_t __user *sig; |
| | 9276 | struct __kernel_timespec __user *ts; |
| | 9277 | |
| | 9278 | ret = io_get_ext_arg(flags, argp, &argsz, &ts, &sig); |
| | 9279 | if (unlikely(ret)) |
| | 9280 | goto out; |
| | 9281 | |
| 9228 | min_complete = min(min_complete, ctx->cq_entries); | 9282 | min_complete = min(min_complete, ctx->cq_entries); |
| 9229 | | 9283 | |
| 9230 | /* | 9284 | /* |
| @@ -9237,7 +9291,7 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit, · 6 unmodified lines |
| 9237 | !(ctx->flags & IORING_SETUP_SQPOLL)) { | 9291 | !(ctx->flags & IORING_SETUP_SQPOLL)) { |
| 9238 | ret = io_iopoll_check(ctx, min_complete); | 9292 | ret = io_iopoll_check(ctx, min_complete); |
| 9239 | } else { | 9293 | } else { |
| 9240 | ret = io_cqring_wait(ctx, min_complete, sig, sigsz); | 9294 | ret = io_cqring_wait(ctx, min_complete, sig, argsz, ts); |
| 9241 | } | 9295 | } |
| 9242 | } | 9296 | } |
| 9243 | | 9297 | |
| @@ -9600,7 +9654,8 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p, · 356 unmodified lines |
| 9600 | p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP | | 9654 | p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP | |
| 9601 | IORING_FEAT_SUBMIT_STABLE | IORING_FEAT_RW_CUR_POS | | 9655 | IORING_FEAT_SUBMIT_STABLE | IORING_FEAT_RW_CUR_POS | |
| 9602 | IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL | | 9656 | IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL | |
| 9603 | IORING_FEAT_POLL_32BITS | IORING_FEAT_SQPOLL_NONFIXED; | 9657 | IORING_FEAT_POLL_32BITS | IORING_FEAT_SQPOLL_NONFIXED | |
| | 9658 | IORING_FEAT_EXT_ARG; |
| 9604 | | 9659 | |
| 9605 | if (copy_to_user(params, p, sizeof(*p))) { | 9660 | if (copy_to_user(params, p, sizeof(*p))) { |
| 9606 | ret = -EFAULT; | 9661 | ret = -EFAULT; |