diff --git a/arch/src/aarch64/mod.rs b/arch/src/aarch64/mod.rs index 04ae65e1e..5c344346e 100644 --- a/arch/src/aarch64/mod.rs +++ b/arch/src/aarch64/mod.rs @@ -35,8 +35,8 @@ pub enum Error { /// Failed to create a GIC. SetupGIC(gic::Error), - /// Failed to compute the initrd address. - InitrdAddress, + /// Failed to compute the initramfs address. + InitramfsAddress, /// Error configuring the general purpose registers REGSConfiguration(regs::Error), @@ -165,6 +165,26 @@ pub fn configure_system( Ok(()) } +/// Returns the memory address where the initramfs could be loaded. +pub fn initramfs_load_addr( + guest_mem: &GuestMemoryMmap, + initramfs_size: usize, +) -> super::Result { + let round_to_pagesize = |size| (size + (super::PAGE_SIZE - 1)) & !(super::PAGE_SIZE - 1); + match GuestAddress(get_fdt_addr(&guest_mem)) + .checked_sub(round_to_pagesize(initramfs_size) as u64) + { + Some(offset) => { + if guest_mem.address_in_range(offset) { + Ok(offset.raw_value()) + } else { + Err(super::Error::AArch64Setup(Error::InitramfsAddress)) + } + } + None => Err(super::Error::AArch64Setup(Error::InitramfsAddress)), + } +} + /// Returns the memory address where the kernel could be loaded. pub fn get_kernel_start() -> u64 { layout::RAM_64BIT_START diff --git a/arch/src/lib.rs b/arch/src/lib.rs index 7e9488e44..2b3baf43d 100644 --- a/arch/src/lib.rs +++ b/arch/src/lib.rs @@ -88,8 +88,8 @@ pub mod aarch64; #[cfg(target_arch = "aarch64")] pub use aarch64::{ arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFDT, - get_host_cpu_phys_bits, get_kernel_start, layout, layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, - layout::IRQ_MAX, EntryPoint, + get_host_cpu_phys_bits, get_kernel_start, initramfs_load_addr, layout, + layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, layout::IRQ_MAX, EntryPoint, }; #[cfg(target_arch = "x86_64")] diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 8f55c10a4..ad4bb31de 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -47,12 +47,10 @@ use linux_loader::loader::elf::PvhBootCapability::PvhEntryPresent; use linux_loader::loader::KernelLoader; use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH}; use std::collections::HashMap; -#[cfg(target_arch = "x86_64")] use std::convert::TryInto; use std::ffi::CString; use std::fs::{File, OpenOptions}; use std::io::{self, Write}; -#[cfg(target_arch = "x86_64")] use std::io::{Seek, SeekFrom}; use std::num::Wrapping; use std::ops::Deref; @@ -60,9 +58,7 @@ use std::path::PathBuf; use std::sync::{Arc, Mutex, RwLock}; use std::{result, str, thread}; use url::Url; -use vm_memory::{Address, GuestAddress, GuestAddressSpace}; -#[cfg(target_arch = "x86_64")] -use vm_memory::{Bytes, GuestMemoryMmap}; +use vm_memory::{Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryMmap}; use vm_migration::{ Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable, Transportable, @@ -245,7 +241,6 @@ impl VmState { pub struct Vm { kernel: File, - #[cfg_attr(target_arch = "aarch64", allow(dead_code))] initramfs: Option, threads: Vec>, device_manager: Arc>, @@ -434,7 +429,6 @@ impl Vm { ) } - #[cfg(target_arch = "x86_64")] fn load_initramfs(&mut self, guest_mem: &GuestMemoryMmap) -> Result { let mut initramfs = self.initramfs.as_ref().unwrap(); let size: usize = initramfs @@ -631,6 +625,10 @@ impl Vm { let vcpu_mpidrs = self.cpu_manager.lock().unwrap().get_mpidrs(); let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory(); let mem = guest_memory.memory(); + let initramfs_config = match self.initramfs { + Some(_) => Some(self.load_initramfs(mem.deref())?), + None => None, + }; let device_info = &self .device_manager @@ -671,7 +669,7 @@ impl Vm { self.cpu_manager.lock().unwrap().boot_vcpus() as u64, vcpu_mpidrs, device_info, - &None, + &initramfs_config, &pci_space, ) .map_err(Error::ConfigureSystem)?;