From 7dc92d1dac088481aab3f3b8fda15fb7af36a117 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 26 Nov 2020 11:16:53 +0100 Subject: [PATCH] hypervisor: emulator: Decoding loop restructuring In preparation for the instruction fetching step, we modify the decoding loop so that we can check what the last decoding error is. We also switch to explictly using decode_out() which removes a 32 bytes copy compared to decode(). Signed-off-by: Samuel Ortiz --- hypervisor/src/arch/x86/emulator/mod.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hypervisor/src/arch/x86/emulator/mod.rs b/hypervisor/src/arch/x86/emulator/mod.rs index 0e20166db..2ab330a0c 100644 --- a/hypervisor/src/arch/x86/emulator/mod.rs +++ b/hypervisor/src/arch/x86/emulator/mod.rs @@ -513,9 +513,15 @@ impl<'a, T: CpuStateManager> Emulator<'a, T> { .cpu_state(cpu_id) .map_err(EmulationError::PlatformEmulationError)?; let mut decoder = Decoder::new(64, insn_stream, DecoderOptions::NONE); + let mut insn = Instruction::default(); + let mut num_insn_emulated: usize = 0; + decoder.set_ip(state.ip()); - for (index, insn) in &mut decoder.iter().enumerate() { + while decoder.can_decode() { + decoder.decode_out(&mut insn); + + // Emulate the decoded instruction self.insn_map .instructions .get(&insn.code()) @@ -524,8 +530,10 @@ impl<'a, T: CpuStateManager> Emulator<'a, T> { })? .emulate(&insn, &mut state, self.platform)?; + num_insn_emulated += 1; + if let Some(num_insn) = num_insn { - if index + 1 >= num_insn { + if num_insn_emulated >= num_insn { // Exit the decoding loop, do not decode the next instruction. break; }