arch: Add SubRegion memory type

We want to be able to differentiate between memory regions that must be
managed separately from the main address space (e.g. the 32-bit memory
hole) and ones that are reserved (i.e. from which we don't want to allow
the VMM to allocate address ranges.

We are going to use a reserved memory region for restricting the 32-bit
memory hole from expanding beyond the IOAPIC and TSS addresses.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz 2019-07-25 10:20:59 +02:00 committed by Rob Bradford
parent 792cc27435
commit 299d887856
3 changed files with 20 additions and 6 deletions

View File

@ -37,8 +37,17 @@ pub type Result<T> = result::Result<T, Error>;
pub enum RegionType { pub enum RegionType {
/// RAM type /// RAM type
Ram, Ram,
/// Reserved type. Designate a region which should not be considered as
/// RAM. Useful to specify a PCI hole for instance. /// SubRegion memory region.
/// A SubRegion is a memory region sub-region, allowing for a region
/// to be split into sub regions managed separately.
/// For example, the x86 32-bit memory hole is a SubRegion.
SubRegion,
/// Reserved type.
/// A Reserved memory region is one that should not be used for memory
/// allocation. This type can be used to prevent the VMM from allocating
/// memory ranges in a specific address range.
Reserved, Reserved,
} }

View File

@ -77,11 +77,11 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region
)); ));
} }
// Add the 32 bits hole as a "reserved" region. // Add the 32 bits hole as a sub region.
regions.push(( regions.push((
memory_gap_start, memory_gap_start,
MEM_32BIT_GAP_SIZE as usize, MEM_32BIT_GAP_SIZE as usize,
RegionType::Reserved, RegionType::SubRegion,
)); ));
regions regions

View File

@ -1232,7 +1232,12 @@ impl<'a> Vm<'a> {
.filter(|r| r.2 == RegionType::Ram) .filter(|r| r.2 == RegionType::Ram)
.map(|r| (r.0, r.1)) .map(|r| (r.0, r.1))
.collect(); .collect();
let reserved_regions: Vec<(GuestAddress, usize)> = arch_mem_regions let sub_regions: Vec<(GuestAddress, usize)> = arch_mem_regions
.iter()
.filter(|r| r.2 == RegionType::SubRegion)
.map(|r| (r.0, r.1))
.collect();
let _reserved_regions: Vec<(GuestAddress, usize)> = arch_mem_regions
.iter() .iter()
.filter(|r| r.2 == RegionType::Reserved) .filter(|r| r.2 == RegionType::Reserved)
.map(|r| (r.0, r.1)) .map(|r| (r.0, r.1))
@ -1241,7 +1246,7 @@ impl<'a> Vm<'a> {
// Check the number of reserved regions, and only take the first one // Check the number of reserved regions, and only take the first one
// that's acrtually a 32-bit hole. // that's acrtually a 32-bit hole.
let mut mem_hole = (GuestAddress(0), 0); let mut mem_hole = (GuestAddress(0), 0);
for region in reserved_regions.iter() { for region in sub_regions.iter() {
if region.0.unchecked_add(region.1 as u64).raw_value() <= 0x1_0000_0000 { if region.0.unchecked_add(region.1 as u64).raw_value() <= 0x1_0000_0000 {
mem_hole = (region.0, region.1); mem_hole = (region.0, region.1);
break; break;