From 164e810069653ba4225777d5485145ae4595a6ac Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 16 Mar 2020 16:15:38 +0100 Subject: [PATCH] vmm: cpu: Move CPUID patching to CpuManager Signed-off-by: Samuel Ortiz --- vmm/src/cpu.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++- vmm/src/vm.rs | 37 +------------------------------------ 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index d317d9666..23bc80ebd 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -31,6 +31,10 @@ use vm_migration::{Migratable, MigratableError, Pausable, Snapshottable, Transpo use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::signal::{register_signal_handler, SIGRTMIN}; +// CPUID feature bits +const TSC_DEADLINE_TIMER_ECX_BIT: u8 = 24; // tsc deadline timer ecx bit. +const HYPERVISOR_ECX_BIT: u8 = 31; // Hypervisor ecx bit. + // Debug I/O port #[cfg(target_arch = "x86_64")] const DEBUG_IOPORT: u16 = 0x80; @@ -84,6 +88,9 @@ pub enum Error { /// Cannot spawn a new vCPU thread. VcpuSpawn(io::Error), + /// Cannot patch the CPU ID + PatchCpuId(kvm_ioctls::Error), + #[cfg(target_arch = "x86_64")] /// Error configuring the general purpose registers REGSConfiguration(arch::x86_64::regs::Error), @@ -504,14 +511,15 @@ impl CpuManager { max_vcpus: u8, device_manager: &Arc>, guest_memory: GuestMemoryAtomic, + kvm: &Kvm, fd: Arc, - cpuid: CpuId, reset_evt: EventFd, ) -> Result>> { let mut vcpu_states = Vec::with_capacity(usize::from(max_vcpus)); vcpu_states.resize_with(usize::from(max_vcpus), VcpuState::default); let device_manager = device_manager.lock().unwrap(); + let cpuid = CpuManager::patch_cpuid(kvm)?; let cpu_manager = Arc::new(Mutex::new(CpuManager { boot_vcpus, max_vcpus, @@ -545,6 +553,41 @@ impl CpuManager { Ok(cpu_manager) } + fn patch_cpuid(kvm: &Kvm) -> Result { + let mut cpuid_patches = Vec::new(); + + // Patch tsc deadline timer bit + cpuid_patches.push(CpuidPatch { + function: 1, + index: 0, + flags_bit: None, + eax_bit: None, + ebx_bit: None, + ecx_bit: Some(TSC_DEADLINE_TIMER_ECX_BIT), + edx_bit: None, + }); + + // Patch hypervisor bit + cpuid_patches.push(CpuidPatch { + function: 1, + index: 0, + flags_bit: None, + eax_bit: None, + ebx_bit: None, + ecx_bit: Some(HYPERVISOR_ECX_BIT), + edx_bit: None, + }); + + // Supported CPUID + let mut cpuid = kvm + .get_supported_cpuid(kvm_bindings::KVM_MAX_CPUID_ENTRIES) + .map_err(Error::PatchCpuId)?; + + CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches); + + Ok(cpuid) + } + fn activate_vcpus(&mut self, desired_vcpus: u8, entry_point: Option) -> Result<()> { if desired_vcpus > self.max_vcpus { return Err(Error::DesiredVCPUCountExceedsMax); diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 44978e9c7..1fa244777 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -58,10 +58,6 @@ use vmm_sys_util::terminal::Terminal; const X86_64_IRQ_BASE: u32 = 5; -// CPUID feature bits -const TSC_DEADLINE_TIMER_ECX_BIT: u8 = 24; // tsc deadline timer ecx bit. -const HYPERVISOR_ECX_BIT: u8 = 31; // Hypervisor ecx bit. - // 64 bit direct boot entry offset for bzImage const KERNEL_64BIT_ENTRY_OFFSET: u64 = 0x200; @@ -321,37 +317,6 @@ impl Vm { .transpose() .map_err(Error::InitramfsFile)?; - let mut cpuid_patches = Vec::new(); - - // Patch tsc deadline timer bit - cpuid_patches.push(cpu::CpuidPatch { - function: 1, - index: 0, - flags_bit: None, - eax_bit: None, - ebx_bit: None, - ecx_bit: Some(TSC_DEADLINE_TIMER_ECX_BIT), - edx_bit: None, - }); - - // Patch hypervisor bit - cpuid_patches.push(cpu::CpuidPatch { - function: 1, - index: 0, - flags_bit: None, - eax_bit: None, - ebx_bit: None, - ecx_bit: Some(HYPERVISOR_ECX_BIT), - edx_bit: None, - }); - - // Supported CPUID - let mut cpuid = kvm - .get_supported_cpuid(kvm_bindings::KVM_MAX_CPUID_ENTRIES) - .map_err(Error::VmSetup)?; - - cpu::CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches); - let ioapic = GsiApic::new( X86_64_IRQ_BASE, ioapic::NUM_IOAPIC_PINS as u32 - X86_64_IRQ_BASE, @@ -406,8 +371,8 @@ impl Vm { max_vcpus, &device_manager, guest_memory, + &kvm, fd, - cpuid, reset_evt, ) .map_err(Error::CpuManager)?;