From 0ef999978c9f388a1799a39880d1f82067fcd757 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Wed, 27 Nov 2019 17:18:10 +0000 Subject: [PATCH] vmm: cpu: Support only partially configuring the vCPU When configuring a processor after boot as a hotplug CPU we only configure a subset of the CPU state. In particular we should not configure the FPU, segment registers (or reconfigure the paging which is a side-effect of that) nor the main registers. Achieve this by making the function take an Option type for the start address. Signed-off-by: Rob Bradford --- vmm/src/cpu.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 25ca31c0d..af1cea17b 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -245,7 +245,7 @@ impl Vcpu { /// * `vm` - The virtual machine this vcpu will get attached to. pub fn configure( &mut self, - kernel_start_addr: GuestAddress, + kernel_start_addr: Option, vm_memory: &Arc>, cpuid: CpuId, ) -> Result<()> { @@ -256,17 +256,19 @@ impl Vcpu { .map_err(Error::SetSupportedCpusFailed)?; arch::x86_64::regs::setup_msrs(&self.fd).map_err(Error::MSRSConfiguration)?; - // Safe to unwrap because this method is called after the VM is configured - arch::x86_64::regs::setup_regs( - &self.fd, - kernel_start_addr.raw_value(), - arch::x86_64::layout::BOOT_STACK_POINTER.raw_value(), - arch::x86_64::layout::ZERO_PAGE_START.raw_value(), - ) - .map_err(Error::REGSConfiguration)?; - arch::x86_64::regs::setup_fpu(&self.fd).map_err(Error::FPUConfiguration)?; - arch::x86_64::regs::setup_sregs(&vm_memory.read().unwrap(), &self.fd) - .map_err(Error::SREGSConfiguration)?; + if let Some(kernel_start_addr) = kernel_start_addr { + // Safe to unwrap because this method is called after the VM is configured + arch::x86_64::regs::setup_regs( + &self.fd, + kernel_start_addr.raw_value(), + arch::x86_64::layout::BOOT_STACK_POINTER.raw_value(), + arch::x86_64::layout::ZERO_PAGE_START.raw_value(), + ) + .map_err(Error::REGSConfiguration)?; + arch::x86_64::regs::setup_fpu(&self.fd).map_err(Error::FPUConfiguration)?; + arch::x86_64::regs::setup_sregs(&vm_memory.read().unwrap(), &self.fd) + .map_err(Error::SREGSConfiguration)?; + } arch::x86_64::interrupts::set_lint(&self.fd).map_err(Error::LocalIntConfiguration)?; Ok(()) } @@ -496,7 +498,7 @@ impl CpuManager { ioapic, creation_ts, )?; - vcpu.configure(entry_addr, &self.vm_memory, self.cpuid.clone())?; + vcpu.configure(Some(entry_addr), &self.vm_memory, self.cpuid.clone())?; let vcpu_thread_barrier = vcpu_thread_barrier.clone();