File tree 1 file changed +29
-1
lines changed
1 file changed +29
-1
lines changed Original file line number Diff line number Diff line change @@ -380,7 +380,16 @@ impl<S: PageSize> Iterator for PageRangeInclusive<S> {
380
380
fn next ( & mut self ) -> Option < Self :: Item > {
381
381
if self . start <= self . end {
382
382
let page = self . start ;
383
- self . start += 1 ;
383
+
384
+ // If the end of the inclusive range is the maximum page possible for size S,
385
+ // incrementing start until it is greater than the end will cause an integer overflow.
386
+ // So instead, in that case we decrement end rather than incrementing start.
387
+ let max_page_addr = VirtAddr :: new ( u64:: MAX ) - ( S :: SIZE - 1 ) ;
388
+ if self . start . start_address ( ) < max_page_addr {
389
+ self . start += 1 ;
390
+ } else {
391
+ self . end -= 1 ;
392
+ }
384
393
Some ( page)
385
394
} else {
386
395
None
@@ -438,4 +447,23 @@ mod tests {
438
447
}
439
448
assert_eq ! ( range_inclusive. next( ) , None ) ;
440
449
}
450
+
451
+ #[ test]
452
+ pub fn test_page_range_inclusive_overflow ( ) {
453
+ let page_size = Size4KiB :: SIZE ;
454
+ let number = 1000 ;
455
+
456
+ let start_addr = VirtAddr :: new ( u64:: MAX ) . align_down ( page_size) - number * page_size;
457
+ let start: Page = Page :: containing_address ( start_addr) ;
458
+ let end = start + number;
459
+
460
+ let mut range_inclusive = Page :: range_inclusive ( start, end) ;
461
+ for i in 0 ..=number {
462
+ assert_eq ! (
463
+ range_inclusive. next( ) ,
464
+ Some ( Page :: containing_address( start_addr + page_size * i) )
465
+ ) ;
466
+ }
467
+ assert_eq ! ( range_inclusive. next( ) , None ) ;
468
+ }
441
469
}
You can’t perform that action at this time.
0 commit comments