diff --git a/arch/src/aarch64/mod.rs b/arch/src/aarch64/mod.rs index c5b20e245..a79ce0ac4 100644 --- a/arch/src/aarch64/mod.rs +++ b/arch/src/aarch64/mod.rs @@ -19,7 +19,7 @@ use std::collections::HashMap; use std::convert::TryInto; use std::fmt::Debug; use std::sync::{Arc, Mutex}; -use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryAtomic, GuestUsize}; +use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryAtomic}; pub const _NSIG: i32 = 65; @@ -83,8 +83,8 @@ pub fn configure_vcpu( Ok(mpidr) } -pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, RegionType)> { - let mut regions = vec![ +pub fn arch_memory_regions() -> Vec<(GuestAddress, usize, RegionType)> { + vec![ // 0 MiB ~ 256 MiB: UEFI, GIC and legacy devices ( GuestAddress(0), @@ -103,39 +103,21 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region layout::PCI_MMCONFIG_SIZE as usize, RegionType::Reserved, ), - ]; - - let ram_32bit_space_size = - layout::MEM_32BIT_RESERVED_START.unchecked_offset_from(layout::RAM_START); - - // RAM space - // Case1: guest memory fits before the gap - if size <= ram_32bit_space_size { - regions.push((layout::RAM_START, size as usize, RegionType::Ram)); - // Case2: guest memory extends beyond the gap - } else { - // Push memory before the gap - regions.push(( + // 1GiB ~ 4032 MiB: RAM before the gap + ( layout::RAM_START, - ram_32bit_space_size as usize, + layout::MEM_32BIT_RESERVED_START.unchecked_offset_from(layout::RAM_START) as usize, RegionType::Ram, - )); - // Other memory is placed after 4GiB - regions.push(( - layout::RAM_64BIT_START, - (size - ram_32bit_space_size) as usize, - RegionType::Ram, - )); - } - - // Add the 32-bit reserved memory hole as a reserved region - regions.push(( - layout::MEM_32BIT_RESERVED_START, - layout::MEM_32BIT_RESERVED_SIZE as usize, - RegionType::Reserved, - )); - - regions + ), + // 4GiB ~ inf: RAM after the gap + (layout::RAM_64BIT_START, usize::MAX, RegionType::Ram), + // Add the 32-bit reserved memory hole as a reserved region + ( + layout::MEM_32BIT_RESERVED_START, + layout::MEM_32BIT_RESERVED_SIZE as usize, + RegionType::Reserved, + ), + ] } /// Configures the system and should be called once per vm before starting vcpu threads. @@ -214,26 +196,12 @@ mod tests { use super::*; #[test] - fn test_arch_memory_regions_dram_2gb() { - let regions = arch_memory_regions((1usize << 31) as u64); //2GB - assert_eq!(5, regions.len()); - assert_eq!(layout::RAM_START, regions[3].0); - assert_eq!((1usize << 31), regions[3].1); - assert_eq!(RegionType::Ram, regions[3].2); - assert_eq!(RegionType::Reserved, regions[4].2); - } - - #[test] - fn test_arch_memory_regions_dram_4gb() { - let regions = arch_memory_regions((1usize << 32) as u64); //4GB - let ram_32bit_space_size = - layout::MEM_32BIT_RESERVED_START.unchecked_offset_from(layout::RAM_START) as usize; + fn test_arch_memory_regions_dram() { + let regions = arch_memory_regions(); assert_eq!(6, regions.len()); assert_eq!(layout::RAM_START, regions[3].0); - assert_eq!(ram_32bit_space_size, regions[3].1); assert_eq!(RegionType::Ram, regions[3].2); assert_eq!(RegionType::Reserved, regions[5].2); assert_eq!(RegionType::Ram, regions[4].2); - assert_eq!(((1usize << 32) - ram_32bit_space_size), regions[4].1); } } diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index 4f1f6414e..72d479ebf 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -834,47 +834,29 @@ pub fn configure_vcpu( /// These should be used to configure the GuestMemory structure for the platform. /// For x86_64 all addresses are valid from the start of the kernel except a /// carve out at the end of 32bit address space. -pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, RegionType)> { - let reserved_memory_gap_start = layout::MEM_32BIT_RESERVED_START - .checked_add(layout::MEM_32BIT_DEVICES_SIZE) - .expect("32-bit reserved region is too large"); - - let requested_memory_size = GuestAddress(size); - let mut regions = Vec::new(); - - // case1: guest memory fits before the gap - if size <= layout::MEM_32BIT_RESERVED_START.raw_value() { - regions.push((GuestAddress(0), size as usize, RegionType::Ram)); - // case2: guest memory extends beyond the gap - } else { - // push memory before the gap - regions.push(( +pub fn arch_memory_regions() -> Vec<(GuestAddress, usize, RegionType)> { + vec![ + // 0 GiB ~ 3GiB: memory before the gap + ( GuestAddress(0), layout::MEM_32BIT_RESERVED_START.raw_value() as usize, RegionType::Ram, - )); - regions.push(( - layout::RAM_64BIT_START, - requested_memory_size.unchecked_offset_from(layout::MEM_32BIT_RESERVED_START) as usize, - RegionType::Ram, - )); - } - - // Add the 32-bit device memory hole as a sub region. - regions.push(( - layout::MEM_32BIT_RESERVED_START, - layout::MEM_32BIT_DEVICES_SIZE as usize, - RegionType::SubRegion, - )); - - // Add the 32-bit reserved memory hole as a sub region. - regions.push(( - reserved_memory_gap_start, - (layout::MEM_32BIT_RESERVED_SIZE - layout::MEM_32BIT_DEVICES_SIZE) as usize, - RegionType::Reserved, - )); - - regions + ), + // 4 GiB ~ inf: memory after the gap + (layout::RAM_64BIT_START, usize::MAX, RegionType::Ram), + // 3 GiB ~ 3712 MiB: 32-bit device memory hole + ( + layout::MEM_32BIT_RESERVED_START, + layout::MEM_32BIT_DEVICES_SIZE as usize, + RegionType::SubRegion, + ), + // 3712 MiB ~ 3968 MiB: 32-bit reserved memory hole + ( + layout::MEM_32BIT_RESERVED_START.unchecked_add(layout::MEM_32BIT_DEVICES_SIZE), + (layout::MEM_32BIT_RESERVED_SIZE - layout::MEM_32BIT_DEVICES_SIZE) as usize, + RegionType::Reserved, + ), + ] } /// Configures the system and should be called once per vm before starting vcpu threads. @@ -1254,16 +1236,8 @@ mod tests { use super::*; #[test] - fn regions_lt_4gb() { - let regions = arch_memory_regions(1 << 29); - assert_eq!(3, regions.len()); - assert_eq!(GuestAddress(0), regions[0].0); - assert_eq!(1usize << 29, regions[0].1); - } - - #[test] - fn regions_gt_4gb() { - let regions = arch_memory_regions((1 << 32) + 0x8000); + fn regions_base_addr() { + let regions = arch_memory_regions(); assert_eq!(4, regions.len()); assert_eq!(GuestAddress(0), regions[0].0); assert_eq!(GuestAddress(1 << 32), regions[1].0); @@ -1287,11 +1261,10 @@ mod tests { assert!(config_err.is_err()); // Now assigning some memory that falls before the 32bit memory hole. - let mem_size = 128 << 20; - let arch_mem_regions = arch_memory_regions(mem_size); + let arch_mem_regions = arch_memory_regions(); let ram_regions: Vec<(GuestAddress, usize)> = arch_mem_regions .iter() - .filter(|r| r.2 == RegionType::Ram) + .filter(|r| r.2 == RegionType::Ram && r.1 != usize::MAX) .map(|r| (r.0, r.1)) .collect(); let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap(); @@ -1309,48 +1282,18 @@ mod tests { ) .unwrap(); - // Now assigning some memory that is equal to the start of the 32bit memory hole. - let mem_size = 3328 << 20; - let arch_mem_regions = arch_memory_regions(mem_size); - let ram_regions: Vec<(GuestAddress, usize)> = arch_mem_regions - .iter() - .filter(|r| r.2 == RegionType::Ram) - .map(|r| (r.0, r.1)) - .collect(); - let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap(); - configure_system( - &gm, - GuestAddress(0), - &None, - no_vcpus, - None, - None, - None, - None, - None, - ) - .unwrap(); - - configure_system( - &gm, - GuestAddress(0), - &None, - no_vcpus, - None, - None, - None, - None, - None, - ) - .unwrap(); - // Now assigning some memory that falls after the 32bit memory hole. - let mem_size = 3330 << 20; - let arch_mem_regions = arch_memory_regions(mem_size); + let arch_mem_regions = arch_memory_regions(); let ram_regions: Vec<(GuestAddress, usize)> = arch_mem_regions .iter() .filter(|r| r.2 == RegionType::Ram) - .map(|r| (r.0, r.1)) + .map(|r| { + if r.1 == usize::MAX { + (r.0, 128 << 20) + } else { + (r.0, r.1) + } + }) .collect(); let gm = GuestMemoryMmap::from_ranges(&ram_regions).unwrap(); configure_system( diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index 52ad3a916..86971a872 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -933,7 +933,7 @@ impl MemoryManager { ) } else { // Init guest memory - let arch_mem_regions = arch::arch_memory_regions(ram_size); + let arch_mem_regions = arch::arch_memory_regions(); let ram_regions: Vec<(GuestAddress, usize)> = arch_mem_regions .iter()