diff --git a/arch/src/aarch64/mod.rs b/arch/src/aarch64/mod.rs index 850b363e9..9bad15cd5 100644 --- a/arch/src/aarch64/mod.rs +++ b/arch/src/aarch64/mod.rs @@ -63,6 +63,7 @@ pub fn configure_vcpu( id: u8, kernel_entry_point: Option, vm_memory: &GuestMemoryAtomic, + _phys_bits: u8, ) -> super::Result { if let Some(kernel_entry_point) = kernel_entry_point { regs::setup_regs( diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index 95f90553a..8773f3b16 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -337,6 +337,7 @@ pub fn configure_vcpu( vm_memory: &GuestMemoryAtomic, cpuid: CpuId, kvm_hyperv: bool, + phys_bits: u8, ) -> super::Result<()> { let mut cpuid = cpuid; CpuidPatch::set_cpuid_reg(&mut cpuid, 0xb, None, CpuidReg::EDX, u32::from(id)); @@ -410,6 +411,13 @@ pub fn configure_vcpu( .map_err(|_| Error::PopulatingCpuid)?; } + // Set CPU physical bits + for entry in cpuid.as_mut_slice().iter_mut() { + if entry.function == 0x8000_0008 { + entry.eax = (entry.eax & 0xffff_ff00) | (phys_bits as u32 & 0xff); + } + } + fd.set_cpuid2(&cpuid) .map_err(|e| Error::SetSupportedCpusFailed(e.into()))?; diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index a1e6c56bf..61cbaf8f0 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -17,6 +17,7 @@ use crate::config::CpusConfig; use crate::device_manager::DeviceManager; use crate::memory_manager::MemoryManager; use crate::seccomp_filters::{get_seccomp_filter, Thread}; +use crate::vm::physical_bits; use crate::CPU_MANAGER_SNAPSHOT_ID; #[cfg(feature = "acpi")] use acpi_tables::{aml, aml::Aml, sdt::SDT}; @@ -259,12 +260,19 @@ impl Vcpu { vm_memory: &GuestMemoryAtomic, #[cfg(target_arch = "x86_64")] cpuid: CpuId, #[cfg(target_arch = "x86_64")] kvm_hyperv: bool, + phys_bits: u8, ) -> Result<()> { #[cfg(target_arch = "aarch64")] { self.init(vm)?; - self.mpidr = arch::configure_vcpu(&self.vcpu, self.id, kernel_entry_point, vm_memory) - .map_err(Error::VcpuConfiguration)?; + self.mpidr = arch::configure_vcpu( + &self.vcpu, + self.id, + kernel_entry_point, + vm_memory, + phys_bits, + ) + .map_err(Error::VcpuConfiguration)?; } #[cfg(target_arch = "x86_64")] @@ -275,6 +283,7 @@ impl Vcpu { vm_memory, cpuid, kvm_hyperv, + phys_bits, ) .map_err(Error::VcpuConfiguration)?; @@ -703,6 +712,8 @@ impl CpuManager { } else { let vm_memory = self.vm_memory.clone(); + let phys_bits = physical_bits(self.config.max_phys_bits); + #[cfg(target_arch = "x86_64")] vcpu.lock() .unwrap() @@ -711,13 +722,14 @@ impl CpuManager { &vm_memory, self.cpuid.clone(), self.config.kvm_hyperv, + phys_bits, ) .expect("Failed to configure vCPU"); #[cfg(target_arch = "aarch64")] vcpu.lock() .unwrap() - .configure(&self.vm, entry_point, &vm_memory) + .configure(&self.vm, entry_point, &vm_memory, phys_bits) .expect("Failed to configure vCPU"); } diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 7bd0d527f..22afab496 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -433,7 +433,7 @@ impl VmmOps for VmOps { } } -fn physical_bits(max_phys_bits: Option) -> u8 { +pub fn physical_bits(max_phys_bits: Option) -> u8 { let host_phys_bits = get_host_cpu_phys_bits(); cmp::min(host_phys_bits, max_phys_bits.unwrap_or(host_phys_bits)) }