Commit 4a2f704e authored by Ming Lei's avatar Ming Lei Committed by Jens Axboe

block: fix get_max_segment_size() overflow on 32bit arch

Commit 429120f3 starts to take account of segment's start dma address
when computing max segment size, and data type of 'unsigned long'
is used to do that. However, the segment mask may be 0xffffffff, so
the figured out segment size may be overflowed in case of zero physical
address on 32bit arch.

Fix the issue by returning queue_max_segment_size() directly when that
happens.

Fixes: 429120f3 ("block: fix splitting segments on boundary masks")
Reported-by: default avatarGuenter Roeck <linux@roeck-us.net>
Tested-by: default avatarGuenter Roeck <linux@roeck-us.net>
Cc: Christoph Hellwig <hch@lst.de>
Tested-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: default avatarMing Lei <ming.lei@redhat.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent e17016f6
...@@ -164,8 +164,13 @@ static inline unsigned get_max_segment_size(const struct request_queue *q, ...@@ -164,8 +164,13 @@ static inline unsigned get_max_segment_size(const struct request_queue *q,
unsigned long mask = queue_segment_boundary(q); unsigned long mask = queue_segment_boundary(q);
offset = mask & (page_to_phys(start_page) + offset); offset = mask & (page_to_phys(start_page) + offset);
return min_t(unsigned long, mask - offset + 1,
queue_max_segment_size(q)); /*
* overflow may be triggered in case of zero page physical address
* on 32bit arch, use queue's max segment size when that happens.
*/
return min_not_zero(mask - offset + 1,
(unsigned long)queue_max_segment_size(q));
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment