diff options
author | Joerg Roedel <jroedel@suse.de> | 2023-10-26 17:05:58 +0200 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2023-10-26 17:05:58 +0200 |
commit | 3613047280ec42a4e1350fdc1a6dd161ff4008cc (patch) | |
tree | 6cf2f03f518537f3229e6066a8b2638755f0bb48 /io_uring/io_uring.c | |
parent | bbc70e0aec287e164344b1a071bd46466a4f29b3 (diff) | |
parent | 05d3ef8bba77c1b5f98d941d8b2d4aeab8118ef1 (diff) |
Merge tag 'v6.6-rc7' into core
Linux 6.6-rc7
Diffstat (limited to 'io_uring/io_uring.c')
-rw-r--r-- | io_uring/io_uring.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 783ed0fff71b..8d1bc6cdfe71 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -2674,7 +2674,11 @@ static void io_pages_free(struct page ***pages, int npages) if (!pages) return; + page_array = *pages; + if (!page_array) + return; + for (i = 0; i < npages; i++) unpin_user_page(page_array[i]); kvfree(page_array); @@ -2686,7 +2690,7 @@ static void *__io_uaddr_map(struct page ***pages, unsigned short *npages, { struct page **page_array; unsigned int nr_pages; - int ret; + int ret, i; *npages = 0; @@ -2716,6 +2720,20 @@ err: */ if (page_array[0] != page_array[ret - 1]) goto err; + + /* + * Can't support mapping user allocated ring memory on 32-bit archs + * where it could potentially reside in highmem. Just fail those with + * -EINVAL, just like we did on kernels that didn't support this + * feature. + */ + for (i = 0; i < nr_pages; i++) { + if (PageHighMem(page_array[i])) { + ret = -EINVAL; + goto err; + } + } + *pages = page_array; *npages = nr_pages; return page_to_virt(page_array[0]); @@ -2744,7 +2762,9 @@ static void io_rings_free(struct io_ring_ctx *ctx) ctx->sq_sqes = NULL; } else { io_pages_free(&ctx->ring_pages, ctx->n_ring_pages); + ctx->n_ring_pages = 0; io_pages_free(&ctx->sqe_pages, ctx->n_sqe_pages); + ctx->n_sqe_pages = 0; } } |