diff --git a/hypervisor/src/arch/x86/emulator/mod.rs b/hypervisor/src/arch/x86/emulator/mod.rs index 35a35a0ec..4b60ceb71 100644 --- a/hypervisor/src/arch/x86/emulator/mod.rs +++ b/hypervisor/src/arch/x86/emulator/mod.rs @@ -711,7 +711,7 @@ mod mock_vmm { insn: &[u8], num_insn: Option, ) -> MockResult { - let mut state = self + let state = self .cpu_state(cpu_id) .map_err(EmulationError::PlatformEmulationError)?; let ip = state.ip(); diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 43597ba6d..0c8d2632c 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -733,7 +733,7 @@ impl cpu::Vcpu for MshvVcpu { // Set CPU state back. context - .set_cpu_state(self.vp_index as usize, new_state) + .update_cpu_state(self.vp_index as usize, old_state, new_state) .map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?; Ok(cpu::VmExit::Ignore) diff --git a/hypervisor/src/mshv/x86_64/emulator.rs b/hypervisor/src/mshv/x86_64/emulator.rs index 3000cdf59..d668dedde 100644 --- a/hypervisor/src/mshv/x86_64/emulator.rs +++ b/hypervisor/src/mshv/x86_64/emulator.rs @@ -106,6 +106,38 @@ impl MshvEmulatorContext<'_> { Ok(()) } + + pub fn update_cpu_state( + &self, + cpu_id: usize, + old_state: ::CpuState, + new_state: ::CpuState, + ) -> Result<(), PlatformError> { + if cpu_id != self.vcpu.vp_index as usize { + return Err(PlatformError::SetCpuStateFailure(anyhow!( + "CPU id mismatch {:?} {:?}", + cpu_id, + self.vcpu.vp_index + ))); + } + + debug!("mshv emulator: Updating CPU state"); + debug!("mshv emulator: {:#x?}", new_state.regs); + + self.vcpu + .set_regs(&new_state.regs) + .map_err(|e| PlatformError::SetCpuStateFailure(e.into()))?; + + if old_state.sregs != new_state.sregs { + debug!("mshv emulator: Updating CPU special registers"); + debug!("mshv emulator: {:#x?}", new_state.sregs); + self.vcpu + .set_sregs(&new_state.sregs) + .map_err(|e| PlatformError::SetCpuStateFailure(e.into()))?; + } + + Ok(()) + } } /// Platform emulation for Hyper-V