diff options
| author | Pavel Begunkov <asml.silence@gmail.com> | 2025-06-24 14:40:34 +0100 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-07-06 11:01:47 +0200 |
| commit | 50998b0ae7d9d552e96d8b7239981cf05f65eff5 (patch) | |
| tree | 4d525db2f52cf825c02ab52e643202772830e376 /io_uring | |
| parent | 53fd75f25b223878b5fff14932e3a22f42b54f77 (diff) | |
| download | linux-50998b0ae7d9d552e96d8b7239981cf05f65eff5.tar.gz linux-50998b0ae7d9d552e96d8b7239981cf05f65eff5.tar.bz2 linux-50998b0ae7d9d552e96d8b7239981cf05f65eff5.zip | |
io_uring/rsrc: don't rely on user vaddr alignment
Commit 3a3c6d61577dbb23c09df3e21f6f9eda1ecd634b upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'io_uring')
| -rw-r--r-- | io_uring/rsrc.c | 5 | ||||
| -rw-r--r-- | io_uring/rsrc.h | 1 |
2 files changed, 5 insertions, 1 deletions
diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index 1380fe8bf7c8..1687e35e21c9 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -918,6 +918,7 @@ static bool io_try_coalesce_buffer(struct page ***pages, int *nr_pages, return false; 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 * the same page count except for the head and tail. @@ -998,7 +999,9 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, struct iovec *iov, 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; *pimu = imu; ret = 0; diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index 8ed588036210..459cf4c6e856 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -56,6 +56,7 @@ struct io_imu_folio_data { /* For non-head/tail folios, has to be fully included */ unsigned int nr_pages_mid; unsigned int folio_shift; + unsigned long first_folio_page_idx; }; void io_rsrc_node_ref_zero(struct io_rsrc_node *node); |
