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