diff --git a/hypervisor/src/arch/x86/emulator/mod.rs b/hypervisor/src/arch/x86/emulator/mod.rs index 3de545e47..35a35a0ec 100644 --- a/hypervisor/src/arch/x86/emulator/mod.rs +++ b/hypervisor/src/arch/x86/emulator/mod.rs @@ -538,16 +538,13 @@ impl Emulator<'_, T> { handler } - fn emulate_insn_stream( + pub fn emulate_insn_stream( &mut self, - cpu_id: usize, + old_state: &T, insn_stream: &[u8], num_insn: Option, ) -> EmulationResult { - let mut state = self - .platform - .cpu_state(cpu_id) - .map_err(EmulationError::PlatformEmulationError)?; + let mut state = old_state.clone(); let mut decoder = Decoder::new(64, insn_stream, DecoderOptions::NONE); let mut insn = Instruction::default(); let mut num_insn_emulated: usize = 0; @@ -627,7 +624,11 @@ impl Emulator<'_, T> { /// Emulate all instructions from the instructions stream. pub fn emulate(&mut self, cpu_id: usize, insn_stream: &[u8]) -> EmulationResult { - self.emulate_insn_stream(cpu_id, insn_stream, None) + let state = self + .platform + .cpu_state(cpu_id) + .map_err(EmulationError::PlatformEmulationError)?; + self.emulate_insn_stream(&state, insn_stream, None) } /// Only emulate the first instruction from the stream. @@ -640,7 +641,11 @@ impl Emulator<'_, T> { cpu_id: usize, insn_stream: &[u8], ) -> EmulationResult { - self.emulate_insn_stream(cpu_id, insn_stream, Some(1)) + let state = self + .platform + .cpu_state(cpu_id) + .map_err(EmulationError::PlatformEmulationError)?; + self.emulate_insn_stream(&state, insn_stream, Some(1)) } } @@ -706,10 +711,13 @@ mod mock_vmm { insn: &[u8], num_insn: Option, ) -> MockResult { - let ip = self.cpu_state(cpu_id).unwrap().ip(); + let mut state = self + .cpu_state(cpu_id) + .map_err(EmulationError::PlatformEmulationError)?; + let ip = state.ip(); let mut emulator = Emulator::new(self); - let new_state = emulator.emulate_insn_stream(cpu_id, insn, num_insn)?; + let new_state = emulator.emulate_insn_stream(&state, insn, num_insn)?; if num_insn.is_none() { assert_eq!(ip + insn.len() as u64, new_state.ip()); } diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 8ef150294..43597ba6d 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -715,14 +715,19 @@ impl cpu::Vcpu for MshvVcpu { map: (gva, gpa), }; + let old_state = context + .cpu_state(self.vp_index as usize) + .map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?; + // Create a new emulator. let mut emul = Emulator::new(&mut context); // Emulate the trapped instruction, and only the first one. let new_state = emul - .emulate_first_insn( - self.vp_index as usize, + .emulate_insn_stream( + &old_state, &info.instruction_bytes[..insn_len], + Some(1), ) .map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?;