diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index ff7575c0b..e6925bb7f 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -21,10 +21,12 @@ use std::sync::{Arc, Barrier, Mutex}; use std::{any, cmp, hint, io, panic, result, thread, time}; #[cfg(target_arch = "aarch64")] -use acpi_tables::pptt::{PPTT, ProcessorNode}; +use acpi_tables::pptt::{CacheNodeBuilder, CacheType, PPTT, ProcessorNode}; use acpi_tables::sdt::Sdt; use acpi_tables::{Aml, aml}; use anyhow::anyhow; +#[cfg(target_arch = "aarch64")] +use arch::aarch64::cache::{CacheTopologyInfo, read_cache_topology}; use arch::{EntryPoint, NumaNodes, layout}; #[cfg(target_arch = "aarch64")] use devices::gic::Gic; @@ -1955,11 +1957,90 @@ impl CpuManager { .unwrap_or((1, u16::try_from(self.max_vcpus()).unwrap(), 1, 1)); let cores_per_package = cores_per_die * dies_per_package; + // Add cache info. + let cache_info = read_cache_topology(); + let CacheTopologyInfo { + l1_d_cache_size, + l1_d_cache_line_size, + l1_d_cache_sets, + l1_i_cache_size, + l1_i_cache_line_size, + l1_i_cache_sets, + l2_cache_size, + l2_cache_line_size, + l2_cache_sets, + l3_cache_size, + l3_cache_line_size, + l3_cache_sets, + .. + } = cache_info.unwrap_or_default(); + let mut pptt = PPTT::new(*b"CLOUDH", *b"CHPPTT ", 1); + let l3_cache_handle = if l3_cache_size != 0 { + let l3_cache_node = CacheNodeBuilder::default() + .cache_type(CacheType::Unified) + .sets(l3_cache_sets) + .size(l3_cache_size) + .line_size(l3_cache_line_size as u16) + .to_node(); + Some(pptt.add_cache(l3_cache_node)) + } else { + None + }; + + let l2_cache_handle = if l2_cache_size != 0 { + let l2_cache_node = CacheNodeBuilder::default() + .cache_type(CacheType::Unified) + .sets(l2_cache_sets) + .size(l2_cache_size) + .line_size(l2_cache_line_size as u16) + .to_node(); + Some(pptt.add_cache(l2_cache_node)) + } else { + None + }; + + let l1d_cache_handle = if l1_d_cache_size != 0 { + let mut l1d_cache_node = CacheNodeBuilder::default() + .cache_type(CacheType::Data) + .sets(l1_d_cache_sets) + .size(l1_d_cache_size) + .line_size(l1_d_cache_line_size as u16); + + if let Some(ref l2_cache_handle) = l2_cache_handle { + l1d_cache_node = l1d_cache_node.next_level(l2_cache_handle); + } + + Some(pptt.add_cache(l1d_cache_node.to_node())) + } else { + None + }; + + let l1i_cache_handle = if l1_i_cache_size != 0 { + let mut l1i_cache_node = CacheNodeBuilder::default() + .cache_type(CacheType::Instruction) + .sets(l1_i_cache_sets) + .size(l1_i_cache_size) + .line_size(l1_i_cache_line_size as u16); + + if let Some(ref l2_cache_handle) = l2_cache_handle { + l1i_cache_node = l1i_cache_node.next_level(l2_cache_handle); + } + + Some(pptt.add_cache(l1i_cache_node.to_node())) + } else { + None + }; + for cluster_idx in 0..packages { if cpus < self.config.boot_vcpus as usize { - let cluster_hierarchy_node = ProcessorNode::new(None, cluster_idx as u32).valid(); + let mut cluster_hierarchy_node = + ProcessorNode::new(None, cluster_idx as u32).valid(); + if let Some(ref l3_cache_handle) = l3_cache_handle { + cluster_hierarchy_node = cluster_hierarchy_node.add_cache(l3_cache_handle); + } + let cluster_handle = pptt.add_processor(cluster_hierarchy_node); for core_idx in 0..cores_per_package { @@ -1969,19 +2050,41 @@ impl CpuManager { let core_handle = pptt.add_processor(core_hierarchy_node); for _thread_idx in 0..threads_per_core { - let thread_hierarchy_node = + let mut thread_hierarchy_node = ProcessorNode::new(Some(&core_handle), uid as u32) .valid() .thread() .leaf(); + + if let Some(ref l1d_cache_handle) = l1d_cache_handle { + thread_hierarchy_node = + thread_hierarchy_node.add_cache(l1d_cache_handle); + } + + if let Some(ref l1i_cache_handle) = l1i_cache_handle { + thread_hierarchy_node = + thread_hierarchy_node.add_cache(l1i_cache_handle); + } + pptt.add_processor(thread_hierarchy_node); uid += 1; } } else { - let thread_hierarchy_node = + let mut thread_hierarchy_node = ProcessorNode::new(Some(&cluster_handle), uid as u32) .valid() .leaf(); + + if let Some(ref l1d_cache_handle) = l1d_cache_handle { + thread_hierarchy_node = + thread_hierarchy_node.add_cache(l1d_cache_handle); + } + + if let Some(ref l1i_cache_handle) = l1i_cache_handle { + thread_hierarchy_node = + thread_hierarchy_node.add_cache(l1i_cache_handle); + } + pptt.add_processor(thread_hierarchy_node); uid += 1; }