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.

Merge tag 'io_uring-6.6-2023-10-06' of git://git.kernel.dk/linux

Pull io_uring fixes from Jens Axboe:

- syzbot report on a crash on 32-bit arm with highmem, and went digging
to check for potentially similar issues and found one more (me)

- Fix a syzbot report with PROVE_LOCKING=y and setting up the ring in a
disabled state (me)

- Fix for race with CPU hotplut and io-wq init (Jeff)

* tag 'io_uring-6.6-2023-10-06' of git://git.kernel.dk/linux:
io-wq: fully initialize wqe before calling cpuhp_state_add_instance_nocalls()
io_uring: don't allow IORING_SETUP_NO_MMAP rings on highmem pages
io_uring: ensure io_lockdep_assert_cq_locked() handles disabled rings
io_uring/kbuf: don't allow registered buffer rings on highmem pages

+65 -29
+4 -6
io_uring/io-wq.c
··· 1151 1151 wq = kzalloc(sizeof(struct io_wq), GFP_KERNEL); 1152 1152 if (!wq) 1153 1153 return ERR_PTR(-ENOMEM); 1154 - ret = cpuhp_state_add_instance_nocalls(io_wq_online, &wq->cpuhp_node); 1155 - if (ret) 1156 - goto err_wq; 1157 1154 1158 1155 refcount_inc(&data->hash->refs); 1159 1156 wq->hash = data->hash; ··· 1183 1186 wq->task = get_task_struct(data->task); 1184 1187 atomic_set(&wq->worker_refs, 1); 1185 1188 init_completion(&wq->worker_done); 1189 + ret = cpuhp_state_add_instance_nocalls(io_wq_online, &wq->cpuhp_node); 1190 + if (ret) 1191 + goto err; 1192 + 1186 1193 return wq; 1187 1194 err: 1188 1195 io_wq_put_hash(data->hash); 1189 - cpuhp_state_remove_instance_nocalls(io_wq_online, &wq->cpuhp_node); 1190 - 1191 1196 free_cpumask_var(wq->cpu_mask); 1192 - err_wq: 1193 1197 kfree(wq); 1194 1198 return ERR_PTR(ret); 1195 1199 }
+15 -1
io_uring/io_uring.c
··· 2686 2686 { 2687 2687 struct page **page_array; 2688 2688 unsigned int nr_pages; 2689 - int ret; 2689 + int ret, i; 2690 2690 2691 2691 *npages = 0; 2692 2692 ··· 2716 2716 */ 2717 2717 if (page_array[0] != page_array[ret - 1]) 2718 2718 goto err; 2719 + 2720 + /* 2721 + * Can't support mapping user allocated ring memory on 32-bit archs 2722 + * where it could potentially reside in highmem. Just fail those with 2723 + * -EINVAL, just like we did on kernels that didn't support this 2724 + * feature. 2725 + */ 2726 + for (i = 0; i < nr_pages; i++) { 2727 + if (PageHighMem(page_array[i])) { 2728 + ret = -EINVAL; 2729 + goto err; 2730 + } 2731 + } 2732 + 2719 2733 *pages = page_array; 2720 2734 *npages = nr_pages; 2721 2735 return page_to_virt(page_array[0]);
+27 -14
io_uring/io_uring.h
··· 86 86 bool io_match_task_safe(struct io_kiocb *head, struct task_struct *task, 87 87 bool cancel_all); 88 88 89 - #define io_lockdep_assert_cq_locked(ctx) \ 90 - do { \ 91 - lockdep_assert(in_task()); \ 92 - \ 93 - if (ctx->flags & IORING_SETUP_IOPOLL) { \ 94 - lockdep_assert_held(&ctx->uring_lock); \ 95 - } else if (!ctx->task_complete) { \ 96 - lockdep_assert_held(&ctx->completion_lock); \ 97 - } else if (ctx->submitter_task->flags & PF_EXITING) { \ 98 - lockdep_assert(current_work()); \ 99 - } else { \ 100 - lockdep_assert(current == ctx->submitter_task); \ 101 - } \ 102 - } while (0) 89 + #if defined(CONFIG_PROVE_LOCKING) 90 + static inline void io_lockdep_assert_cq_locked(struct io_ring_ctx *ctx) 91 + { 92 + lockdep_assert(in_task()); 93 + 94 + if (ctx->flags & IORING_SETUP_IOPOLL) { 95 + lockdep_assert_held(&ctx->uring_lock); 96 + } else if (!ctx->task_complete) { 97 + lockdep_assert_held(&ctx->completion_lock); 98 + } else if (ctx->submitter_task) { 99 + /* 100 + * ->submitter_task may be NULL and we can still post a CQE, 101 + * if the ring has been setup with IORING_SETUP_R_DISABLED. 102 + * Not from an SQE, as those cannot be submitted, but via 103 + * updating tagged resources. 104 + */ 105 + if (ctx->submitter_task->flags & PF_EXITING) 106 + lockdep_assert(current_work()); 107 + else 108 + lockdep_assert(current == ctx->submitter_task); 109 + } 110 + } 111 + #else 112 + static inline void io_lockdep_assert_cq_locked(struct io_ring_ctx *ctx) 113 + { 114 + } 115 + #endif 103 116 104 117 static inline void io_req_task_work_add(struct io_kiocb *req) 105 118 {
+19 -8
io_uring/kbuf.c
··· 477 477 { 478 478 struct io_uring_buf_ring *br; 479 479 struct page **pages; 480 - int nr_pages; 480 + int i, nr_pages; 481 481 482 482 pages = io_pin_pages(reg->ring_addr, 483 483 flex_array_size(br, bufs, reg->ring_entries), 484 484 &nr_pages); 485 485 if (IS_ERR(pages)) 486 486 return PTR_ERR(pages); 487 + 488 + /* 489 + * Apparently some 32-bit boxes (ARM) will return highmem pages, 490 + * which then need to be mapped. We could support that, but it'd 491 + * complicate the code and slowdown the common cases quite a bit. 492 + * So just error out, returning -EINVAL just like we did on kernels 493 + * that didn't support mapped buffer rings. 494 + */ 495 + for (i = 0; i < nr_pages; i++) 496 + if (PageHighMem(pages[i])) 497 + goto error_unpin; 487 498 488 499 br = page_address(pages[0]); 489 500 #ifdef SHM_COLOUR ··· 507 496 * should use IOU_PBUF_RING_MMAP instead, and liburing will handle 508 497 * this transparently. 509 498 */ 510 - if ((reg->ring_addr | (unsigned long) br) & (SHM_COLOUR - 1)) { 511 - int i; 512 - 513 - for (i = 0; i < nr_pages; i++) 514 - unpin_user_page(pages[i]); 515 - return -EINVAL; 516 - } 499 + if ((reg->ring_addr | (unsigned long) br) & (SHM_COLOUR - 1)) 500 + goto error_unpin; 517 501 #endif 518 502 bl->buf_pages = pages; 519 503 bl->buf_nr_pages = nr_pages; ··· 516 510 bl->is_mapped = 1; 517 511 bl->is_mmap = 0; 518 512 return 0; 513 + error_unpin: 514 + for (i = 0; i < nr_pages; i++) 515 + unpin_user_page(pages[i]); 516 + kvfree(pages); 517 + return -EINVAL; 519 518 } 520 519 521 520 static int io_alloc_pbuf_ring(struct io_uring_buf_reg *reg,