diff options
author | Pavel Begunkov <asml.silence@gmail.com> | 2025-06-24 14:40:34 +0100 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2025-06-24 20:50:59 -0600 |
commit | 3a3c6d61577dbb23c09df3e21f6f9eda1ecd634b (patch) | |
tree | a06519191c7d9638f3f55a46f9f57dc9eac58df8 | |
parent | 5afb4bf9fc62d828647647ec31745083637132e4 (diff) |
io_uring/rsrc: don't rely on user vaddr alignment
There is no guaranteed alignment for user pointers, however the
calculation of an offset of the first page into a folio after coalescing
uses some weird bit mask logic, get rid of it.
Cc: stable@vger.kernel.org
Reported-by: David Hildenbrand <david@redhat.com>
Fixes: a8edbb424b139 ("io_uring/rsrc: enable multi-hugepage buffer coalescing")
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/io-uring/e387b4c78b33f231105a601d84eefd8301f57954.1750771718.git.asml.silence@gmail.com/
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | io_uring/rsrc.c | 7 | ||||
-rw-r--r-- | io_uring/rsrc.h | 1 |
2 files changed, 7 insertions, 1 deletions
diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index 0c09e38784c9..afc67530f912 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -734,6 +734,7 @@ bool io_check_coalesce_buffer(struct page **page_array, int nr_pages, data->nr_pages_mid = folio_nr_pages(folio); data->folio_shift = folio_shift(folio); + data->first_folio_page_idx = folio_page_idx(folio, page_array[0]); /* * Check if pages are contiguous inside a folio, and all folios have @@ -827,7 +828,11 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx, if (coalesced) imu->folio_shift = data.folio_shift; refcount_set(&imu->refs, 1); - off = (unsigned long) iov->iov_base & ((1UL << imu->folio_shift) - 1); + + off = (unsigned long)iov->iov_base & ~PAGE_MASK; + if (coalesced) + off += data.first_folio_page_idx << PAGE_SHIFT; + node->buf = imu; ret = 0; diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index 0d2138f16322..25e7e998dcfd 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -49,6 +49,7 @@ struct io_imu_folio_data { unsigned int nr_pages_mid; unsigned int folio_shift; unsigned int nr_folios; + unsigned long first_folio_page_idx; }; bool io_rsrc_cache_init(struct io_ring_ctx *ctx); |