From 725e388684166e8352d685f90ccf1ddeadb0123e Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Thu, 1 Dec 2022 16:43:09 +0000 Subject: [PATCH] vmm: Seperate the CPUID setup from the CpuManager::new() This allows the decoupling of CpuManager and MemoryManager. See: #4761 Signed-off-by: Rob Bradford --- arch/src/x86_64/mod.rs | 2 +- vmm/src/cpu.rs | 67 +++++++++++++++++++++++++----------------- vmm/src/lib.rs | 4 +-- vmm/src/vm.rs | 17 +++++++++-- 4 files changed, 57 insertions(+), 33 deletions(-) diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index 0789db72b..af45c272d 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -547,7 +547,7 @@ impl CpuidFeatureEntry { } pub fn generate_common_cpuid( - hypervisor: Arc, + hypervisor: &Arc, topology: Option<(u8, u8, u8)>, sgx_epc_sections: Option>, phys_bits: u8, diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 5c2cd4206..cc0d7a480 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -20,6 +20,7 @@ use crate::coredump::{ }; #[cfg(feature = "guest_debug")] use crate::gdb::{get_raw_tid, Debuggable, DebuggableError}; +#[cfg(target_arch = "x86_64")] use crate::memory_manager::MemoryManager; use crate::seccomp_filters::{get_seccomp_filter, Thread}; #[cfg(target_arch = "x86_64")] @@ -576,12 +577,11 @@ impl CpuManager { #[allow(clippy::too_many_arguments)] pub fn new( config: &CpusConfig, - memory_manager: &Arc>, vm: Arc, exit_evt: EventFd, reset_evt: EventFd, #[cfg(feature = "guest_debug")] vm_debug_evt: EventFd, - hypervisor: Arc, + hypervisor: &Arc, seccomp_action: SeccompAction, vm_ops: Arc, #[cfg(feature = "tdx")] tdx_enabled: bool, @@ -591,30 +591,6 @@ impl CpuManager { vcpu_states.resize_with(usize::from(config.max_vcpus), VcpuState::default); let hypervisor_type = hypervisor.hypervisor_type(); - #[cfg(target_arch = "x86_64")] - let sgx_epc_sections = memory_manager - .lock() - .unwrap() - .sgx_epc_region() - .as_ref() - .map(|sgx_epc_region| sgx_epc_region.epc_sections().values().cloned().collect()); - #[cfg(target_arch = "x86_64")] - let cpuid = { - let phys_bits = physical_bits(config.max_phys_bits); - arch::generate_common_cpuid( - hypervisor, - config - .topology - .clone() - .map(|t| (t.threads_per_core, t.cores_per_die, t.dies_per_package)), - sgx_epc_sections, - phys_bits, - config.kvm_hyperv, - #[cfg(feature = "tdx")] - tdx_enabled, - ) - .map_err(Error::CommonCpuId)? - }; #[cfg(target_arch = "x86_64")] if config.features.amx { const ARCH_GET_XCOMP_GUEST_PERM: usize = 0x1024; @@ -678,7 +654,7 @@ impl CpuManager { config: config.clone(), interrupt_controller: None, #[cfg(target_arch = "x86_64")] - cpuid, + cpuid: Vec::new(), vm, vcpus_kill_signalled: Arc::new(AtomicBool::new(false)), vcpus_pause_signalled: Arc::new(AtomicBool::new(false)), @@ -698,6 +674,39 @@ impl CpuManager { }))) } + #[cfg(target_arch = "x86_64")] + pub fn populate_cpuid( + &mut self, + memory_manager: &Arc>, + hypervisor: &Arc, + #[cfg(feature = "tdx")] tdx_enabled: bool, + ) -> Result<()> { + let sgx_epc_sections = memory_manager + .lock() + .unwrap() + .sgx_epc_region() + .as_ref() + .map(|sgx_epc_region| sgx_epc_region.epc_sections().values().cloned().collect()); + self.cpuid = { + let phys_bits = physical_bits(self.config.max_phys_bits); + arch::generate_common_cpuid( + hypervisor, + self.config + .topology + .clone() + .map(|t| (t.threads_per_core, t.cores_per_die, t.dies_per_package)), + sgx_epc_sections, + phys_bits, + self.config.kvm_hyperv, + #[cfg(feature = "tdx")] + tdx_enabled, + ) + .map_err(Error::CommonCpuId)? + }; + + Ok(()) + } + fn create_vcpu(&mut self, cpu_id: u8, snapshot: Option) -> Result>> { info!("Creating vCPU: cpu_id = {}", cpu_id); @@ -733,6 +742,9 @@ impl CpuManager { ) -> Result<()> { let mut vcpu = vcpu.lock().unwrap(); + #[cfg(target_arch = "x86_64")] + assert!(!self.cpuid.is_empty()); + #[cfg(target_arch = "x86_64")] vcpu.configure(boot_setup, self.cpuid.clone(), self.config.kvm_hyperv) .expect("Failed to configure vCPU"); @@ -1200,6 +1212,7 @@ impl CpuManager { #[cfg(target_arch = "x86_64")] pub fn common_cpuid(&self) -> Vec { + assert!(!self.cpuid.is_empty()); self.cpuid.clone() } diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 6376ffff1..d198dba2d 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -1505,7 +1505,7 @@ impl Vmm { let common_cpuid = { let phys_bits = vm::physical_bits(vm_config.lock().unwrap().cpus.max_phys_bits); arch::generate_common_cpuid( - hypervisor, + &hypervisor, None, None, phys_bits, @@ -1695,7 +1695,7 @@ impl Vmm { let phys_bits = vm::physical_bits(vm_config.cpus.max_phys_bits); arch::generate_common_cpuid( - self.hypervisor.clone(), + &self.hypervisor.clone(), None, None, phys_bits, diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 20857df0b..c4837257e 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -525,13 +525,12 @@ impl Vm { let cpus_config = { &config.lock().unwrap().cpus.clone() }; let cpu_manager = cpu::CpuManager::new( cpus_config, - &memory_manager, vm.clone(), exit_evt.try_clone().map_err(Error::EventFdClone)?, reset_evt.try_clone().map_err(Error::EventFdClone)?, #[cfg(feature = "guest_debug")] vm_debug_evt, - hypervisor.clone(), + &hypervisor, seccomp_action.clone(), vm_ops, #[cfg(feature = "tdx")] @@ -540,6 +539,18 @@ impl Vm { ) .map_err(Error::CpuManager)?; + #[cfg(target_arch = "x86_64")] + cpu_manager + .lock() + .unwrap() + .populate_cpuid( + &memory_manager, + &hypervisor, + #[cfg(feature = "tdx")] + tdx_enabled, + ) + .map_err(Error::CpuManager)?; + cpu_manager .lock() .unwrap() @@ -2487,7 +2498,7 @@ impl Snapshottable for Vm { let common_cpuid = { let phys_bits = physical_bits(self.config.lock().unwrap().cpus.max_phys_bits); arch::generate_common_cpuid( - self.hypervisor.clone(), + &self.hypervisor, None, None, phys_bits,