mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-02 11:35:46 +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
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
//
|
//
|
||||||
// Memory layout of Aarch64 guest:
|
// Memory layout of AArch64 guest:
|
||||||
//
|
//
|
||||||
// Physical +---------------------------------------------------------------+
|
// Physical +---------------------------------------------------------------+
|
||||||
// address | |
|
// address | |
|
||||||
@ -20,6 +20,13 @@
|
|||||||
// | DRAM |
|
// | DRAM |
|
||||||
// | |
|
// | |
|
||||||
// | |
|
// | |
|
||||||
|
// 4GB +---------------------------------------------------------------+
|
||||||
|
// | 32-bit devices hole |
|
||||||
|
// 4GB-64M +---------------------------------------------------------------+
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | DRAM |
|
||||||
|
// | |
|
||||||
// | |
|
// | |
|
||||||
// 1GB +---------------------------------------------------------------+
|
// 1GB +---------------------------------------------------------------+
|
||||||
// | |
|
// | |
|
||||||
@ -88,6 +95,13 @@ pub const PCI_MMIO_CONFIG_SIZE_PER_SEGMENT: u64 = 4096 * 256;
|
|||||||
/// Start of RAM.
|
/// Start of RAM.
|
||||||
pub const RAM_START: GuestAddress = GuestAddress(0x4000_0000);
|
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.
|
/// Kernel command line maximum size.
|
||||||
/// As per `arch/arm64/include/uapi/asm/setup.h`.
|
/// As per `arch/arm64/include/uapi/asm/setup.h`.
|
||||||
pub const CMDLINE_MAX_SIZE: usize = 2048;
|
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)> {
|
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.
|
let mut regions = vec![
|
||||||
// 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![
|
|
||||||
// 0 ~ 4 MiB: Reserved for UEFI space
|
// 0 ~ 4 MiB: Reserved for UEFI space
|
||||||
(GuestAddress(0), layout::UEFI_SIZE as usize, RegionType::Ram),
|
(GuestAddress(0), layout::UEFI_SIZE as usize, RegionType::Ram),
|
||||||
// 4 MiB ~ 256 MiB: Gic and legacy devices
|
// 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,
|
layout::PCI_MMCONFIG_SIZE as usize,
|
||||||
RegionType::Reserved,
|
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,
|
layout::RAM_START,
|
||||||
(size - ram_deduction) as usize,
|
ram_32bit_space_size as usize,
|
||||||
RegionType::Ram,
|
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.
|
/// 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
|
// If memory hotplug is allowed, the start address needs to be aligned
|
||||||
// (rounded-up) to 128MiB boundary.
|
// (rounded-up) to 128MiB boundary.
|
||||||
// If memory hotplug is not allowed, there is no alignment required.
|
// 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> {
|
fn start_addr(mem_end: GuestAddress, allow_mem_hotplug: bool) -> Result<GuestAddress, Error> {
|
||||||
let mut start_addr = if allow_mem_hotplug {
|
let mut start_addr = if allow_mem_hotplug {
|
||||||
GuestAddress(mem_end.0 | ((128 << 20) - 1))
|
GuestAddress(mem_end.0 | ((128 << 20) - 1))
|
||||||
@ -1339,7 +1339,6 @@ impl MemoryManager {
|
|||||||
.checked_add(1)
|
.checked_add(1)
|
||||||
.ok_or(Error::GuestAddressOverFlow)?;
|
.ok_or(Error::GuestAddressOverFlow)?;
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
if mem_end < arch::layout::MEM_32BIT_RESERVED_START {
|
if mem_end < arch::layout::MEM_32BIT_RESERVED_START {
|
||||||
return Ok(arch::layout::RAM_64BIT_START);
|
return Ok(arch::layout::RAM_64BIT_START);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user