From 1fc97e91a4283953f52adf45de6f505d61b2c562 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 19 Nov 2020 20:00:32 +0100 Subject: [PATCH] hypervisor: x86: Add an InstructionHandler interface And an InstructionMap helper structure to map x86 mnemonic codes to instruction handlers. Any instruction emulation implementation should then boil down with implementing InstructionHandler for any supported mnemonic. Signed-off-by: Samuel Ortiz --- .../src/arch/x86/emulator/instructions/mod.rs | 49 +++++++++++++++++++ hypervisor/src/arch/x86/emulator/mod.rs | 2 + hypervisor/src/arch/x86/mod.rs | 25 ++++++++++ 3 files changed, 76 insertions(+) create mode 100644 hypervisor/src/arch/x86/emulator/instructions/mod.rs diff --git a/hypervisor/src/arch/x86/emulator/instructions/mod.rs b/hypervisor/src/arch/x86/emulator/instructions/mod.rs new file mode 100644 index 000000000..ff5e02813 --- /dev/null +++ b/hypervisor/src/arch/x86/emulator/instructions/mod.rs @@ -0,0 +1,49 @@ +// +// Copyright © 2020 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +extern crate iced_x86; + +use crate::arch::emulator::{EmulationError, PlatformEmulator}; +use crate::arch::x86::emulator::CpuStateManager; +use crate::arch::x86::Exception; +use iced_x86::*; +use std::collections::HashMap; +use std::sync::{Arc, Mutex}; + +pub trait InstructionHandler { + fn emulate( + &self, + insn: &Instruction, + state: &mut T, + platform: Arc>>, + ) -> Result<(), EmulationError>; +} + +pub struct InstructionMap { + pub instructions: HashMap + Sync + Send>>>, +} + +impl InstructionMap { + pub fn new() -> InstructionMap { + InstructionMap { + instructions: HashMap::new(), + } + } + + pub fn add_insn( + &mut self, + insn: Code, + insn_handler: Box + Sync + Send>, + ) { + self.instructions.insert(insn, Box::new(insn_handler)); + } +} + +impl Default for InstructionMap { + fn default() -> Self { + Self::new() + } +} diff --git a/hypervisor/src/arch/x86/emulator/mod.rs b/hypervisor/src/arch/x86/emulator/mod.rs index c2c5a8ee1..ce8032407 100644 --- a/hypervisor/src/arch/x86/emulator/mod.rs +++ b/hypervisor/src/arch/x86/emulator/mod.rs @@ -10,6 +10,8 @@ use crate::arch::emulator::PlatformError; use crate::x86_64::{SegmentRegister, SpecialRegisters, StandardRegisters}; use iced_x86::*; +mod instructions; + /// CpuStateManager manages an x86 CPU state. /// /// Instruction emulation handlers get a mutable reference to diff --git a/hypervisor/src/arch/x86/mod.rs b/hypervisor/src/arch/x86/mod.rs index ac0e8c69f..6847f09a3 100644 --- a/hypervisor/src/arch/x86/mod.rs +++ b/hypervisor/src/arch/x86/mod.rs @@ -38,3 +38,28 @@ pub const MTRR_MEM_TYPE_WB: u64 = 0x6; // IOAPIC pins pub const NUM_IOAPIC_PINS: usize = 24; + +// X86 Exceptions +#[allow(dead_code)] +#[derive(Clone, Debug)] +pub enum Exception { + DE = 1, // Divide Error + DB = 2, // Debug Exception + BP = 3, // Breakpoint + OF = 4, // Overflow + BR = 5, // BOUND Range Exceeded + UD = 6, // Invalid/Undefined Opcode + NM = 7, // No Math Coprocessor + DF = 8, // Double Fault + TS = 10, // Invalid TSS + NP = 11, // Segment Not Present + SS = 12, // Stack Segment Fault + GP = 13, // General Protection + PF = 14, // Page Fault + MF = 16, // Math Fault + AC = 17, // Alignment Check + MC = 18, // Machine Check + XM = 19, // SIMD Floating-Point Exception + VE = 20, // Virtualization Exception + CP = 21, // Control Protection Exception +}