summaryrefslogtreecommitdiffstats
path: root/io_uring
diff options
context:
space:
mode:
authorGabriel Krisman Bertazi <krisman@suse.de>2023-10-04 20:05:30 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-11-20 11:59:11 +0100
commit464848643e999c964051600bc479527e2a25200e (patch)
tree6726d65d7dd8464a620c30e4da99d63329d39419 /io_uring
parentde92bc45c00b0fdde5c261e91e67c38e2d045b07 (diff)
downloadlinux-stable-464848643e999c964051600bc479527e2a25200e.tar.gz
linux-stable-464848643e999c964051600bc479527e2a25200e.tar.bz2
linux-stable-464848643e999c964051600bc479527e2a25200e.zip
io_uring/kbuf: Allow the full buffer id space for provided buffers
[ Upstream commit f74c746e476b9dad51448b9a9421aae72b60e25f ] nbufs tracks the number of buffers and not the last bgid. In 16-bit, we have 2^16 valid buffers, but the check mistakenly rejects the last bid. Let's fix it to make the interface consistent with the documentation. Fixes: ddf0322db79c ("io_uring: add IORING_OP_PROVIDE_BUFFERS") Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> Link: https://lore.kernel.org/r/20231005000531.30800-3-krisman@suse.de Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'io_uring')
-rw-r--r--io_uring/kbuf.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
index 74a4f9600642..f6e5ae026e4b 100644
--- a/io_uring/kbuf.c
+++ b/io_uring/kbuf.c
@@ -19,12 +19,15 @@
#define BGID_ARRAY 64
+/* BIDs are addressed by a 16-bit field in a CQE */
+#define MAX_BIDS_PER_BGID (1 << 16)
+
struct io_provide_buf {
struct file *file;
__u64 addr;
__u32 len;
__u32 bgid;
- __u16 nbufs;
+ __u32 nbufs;
__u16 bid;
};
@@ -289,7 +292,7 @@ int io_remove_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
return -EINVAL;
tmp = READ_ONCE(sqe->fd);
- if (!tmp || tmp > USHRT_MAX)
+ if (!tmp || tmp > MAX_BIDS_PER_BGID)
return -EINVAL;
memset(p, 0, sizeof(*p));
@@ -332,7 +335,7 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
return -EINVAL;
tmp = READ_ONCE(sqe->fd);
- if (!tmp || tmp > USHRT_MAX)
+ if (!tmp || tmp > MAX_BIDS_PER_BGID)
return -E2BIG;
p->nbufs = tmp;
p->addr = READ_ONCE(sqe->addr);
@@ -352,7 +355,7 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
tmp = READ_ONCE(sqe->off);
if (tmp > USHRT_MAX)
return -E2BIG;
- if (tmp + p->nbufs > USHRT_MAX)
+ if (tmp + p->nbufs > MAX_BIDS_PER_BGID)
return -EINVAL;
p->bid = tmp;
return 0;