Skip to content

Commit 4a2f704

Browse files
Ming Leiaxboe
authored andcommitted
block: fix get_max_segment_size() overflow on 32bit arch
Commit 429120f 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: 429120f ("block: fix splitting segments on boundary masks") Reported-by: Guenter Roeck <[email protected]> Tested-by: Guenter Roeck <[email protected]> Cc: Christoph Hellwig <[email protected]> Tested-by: Steven Rostedt (VMware) <[email protected]> Signed-off-by: Ming Lei <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent e17016f commit 4a2f704

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

block/blk-merge.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,13 @@ static inline unsigned get_max_segment_size(const struct request_queue *q,
164164
unsigned long mask = queue_segment_boundary(q);
165165

166166
offset = mask & (page_to_phys(start_page) + offset);
167-
return min_t(unsigned long, mask - offset + 1,
168-
queue_max_segment_size(q));
167+
168+
/*
169+
* overflow may be triggered in case of zero page physical address
170+
* on 32bit arch, use queue's max segment size when that happens.
171+
*/
172+
return min_not_zero(mask - offset + 1,
173+
(unsigned long)queue_max_segment_size(q));
169174
}
170175

171176
/**

0 commit comments

Comments
 (0)