mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-03-20 07:58:55 +00:00
vmm: Configure VM on AArch64
Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
parent
917219fa92
commit
5cd1730bc4
@ -16,7 +16,6 @@ pub mod regs;
|
||||
pub use self::fdt::DeviceInfoForFDT;
|
||||
use crate::DeviceType;
|
||||
use crate::RegionType;
|
||||
use aarch64::gic::GICDevice;
|
||||
use kvm_ioctls::*;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::CStr;
|
||||
@ -29,9 +28,12 @@ use vm_memory::{
|
||||
/// Errors thrown while configuring aarch64 system.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Failed to create a Flattened Device Tree for this aarch64 VM.
|
||||
/// Failed to create a FDT.
|
||||
SetupFDT(fdt::Error),
|
||||
|
||||
/// Failed to create a GIC.
|
||||
SetupGIC(gic::Error),
|
||||
|
||||
/// Failed to compute the initrd address.
|
||||
InitrdAddress,
|
||||
|
||||
@ -136,19 +138,22 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[allow(unused_variables)]
|
||||
pub fn configure_system<T: DeviceInfoForFDT + Clone + Debug>(
|
||||
vm_fd: &VmFd,
|
||||
guest_mem: &GuestMemoryMmap,
|
||||
cmdline_cstring: &CStr,
|
||||
vcpu_count: u64,
|
||||
vcpu_mpidr: Vec<u64>,
|
||||
device_info: &HashMap<(DeviceType, String), T>,
|
||||
gic_device: &Box<dyn GICDevice>,
|
||||
initrd: &Option<super::InitramfsConfig>,
|
||||
) -> super::Result<()> {
|
||||
let gic_device = gic::create_gic(vm_fd, vcpu_count).map_err(Error::SetupGIC)?;
|
||||
|
||||
let dtb = fdt::create_fdt(
|
||||
guest_mem,
|
||||
cmdline_cstring,
|
||||
vcpu_mpidr,
|
||||
device_info,
|
||||
gic_device,
|
||||
&gic_device,
|
||||
initrd,
|
||||
)
|
||||
.map_err(Error::SetupFDT)?;
|
||||
|
@ -46,7 +46,7 @@ tempfile = "3.1.0"
|
||||
|
||||
[dependencies.linux-loader]
|
||||
git = "https://github.com/rust-vmm/linux-loader"
|
||||
features = ["elf", "bzimage"]
|
||||
features = ["elf", "bzimage", "pe"]
|
||||
|
||||
[dev-dependencies]
|
||||
credibility = "0.1.3"
|
||||
|
@ -1000,13 +1000,13 @@ impl CpuManager {
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub fn get_mpidr(&self) -> Vec<u64> {
|
||||
let vcpu_mpidr = self
|
||||
pub fn get_mpidrs(&self) -> Vec<u64> {
|
||||
let vcpu_mpidrs = self
|
||||
.vcpus
|
||||
.iter()
|
||||
.map(|cpu| cpu.lock().unwrap().get_mpidr())
|
||||
.collect();
|
||||
vcpu_mpidr
|
||||
vcpu_mpidrs
|
||||
}
|
||||
|
||||
#[cfg(feature = "acpi")]
|
||||
|
@ -1092,6 +1092,14 @@ impl DeviceManager {
|
||||
Ok(interrupt_controller)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub fn enable_interrupt_controller(&self) -> DeviceManagerResult<()> {
|
||||
if let Some(interrupt_controller) = &self.interrupt_controller {
|
||||
interrupt_controller.lock().unwrap().enable().unwrap();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn add_interrupt_controller(
|
||||
&mut self,
|
||||
|
@ -56,7 +56,7 @@ pub struct MemoryManager {
|
||||
next_kvm_memory_slot: u32,
|
||||
start_of_device_area: GuestAddress,
|
||||
end_of_device_area: GuestAddress,
|
||||
fd: Arc<VmFd>,
|
||||
pub fd: Arc<VmFd>,
|
||||
hotplug_slots: Vec<HotPlugState>,
|
||||
selected_slot: usize,
|
||||
backing_file: Option<PathBuf>,
|
||||
|
@ -29,7 +29,7 @@ use crate::config::{
|
||||
VmConfig, VsockConfig,
|
||||
};
|
||||
use crate::cpu;
|
||||
use crate::device_manager::{get_win_size, Console, DeviceManager, DeviceManagerError};
|
||||
use crate::device_manager::{self, get_win_size, Console, DeviceManager, DeviceManagerError};
|
||||
use crate::memory_manager::{Error as MemoryManagerError, MemoryManager};
|
||||
use crate::migration::{url_to_path, vm_config_from_snapshot, VM_SNAPSHOT_FILE};
|
||||
use crate::{CPU_MANAGER_SNAPSHOT_ID, DEVICE_MANAGER_SNAPSHOT_ID, MEMORY_MANAGER_SNAPSHOT_ID};
|
||||
@ -46,7 +46,6 @@ use kvm_ioctls::*;
|
||||
use linux_loader::cmdline::Cmdline;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use linux_loader::loader::elf::Error::InvalidElfMagicNumber;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use linux_loader::loader::KernelLoader;
|
||||
use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@ -56,17 +55,14 @@ use std::fs::{File, OpenOptions};
|
||||
use std::io::{self, Write};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::io::{Seek, SeekFrom};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::{result, str, thread};
|
||||
use url::Url;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use vm_memory::{
|
||||
Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryMmap,
|
||||
GuestMemoryRegion,
|
||||
};
|
||||
use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryMmap, GuestMemoryRegion};
|
||||
use vm_memory::{GuestAddress, GuestAddressSpace};
|
||||
use vm_migration::{
|
||||
Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable,
|
||||
Transportable,
|
||||
@ -114,6 +110,9 @@ pub enum Error {
|
||||
/// Cannot configure system
|
||||
ConfigureSystem(arch::Error),
|
||||
|
||||
/// Cannot enable interrupt controller
|
||||
EnableInterruptController(device_manager::DeviceManagerError),
|
||||
|
||||
PoisonedState,
|
||||
|
||||
/// Cannot create a device manager.
|
||||
@ -254,7 +253,6 @@ impl VmState {
|
||||
}
|
||||
|
||||
pub struct Vm {
|
||||
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
|
||||
kernel: File,
|
||||
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
|
||||
initramfs: Option<File>,
|
||||
@ -485,7 +483,25 @@ impl Vm {
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn load_kernel(&mut self) -> Result<EntryPoint> {
|
||||
unimplemented!();
|
||||
let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory();
|
||||
let mem = guest_memory.memory();
|
||||
let entry_addr = match linux_loader::loader::pe::PE::load(
|
||||
mem.deref(),
|
||||
Some(GuestAddress(arch::get_kernel_start())),
|
||||
&mut self.kernel,
|
||||
None,
|
||||
) {
|
||||
Ok(entry_addr) => entry_addr,
|
||||
Err(e) => {
|
||||
return Err(Error::KernelLoad(e));
|
||||
}
|
||||
};
|
||||
|
||||
let entry_point_addr: GuestAddress = entry_addr.kernel_load;
|
||||
|
||||
Ok(EntryPoint {
|
||||
entry_addr: entry_point_addr,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@ -614,11 +630,36 @@ impl Vm {
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn configure_system(&mut self, _entry_addr: EntryPoint) -> Result<()> {
|
||||
let _cmdline_cstring = self.get_cmdline()?;
|
||||
// What to do on AArch64 is:
|
||||
// - Setup GIC
|
||||
// - Generate FDT
|
||||
unimplemented!();
|
||||
let cmdline_cstring = self.get_cmdline()?;
|
||||
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 device_info = &self
|
||||
.device_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_device_info()
|
||||
.clone();
|
||||
|
||||
arch::configure_system(
|
||||
&self.memory_manager.lock().as_ref().unwrap().fd,
|
||||
&mem,
|
||||
&cmdline_cstring,
|
||||
self.cpu_manager.lock().unwrap().boot_vcpus() as u64,
|
||||
vcpu_mpidrs,
|
||||
device_info,
|
||||
&None,
|
||||
)
|
||||
.map_err(Error::ConfigureSystem)?;
|
||||
|
||||
self.device_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.enable_interrupt_controller()
|
||||
.map_err(Error::EnableInterruptController)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn shutdown(&mut self) -> Result<()> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user