mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
hypervisor: x86: Add a CpuStateManager interface
For efficiently emulating x86 instructions, we need to build and pass a CPU state copy/reference to instruction emulation handlers. Those handlers will typically modify the CPU state and let the caller commit those changes back through the PlatformEmulator trait set_cpu_state method. Hypervisors typically have internal CPU state structures, that maps back to the correspinding kernel APIs. By implementing the CpuState trait, instruction emulators will be able to directly work on CPU state instances that are directly consumable by the underlying hypervisor and its kernel APIs. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
f0360aff83
commit
546778ebfb
42
Cargo.lock
generated
42
Cargo.lock
generated
@ -502,6 +502,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arc-swap",
|
||||
"iced-x86",
|
||||
"kvm-bindings",
|
||||
"kvm-ioctls",
|
||||
"libc",
|
||||
@ -515,6 +516,17 @@ dependencies = [
|
||||
"vmm-sys-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iced-x86"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "248ce8ff0784d2b15f3c3d8b01f529be0e18aa693a2ba7415df76857967c8fc3"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"rustc_version",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.0"
|
||||
@ -1126,6 +1138,15 @@ version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
@ -1146,6 +1167,21 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.117"
|
||||
@ -1217,6 +1253,12 @@ dependencies = [
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
|
@ -25,3 +25,8 @@ vmm-sys-util = { version = ">=0.5.0", features = ["with-serde"] }
|
||||
[dependencies.linux-loader]
|
||||
git = "https://github.com/rust-vmm/linux-loader"
|
||||
features = ["elf", "bzimage"]
|
||||
|
||||
[dependencies.iced-x86]
|
||||
version = "1.9.1"
|
||||
default-features = false
|
||||
features = ["std", "decoder", "op_code_info", "instr_info"]
|
||||
|
86
hypervisor/src/arch/x86/emulator/mod.rs
Normal file
86
hypervisor/src/arch/x86/emulator/mod.rs
Normal file
@ -0,0 +1,86 @@
|
||||
//
|
||||
// Copyright © 2020 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
extern crate iced_x86;
|
||||
|
||||
use crate::arch::emulator::PlatformError;
|
||||
use crate::x86_64::SegmentRegister;
|
||||
use iced_x86::*;
|
||||
|
||||
/// CpuStateManager manages an x86 CPU state.
|
||||
///
|
||||
/// Instruction emulation handlers get a mutable reference to
|
||||
/// a `CpuStateManager` implementation, representing the current state of the
|
||||
/// CPU they have to emulate an instruction stream against. Usually those
|
||||
/// handlers will modify the CPU state by modifying `CpuState` and it is up to
|
||||
/// the handler caller to commit those changes back by invoking a
|
||||
/// `PlatformEmulator` implementation `set_state()` method.
|
||||
///
|
||||
pub trait CpuStateManager: Clone {
|
||||
/// Reads a CPU register.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `reg` - A general purpose, control or debug register.
|
||||
fn read_reg(&self, reg: Register) -> Result<u64, PlatformError>;
|
||||
|
||||
/// Write to a CPU register.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `reg` - A general purpose, control or debug register.
|
||||
/// * `val` - The value to load.
|
||||
fn write_reg(&mut self, reg: Register, val: u64) -> Result<(), PlatformError>;
|
||||
|
||||
/// Reads a segment register.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `reg` - A segment register.
|
||||
fn read_segment(&self, reg: Register) -> Result<SegmentRegister, PlatformError>;
|
||||
|
||||
/// Write to a segment register.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `reg` - A segment register.
|
||||
/// * `segment_reg` - The segment register value to load.
|
||||
fn write_segment(
|
||||
&mut self,
|
||||
reg: Register,
|
||||
segment_reg: SegmentRegister,
|
||||
) -> Result<(), PlatformError>;
|
||||
|
||||
/// Get the CPU instruction pointer.
|
||||
fn ip(&self) -> u64;
|
||||
|
||||
/// Set the CPU instruction pointer.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `ip` - The CPU instruction pointer.
|
||||
fn set_ip(&mut self, ip: u64);
|
||||
|
||||
/// Get the CPU Extended Feature Enable Register.
|
||||
fn efer(&self) -> u64;
|
||||
|
||||
/// Set the CPU Extended Feature Enable Register.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `efer` - The CPU EFER value.
|
||||
fn set_efer(&mut self, efer: u64);
|
||||
|
||||
/// Get the CPU flags.
|
||||
fn flags(&self) -> u64;
|
||||
|
||||
/// Set the CPU flags.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `flags` - The CPU flags
|
||||
fn set_flags(&mut self, flags: u64);
|
||||
}
|
@ -30,6 +30,8 @@ pub mod gdt;
|
||||
)]
|
||||
pub mod msr_index;
|
||||
|
||||
pub mod emulator;
|
||||
|
||||
// MTRR constants
|
||||
pub const MTRR_ENABLE: u64 = 0x800; // IA32_MTRR_DEF_TYPE MSR: E (MTRRs enabled) flag, bit 11
|
||||
pub const MTRR_MEM_TYPE_WB: u64 = 0x6;
|
||||
|
Loading…
Reference in New Issue
Block a user