From 7fb980f17bc2f5be9a0f9b62e1cc694b700503a3 Mon Sep 17 00:00:00 2001 From: Henry Wang Date: Thu, 29 Jul 2021 03:44:50 -0400 Subject: [PATCH] arch, vmm: Pass cpu topology configuation to FDT In an Arm system, the hierarchy of CPUs is defined through three entities that are used to describe the layout of physical CPUs in the system: - cluster - core - thread All these three entities have their own FDT node field. Therefore, This commit adds an AArch64-specific helper to pass the config from the Cloud Hypervisor command line to the `configure_system`, where eventually the `create_fdt` is called. Signed-off-by: Henry Wang --- arch/src/aarch64/fdt.rs | 10 ++++++++-- arch/src/aarch64/mod.rs | 3 +++ vmm/src/cpu.rs | 8 ++++++++ vmm/src/vm.rs | 3 +++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/src/aarch64/fdt.rs b/arch/src/aarch64/fdt.rs index bca1b1192..5e704465b 100644 --- a/arch/src/aarch64/fdt.rs +++ b/arch/src/aarch64/fdt.rs @@ -72,10 +72,12 @@ pub enum Error { type Result = result::Result; /// Creates the flattened device tree for this aarch64 VM. +#[allow(clippy::too_many_arguments)] pub fn create_fdt( guest_mem: &GuestMemoryMmap, cmdline: &CStr, vcpu_mpidr: Vec, + vcpu_topology: Option<(u8, u8, u8)>, device_info: &HashMap<(DeviceType, String), T, S>, gic_device: &dyn GicDevice, initrd: &Option, @@ -98,7 +100,7 @@ pub fn create_fdt, guest_mem: &GuestMemoryMmap) -> R } // Following are the auxiliary function for creating the different nodes that we append to our FDT. -fn create_cpu_nodes(fdt: &mut FdtWriter, vcpu_mpidr: &[u64]) -> FdtWriterResult<()> { +fn create_cpu_nodes( + fdt: &mut FdtWriter, + vcpu_mpidr: &[u64], + vcpu_topology: Option<(u8, u8, u8)>, +) -> FdtWriterResult<()> { // See https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/arm/cpus.yaml. let cpus_node = fdt.begin_node("cpus")?; fdt.property_u32("#address-cells", 0x1)?; diff --git a/arch/src/aarch64/mod.rs b/arch/src/aarch64/mod.rs index 52a326194..d2f786c61 100644 --- a/arch/src/aarch64/mod.rs +++ b/arch/src/aarch64/mod.rs @@ -135,10 +135,12 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region } /// Configures the system and should be called once per vm before starting vcpu threads. +#[allow(clippy::too_many_arguments)] pub fn configure_system( guest_mem: &GuestMemoryMmap, cmdline_cstring: &CStr, vcpu_mpidr: Vec, + vcpu_topology: Option<(u8, u8, u8)>, device_info: &HashMap<(DeviceType, String), T, S>, initrd: &Option, pci_space_address: &(u64, u64), @@ -148,6 +150,7 @@ pub fn configure_system Option<(u8, u8, u8)> { + self.config + .topology + .clone() + .map(|t| (t.threads_per_core, t.cores_per_die, t.packages)) + } + #[cfg(feature = "acpi")] pub fn create_madt(&self) -> Sdt { use crate::acpi; diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index e263e70a3..55b300777 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -1072,6 +1072,7 @@ impl Vm { fn configure_system(&mut self) -> Result<()> { let cmdline_cstring = self.get_cmdline()?; let vcpu_mpidrs = self.cpu_manager.lock().unwrap().get_mpidrs(); + let vcpu_topology = self.cpu_manager.lock().unwrap().get_vcpu_topology(); let mem = self.memory_manager.lock().unwrap().boot_guest_memory(); let initramfs_config = match self.initramfs { Some(_) => Some(self.load_initramfs(&mem)?), @@ -1129,6 +1130,7 @@ impl Vm { &mem, &cmdline_cstring, vcpu_mpidrs, + vcpu_topology, device_info, &initramfs_config, &pci_space, @@ -2653,6 +2655,7 @@ mod tests { &mem, &CString::new("console=tty0").unwrap(), vec![0], + Some((0, 0, 0)), &dev_info, &*gic, &None,