@@ -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 ) ,
@@ -471,26 +474,33 @@ pub fn load_kernel(
471474
472475#[ cfg( kani) ]
473476mod verification {
477+
474478 use crate :: arch:: arch_memory_regions;
475479 use crate :: arch:: x86_64:: layout:: {
476- FIRST_ADDR_PAST_32BITS , FIRST_ADDR_PAST_64BITS_MMIO , MMIO32_MEM_START , MMIO64_MEM_START ,
480+ FIRST_ADDR_PAST_32BITS , FIRST_ADDR_PAST_64BITS_MMIO , MAX_PHYSICAL_ADDRESS_SPACE ,
481+ MMIO32_MEM_SIZE , MMIO32_MEM_START , MMIO64_MEM_SIZE , MMIO64_MEM_START ,
477482 } ;
483+ use crate :: utils:: usize_to_u64;
478484
479485 #[ kani:: proof]
480486 #[ kani:: unwind( 4 ) ]
481487 fn verify_arch_memory_regions ( ) {
482- let offset: u64 = kani:: any :: < u64 > ( ) ;
483488 let len: u64 = kani:: any :: < u64 > ( ) ;
484489
485490 kani:: assume ( len > 0 ) ;
486- kani:: assume ( offset. checked_add ( len) . is_some ( ) ) ;
491+ kani:: assume (
492+ len <= usize_to_u64 ( MAX_PHYSICAL_ADDRESS_SPACE ) - MMIO32_MEM_SIZE - MMIO64_MEM_SIZE ,
493+ ) ;
487494
488- let regions = arch_memory_regions ( offset as usize , len as usize ) ;
495+ let regions = arch_memory_regions ( len as usize ) ;
489496
490497 // There are two MMIO gaps, so we can get either 1, 2 or 3 regions
491498 assert ! ( regions. len( ) <= 3 ) ;
492499 assert ! ( regions. len( ) >= 1 ) ;
493500
501+ // The first address is always 0
502+ assert_eq ! ( regions[ 0 ] . 0.0 , 0 ) ;
503+
494504 // The total length of all regions is what we requested
495505 assert_eq ! (
496506 regions. iter( ) . map( |& ( _, len) | len) . sum:: <usize >( ) ,
@@ -507,23 +517,15 @@ mod verification {
507517 || start. 0 + len as u64 <= MMIO64_MEM_START ) )
508518 ) ;
509519
510- // All regions start after our specified offset
511- assert ! ( regions. iter( ) . all( |& ( start, _) | start. 0 >= offset as u64 ) ) ;
512-
513520 // All regions have non-zero length
514521 assert ! ( regions. iter( ) . all( |& ( _, len) | len > 0 ) ) ;
515522
516523 // If there's at least two regions, they perfectly snuggle up to one of the two MMIO gaps
517524 if regions. len ( ) >= 2 {
518525 kani:: cover!( ) ;
519526
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- }
527+ assert_eq ! ( regions[ 0 ] . 0.0 + regions[ 0 ] . 1 as u64 , MMIO32_MEM_START ) ;
528+ assert_eq ! ( regions[ 1 ] . 0.0 , FIRST_ADDR_PAST_32BITS ) ;
527529 }
528530
529531 // If there are three regions, the last two perfectly snuggle up to the 64bit
@@ -548,34 +550,21 @@ mod tests {
548550
549551 #[ test]
550552 fn regions_lt_4gb ( ) {
551- let regions = arch_memory_regions ( 0 , 1usize << 29 ) ;
553+ let regions = arch_memory_regions ( 1usize << 29 ) ;
552554 assert_eq ! ( 1 , regions. len( ) ) ;
553555 assert_eq ! ( GuestAddress ( 0 ) , regions[ 0 ] . 0 ) ;
554556 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 ) ) ;
559557 }
560558
561559 #[ test]
562560 fn regions_gt_4gb ( ) {
563561 const MEMORY_SIZE : usize = ( 1 << 32 ) + 0x8000 ;
564562
565- let regions = arch_memory_regions ( 0 , MEMORY_SIZE ) ;
563+ let regions = arch_memory_regions ( MEMORY_SIZE ) ;
566564 assert_eq ! ( 2 , regions. len( ) ) ;
567565 assert_eq ! ( GuestAddress ( 0 ) , regions[ 0 ] . 0 ) ;
568566 assert_eq ! ( GuestAddress ( 1u64 << 32 ) , regions[ 1 ] . 0 ) ;
569567
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- ) ;
579568 assert_eq ! (
580569 regions[ 1 ] ,
581570 (
0 commit comments