@@ -34,8 +34,8 @@ pub mod generated;
3434use std:: fs:: File ;
3535
3636use layout:: {
37- CMDLINE_START , FIRST_ADDR_PAST_32BITS , FIRST_ADDR_PAST_64BITS_MMIO , MMIO32_MEM_SIZE ,
38- MMIO32_MEM_START , MMIO64_MEM_SIZE , MMIO64_MEM_START ,
37+ CMDLINE_START , FIRST_ADDR_PAST_32BITS , FIRST_ADDR_PAST_64BITS_MMIO , MAX_PHYSICAL_ADDRESS_SPACE ,
38+ MMIO32_MEM_SIZE , MMIO32_MEM_START , MMIO64_MEM_SIZE , MMIO64_MEM_START ,
3939} ;
4040use linux_loader:: configurator:: linux:: LinuxBootConfigurator ;
4141use linux_loader:: configurator:: pvh:: PvhBootConfigurator ;
@@ -101,22 +101,25 @@ pub enum ConfigurationError {
101101
102102/// Returns a Vec of the valid memory addresses.
103103/// These should be used to configure the GuestMemoryMmap structure for the platform.
104- /// For x86_64 all addresses are valid from the start of the kernel except a
105- /// carve out at the end of 32bit address space.
106- pub fn arch_memory_regions ( offset : usize , size : usize ) -> Vec < ( GuestAddress , usize ) > {
104+ /// For x86_64 all addresses are valid from the start of the kernel except an 1GB
105+ /// carve out at the end of 32bit address space and a second 256GB one at the 256GB limit .
106+ pub fn arch_memory_regions ( size : usize ) -> Vec < ( GuestAddress , usize ) > {
107107 // If we get here with size == 0 something has seriously gone wrong. Firecracker should never
108108 // try to allocate guest memory of size 0
109109 assert ! ( size > 0 , "Attempt to allocate guest memory of length 0" ) ;
110+ // The resulting address space must fit in 48 bits.
110111 assert ! (
111- offset. checked_add( size) . is_some( ) ,
112- "Attempt to allocate guest memory such that the address space would wrap around"
112+ size <= MAX_PHYSICAL_ADDRESS_SPACE
113+ - u64_to_usize( MMIO32_MEM_SIZE )
114+ - u64_to_usize( MMIO64_MEM_SIZE ) ,
115+ "Memory size would result in an address space that exceeds 48 bits."
113116 ) ;
114117
115118 let mut regions = vec ! [ ] ;
116119
117120 if let Some ( ( start_past_32bit_gap, remaining_past_32bit_gap) ) = arch_memory_regions_with_gap (
118121 & mut regions,
119- offset ,
122+ 0 ,
120123 size,
121124 u64_to_usize ( MMIO32_MEM_START ) ,
122125 u64_to_usize ( MMIO32_MEM_SIZE ) ,
@@ -473,24 +476,30 @@ pub fn load_kernel(
473476mod verification {
474477 use crate :: arch:: arch_memory_regions;
475478 use crate :: arch:: x86_64:: layout:: {
476- FIRST_ADDR_PAST_32BITS , FIRST_ADDR_PAST_64BITS_MMIO , MMIO32_MEM_START , MMIO64_MEM_START ,
479+ FIRST_ADDR_PAST_32BITS , FIRST_ADDR_PAST_64BITS_MMIO , MAX_PHYSICAL_ADDRESS_SPACE ,
480+ MMIO32_MEM_SIZE , MMIO32_MEM_START , MMIO64_MEM_SIZE , MMIO64_MEM_START ,
477481 } ;
482+ use crate :: utils:: usize_to_u64;
478483
479484 #[ kani:: proof]
480485 #[ kani:: unwind( 4 ) ]
481486 fn verify_arch_memory_regions ( ) {
482- let offset: u64 = kani:: any :: < u64 > ( ) ;
483487 let len: u64 = kani:: any :: < u64 > ( ) ;
484488
485489 kani:: assume ( len > 0 ) ;
486- kani:: assume ( offset. checked_add ( len) . is_some ( ) ) ;
490+ kani:: assume (
491+ len <= usize_to_u64 ( MAX_PHYSICAL_ADDRESS_SPACE ) - MMIO32_MEM_SIZE - MMIO64_MEM_SIZE ,
492+ ) ;
487493
488- let regions = arch_memory_regions ( offset as usize , len as usize ) ;
494+ let regions = arch_memory_regions ( len as usize ) ;
489495
490496 // There are two MMIO gaps, so we can get either 1, 2 or 3 regions
491497 assert ! ( regions. len( ) <= 3 ) ;
492498 assert ! ( regions. len( ) >= 1 ) ;
493499
500+ // The first address is always 0
501+ assert_eq ! ( regions[ 0 ] . 0.0 , 0 ) ;
502+
494503 // The total length of all regions is what we requested
495504 assert_eq ! (
496505 regions. iter( ) . map( |& ( _, len) | len) . sum:: <usize >( ) ,
@@ -507,23 +516,15 @@ mod verification {
507516 || start. 0 + len as u64 <= MMIO64_MEM_START ) )
508517 ) ;
509518
510- // All regions start after our specified offset
511- assert ! ( regions. iter( ) . all( |& ( start, _) | start. 0 >= offset as u64 ) ) ;
512-
513519 // All regions have non-zero length
514520 assert ! ( regions. iter( ) . all( |& ( _, len) | len > 0 ) ) ;
515521
516522 // If there's at least two regions, they perfectly snuggle up to one of the two MMIO gaps
517523 if regions. len ( ) >= 2 {
518524 kani:: cover!( ) ;
519525
520- if offset < MMIO32_MEM_START {
521- assert_eq ! ( regions[ 0 ] . 0.0 + regions[ 0 ] . 1 as u64 , MMIO32_MEM_START ) ;
522- assert_eq ! ( regions[ 1 ] . 0.0 , FIRST_ADDR_PAST_32BITS ) ;
523- } else {
524- assert_eq ! ( regions[ 0 ] . 0.0 + regions[ 0 ] . 1 as u64 , MMIO64_MEM_START ) ;
525- assert_eq ! ( regions[ 1 ] . 0.0 , FIRST_ADDR_PAST_64BITS_MMIO ) ;
526- }
526+ assert_eq ! ( regions[ 0 ] . 0.0 + regions[ 0 ] . 1 as u64 , MMIO32_MEM_START ) ;
527+ assert_eq ! ( regions[ 1 ] . 0.0 , FIRST_ADDR_PAST_64BITS_MMIO ) ;
527528 }
528529
529530 // If there are three regions, the last two perfectly snuggle up to the 64bit
@@ -548,34 +549,21 @@ mod tests {
548549
549550 #[ test]
550551 fn regions_lt_4gb ( ) {
551- let regions = arch_memory_regions ( 0 , 1usize << 29 ) ;
552+ let regions = arch_memory_regions ( 1usize << 29 ) ;
552553 assert_eq ! ( 1 , regions. len( ) ) ;
553554 assert_eq ! ( GuestAddress ( 0 ) , regions[ 0 ] . 0 ) ;
554555 assert_eq ! ( 1usize << 29 , regions[ 0 ] . 1 ) ;
555-
556- let regions = arch_memory_regions ( 1 << 28 , 1 << 29 ) ;
557- assert_eq ! ( 1 , regions. len( ) ) ;
558- assert_eq ! ( regions[ 0 ] , ( GuestAddress ( 1 << 28 ) , 1 << 29 ) ) ;
559556 }
560557
561558 #[ test]
562559 fn regions_gt_4gb ( ) {
563560 const MEMORY_SIZE : usize = ( 1 << 32 ) + 0x8000 ;
564561
565- let regions = arch_memory_regions ( 0 , MEMORY_SIZE ) ;
562+ let regions = arch_memory_regions ( MEMORY_SIZE ) ;
566563 assert_eq ! ( 2 , regions. len( ) ) ;
567564 assert_eq ! ( GuestAddress ( 0 ) , regions[ 0 ] . 0 ) ;
568565 assert_eq ! ( GuestAddress ( 1u64 << 32 ) , regions[ 1 ] . 0 ) ;
569566
570- let regions = arch_memory_regions ( 1 << 31 , MEMORY_SIZE ) ;
571- assert_eq ! ( 2 , regions. len( ) ) ;
572- assert_eq ! (
573- regions[ 0 ] ,
574- (
575- GuestAddress ( 1 << 31 ) ,
576- u64_to_usize( MMIO32_MEM_START ) - ( 1 << 31 )
577- )
578- ) ;
579567 assert_eq ! (
580568 regions[ 1 ] ,
581569 (
0 commit comments