@@ -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 ,  MMIO64_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