diff --git a/src/dragonball/Cargo.lock b/src/dragonball/Cargo.lock index c5be35bfb9..f2e087213b 100644 --- a/src/dragonball/Cargo.lock +++ b/src/dragonball/Cargo.lock @@ -247,9 +247,9 @@ dependencies = [ [[package]] name = "dbs-boot" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a74a8c05a1674d3032e610b4f201c7440c345559bad3dfe6b455ce195785108" +checksum = "5466a92f75aa928a9103dcb2088f6d1638ef9da8945fad7389a73864dfa0182c" dependencies = [ "dbs-arch", "kvm-bindings", diff --git a/src/dragonball/Cargo.toml b/src/dragonball/Cargo.toml index 5036d72728..f70463266e 100644 --- a/src/dragonball/Cargo.toml +++ b/src/dragonball/Cargo.toml @@ -15,7 +15,7 @@ bytes = "1.1.0" dbs-address-space = "0.2.0" dbs-allocator = "0.1.0" dbs-arch = "0.2.0" -dbs-boot = "0.3.0" +dbs-boot = "0.4.0" dbs-device = "0.2.0" dbs-interrupt = { version = "0.2.0", features = ["kvm-irq"] } dbs-legacy-devices = "0.1.0" diff --git a/src/dragonball/src/vm/aarch64.rs b/src/dragonball/src/vm/aarch64.rs index 0ac4553edf..d6ff4c79d5 100644 --- a/src/dragonball/src/vm/aarch64.rs +++ b/src/dragonball/src/vm/aarch64.rs @@ -6,65 +6,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the THIRD-PARTY file. -use std::collections::HashMap; -use std::fmt::Debug; use std::ops::Deref; +use std::sync::MutexGuard; use dbs_arch::gic::GICDevice; use dbs_arch::pmu::initialize_pmu; -use dbs_arch::{DeviceInfoForFDT, DeviceType, VpmuFeatureLevel}; +use dbs_arch::{MMIODeviceInfo, VpmuFeatureLevel}; +use dbs_boot::fdt_utils::*; use dbs_boot::InitrdConfig; use dbs_utils::epoll_manager::EpollManager; use dbs_utils::time::TimestampUs; -use linux_loader::loader::Cmdline; -use vm_memory::{GuestAddressSpace, GuestMemory}; +use linux_loader::cmdline::{Cmdline, Error as CmdlineError}; +use vm_memory::GuestAddressSpace; use vmm_sys_util::eventfd::EventFd; use super::{Vm, VmError}; use crate::address_space_manager::{GuestAddressSpaceImpl, GuestMemoryImpl}; use crate::error::{Error, StartMicroVmError}; use crate::event_manager::EventManager; +use crate::vcpu::VcpuManager; -/// Configures the system and should be called once per vm before starting vcpu threads. -/// For aarch64, we only setup the FDT. -/// -/// # Arguments -/// -/// * `guest_mem` - The memory to be used by the guest. -/// * `cmdline` - The kernel commandline. -/// * `vcpu_mpidr` - Array of MPIDR register values per vcpu. -/// * `device_info` - A hashmap containing the attached devices for building FDT device nodes. -/// * `gic_device` - The GIC device. -/// * `initrd` - Information about an optional initrd. -#[allow(clippy::borrowed_box)] -fn configure_system( - guest_mem: &M, - cmdline: &str, - vcpu_mpidr: Vec, - device_info: Option<&HashMap<(DeviceType, String), T>>, - gic_device: &Box, - initrd: &Option, - vpmu_feature: &VpmuFeatureLevel, -) -> super::Result<()> { - dbs_boot::fdt::create_fdt( - guest_mem, - vcpu_mpidr, - cmdline, - device_info, - gic_device, - initrd, - vpmu_feature, - ) - .map_err(Error::BootSystem)?; - Ok(()) -} - -#[cfg(target_arch = "aarch64")] impl Vm { /// Gets a reference to the irqchip of the VM - #[allow(clippy::borrowed_box)] - pub fn get_irqchip(&self) -> &Box { - self.irqchip_handle.as_ref().unwrap() + pub fn get_irqchip(&self) -> &dyn GICDevice { + self.irqchip_handle.as_ref().unwrap().as_ref() } /// Creates the irq chip in-kernel device model. @@ -138,6 +103,50 @@ impl Vm { Ok(()) } + /// Generate fdt information about VM. + fn get_fdt_vm_info<'a>( + &'a self, + vm_memory: &'a GuestMemoryImpl, + cmdline: &'a str, + initrd_config: Option<&'a InitrdConfig>, + vcpu_manager: &'a MutexGuard, + ) -> FdtVmInfo { + let guest_memory = vm_memory.memory(); + let vcpu_mpidr = vcpu_manager + .vcpus() + .into_iter() + .map(|cpu| cpu.get_mpidr()) + .collect(); + let vcpu_boot_onlined = vec![]; + let vpmu_feature = vcpu_manager.vpmu_feature(); + // This configuration is used for passing cache information into guest. + // TODO: dragonball-sandbox #274; kata-containers #6969 + let cache_passthrough_enabled = false; + let fdt_vcpu_info = FdtVcpuInfo::new( + vcpu_mpidr, + vcpu_boot_onlined, + vpmu_feature, + cache_passthrough_enabled, + ); + + FdtVmInfo::new(guest_memory, cmdline, initrd_config, fdt_vcpu_info) + } + + // This method is used for passing cache/numa information into guest + // TODO: dragonball-sandbox #274,#275; kata-containers #6969 + /// Generate fdt information about cache/numa + fn get_fdt_numa_info(&self) -> FdtNumaInfo { + FdtNumaInfo::default() + } + + /// Generate fdt information about devices + fn get_fdt_device_info(&self) -> FdtDeviceInfo { + FdtDeviceInfo::new( + self.device_manager().get_mmio_device_info(), + self.get_irqchip(), + ) + } + /// Execute system architecture specific configurations. /// /// 1) set guest kernel boot parameters @@ -149,24 +158,23 @@ impl Vm { initrd: Option, ) -> std::result::Result<(), StartMicroVmError> { let vcpu_manager = self.vcpu_manager().map_err(StartMicroVmError::Vcpu)?; - let vpmu_feature = vcpu_manager.vpmu_feature(); - let vcpu_mpidr = vcpu_manager - .vcpus() - .into_iter() - .map(|cpu| cpu.get_mpidr()) - .collect(); - let guest_memory = vm_memory.memory(); + let cmdline_cstring = cmdline + .as_cstring() + .map_err(StartMicroVmError::ProcessCommandlne)?; + let fdt_vm_info = self.get_fdt_vm_info( + vm_memory, + cmdline_cstring + .to_str() + .map_err(|_| StartMicroVmError::ProcessCommandlne(CmdlineError::InvalidAscii))?, + initrd.as_ref(), + &vcpu_manager, + ); + let fdt_numa_info = self.get_fdt_numa_info(); + let fdt_device_info = self.get_fdt_device_info(); - configure_system( - guest_memory, - cmdline.as_cstring().unwrap().to_str().unwrap(), - vcpu_mpidr, - self.device_manager.get_mmio_device_info(), - self.get_irqchip(), - &initrd, - &vpmu_feature, - ) - .map_err(StartMicroVmError::ConfigureSystem) + dbs_boot::fdt::create_fdt(fdt_vm_info, fdt_numa_info, fdt_device_info) + .map(|_| ()) + .map_err(|e| StartMicroVmError::ConfigureSystem(Error::BootSystem(e))) } pub(crate) fn register_events(