diff --git a/arch/src/aarch64/mod.rs b/arch/src/aarch64/mod.rs index 124b8cbe9..c5b20e245 100644 --- a/arch/src/aarch64/mod.rs +++ b/arch/src/aarch64/mod.rs @@ -198,11 +198,8 @@ pub fn initramfs_load_addr( } } -pub fn get_host_cpu_phys_bits() -> u8 { - // A dummy hypervisor created only for querying the host IPA size and will - // be freed after the query. - let hv = hypervisor::new().unwrap(); - let host_cpu_phys_bits = hv.get_host_ipa_limit().try_into().unwrap(); +pub fn get_host_cpu_phys_bits(hypervisor: &Arc) -> u8 { + let host_cpu_phys_bits = hypervisor.get_host_ipa_limit().try_into().unwrap(); if host_cpu_phys_bits == 0 { // Host kernel does not support `get_host_ipa_limit`, // we return the default value 40 here. diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index a7d97aabc..567c47f36 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -16,7 +16,7 @@ use crate::GuestMemoryMmap; use crate::InitramfsConfig; use crate::RegionType; use hypervisor::arch::x86::{CpuIdEntry, CPUID_FLAG_VALID_INDEX}; -use hypervisor::{HypervisorCpuError, HypervisorError}; +use hypervisor::{CpuVendor, HypervisorCpuError, HypervisorError}; use linux_loader::loader::bootparam::boot_params; use linux_loader::loader::elf::start_info::{ hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info, @@ -1078,7 +1078,7 @@ pub fn initramfs_load_addr( Ok(aligned_addr) } -pub fn get_host_cpu_phys_bits() -> u8 { +pub fn get_host_cpu_phys_bits(hypervisor: &Arc) -> u8 { // SAFETY: call cpuid with valid leaves unsafe { let leaf = x86_64::__cpuid(0x8000_0000); @@ -1087,9 +1087,7 @@ pub fn get_host_cpu_phys_bits() -> u8 { // Some physical address bits may become reserved when the feature is enabled. // See AMD64 Architecture Programmer's Manual Volume 2, Section 7.10.1 let reduced = if leaf.eax >= 0x8000_001f - && leaf.ebx == 0x6874_7541 // Vendor ID: AuthenticAMD - && leaf.ecx == 0x444d_4163 - && leaf.edx == 0x6974_6e65 + && matches!(hypervisor.get_cpu_vendor(), CpuVendor::AMD) && x86_64::__cpuid(0x8000_001f).eax & 0x1 != 0 { (x86_64::__cpuid(0x8000_001f).ebx >> 6) & 0x3f diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index d334a56d5..2fbb276b0 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -716,7 +716,7 @@ impl CpuManager { ); self.cpuid = { - let phys_bits = physical_bits(self.config.max_phys_bits); + let phys_bits = physical_bits(hypervisor, self.config.max_phys_bits); arch::generate_common_cpuid( hypervisor, topology, diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 7d8f41aab..910dbce45 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -1219,7 +1219,8 @@ impl Vmm { )) })?; - let phys_bits = vm::physical_bits(config.lock().unwrap().cpus.max_phys_bits); + let phys_bits = + vm::physical_bits(&self.hypervisor, config.lock().unwrap().cpus.max_phys_bits); let memory_manager = MemoryManager::new( vm, @@ -1535,7 +1536,8 @@ impl Vmm { let vm_config = vm.get_config(); #[cfg(all(feature = "kvm", target_arch = "x86_64"))] let common_cpuid = { - let phys_bits = vm::physical_bits(vm_config.lock().unwrap().cpus.max_phys_bits); + let phys_bits = + vm::physical_bits(&hypervisor, vm_config.lock().unwrap().cpus.max_phys_bits); arch::generate_common_cpuid( &hypervisor, None, @@ -1725,7 +1727,7 @@ impl Vmm { let dest_cpuid = &{ let vm_config = &src_vm_config.lock().unwrap(); - let phys_bits = vm::physical_bits(vm_config.cpus.max_phys_bits); + let phys_bits = vm::physical_bits(&self.hypervisor, vm_config.cpus.max_phys_bits); arch::generate_common_cpuid( &self.hypervisor.clone(), None, diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 609f6d0ca..790c9c332 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -417,8 +417,8 @@ impl VmOps for VmOpsHandler { } } -pub fn physical_bits(max_phys_bits: u8) -> u8 { - let host_phys_bits = get_host_cpu_phys_bits(); +pub fn physical_bits(hypervisor: &Arc, max_phys_bits: u8) -> u8 { + let host_phys_bits = get_host_cpu_phys_bits(hypervisor); cmp::min(host_phys_bits, max_phys_bits) } @@ -762,7 +762,7 @@ impl Vm { tdx_enabled, )?; - let phys_bits = physical_bits(vm_config.lock().unwrap().cpus.max_phys_bits); + let phys_bits = physical_bits(&hypervisor, vm_config.lock().unwrap().cpus.max_phys_bits); let memory_manager = if let Some(snapshot) = snapshot_from_id(snapshot.as_ref(), MEMORY_MANAGER_SNAPSHOT_ID) @@ -2413,7 +2413,10 @@ impl Snapshottable for Vm { #[cfg(all(feature = "kvm", target_arch = "x86_64"))] let common_cpuid = { - let phys_bits = physical_bits(self.config.lock().unwrap().cpus.max_phys_bits); + let phys_bits = physical_bits( + &self.hypervisor, + self.config.lock().unwrap().cpus.max_phys_bits, + ); arch::generate_common_cpuid( &self.hypervisor, None,