mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-05 21:15:45 +00:00
arch: x86_64: allow more than 2 E820_RAM ranges
The 'generate_ram_ranges' function currently hardcodes the assumption that there are only 2 E820 RAM entries. This is not flexible enough to handle vendor specific memory holes. Returning a Vec is also more convenient for users of this function. Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
This commit is contained in:
parent
bcdd23956f
commit
ce7db3f7c3
@ -934,12 +934,7 @@ type RamRange = (u64, u64);
|
|||||||
|
|
||||||
/// Returns usable physical memory ranges for the guest
|
/// Returns usable physical memory ranges for the guest
|
||||||
/// These should be used to create e820_RAM memory maps
|
/// These should be used to create e820_RAM memory maps
|
||||||
///
|
pub fn generate_ram_ranges(guest_mem: &GuestMemoryMmap) -> super::Result<Vec<RamRange>> {
|
||||||
/// There are up to two usable physical memory ranges,
|
|
||||||
/// divided by the gap at the end of 32bit address space.
|
|
||||||
pub fn generate_ram_ranges(
|
|
||||||
guest_mem: &GuestMemoryMmap,
|
|
||||||
) -> super::Result<(RamRange, Option<RamRange>)> {
|
|
||||||
// Merge continuous memory regions into one region.
|
// Merge continuous memory regions into one region.
|
||||||
// Note: memory regions from "GuestMemory" are sorted and non-zero sized.
|
// Note: memory regions from "GuestMemory" are sorted and non-zero sized.
|
||||||
let ram_regions = {
|
let ram_regions = {
|
||||||
@ -972,15 +967,11 @@ pub fn generate_ram_ranges(
|
|||||||
ram_regions
|
ram_regions
|
||||||
};
|
};
|
||||||
|
|
||||||
if ram_regions.len() > 2 {
|
// Create the memory map entry for memory region before the gap
|
||||||
error!(
|
let mut ram_ranges = vec![];
|
||||||
"There should be up to two usable physical memory ranges, devidided by the
|
|
||||||
gap at the end of 32bit address space (e.g. between 3G and 4G)."
|
|
||||||
);
|
|
||||||
return Err(super::Error::MemmapTableSetup);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the first usable physical memory range before the gap
|
// Generate the first usable physical memory range before the gap. The e820 map
|
||||||
|
// should only report memory above 1MiB.
|
||||||
let first_ram_range = {
|
let first_ram_range = {
|
||||||
let (first_region_start, first_region_end) =
|
let (first_region_start, first_region_end) =
|
||||||
ram_regions.first().ok_or(super::Error::MemmapTableSetup)?;
|
ram_regions.first().ok_or(super::Error::MemmapTableSetup)?;
|
||||||
@ -1007,33 +998,19 @@ pub fn generate_ram_ranges(
|
|||||||
|
|
||||||
(high_ram_start, *first_region_end)
|
(high_ram_start, *first_region_end)
|
||||||
};
|
};
|
||||||
|
ram_ranges.push(first_ram_range);
|
||||||
|
|
||||||
// Generate the second usable physical memory range after the gap if any
|
// Generate additional usable physical memory range after the gap if any.
|
||||||
let second_ram_range = if let Some((second_region_start, second_region_end)) =
|
for ram_region in ram_regions.iter().skip(1) {
|
||||||
ram_regions.get(1)
|
info!(
|
||||||
{
|
"found usable physical memory range, start: 0x{:08x}, end: 0x{:08x}",
|
||||||
let ram_64bit_start = layout::RAM_64BIT_START.raw_value();
|
ram_region.0, ram_region.1
|
||||||
|
|
||||||
if second_region_start != &ram_64bit_start {
|
|
||||||
error!(
|
|
||||||
"Unexpected second memory region layout: start: 0x{:08x}, ram_64bit_start: 0x{:08x}",
|
|
||||||
second_region_start, ram_64bit_start
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return Err(super::Error::MemmapTableSetup);
|
ram_ranges.push(*ram_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(
|
Ok(ram_ranges)
|
||||||
"Second usable physical memory range, start: 0x{:08x}, end: 0x{:08x}",
|
|
||||||
ram_64bit_start, second_region_end
|
|
||||||
);
|
|
||||||
|
|
||||||
Some((ram_64bit_start, *second_region_end))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((first_ram_range, second_ram_range))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_pvh(
|
fn configure_pvh(
|
||||||
@ -1084,30 +1061,18 @@ fn configure_pvh(
|
|||||||
add_memmap_entry(&mut memmap, 0, layout::EBDA_START.raw_value(), E820_RAM);
|
add_memmap_entry(&mut memmap, 0, layout::EBDA_START.raw_value(), E820_RAM);
|
||||||
|
|
||||||
// Get usable physical memory ranges
|
// Get usable physical memory ranges
|
||||||
let (first_ram_range, second_ram_range) = generate_ram_ranges(guest_mem)?;
|
let ram_ranges = generate_ram_ranges(guest_mem)?;
|
||||||
|
|
||||||
// Create e820 memory map entry before the gap
|
// Create e820 memory map entries
|
||||||
|
for ram_range in ram_ranges {
|
||||||
info!(
|
info!(
|
||||||
"create_memmap_entry, start: 0x{:08x}, end: 0x{:08x}",
|
"create_memmap_entry, start: 0x{:08x}, end: 0x{:08x}",
|
||||||
first_ram_range.0, first_ram_range.1
|
ram_range.0, ram_range.1
|
||||||
);
|
);
|
||||||
add_memmap_entry(
|
add_memmap_entry(
|
||||||
&mut memmap,
|
&mut memmap,
|
||||||
first_ram_range.0,
|
ram_range.0,
|
||||||
first_ram_range.1 - first_ram_range.0,
|
ram_range.1 - ram_range.0,
|
||||||
E820_RAM,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create e820 memory map after the gap if any
|
|
||||||
if let Some(second_ram_range) = second_ram_range {
|
|
||||||
info!(
|
|
||||||
"create_memmap_entry, start: 0x{:08x}, end: 0x{:08x}",
|
|
||||||
second_ram_range.0, second_ram_range.1
|
|
||||||
);
|
|
||||||
add_memmap_entry(
|
|
||||||
&mut memmap,
|
|
||||||
second_ram_range.0,
|
|
||||||
second_ram_range.1 - second_ram_range.0,
|
|
||||||
E820_RAM,
|
E820_RAM,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -92,15 +92,10 @@ fn generate_memory_map(
|
|||||||
let mut memory_map = Vec::new();
|
let mut memory_map = Vec::new();
|
||||||
|
|
||||||
// Get usable physical memory ranges
|
// Get usable physical memory ranges
|
||||||
let (first_ram_range, second_ram_range) =
|
let ram_ranges = arch::generate_ram_ranges(guest_mem).map_err(Error::InvalidGuestMemmap)?;
|
||||||
arch::generate_ram_ranges(guest_mem).map_err(Error::InvalidGuestMemmap)?;
|
|
||||||
|
|
||||||
// Create the memory map entry for memory region before the gap
|
for ram_range in ram_ranges {
|
||||||
memory_map.push(igvm_memmap_from_ram_range(first_ram_range));
|
memory_map.push(igvm_memmap_from_ram_range(ram_range));
|
||||||
|
|
||||||
// Create the memory map entry for memory region after the gap if any
|
|
||||||
if let Some(second_ram_range) = second_ram_range {
|
|
||||||
memory_map.push(igvm_memmap_from_ram_range(second_ram_range));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(memory_map)
|
Ok(memory_map)
|
||||||
|
Loading…
Reference in New Issue
Block a user