aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAKASHI Takahiro <takahiro.akashi@linaro.org>2023-11-15 10:53:45 +0900
committerTom Rini <trini@konsulko.com>2023-11-29 09:32:15 -0500
commit654580eee13bc7a0d4ed4cad2b2fead1ec88107a (patch)
tree127e6348b9e08386d2c16d1bff568043b87cc595 /drivers
parentd6d8078cb3604b60a579eb700ef8151d2b2b25fa (diff)
downloadu-boot-654580eee13bc7a0d4ed4cad2b2fead1ec88107a.zip
u-boot-654580eee13bc7a0d4ed4cad2b2fead1ec88107a.tar.gz
u-boot-654580eee13bc7a0d4ed4cad2b2fead1ec88107a.tar.bz2
xen: pvblock: fix the maximum io size in one operation
The current implementation may cause BUG_ON() in blkfront_aio() BUG_ON(n > BLKIF_MAX_SEGMENTS_PER_REQUEST); In pvblock_iop(), a read/write operation will be split into smaller chunks of data so that the size in one access (aio_nbytes) is limited to, at the maximum, BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE But this works only if when the *buffer* passed in to pvblock_io() is page-aligned. If not, the given data region may stand across (BLKIF_MAX_SEGMENTS_PER_REQUEST + 1) pages. See the logic in blkfront_aio(): start = (uintptr_t)aiocbp->aio_buf & PAGE_MASK; end = ((uintptr_t)aiocbp->aio_buf + aiocbp->aio_nbytes + PAGE_SIZE - 1) & PAGE_MASK; Then this will lead to BUG_ON() above. This can be fixed by decreasing the maximum size of aio_nbytes. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Fixes: commit 3a739cc6c948 ("xen: pvblock: Implement front-back protocol and do IO")
Diffstat (limited to 'drivers')
-rw-r--r--drivers/xen/pvblock.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/xen/pvblock.c b/drivers/xen/pvblock.c
index 4ad548d..1df04e2 100644
--- a/drivers/xen/pvblock.c
+++ b/drivers/xen/pvblock.c
@@ -632,7 +632,8 @@ static ulong pvblock_iop(struct udevice *udev, lbaint_t blknr,
memcpy(blk_dev->bounce_buffer, buffer, desc->blksz);
aiocb.aio_nbytes = unaligned ? desc->blksz :
- min((size_t)(BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE),
+ min((size_t)((BLKIF_MAX_SEGMENTS_PER_REQUEST - 1)
+ * PAGE_SIZE),
(size_t)(blocks_todo * desc->blksz));
blkfront_io(&aiocb, write);