From 7dd260f82fba0c37ff092cd770edf16019b7d500 Mon Sep 17 00:00:00 2001 From: Bo Chen Date: Wed, 11 Oct 2023 11:52:24 -0700 Subject: [PATCH] arch, vmm: Add new struct CpuidConfig This struct contains all configuration fields that controls the way how we generate CPUID for the guest on x86_64. This allows cleaner extension when adding new configuration fields. Signed-off-by: Bo Chen --- arch/src/lib.rs | 2 +- arch/src/x86_64/mod.rs | 30 +++++++++++++++++++----------- vmm/src/cpu.rs | 14 ++++++++------ vmm/src/lib.rs | 26 +++++++++++++++----------- vmm/src/vm.rs | 12 +++++++----- 5 files changed, 50 insertions(+), 34 deletions(-) diff --git a/arch/src/lib.rs b/arch/src/lib.rs index 62cd1df6c..5de2247ea 100644 --- a/arch/src/lib.rs +++ b/arch/src/lib.rs @@ -92,7 +92,7 @@ pub mod x86_64; pub use x86_64::{ arch_memory_regions, configure_system, configure_vcpu, generate_common_cpuid, get_host_cpu_phys_bits, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE, - layout::CMDLINE_START, regs, CpuidFeatureEntry, EntryPoint, _NSIG, + layout::CMDLINE_START, regs, CpuidConfig, CpuidFeatureEntry, EntryPoint, _NSIG, }; /// Safe wrapper for `sysconf(_SC_PAGESIZE)`. diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index ba65b9423..f0cee7526 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -145,6 +145,14 @@ struct BootParamsWrapper(boot_params); // SAFETY: BootParamsWrap is a wrapper over `boot_params` (a series of ints). unsafe impl ByteValued for BootParamsWrapper {} +pub struct CpuidConfig { + pub sgx_epc_sections: Option>, + pub phys_bits: u8, + pub kvm_hyperv: bool, + #[cfg(feature = "tdx")] + pub tdx: bool, +} + #[derive(Debug)] pub enum Error { /// Error writing MP table to memory. @@ -552,10 +560,7 @@ impl CpuidFeatureEntry { pub fn generate_common_cpuid( hypervisor: &Arc, - sgx_epc_sections: Option>, - phys_bits: u8, - kvm_hyperv: bool, - #[cfg(feature = "tdx")] tdx_enabled: bool, + config: &CpuidConfig, ) -> super::Result> { // SAFETY: cpuid called with valid leaves if unsafe { x86_64::__cpuid(1) }.ecx & 1 << HYPERVISOR_ECX_BIT == 1 << HYPERVISOR_ECX_BIT { @@ -573,7 +578,10 @@ pub fn generate_common_cpuid( ); } - info!("Generating guest CPUID for with physical address size: {phys_bits}"); + info!( + "Generating guest CPUID for with physical address size: {}", + config.phys_bits + ); let cpuid_patches = vec![ // Patch tsc deadline timer bit CpuidPatch { @@ -614,12 +622,12 @@ pub fn generate_common_cpuid( CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches); - if let Some(sgx_epc_sections) = sgx_epc_sections { + if let Some(sgx_epc_sections) = &config.sgx_epc_sections { update_cpuid_sgx(&mut cpuid, sgx_epc_sections)?; } #[cfg(feature = "tdx")] - let tdx_capabilities = if tdx_enabled { + let tdx_capabilities = if config.tdx { let caps = hypervisor .tdx_capabilities() .map_err(Error::TdxCapabilities)?; @@ -667,12 +675,12 @@ pub fn generate_common_cpuid( } // Set CPU physical bits 0x8000_0008 => { - entry.eax = (entry.eax & 0xffff_ff00) | (phys_bits as u32 & 0xff); + entry.eax = (entry.eax & 0xffff_ff00) | (config.phys_bits as u32 & 0xff); } 0x4000_0001 => { // These features are not supported by TDX #[cfg(feature = "tdx")] - if tdx_enabled { + if config.tdx { entry.eax &= !(1 << KVM_FEATURE_CLOCKSOURCE_BIT | 1 << KVM_FEATURE_CLOCKSOURCE2_BIT | 1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT @@ -700,7 +708,7 @@ pub fn generate_common_cpuid( }); } - if kvm_hyperv { + if config.kvm_hyperv { // Remove conflicting entries cpuid.retain(|c| c.function != 0x4000_0000); cpuid.retain(|c| c.function != 0x4000_0001); @@ -1293,7 +1301,7 @@ fn update_cpuid_topology( // sections exposed to the guest. fn update_cpuid_sgx( cpuid: &mut Vec, - epc_sections: Vec, + epc_sections: &Vec, ) -> Result<(), Error> { // Something's wrong if there's no EPC section. if epc_sections.is_empty() { diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index ebb4c9ac0..f0cbfe653 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -726,7 +726,7 @@ impl CpuManager { &mut self, memory_manager: &Arc>, hypervisor: &Arc, - #[cfg(feature = "tdx")] tdx_enabled: bool, + #[cfg(feature = "tdx")] tdx: bool, ) -> Result<()> { let sgx_epc_sections = memory_manager .lock() @@ -739,11 +739,13 @@ impl CpuManager { let phys_bits = physical_bits(hypervisor, self.config.max_phys_bits); arch::generate_common_cpuid( hypervisor, - sgx_epc_sections, - phys_bits, - self.config.kvm_hyperv, - #[cfg(feature = "tdx")] - tdx_enabled, + &arch::CpuidConfig { + sgx_epc_sections, + phys_bits, + kvm_hyperv: self.config.kvm_hyperv, + #[cfg(feature = "tdx")] + tdx, + }, ) .map_err(Error::CommonCpuId)? }; diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 4e859ecef..c7e61f636 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -1664,16 +1664,18 @@ impl Vmm { #[cfg(all(feature = "kvm", target_arch = "x86_64"))] let common_cpuid = { #[cfg(feature = "tdx")] - let tdx_enabled = vm_config.lock().unwrap().is_tdx_enabled(); + let tdx = vm_config.lock().unwrap().is_tdx_enabled(); let phys_bits = vm::physical_bits(&hypervisor, vm_config.lock().unwrap().cpus.max_phys_bits); arch::generate_common_cpuid( &hypervisor, - None, - phys_bits, - vm_config.lock().unwrap().cpus.kvm_hyperv, - #[cfg(feature = "tdx")] - tdx_enabled, + &arch::CpuidConfig { + sgx_epc_sections: None, + phys_bits, + kvm_hyperv: vm_config.lock().unwrap().cpus.kvm_hyperv, + #[cfg(feature = "tdx")] + tdx, + }, ) .map_err(|e| { MigratableError::MigrateReceive(anyhow!("Error generating common cpuid': {:?}", e)) @@ -1858,11 +1860,13 @@ impl Vmm { let phys_bits = vm::physical_bits(&self.hypervisor, vm_config.cpus.max_phys_bits); arch::generate_common_cpuid( &self.hypervisor.clone(), - None, - phys_bits, - vm_config.cpus.kvm_hyperv, - #[cfg(feature = "tdx")] - vm_config.is_tdx_enabled(), + &arch::CpuidConfig { + sgx_epc_sections: None, + phys_bits, + kvm_hyperv: vm_config.cpus.kvm_hyperv, + #[cfg(feature = "tdx")] + tdx: vm_config.is_tdx_enabled(), + }, ) .map_err(|e| { MigratableError::MigrateReceive(anyhow!("Error generating common cpuid: {:?}", e)) diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 81a0382a0..6f474779a 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -2415,11 +2415,13 @@ impl Snapshottable for Vm { ); arch::generate_common_cpuid( &self.hypervisor, - None, - phys_bits, - self.config.lock().unwrap().cpus.kvm_hyperv, - #[cfg(feature = "tdx")] - tdx_enabled, + &arch::CpuidConfig { + sgx_epc_sections: None, + phys_bits, + kvm_hyperv: self.config.lock().unwrap().cpus.kvm_hyperv, + #[cfg(feature = "tdx")] + tdx: tdx_enabled, + }, ) .map_err(|e| { MigratableError::MigrateReceive(anyhow!("Error generating common cpuid: {:?}", e))