mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
hypervisor: Switch to use the new StandardRegisters
With this we are removing the CloudHypervisor definition of StandardRegisters instead using an enum which contains different variants of StandardRegisters coming from their bindigs crate. Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
This commit is contained in:
@@ -14,6 +14,7 @@ tdx = []
|
||||
[dependencies]
|
||||
anyhow = "1.0.86"
|
||||
byteorder = "1.5.0"
|
||||
cfg-if = "1.0.0"
|
||||
concat-idents = "1.1.5"
|
||||
igvm = { version = "0.3.3", optional = true }
|
||||
igvm_defs = { version = "0.3.1", optional = true }
|
||||
|
||||
@@ -9,8 +9,8 @@ use crate::arch::x86::emulator::instructions::*;
|
||||
use crate::arch::x86::regs::{CR0_PE, EFER_LMA};
|
||||
use crate::arch::x86::{
|
||||
segment_type_expand_down, segment_type_ro, Exception, SegmentRegister, SpecialRegisters,
|
||||
StandardRegisters,
|
||||
};
|
||||
use crate::StandardRegisters;
|
||||
use anyhow::Context;
|
||||
use iced_x86::*;
|
||||
|
||||
@@ -203,7 +203,7 @@ macro_rules! set_reg {
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
/// A minimal, emulated CPU state.
|
||||
///
|
||||
/// Hypervisors needing x86 emulation can choose to either use their own
|
||||
@@ -220,29 +220,29 @@ impl CpuStateManager for EmulatorCpuState {
|
||||
fn read_reg(&self, reg: Register) -> Result<u64, PlatformError> {
|
||||
let mut reg_value: u64 = match reg {
|
||||
Register::RAX | Register::EAX | Register::AX | Register::AL | Register::AH => {
|
||||
self.regs.rax
|
||||
self.regs.get_rax()
|
||||
}
|
||||
Register::RBX | Register::EBX | Register::BX | Register::BL | Register::BH => {
|
||||
self.regs.rbx
|
||||
self.regs.get_rbx()
|
||||
}
|
||||
Register::RCX | Register::ECX | Register::CX | Register::CL | Register::CH => {
|
||||
self.regs.rcx
|
||||
self.regs.get_rcx()
|
||||
}
|
||||
Register::RDX | Register::EDX | Register::DX | Register::DL | Register::DH => {
|
||||
self.regs.rdx
|
||||
self.regs.get_rdx()
|
||||
}
|
||||
Register::RSP | Register::ESP | Register::SP => self.regs.rsp,
|
||||
Register::RBP | Register::EBP | Register::BP => self.regs.rbp,
|
||||
Register::RSI | Register::ESI | Register::SI | Register::SIL => self.regs.rsi,
|
||||
Register::RDI | Register::EDI | Register::DI | Register::DIL => self.regs.rdi,
|
||||
Register::R8 | Register::R8D | Register::R8W | Register::R8L => self.regs.r8,
|
||||
Register::R9 | Register::R9D | Register::R9W | Register::R9L => self.regs.r9,
|
||||
Register::R10 | Register::R10D | Register::R10W | Register::R10L => self.regs.r10,
|
||||
Register::R11 | Register::R11D | Register::R11W | Register::R11L => self.regs.r11,
|
||||
Register::R12 | Register::R12D | Register::R12W | Register::R12L => self.regs.r12,
|
||||
Register::R13 | Register::R13D | Register::R13W | Register::R13L => self.regs.r13,
|
||||
Register::R14 | Register::R14D | Register::R14W | Register::R14L => self.regs.r14,
|
||||
Register::R15 | Register::R15D | Register::R15W | Register::R15L => self.regs.r15,
|
||||
Register::RSP | Register::ESP | Register::SP => self.regs.get_rsp(),
|
||||
Register::RBP | Register::EBP | Register::BP => self.regs.get_rbp(),
|
||||
Register::RSI | Register::ESI | Register::SI | Register::SIL => self.regs.get_rsi(),
|
||||
Register::RDI | Register::EDI | Register::DI | Register::DIL => self.regs.get_rdi(),
|
||||
Register::R8 | Register::R8D | Register::R8W | Register::R8L => self.regs.get_r8(),
|
||||
Register::R9 | Register::R9D | Register::R9W | Register::R9L => self.regs.get_r9(),
|
||||
Register::R10 | Register::R10D | Register::R10W | Register::R10L => self.regs.get_r10(),
|
||||
Register::R11 | Register::R11D | Register::R11W | Register::R11L => self.regs.get_r11(),
|
||||
Register::R12 | Register::R12D | Register::R12W | Register::R12L => self.regs.get_r12(),
|
||||
Register::R13 | Register::R13D | Register::R13W | Register::R13L => self.regs.get_r13(),
|
||||
Register::R14 | Register::R14D | Register::R14W | Register::R14L => self.regs.get_r14(),
|
||||
Register::R15 | Register::R15D | Register::R15W | Register::R15L => self.regs.get_r15(),
|
||||
Register::CR0 => self.sregs.cr0,
|
||||
Register::CR2 => self.sregs.cr2,
|
||||
Register::CR3 => self.sregs.cr3,
|
||||
@@ -318,52 +318,52 @@ impl CpuStateManager for EmulatorCpuState {
|
||||
|
||||
match reg {
|
||||
Register::RAX | Register::EAX | Register::AX | Register::AL | Register::AH => {
|
||||
set_reg!(self.regs.rax, mask, reg_value);
|
||||
self.regs.set_rax((self.regs.get_rax() & mask) | reg_value);
|
||||
}
|
||||
Register::RBX | Register::EBX | Register::BX | Register::BL | Register::BH => {
|
||||
set_reg!(self.regs.rbx, mask, reg_value);
|
||||
self.regs.set_rbx((self.regs.get_rbx() & mask) | reg_value);
|
||||
}
|
||||
Register::RCX | Register::ECX | Register::CX | Register::CL | Register::CH => {
|
||||
set_reg!(self.regs.rcx, mask, reg_value);
|
||||
self.regs.set_rcx((self.regs.get_rcx() & mask) | reg_value);
|
||||
}
|
||||
Register::RDX | Register::EDX | Register::DX | Register::DL | Register::DH => {
|
||||
set_reg!(self.regs.rdx, mask, reg_value);
|
||||
self.regs.set_rdx((self.regs.get_rdx() & mask) | reg_value);
|
||||
}
|
||||
Register::RSP | Register::ESP | Register::SP => {
|
||||
set_reg!(self.regs.rsp, mask, reg_value)
|
||||
self.regs.set_rsp((self.regs.get_rsp() & mask) | reg_value);
|
||||
}
|
||||
Register::RBP | Register::EBP | Register::BP => {
|
||||
set_reg!(self.regs.rbp, mask, reg_value)
|
||||
self.regs.set_rbp((self.regs.get_rbp() & mask) | reg_value);
|
||||
}
|
||||
Register::RSI | Register::ESI | Register::SI | Register::SIL => {
|
||||
set_reg!(self.regs.rsi, mask, reg_value)
|
||||
self.regs.set_rsi((self.regs.get_rsi() & mask) | reg_value);
|
||||
}
|
||||
Register::RDI | Register::EDI | Register::DI | Register::DIL => {
|
||||
set_reg!(self.regs.rdi, mask, reg_value)
|
||||
self.regs.set_rdi((self.regs.get_rdi() & mask) | reg_value);
|
||||
}
|
||||
Register::R8 | Register::R8D | Register::R8W | Register::R8L => {
|
||||
set_reg!(self.regs.r8, mask, reg_value)
|
||||
self.regs.set_r8((self.regs.get_r8() & mask) | reg_value);
|
||||
}
|
||||
Register::R9 | Register::R9D | Register::R9W | Register::R9L => {
|
||||
set_reg!(self.regs.r9, mask, reg_value)
|
||||
self.regs.set_r9((self.regs.get_r9() & mask) | reg_value);
|
||||
}
|
||||
Register::R10 | Register::R10D | Register::R10W | Register::R10L => {
|
||||
set_reg!(self.regs.r10, mask, reg_value)
|
||||
self.regs.set_r10((self.regs.get_r10() & mask) | reg_value);
|
||||
}
|
||||
Register::R11 | Register::R11D | Register::R11W | Register::R11L => {
|
||||
set_reg!(self.regs.r11, mask, reg_value)
|
||||
self.regs.set_r11((self.regs.get_r11() & mask) | reg_value);
|
||||
}
|
||||
Register::R12 | Register::R12D | Register::R12W | Register::R12L => {
|
||||
set_reg!(self.regs.r12, mask, reg_value)
|
||||
self.regs.set_r12((self.regs.get_r12() & mask) | reg_value);
|
||||
}
|
||||
Register::R13 | Register::R13D | Register::R13W | Register::R13L => {
|
||||
set_reg!(self.regs.r13, mask, reg_value)
|
||||
self.regs.set_r13((self.regs.get_r13() & mask) | reg_value);
|
||||
}
|
||||
Register::R14 | Register::R14D | Register::R14W | Register::R14L => {
|
||||
set_reg!(self.regs.r14, mask, reg_value)
|
||||
self.regs.set_r14((self.regs.get_r14() & mask) | reg_value);
|
||||
}
|
||||
Register::R15 | Register::R15D | Register::R15W | Register::R15L => {
|
||||
set_reg!(self.regs.r15, mask, reg_value)
|
||||
self.regs.set_r15((self.regs.get_r15() & mask) | reg_value);
|
||||
}
|
||||
Register::CR0 => set_reg!(self.sregs.cr0, mask, reg_value),
|
||||
Register::CR2 => set_reg!(self.sregs.cr2, mask, reg_value),
|
||||
@@ -426,11 +426,11 @@ impl CpuStateManager for EmulatorCpuState {
|
||||
}
|
||||
|
||||
fn ip(&self) -> u64 {
|
||||
self.regs.rip
|
||||
self.regs.get_rip()
|
||||
}
|
||||
|
||||
fn set_ip(&mut self, ip: u64) {
|
||||
self.regs.rip = ip;
|
||||
self.regs.set_rip(ip);
|
||||
}
|
||||
|
||||
fn efer(&self) -> u64 {
|
||||
@@ -442,11 +442,11 @@ impl CpuStateManager for EmulatorCpuState {
|
||||
}
|
||||
|
||||
fn flags(&self) -> u64 {
|
||||
self.regs.rflags
|
||||
self.regs.get_rflags()
|
||||
}
|
||||
|
||||
fn set_flags(&mut self, flags: u64) {
|
||||
self.regs.rflags = flags;
|
||||
self.regs.set_rflags(flags);
|
||||
}
|
||||
|
||||
fn mode(&self) -> Result<CpuMode, PlatformError> {
|
||||
@@ -656,6 +656,7 @@ mod mock_vmm {
|
||||
use super::*;
|
||||
use crate::arch::x86::emulator::EmulatorCpuState as CpuState;
|
||||
use crate::arch::x86::gdt::{gdt_entry, segment_from_gdt};
|
||||
use crate::StandardRegisters;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -672,7 +673,19 @@ mod mock_vmm {
|
||||
let cs_reg = segment_from_gdt(gdt_entry(0xc09b, 0, 0xffffffff), 1);
|
||||
let ds_reg = segment_from_gdt(gdt_entry(0xc093, 0, 0xffffffff), 2);
|
||||
let es_reg = segment_from_gdt(gdt_entry(0xc093, 0, 0xffffffff), 3);
|
||||
let mut initial_state = CpuState::default();
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "kvm")] {
|
||||
let std_regs: StandardRegisters = kvm_bindings::kvm_regs::default().into();
|
||||
} else if #[cfg(feature = "mshv")] {
|
||||
let std_regs: StandardRegisters = mshv_bindings::StandardRegisters::default().into();
|
||||
} else {
|
||||
panic!("Unsupported hypervisor type!")
|
||||
}
|
||||
};
|
||||
let mut initial_state = CpuState {
|
||||
regs: std_regs,
|
||||
sregs: SpecialRegisters::default(),
|
||||
};
|
||||
initial_state.set_ip(ip);
|
||||
initial_state.write_segment(Register::CS, cs_reg).unwrap();
|
||||
initial_state.write_segment(Register::DS, ds_reg).unwrap();
|
||||
|
||||
@@ -172,28 +172,6 @@ macro_rules! msr_data {
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct StandardRegisters {
|
||||
pub rax: u64,
|
||||
pub rbx: u64,
|
||||
pub rcx: u64,
|
||||
pub rdx: u64,
|
||||
pub rsi: u64,
|
||||
pub rdi: u64,
|
||||
pub rsp: u64,
|
||||
pub rbp: u64,
|
||||
pub r8: u64,
|
||||
pub r9: u64,
|
||||
pub r10: u64,
|
||||
pub r11: u64,
|
||||
pub r12: u64,
|
||||
pub r13: u64,
|
||||
pub r14: u64,
|
||||
pub r15: u64,
|
||||
pub rip: u64,
|
||||
pub rflags: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct DescriptorTable {
|
||||
pub base: u64,
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use crate::aarch64::{RegList, StandardRegisters, VcpuInit};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::x86::{
|
||||
CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters, StandardRegisters,
|
||||
};
|
||||
use crate::arch::x86::{CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters};
|
||||
#[cfg(feature = "tdx")]
|
||||
use crate::kvm::{TdxExitDetails, TdxExitStatus};
|
||||
use crate::CpuState;
|
||||
use crate::MpState;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::StandardRegisters;
|
||||
use thiserror::Error;
|
||||
use vm_memory::GuestAddress;
|
||||
|
||||
|
||||
@@ -44,11 +44,12 @@ use vmm_sys_util::eventfd::EventFd;
|
||||
pub mod x86_64;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::x86::{
|
||||
CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters, StandardRegisters, XsaveState,
|
||||
NUM_IOAPIC_PINS,
|
||||
CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters, XsaveState, NUM_IOAPIC_PINS,
|
||||
};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::ClockData;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::StandardRegisters;
|
||||
use crate::{
|
||||
CpuState, IoEventAddress, IrqRoutingEntry, MpState, UserMemoryRegion,
|
||||
USER_MEMORY_REGION_LOG_DIRTY, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
use crate::arch::x86::{
|
||||
CpuIdEntry, DescriptorTable, FpuState, LapicState, MsrEntry, SegmentRegister, SpecialRegisters,
|
||||
StandardRegisters, XsaveState, CPUID_FLAG_VALID_INDEX,
|
||||
XsaveState, CPUID_FLAG_VALID_INDEX,
|
||||
};
|
||||
use crate::kvm::{Cap, Kvm, KvmError, KvmResult};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -78,56 +78,6 @@ pub struct VcpuKvmState {
|
||||
pub tsc_khz: Option<u32>,
|
||||
}
|
||||
|
||||
impl From<StandardRegisters> for kvm_regs {
|
||||
fn from(regs: StandardRegisters) -> Self {
|
||||
Self {
|
||||
rax: regs.rax,
|
||||
rbx: regs.rbx,
|
||||
rcx: regs.rcx,
|
||||
rdx: regs.rdx,
|
||||
rsi: regs.rsi,
|
||||
rdi: regs.rdi,
|
||||
rsp: regs.rsp,
|
||||
rbp: regs.rbp,
|
||||
r8: regs.r8,
|
||||
r9: regs.r9,
|
||||
r10: regs.r10,
|
||||
r11: regs.r11,
|
||||
r12: regs.r12,
|
||||
r13: regs.r13,
|
||||
r14: regs.r14,
|
||||
r15: regs.r15,
|
||||
rip: regs.rip,
|
||||
rflags: regs.rflags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<kvm_regs> for StandardRegisters {
|
||||
fn from(regs: kvm_regs) -> Self {
|
||||
Self {
|
||||
rax: regs.rax,
|
||||
rbx: regs.rbx,
|
||||
rcx: regs.rcx,
|
||||
rdx: regs.rdx,
|
||||
rsi: regs.rsi,
|
||||
rdi: regs.rdi,
|
||||
rsp: regs.rsp,
|
||||
rbp: regs.rbp,
|
||||
r8: regs.r8,
|
||||
r9: regs.r9,
|
||||
r10: regs.r10,
|
||||
r11: regs.r11,
|
||||
r12: regs.r12,
|
||||
r13: regs.r13,
|
||||
r14: regs.r14,
|
||||
r15: regs.r15,
|
||||
rip: regs.rip,
|
||||
rflags: regs.rflags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SegmentRegister> for kvm_segment {
|
||||
fn from(s: SegmentRegister) -> Self {
|
||||
Self {
|
||||
|
||||
@@ -434,14 +434,14 @@ impl cpu::Vcpu for MshvVcpu {
|
||||
/// Returns StandardRegisters with default value set
|
||||
///
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn create_standard_regs(&self) -> crate::arch::x86::StandardRegisters {
|
||||
fn create_standard_regs(&self) -> crate::StandardRegisters {
|
||||
mshv_bindings::StandardRegisters::default().into()
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
///
|
||||
/// Returns the vCPU general purpose registers.
|
||||
///
|
||||
fn get_regs(&self) -> cpu::Result<crate::arch::x86::StandardRegisters> {
|
||||
fn get_regs(&self) -> cpu::Result<crate::StandardRegisters> {
|
||||
Ok(self
|
||||
.fd
|
||||
.get_regs()
|
||||
@@ -453,7 +453,7 @@ impl cpu::Vcpu for MshvVcpu {
|
||||
///
|
||||
/// Sets the vCPU general purpose registers.
|
||||
///
|
||||
fn set_regs(&self, regs: &crate::arch::x86::StandardRegisters) -> cpu::Result<()> {
|
||||
fn set_regs(&self, regs: &crate::StandardRegisters) -> cpu::Result<()> {
|
||||
let regs = (*regs).into();
|
||||
self.fd
|
||||
.set_regs(®s)
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
//
|
||||
use crate::arch::x86::{
|
||||
CpuIdEntry, DescriptorTable, FpuState, LapicState, MsrEntry, SegmentRegister, SpecialRegisters,
|
||||
StandardRegisters,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
@@ -73,56 +72,6 @@ impl fmt::Display for VcpuMshvState {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StandardRegisters> for MshvStandardRegisters {
|
||||
fn from(regs: StandardRegisters) -> Self {
|
||||
Self {
|
||||
rax: regs.rax,
|
||||
rbx: regs.rbx,
|
||||
rcx: regs.rcx,
|
||||
rdx: regs.rdx,
|
||||
rsi: regs.rsi,
|
||||
rdi: regs.rdi,
|
||||
rsp: regs.rsp,
|
||||
rbp: regs.rbp,
|
||||
r8: regs.r8,
|
||||
r9: regs.r9,
|
||||
r10: regs.r10,
|
||||
r11: regs.r11,
|
||||
r12: regs.r12,
|
||||
r13: regs.r13,
|
||||
r14: regs.r14,
|
||||
r15: regs.r15,
|
||||
rip: regs.rip,
|
||||
rflags: regs.rflags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MshvStandardRegisters> for StandardRegisters {
|
||||
fn from(regs: MshvStandardRegisters) -> Self {
|
||||
Self {
|
||||
rax: regs.rax,
|
||||
rbx: regs.rbx,
|
||||
rcx: regs.rcx,
|
||||
rdx: regs.rdx,
|
||||
rsi: regs.rsi,
|
||||
rdi: regs.rdi,
|
||||
rsp: regs.rsp,
|
||||
rbp: regs.rbp,
|
||||
r8: regs.r8,
|
||||
r9: regs.r9,
|
||||
r10: regs.r10,
|
||||
r11: regs.r11,
|
||||
r12: regs.r12,
|
||||
r13: regs.r13,
|
||||
r14: regs.r14,
|
||||
r15: regs.r15,
|
||||
rip: regs.rip,
|
||||
rflags: regs.rflags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SegmentRegister> for MshvSegmentRegister {
|
||||
fn from(s: SegmentRegister) -> Self {
|
||||
Self {
|
||||
|
||||
Reference in New Issue
Block a user