From 9446dad1d0e8fa702563ece5a148a06b1cdeccef Mon Sep 17 00:00:00 2001 From: Anirudh Rayabharam Date: Tue, 28 Apr 2026 13:02:24 +0000 Subject: [PATCH] arch: aarch64: extract cache topology collection into a helper Both arch/src/aarch64/fdt.rs and vmm/src/cpu.rs declared the same ~14 cache info locals (size/line_size/sets for L1D/L1I/L2/L3, plus shared flags for L2/L3), checked for /sys/devices/system/cpu/cpu0/cache, and populated those locals via get_cache_size / get_cache_coherency_line_size / get_cache_number_of_sets / get_cache_shared. Two near-identical ~30-line blocks. Add a CacheTopologyInfo struct in arch/src/aarch64/cache.rs whose field names mirror the existing locals, plus a read_cache_topology() helper that returns None when the sysfs hierarchy is missing and only queries get_cache_shared for L2/L3 when their size is non-zero (preserving current behavior). Both call sites now obtain the info via read_cache_topology() and destructure it back into locals of the same name, so all downstream references are unchanged. Assisted-by: Copilot-CLI:Claude-Opus-4.7 Signed-off-by: Anirudh Rayabharam --- arch/src/aarch64/cache.rs | 63 +++++++++++++++++++++++++++++ arch/src/aarch64/fdt.rs | 83 ++++++++++----------------------------- 2 files changed, 83 insertions(+), 63 deletions(-) diff --git a/arch/src/aarch64/cache.rs b/arch/src/aarch64/cache.rs index 20247821d..9200c5962 100644 --- a/arch/src/aarch64/cache.rs +++ b/arch/src/aarch64/cache.rs @@ -9,6 +9,8 @@ use std::fs; use std::path::Path; +use log::warn; + #[derive(Copy, Clone)] pub enum CacheLevel { /// L1 data cache @@ -123,3 +125,64 @@ pub fn get_cache_shared(cache_level: CacheLevel) -> bool { result } + +#[derive(Default, Copy, Clone, Debug)] +pub struct CacheTopologyInfo { + pub l1_d_cache_size: u32, + pub l1_d_cache_line_size: u32, + pub l1_d_cache_sets: u32, + + pub l1_i_cache_size: u32, + pub l1_i_cache_line_size: u32, + pub l1_i_cache_sets: u32, + + pub l2_cache_size: u32, + pub l2_cache_line_size: u32, + pub l2_cache_sets: u32, + + pub l3_cache_size: u32, + pub l3_cache_line_size: u32, + pub l3_cache_sets: u32, + + pub l2_cache_shared: bool, + pub l3_cache_shared: bool, +} + +/// Reads cache topology information from sysfs for cpu0. +pub fn read_cache_topology() -> Option { + let cache_path = Path::new("/sys/devices/system/cpu/cpu0/cache"); + if !cache_path.exists() { + warn!("Cache topology information is not available in sysfs."); + return None; + } + + let mut info = CacheTopologyInfo { + l1_d_cache_size: get_cache_size(CacheLevel::L1D), + l1_d_cache_line_size: get_cache_coherency_line_size(CacheLevel::L1D), + l1_d_cache_sets: get_cache_number_of_sets(CacheLevel::L1D), + + l1_i_cache_size: get_cache_size(CacheLevel::L1I), + l1_i_cache_line_size: get_cache_coherency_line_size(CacheLevel::L1I), + l1_i_cache_sets: get_cache_number_of_sets(CacheLevel::L1I), + + l2_cache_size: get_cache_size(CacheLevel::L2), + l2_cache_line_size: get_cache_coherency_line_size(CacheLevel::L2), + l2_cache_sets: get_cache_number_of_sets(CacheLevel::L2), + + l3_cache_size: get_cache_size(CacheLevel::L3), + l3_cache_line_size: get_cache_coherency_line_size(CacheLevel::L3), + l3_cache_sets: get_cache_number_of_sets(CacheLevel::L3), + + l2_cache_shared: false, + l3_cache_shared: false, + }; + + if info.l2_cache_size != 0 { + info.l2_cache_shared = get_cache_shared(CacheLevel::L2); + } + if info.l3_cache_size != 0 { + info.l3_cache_shared = get_cache_shared(CacheLevel::L3); + } + + Some(info) +} diff --git a/arch/src/aarch64/fdt.rs b/arch/src/aarch64/fdt.rs index 17216db55..2428e7047 100644 --- a/arch/src/aarch64/fdt.rs +++ b/arch/src/aarch64/fdt.rs @@ -10,7 +10,6 @@ use std::collections::HashMap; use std::ffi::CStr; use std::fmt::Debug; use std::hash::BuildHasher; -use std::path::Path; use std::sync::{Arc, Mutex}; use std::{cmp, result, str}; @@ -21,16 +20,13 @@ use hypervisor::arch::aarch64::regs::{ AARCH64_ARCH_TIMER_HYP_IRQ, AARCH64_ARCH_TIMER_PHYS_NONSECURE_IRQ, AARCH64_ARCH_TIMER_PHYS_SECURE_IRQ, AARCH64_ARCH_TIMER_VIRT_IRQ, AARCH64_PMU_IRQ, }; -use log::{debug, info, warn}; +use log::{debug, info}; use thiserror::Error; use vm_fdt::{FdtWriter, FdtWriterResult}; use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryError, GuestMemoryRegion}; use super::super::{DeviceType, GuestMemoryMmap, InitramfsConfig}; -use super::cache::{ - CacheLevel, get_cache_coherency_line_size, get_cache_number_of_sets, get_cache_shared, - get_cache_size, -}; +use super::cache::{CacheTopologyInfo, read_cache_topology}; use super::layout::{ GIC_V2M_COMPATIBLE, GICV2M_SPI_BASE, GICV2M_SPI_NUM, IRQ_BASE, MEM_32BIT_DEVICES_SIZE, MEM_32BIT_DEVICES_START, MEM_PCI_IO_SIZE, MEM_PCI_IO_START, PCI_HIGH_BASE, @@ -178,63 +174,24 @@ fn create_cpu_nodes( threads_per_core as u32 * cores_per_die as u32 * dies_per_package as u32 * packages as u32; // Add cache info. - // L1 Data Cache Info. - let mut l1_d_cache_size: u32 = 0; - let mut l1_d_cache_line_size: u32 = 0; - let mut l1_d_cache_sets: u32 = 0; - - // L1 Instruction Cache Info. - let mut l1_i_cache_size: u32 = 0; - let mut l1_i_cache_line_size: u32 = 0; - let mut l1_i_cache_sets: u32 = 0; - - // L2 Cache Info. - let mut l2_cache_size: u32 = 0; - let mut l2_cache_line_size: u32 = 0; - let mut l2_cache_sets: u32 = 0; - - // L3 Cache Info. - let mut l3_cache_size: u32 = 0; - let mut l3_cache_line_size: u32 = 0; - let mut l3_cache_sets: u32 = 0; - - // Cache Shared Info. - let mut l2_cache_shared: bool = false; - let mut l3_cache_shared: bool = false; - - let cache_path = Path::new("/sys/devices/system/cpu/cpu0/cache"); - let cache_exist: bool = cache_path.exists(); - if cache_exist { - // L1 Data Cache Info. - l1_d_cache_size = get_cache_size(CacheLevel::L1D); - l1_d_cache_line_size = get_cache_coherency_line_size(CacheLevel::L1D); - l1_d_cache_sets = get_cache_number_of_sets(CacheLevel::L1D); - - // L1 Instruction Cache Info. - l1_i_cache_size = get_cache_size(CacheLevel::L1I); - l1_i_cache_line_size = get_cache_coherency_line_size(CacheLevel::L1I); - l1_i_cache_sets = get_cache_number_of_sets(CacheLevel::L1I); - - // L2 Cache Info. - l2_cache_size = get_cache_size(CacheLevel::L2); - l2_cache_line_size = get_cache_coherency_line_size(CacheLevel::L2); - l2_cache_sets = get_cache_number_of_sets(CacheLevel::L2); - - // L3 Cache Info. - l3_cache_size = get_cache_size(CacheLevel::L3); - l3_cache_line_size = get_cache_coherency_line_size(CacheLevel::L3); - l3_cache_sets = get_cache_number_of_sets(CacheLevel::L3); - - // Cache Shared Info. - if l2_cache_size != 0 { - l2_cache_shared = get_cache_shared(CacheLevel::L2); - } - if l3_cache_size != 0 { - l3_cache_shared = get_cache_shared(CacheLevel::L3); - } - } else { - warn!("cache sysfs system does not exist."); - } + let cache_info = read_cache_topology(); + let cache_exist = cache_info.is_some(); + 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, + l2_cache_shared, + l3_cache_shared, + } = cache_info.unwrap_or_default(); // Arm boot protocol requires a minimal Device Tree // https://docs.kernel.org/arch/arm64/booting.html