mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 05:35:20 +00:00
aarch64: Reserve a hole in 32-bit space
The reserved space is for devices. Some devices (like TPM) require arbitrary addresses close to 4GiB. Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
parent
a3dbc3b415
commit
848d88c122
@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//
|
||||
// Memory layout of Aarch64 guest:
|
||||
// Memory layout of AArch64 guest:
|
||||
//
|
||||
// Physical +---------------------------------------------------------------+
|
||||
// address | |
|
||||
@ -20,6 +20,13 @@
|
||||
// | DRAM |
|
||||
// | |
|
||||
// | |
|
||||
// 4GB +---------------------------------------------------------------+
|
||||
// | 32-bit devices hole |
|
||||
// 4GB-64M +---------------------------------------------------------------+
|
||||
// | |
|
||||
// | |
|
||||
// | DRAM |
|
||||
// | |
|
||||
// | |
|
||||
// 1GB +---------------------------------------------------------------+
|
||||
// | |
|
||||
@ -88,6 +95,13 @@ pub const PCI_MMIO_CONFIG_SIZE_PER_SEGMENT: u64 = 4096 * 256;
|
||||
/// Start of RAM.
|
||||
pub const RAM_START: GuestAddress = GuestAddress(0x4000_0000);
|
||||
|
||||
/// 32-bit reserved area: 64MiB before 4GiB
|
||||
pub const MEM_32BIT_RESERVED_START: GuestAddress = GuestAddress(0xfc00_0000);
|
||||
pub const MEM_32BIT_RESERVED_SIZE: u64 = 0x0400_0000;
|
||||
|
||||
/// Start of 64-bit RAM.
|
||||
pub const RAM_64BIT_START: GuestAddress = GuestAddress(0x1_0000_0000);
|
||||
|
||||
/// Kernel command line maximum size.
|
||||
/// As per `arch/arm64/include/uapi/asm/setup.h`.
|
||||
pub const CMDLINE_MAX_SIZE: usize = 2048;
|
||||
|
@ -78,14 +78,7 @@ pub fn configure_vcpu(
|
||||
}
|
||||
|
||||
pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, RegionType)> {
|
||||
// Normally UEFI should be loaded to a flash area at the beginning of memory.
|
||||
// But now flash memory type is not supported.
|
||||
// As a workaround, we take 4 MiB memory from the main RAM for UEFI.
|
||||
// As a result, the RAM that the guest can see is less than what has been
|
||||
// assigned in command line, when ACPI and UEFI is enabled.
|
||||
let ram_deduction = layout::UEFI_SIZE;
|
||||
|
||||
vec![
|
||||
let mut regions = vec![
|
||||
// 0 ~ 4 MiB: Reserved for UEFI space
|
||||
(GuestAddress(0), layout::UEFI_SIZE as usize, RegionType::Ram),
|
||||
// 4 MiB ~ 256 MiB: Gic and legacy devices
|
||||
@ -106,13 +99,45 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region
|
||||
layout::PCI_MMCONFIG_SIZE as usize,
|
||||
RegionType::Reserved,
|
||||
),
|
||||
// 1 GiB ~ : Ram
|
||||
(
|
||||
];
|
||||
|
||||
// Normally UEFI should be loaded to a flash area at the beginning of memory.
|
||||
// But now flash memory type is not supported.
|
||||
// As a workaround, we take 4 MiB memory from the main RAM for UEFI.
|
||||
// As a result, the RAM that the guest can see is less than what has been
|
||||
// assigned in command line, when ACPI and UEFI is enabled.
|
||||
let ram_size = size - layout::UEFI_SIZE;
|
||||
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 ram_size as u64 <= ram_32bit_space_size {
|
||||
regions.push((layout::RAM_START, ram_size as usize, RegionType::Ram));
|
||||
// Case2: guest memory extends beyond the gap
|
||||
} else {
|
||||
// Push memory before the gap
|
||||
regions.push((
|
||||
layout::RAM_START,
|
||||
(size - ram_deduction) as usize,
|
||||
ram_32bit_space_size as usize,
|
||||
RegionType::Ram,
|
||||
),
|
||||
]
|
||||
));
|
||||
// Other memory is placed after 4GiB
|
||||
regions.push((
|
||||
layout::RAM_64BIT_START,
|
||||
(ram_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
|
||||
}
|
||||
|
||||
/// Configures the system and should be called once per vm before starting vcpu threads.
|
||||
|
@ -1327,7 +1327,7 @@ impl MemoryManager {
|
||||
// If memory hotplug is allowed, the start address needs to be aligned
|
||||
// (rounded-up) to 128MiB boundary.
|
||||
// If memory hotplug is not allowed, there is no alignment required.
|
||||
// On x86_64, it must also start at the 64bit start.
|
||||
// And it must also start at the 64bit start.
|
||||
fn start_addr(mem_end: GuestAddress, allow_mem_hotplug: bool) -> Result<GuestAddress, Error> {
|
||||
let mut start_addr = if allow_mem_hotplug {
|
||||
GuestAddress(mem_end.0 | ((128 << 20) - 1))
|
||||
@ -1339,7 +1339,6 @@ impl MemoryManager {
|
||||
.checked_add(1)
|
||||
.ok_or(Error::GuestAddressOverFlow)?;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
if mem_end < arch::layout::MEM_32BIT_RESERVED_START {
|
||||
return Ok(arch::layout::RAM_64BIT_START);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user