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:
Generated
+1
@@ -992,6 +992,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"cfg-if",
|
||||||
"concat-idents",
|
"concat-idents",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"iced-x86",
|
"iced-x86",
|
||||||
|
|||||||
+14
-15
@@ -12,7 +12,7 @@ use crate::layout::{
|
|||||||
use crate::{EntryPoint, GuestMemoryMmap};
|
use crate::{EntryPoint, GuestMemoryMmap};
|
||||||
use hypervisor::arch::x86::gdt::{gdt_entry, segment_from_gdt};
|
use hypervisor::arch::x86::gdt::{gdt_entry, segment_from_gdt};
|
||||||
use hypervisor::arch::x86::regs::CR0_PE;
|
use hypervisor::arch::x86::regs::CR0_PE;
|
||||||
use hypervisor::arch::x86::{FpuState, SpecialRegisters, StandardRegisters};
|
use hypervisor::arch::x86::{FpuState, SpecialRegisters};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{mem, result};
|
use std::{mem, result};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
@@ -94,20 +94,19 @@ pub fn setup_msrs(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
|
|||||||
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
||||||
/// * `entry_point` - Description of the boot entry to set up.
|
/// * `entry_point` - Description of the boot entry to set up.
|
||||||
pub fn setup_regs(vcpu: &Arc<dyn hypervisor::Vcpu>, entry_point: EntryPoint) -> Result<()> {
|
pub fn setup_regs(vcpu: &Arc<dyn hypervisor::Vcpu>, entry_point: EntryPoint) -> Result<()> {
|
||||||
let regs = match entry_point.setup_header {
|
let mut regs = vcpu.create_standard_regs();
|
||||||
None => StandardRegisters {
|
match entry_point.setup_header {
|
||||||
rflags: 0x0000000000000002u64,
|
None => {
|
||||||
rip: entry_point.entry_addr.raw_value(),
|
regs.set_rflags(0x0000000000000002u64);
|
||||||
rbx: PVH_INFO_START.raw_value(),
|
regs.set_rip(entry_point.entry_addr.raw_value());
|
||||||
..Default::default()
|
regs.set_rbx(PVH_INFO_START.raw_value());
|
||||||
},
|
}
|
||||||
Some(_) => StandardRegisters {
|
Some(_) => {
|
||||||
rflags: 0x0000000000000002u64,
|
regs.set_rflags(0x0000000000000002u64);
|
||||||
rip: entry_point.entry_addr.raw_value(),
|
regs.set_rip(entry_point.entry_addr.raw_value());
|
||||||
rsp: BOOT_STACK_POINTER.raw_value(),
|
regs.set_rsp(BOOT_STACK_POINTER.raw_value());
|
||||||
rsi: ZERO_PAGE_START.raw_value(),
|
regs.set_rsi(ZERO_PAGE_START.raw_value());
|
||||||
..Default::default()
|
}
|
||||||
},
|
|
||||||
};
|
};
|
||||||
vcpu.set_regs(®s).map_err(Error::SetBaseRegisters)
|
vcpu.set_regs(®s).map_err(Error::SetBaseRegisters)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ tdx = []
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
byteorder = "1.5.0"
|
byteorder = "1.5.0"
|
||||||
|
cfg-if = "1.0.0"
|
||||||
concat-idents = "1.1.5"
|
concat-idents = "1.1.5"
|
||||||
igvm = { version = "0.3.3", optional = true }
|
igvm = { version = "0.3.3", optional = true }
|
||||||
igvm_defs = { version = "0.3.1", 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::regs::{CR0_PE, EFER_LMA};
|
||||||
use crate::arch::x86::{
|
use crate::arch::x86::{
|
||||||
segment_type_expand_down, segment_type_ro, Exception, SegmentRegister, SpecialRegisters,
|
segment_type_expand_down, segment_type_ro, Exception, SegmentRegister, SpecialRegisters,
|
||||||
StandardRegisters,
|
|
||||||
};
|
};
|
||||||
|
use crate::StandardRegisters;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use iced_x86::*;
|
use iced_x86::*;
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ macro_rules! set_reg {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// A minimal, emulated CPU state.
|
/// A minimal, emulated CPU state.
|
||||||
///
|
///
|
||||||
/// Hypervisors needing x86 emulation can choose to either use their own
|
/// 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> {
|
fn read_reg(&self, reg: Register) -> Result<u64, PlatformError> {
|
||||||
let mut reg_value: u64 = match reg {
|
let mut reg_value: u64 = match reg {
|
||||||
Register::RAX | Register::EAX | Register::AX | Register::AL | Register::AH => {
|
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 => {
|
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 => {
|
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 => {
|
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::RSP | Register::ESP | Register::SP => self.regs.get_rsp(),
|
||||||
Register::RBP | Register::EBP | Register::BP => self.regs.rbp,
|
Register::RBP | Register::EBP | Register::BP => self.regs.get_rbp(),
|
||||||
Register::RSI | Register::ESI | Register::SI | Register::SIL => self.regs.rsi,
|
Register::RSI | Register::ESI | Register::SI | Register::SIL => self.regs.get_rsi(),
|
||||||
Register::RDI | Register::EDI | Register::DI | Register::DIL => self.regs.rdi,
|
Register::RDI | Register::EDI | Register::DI | Register::DIL => self.regs.get_rdi(),
|
||||||
Register::R8 | Register::R8D | Register::R8W | Register::R8L => self.regs.r8,
|
Register::R8 | Register::R8D | Register::R8W | Register::R8L => self.regs.get_r8(),
|
||||||
Register::R9 | Register::R9D | Register::R9W | Register::R9L => self.regs.r9,
|
Register::R9 | Register::R9D | Register::R9W | Register::R9L => self.regs.get_r9(),
|
||||||
Register::R10 | Register::R10D | Register::R10W | Register::R10L => self.regs.r10,
|
Register::R10 | Register::R10D | Register::R10W | Register::R10L => self.regs.get_r10(),
|
||||||
Register::R11 | Register::R11D | Register::R11W | Register::R11L => self.regs.r11,
|
Register::R11 | Register::R11D | Register::R11W | Register::R11L => self.regs.get_r11(),
|
||||||
Register::R12 | Register::R12D | Register::R12W | Register::R12L => self.regs.r12,
|
Register::R12 | Register::R12D | Register::R12W | Register::R12L => self.regs.get_r12(),
|
||||||
Register::R13 | Register::R13D | Register::R13W | Register::R13L => self.regs.r13,
|
Register::R13 | Register::R13D | Register::R13W | Register::R13L => self.regs.get_r13(),
|
||||||
Register::R14 | Register::R14D | Register::R14W | Register::R14L => self.regs.r14,
|
Register::R14 | Register::R14D | Register::R14W | Register::R14L => self.regs.get_r14(),
|
||||||
Register::R15 | Register::R15D | Register::R15W | Register::R15L => self.regs.r15,
|
Register::R15 | Register::R15D | Register::R15W | Register::R15L => self.regs.get_r15(),
|
||||||
Register::CR0 => self.sregs.cr0,
|
Register::CR0 => self.sregs.cr0,
|
||||||
Register::CR2 => self.sregs.cr2,
|
Register::CR2 => self.sregs.cr2,
|
||||||
Register::CR3 => self.sregs.cr3,
|
Register::CR3 => self.sregs.cr3,
|
||||||
@@ -318,52 +318,52 @@ impl CpuStateManager for EmulatorCpuState {
|
|||||||
|
|
||||||
match reg {
|
match reg {
|
||||||
Register::RAX | Register::EAX | Register::AX | Register::AL | Register::AH => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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 => {
|
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::CR0 => set_reg!(self.sregs.cr0, mask, reg_value),
|
||||||
Register::CR2 => set_reg!(self.sregs.cr2, 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 {
|
fn ip(&self) -> u64 {
|
||||||
self.regs.rip
|
self.regs.get_rip()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_ip(&mut self, ip: u64) {
|
fn set_ip(&mut self, ip: u64) {
|
||||||
self.regs.rip = ip;
|
self.regs.set_rip(ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn efer(&self) -> u64 {
|
fn efer(&self) -> u64 {
|
||||||
@@ -442,11 +442,11 @@ impl CpuStateManager for EmulatorCpuState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn flags(&self) -> u64 {
|
fn flags(&self) -> u64 {
|
||||||
self.regs.rflags
|
self.regs.get_rflags()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_flags(&mut self, flags: u64) {
|
fn set_flags(&mut self, flags: u64) {
|
||||||
self.regs.rflags = flags;
|
self.regs.set_rflags(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mode(&self) -> Result<CpuMode, PlatformError> {
|
fn mode(&self) -> Result<CpuMode, PlatformError> {
|
||||||
@@ -656,6 +656,7 @@ mod mock_vmm {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::arch::x86::emulator::EmulatorCpuState as CpuState;
|
use crate::arch::x86::emulator::EmulatorCpuState as CpuState;
|
||||||
use crate::arch::x86::gdt::{gdt_entry, segment_from_gdt};
|
use crate::arch::x86::gdt::{gdt_entry, segment_from_gdt};
|
||||||
|
use crate::StandardRegisters;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -672,7 +673,19 @@ mod mock_vmm {
|
|||||||
let cs_reg = segment_from_gdt(gdt_entry(0xc09b, 0, 0xffffffff), 1);
|
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 ds_reg = segment_from_gdt(gdt_entry(0xc093, 0, 0xffffffff), 2);
|
||||||
let es_reg = segment_from_gdt(gdt_entry(0xc093, 0, 0xffffffff), 3);
|
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.set_ip(ip);
|
||||||
initial_state.write_segment(Register::CS, cs_reg).unwrap();
|
initial_state.write_segment(Register::CS, cs_reg).unwrap();
|
||||||
initial_state.write_segment(Register::DS, ds_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)]
|
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct DescriptorTable {
|
pub struct DescriptorTable {
|
||||||
pub base: u64,
|
pub base: u64,
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use crate::aarch64::{RegList, StandardRegisters, VcpuInit};
|
use crate::aarch64::{RegList, StandardRegisters, VcpuInit};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::arch::x86::{
|
use crate::arch::x86::{CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters};
|
||||||
CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters, StandardRegisters,
|
|
||||||
};
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
use crate::kvm::{TdxExitDetails, TdxExitStatus};
|
use crate::kvm::{TdxExitDetails, TdxExitStatus};
|
||||||
use crate::CpuState;
|
use crate::CpuState;
|
||||||
use crate::MpState;
|
use crate::MpState;
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
use crate::StandardRegisters;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use vm_memory::GuestAddress;
|
use vm_memory::GuestAddress;
|
||||||
|
|
||||||
|
|||||||
@@ -44,11 +44,12 @@ use vmm_sys_util::eventfd::EventFd;
|
|||||||
pub mod x86_64;
|
pub mod x86_64;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::arch::x86::{
|
use crate::arch::x86::{
|
||||||
CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters, StandardRegisters, XsaveState,
|
CpuIdEntry, FpuState, LapicState, MsrEntry, SpecialRegisters, XsaveState, NUM_IOAPIC_PINS,
|
||||||
NUM_IOAPIC_PINS,
|
|
||||||
};
|
};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::ClockData;
|
use crate::ClockData;
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
use crate::StandardRegisters;
|
||||||
use crate::{
|
use crate::{
|
||||||
CpuState, IoEventAddress, IrqRoutingEntry, MpState, UserMemoryRegion,
|
CpuState, IoEventAddress, IrqRoutingEntry, MpState, UserMemoryRegion,
|
||||||
USER_MEMORY_REGION_LOG_DIRTY, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE,
|
USER_MEMORY_REGION_LOG_DIRTY, USER_MEMORY_REGION_READ, USER_MEMORY_REGION_WRITE,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
use crate::arch::x86::{
|
use crate::arch::x86::{
|
||||||
CpuIdEntry, DescriptorTable, FpuState, LapicState, MsrEntry, SegmentRegister, SpecialRegisters,
|
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 crate::kvm::{Cap, Kvm, KvmError, KvmResult};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -78,56 +78,6 @@ pub struct VcpuKvmState {
|
|||||||
pub tsc_khz: Option<u32>,
|
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 {
|
impl From<SegmentRegister> for kvm_segment {
|
||||||
fn from(s: SegmentRegister) -> Self {
|
fn from(s: SegmentRegister) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@@ -434,14 +434,14 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
/// Returns StandardRegisters with default value set
|
/// Returns StandardRegisters with default value set
|
||||||
///
|
///
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[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()
|
mshv_bindings::StandardRegisters::default().into()
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
///
|
///
|
||||||
/// Returns the vCPU general purpose registers.
|
/// 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
|
Ok(self
|
||||||
.fd
|
.fd
|
||||||
.get_regs()
|
.get_regs()
|
||||||
@@ -453,7 +453,7 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
///
|
///
|
||||||
/// Sets the vCPU general purpose registers.
|
/// 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();
|
let regs = (*regs).into();
|
||||||
self.fd
|
self.fd
|
||||||
.set_regs(®s)
|
.set_regs(®s)
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
//
|
//
|
||||||
use crate::arch::x86::{
|
use crate::arch::x86::{
|
||||||
CpuIdEntry, DescriptorTable, FpuState, LapicState, MsrEntry, SegmentRegister, SpecialRegisters,
|
CpuIdEntry, DescriptorTable, FpuState, LapicState, MsrEntry, SegmentRegister, SpecialRegisters,
|
||||||
StandardRegisters,
|
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
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 {
|
impl From<SegmentRegister> for MshvSegmentRegister {
|
||||||
fn from(s: SegmentRegister) -> Self {
|
fn from(s: SegmentRegister) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
+102
-56
@@ -51,7 +51,7 @@ use hypervisor::arch::x86::CpuIdEntry;
|
|||||||
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
||||||
use hypervisor::arch::x86::MsrEntry;
|
use hypervisor::arch::x86::MsrEntry;
|
||||||
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
||||||
use hypervisor::arch::x86::{SpecialRegisters, StandardRegisters};
|
use hypervisor::arch::x86::SpecialRegisters;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use hypervisor::kvm::kvm_bindings;
|
use hypervisor::kvm::kvm_bindings;
|
||||||
#[cfg(all(target_arch = "aarch64", feature = "kvm"))]
|
#[cfg(all(target_arch = "aarch64", feature = "kvm"))]
|
||||||
@@ -62,6 +62,8 @@ use hypervisor::kvm::{TdxExitDetails, TdxExitStatus};
|
|||||||
use hypervisor::CpuVendor;
|
use hypervisor::CpuVendor;
|
||||||
#[cfg(feature = "kvm")]
|
#[cfg(feature = "kvm")]
|
||||||
use hypervisor::HypervisorType;
|
use hypervisor::HypervisorType;
|
||||||
|
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
||||||
|
use hypervisor::StandardRegisters;
|
||||||
use hypervisor::{CpuState, HypervisorCpuError, VmExit, VmOps};
|
use hypervisor::{CpuState, HypervisorCpuError, VmExit, VmOps};
|
||||||
use libc::{c_void, siginfo_t};
|
use libc::{c_void, siginfo_t};
|
||||||
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
||||||
@@ -1595,6 +1597,15 @@ impl CpuManager {
|
|||||||
pptt
|
pptt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
||||||
|
fn create_standard_regs(&self, cpu_id: u8) -> StandardRegisters {
|
||||||
|
self.vcpus[usize::from(cpu_id)]
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.vcpu
|
||||||
|
.create_standard_regs()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "guest_debug")]
|
#[cfg(feature = "guest_debug")]
|
||||||
fn get_regs(&self, cpu_id: u8) -> Result<StandardRegisters> {
|
fn get_regs(&self, cpu_id: u8) -> Result<StandardRegisters> {
|
||||||
self.vcpus[usize::from(cpu_id)]
|
self.vcpus[usize::from(cpu_id)]
|
||||||
@@ -2331,14 +2342,28 @@ impl Debuggable for CpuManager {
|
|||||||
.get_regs(cpu_id as u8)
|
.get_regs(cpu_id as u8)
|
||||||
.map_err(DebuggableError::ReadRegs)?;
|
.map_err(DebuggableError::ReadRegs)?;
|
||||||
let regs = [
|
let regs = [
|
||||||
gregs.rax, gregs.rbx, gregs.rcx, gregs.rdx, gregs.rsi, gregs.rdi, gregs.rbp, gregs.rsp,
|
gregs.get_rax(),
|
||||||
gregs.r8, gregs.r9, gregs.r10, gregs.r11, gregs.r12, gregs.r13, gregs.r14, gregs.r15,
|
gregs.get_rbx(),
|
||||||
|
gregs.get_rcx(),
|
||||||
|
gregs.get_rdx(),
|
||||||
|
gregs.get_rsi(),
|
||||||
|
gregs.get_rdi(),
|
||||||
|
gregs.get_rbp(),
|
||||||
|
gregs.get_rsp(),
|
||||||
|
gregs.get_r8(),
|
||||||
|
gregs.get_r9(),
|
||||||
|
gregs.get_r10(),
|
||||||
|
gregs.get_r11(),
|
||||||
|
gregs.get_r12(),
|
||||||
|
gregs.get_r13(),
|
||||||
|
gregs.get_r14(),
|
||||||
|
gregs.get_r15(),
|
||||||
];
|
];
|
||||||
|
|
||||||
// GDB exposes 32-bit eflags instead of 64-bit rflags.
|
// GDB exposes 32-bit eflags instead of 64-bit rflags.
|
||||||
// https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml
|
// https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml
|
||||||
let eflags = gregs.rflags as u32;
|
let eflags = gregs.get_rflags() as u32;
|
||||||
let rip = gregs.rip;
|
let rip = gregs.get_rip();
|
||||||
|
|
||||||
// Segment registers: CS, SS, DS, ES, FS, GS
|
// Segment registers: CS, SS, DS, ES, FS, GS
|
||||||
let sregs = self
|
let sregs = self
|
||||||
@@ -2386,27 +2411,26 @@ impl Debuggable for CpuManager {
|
|||||||
let orig_gregs = self
|
let orig_gregs = self
|
||||||
.get_regs(cpu_id as u8)
|
.get_regs(cpu_id as u8)
|
||||||
.map_err(DebuggableError::ReadRegs)?;
|
.map_err(DebuggableError::ReadRegs)?;
|
||||||
let gregs = StandardRegisters {
|
let mut gregs = self.create_standard_regs(cpu_id as u8);
|
||||||
rax: regs.regs[0],
|
gregs.set_rax(regs.regs[0]);
|
||||||
rbx: regs.regs[1],
|
gregs.set_rbx(regs.regs[1]);
|
||||||
rcx: regs.regs[2],
|
gregs.set_rcx(regs.regs[2]);
|
||||||
rdx: regs.regs[3],
|
gregs.set_rdx(regs.regs[3]);
|
||||||
rsi: regs.regs[4],
|
gregs.set_rsi(regs.regs[4]);
|
||||||
rdi: regs.regs[5],
|
gregs.set_rdi(regs.regs[5]);
|
||||||
rbp: regs.regs[6],
|
gregs.set_rbp(regs.regs[6]);
|
||||||
rsp: regs.regs[7],
|
gregs.set_rsp(regs.regs[7]);
|
||||||
r8: regs.regs[8],
|
gregs.set_r8(regs.regs[8]);
|
||||||
r9: regs.regs[9],
|
gregs.set_r9(regs.regs[9]);
|
||||||
r10: regs.regs[10],
|
gregs.set_r10(regs.regs[10]);
|
||||||
r11: regs.regs[11],
|
gregs.set_r11(regs.regs[11]);
|
||||||
r12: regs.regs[12],
|
gregs.set_r12(regs.regs[12]);
|
||||||
r13: regs.regs[13],
|
gregs.set_r13(regs.regs[13]);
|
||||||
r14: regs.regs[14],
|
gregs.set_r14(regs.regs[14]);
|
||||||
r15: regs.regs[15],
|
gregs.set_r15(regs.regs[15]);
|
||||||
rip: regs.rip,
|
gregs.set_rip(regs.rip);
|
||||||
// Update the lower 32-bit of rflags.
|
// Update the lower 32-bit of rflags.
|
||||||
rflags: (orig_gregs.rflags & !(u32::MAX as u64)) | (regs.eflags as u64),
|
gregs.set_rflags((orig_gregs.get_rflags() & !(u32::MAX as u64)) | (regs.eflags as u64));
|
||||||
};
|
|
||||||
|
|
||||||
self.set_regs(cpu_id as u8, &gregs)
|
self.set_regs(cpu_id as u8, &gregs)
|
||||||
.map_err(DebuggableError::WriteRegs)?;
|
.map_err(DebuggableError::WriteRegs)?;
|
||||||
@@ -2566,11 +2590,24 @@ impl CpuElf64Writable for CpuManager {
|
|||||||
.map_err(|_e| GuestDebuggableError::Coredump(anyhow!("get regs failed")))?;
|
.map_err(|_e| GuestDebuggableError::Coredump(anyhow!("get regs failed")))?;
|
||||||
|
|
||||||
let regs1 = [
|
let regs1 = [
|
||||||
gregs.r15, gregs.r14, gregs.r13, gregs.r12, gregs.rbp, gregs.rbx, gregs.r11,
|
gregs.get_r15(),
|
||||||
gregs.r10,
|
gregs.get_r14(),
|
||||||
|
gregs.get_r13(),
|
||||||
|
gregs.get_r12(),
|
||||||
|
gregs.get_rbp(),
|
||||||
|
gregs.get_rbx(),
|
||||||
|
gregs.get_r11(),
|
||||||
|
gregs.get_r10(),
|
||||||
];
|
];
|
||||||
let regs2 = [
|
let regs2 = [
|
||||||
gregs.r9, gregs.r8, gregs.rax, gregs.rcx, gregs.rdx, gregs.rsi, gregs.rdi, orig_rax,
|
gregs.get_r9(),
|
||||||
|
gregs.get_r8(),
|
||||||
|
gregs.get_rax(),
|
||||||
|
gregs.get_rcx(),
|
||||||
|
gregs.get_rdx(),
|
||||||
|
gregs.get_rsi(),
|
||||||
|
gregs.get_rdi(),
|
||||||
|
orig_rax,
|
||||||
];
|
];
|
||||||
|
|
||||||
let sregs = self.vcpus[usize::from(vcpu_id)]
|
let sregs = self.vcpus[usize::from(vcpu_id)]
|
||||||
@@ -2582,8 +2619,8 @@ impl CpuElf64Writable for CpuManager {
|
|||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"rip 0x{:x} rsp 0x{:x} gs 0x{:x} cs 0x{:x} ss 0x{:x} ds 0x{:x}",
|
"rip 0x{:x} rsp 0x{:x} gs 0x{:x} cs 0x{:x} ss 0x{:x} ds 0x{:x}",
|
||||||
gregs.rip,
|
gregs.get_rip(),
|
||||||
gregs.rsp,
|
gregs.get_rsp(),
|
||||||
sregs.gs.base,
|
sregs.gs.base,
|
||||||
sregs.cs.selector,
|
sregs.cs.selector,
|
||||||
sregs.ss.selector,
|
sregs.ss.selector,
|
||||||
@@ -2593,10 +2630,10 @@ impl CpuElf64Writable for CpuManager {
|
|||||||
let regs = X86_64UserRegs {
|
let regs = X86_64UserRegs {
|
||||||
regs1,
|
regs1,
|
||||||
regs2,
|
regs2,
|
||||||
rip: gregs.rip,
|
rip: gregs.get_rip(),
|
||||||
cs: sregs.cs.selector as u64,
|
cs: sregs.cs.selector as u64,
|
||||||
eflags: gregs.rflags,
|
eflags: gregs.get_rflags(),
|
||||||
rsp: gregs.rsp,
|
rsp: gregs.get_rsp(),
|
||||||
ss: sregs.ss.selector as u64,
|
ss: sregs.ss.selector as u64,
|
||||||
fs_base: sregs.fs.base,
|
fs_base: sregs.fs.base,
|
||||||
gs_base: sregs.gs.base,
|
gs_base: sregs.gs.base,
|
||||||
@@ -2655,13 +2692,25 @@ impl CpuElf64Writable for CpuManager {
|
|||||||
.map_err(|_e| GuestDebuggableError::Coredump(anyhow!("get regs failed")))?;
|
.map_err(|_e| GuestDebuggableError::Coredump(anyhow!("get regs failed")))?;
|
||||||
|
|
||||||
let regs1 = [
|
let regs1 = [
|
||||||
gregs.rax, gregs.rbx, gregs.rcx, gregs.rdx, gregs.rsi, gregs.rdi, gregs.rsp,
|
gregs.get_rax(),
|
||||||
gregs.rbp,
|
gregs.get_rbx(),
|
||||||
|
gregs.get_rcx(),
|
||||||
|
gregs.get_rdx(),
|
||||||
|
gregs.get_rsi(),
|
||||||
|
gregs.get_rdi(),
|
||||||
|
gregs.get_rsp(),
|
||||||
|
gregs.get_rbp(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let regs2 = [
|
let regs2 = [
|
||||||
gregs.r8, gregs.r9, gregs.r10, gregs.r11, gregs.r12, gregs.r13, gregs.r14,
|
gregs.get_r8(),
|
||||||
gregs.r15,
|
gregs.get_r9(),
|
||||||
|
gregs.get_r10(),
|
||||||
|
gregs.get_r11(),
|
||||||
|
gregs.get_r12(),
|
||||||
|
gregs.get_r13(),
|
||||||
|
gregs.get_r14(),
|
||||||
|
gregs.get_r15(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let sregs = self.vcpus[usize::from(vcpu_id)]
|
let sregs = self.vcpus[usize::from(vcpu_id)]
|
||||||
@@ -2700,8 +2749,8 @@ impl CpuElf64Writable for CpuManager {
|
|||||||
size: size_of::<DumpCpusState>() as u32,
|
size: size_of::<DumpCpusState>() as u32,
|
||||||
regs1,
|
regs1,
|
||||||
regs2,
|
regs2,
|
||||||
rip: gregs.rip,
|
rip: gregs.get_rip(),
|
||||||
rflags: gregs.rflags,
|
rflags: gregs.get_rflags(),
|
||||||
cs,
|
cs,
|
||||||
ds,
|
ds,
|
||||||
es,
|
es,
|
||||||
@@ -2737,7 +2786,8 @@ mod tests {
|
|||||||
use arch::layout::ZERO_PAGE_START;
|
use arch::layout::ZERO_PAGE_START;
|
||||||
use arch::x86_64::interrupts::*;
|
use arch::x86_64::interrupts::*;
|
||||||
use arch::x86_64::regs::*;
|
use arch::x86_64::regs::*;
|
||||||
use hypervisor::arch::x86::{FpuState, LapicState, StandardRegisters};
|
use hypervisor::arch::x86::{FpuState, LapicState};
|
||||||
|
use hypervisor::StandardRegisters;
|
||||||
use linux_loader::loader::bootparam::setup_header;
|
use linux_loader::loader::bootparam::setup_header;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -2822,17 +2872,15 @@ mod tests {
|
|||||||
let vm = hv.create_vm().expect("new VM fd creation failed");
|
let vm = hv.create_vm().expect("new VM fd creation failed");
|
||||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||||
|
|
||||||
let expected_regs: StandardRegisters = StandardRegisters {
|
let mut expected_regs: StandardRegisters = vcpu.create_standard_regs();
|
||||||
rflags: 0x0000000000000002u64,
|
expected_regs.set_rflags(0x0000000000000002u64);
|
||||||
rbx: arch::layout::PVH_INFO_START.0,
|
expected_regs.set_rbx(arch::layout::PVH_INFO_START.0);
|
||||||
rip: 1,
|
expected_regs.set_rip(1);
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
setup_regs(
|
setup_regs(
|
||||||
&vcpu,
|
&vcpu,
|
||||||
arch::EntryPoint {
|
arch::EntryPoint {
|
||||||
entry_addr: vm_memory::GuestAddress(expected_regs.rip),
|
entry_addr: vm_memory::GuestAddress(expected_regs.get_rip()),
|
||||||
setup_header: None,
|
setup_header: None,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -2848,18 +2896,16 @@ mod tests {
|
|||||||
let vm = hv.create_vm().expect("new VM fd creation failed");
|
let vm = hv.create_vm().expect("new VM fd creation failed");
|
||||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||||
|
|
||||||
let expected_regs: StandardRegisters = StandardRegisters {
|
let mut expected_regs: StandardRegisters = vcpu.create_standard_regs();
|
||||||
rflags: 0x0000000000000002u64,
|
expected_regs.set_rflags(0x0000000000000002u64);
|
||||||
rip: 1,
|
expected_regs.set_rip(1);
|
||||||
rsp: BOOT_STACK_POINTER.0,
|
expected_regs.set_rsp(BOOT_STACK_POINTER.0);
|
||||||
rsi: ZERO_PAGE_START.0,
|
expected_regs.set_rsi(ZERO_PAGE_START.0);
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
setup_regs(
|
setup_regs(
|
||||||
&vcpu,
|
&vcpu,
|
||||||
arch::EntryPoint {
|
arch::EntryPoint {
|
||||||
entry_addr: vm_memory::GuestAddress(expected_regs.rip),
|
entry_addr: vm_memory::GuestAddress(expected_regs.get_rip()),
|
||||||
setup_header: Some(setup_header {
|
setup_header: Some(setup_header {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
|
|||||||
+4
-4
@@ -3236,10 +3236,10 @@ pub fn test_vm() {
|
|||||||
vcpu.set_sregs(&vcpu_sregs).expect("set sregs failed");
|
vcpu.set_sregs(&vcpu_sregs).expect("set sregs failed");
|
||||||
|
|
||||||
let mut vcpu_regs = vcpu.get_regs().expect("get regs failed");
|
let mut vcpu_regs = vcpu.get_regs().expect("get regs failed");
|
||||||
vcpu_regs.rip = 0x1000;
|
vcpu_regs.set_rip(0x1000);
|
||||||
vcpu_regs.rax = 2;
|
vcpu_regs.set_rax(2);
|
||||||
vcpu_regs.rbx = 3;
|
vcpu_regs.set_rbx(3);
|
||||||
vcpu_regs.rflags = 2;
|
vcpu_regs.set_rflags(2);
|
||||||
vcpu.set_regs(&vcpu_regs).expect("set regs failed");
|
vcpu.set_regs(&vcpu_regs).expect("set regs failed");
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
Reference in New Issue
Block a user