diff --git a/Cargo.lock b/Cargo.lock index 57b191b7b..cc7ccc373 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -992,6 +992,7 @@ version = "0.1.0" dependencies = [ "anyhow", "byteorder", + "cfg-if", "concat-idents", "env_logger", "iced-x86", diff --git a/arch/src/x86_64/regs.rs b/arch/src/x86_64/regs.rs index e41d7b156..2688c831f 100644 --- a/arch/src/x86_64/regs.rs +++ b/arch/src/x86_64/regs.rs @@ -12,7 +12,7 @@ use crate::layout::{ use crate::{EntryPoint, GuestMemoryMmap}; use hypervisor::arch::x86::gdt::{gdt_entry, segment_from_gdt}; 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::{mem, result}; use thiserror::Error; @@ -94,20 +94,19 @@ pub fn setup_msrs(vcpu: &Arc) -> Result<()> { /// * `vcpu` - Structure for the VCPU that holds the VCPU's fd. /// * `entry_point` - Description of the boot entry to set up. pub fn setup_regs(vcpu: &Arc, entry_point: EntryPoint) -> Result<()> { - let regs = match entry_point.setup_header { - None => StandardRegisters { - rflags: 0x0000000000000002u64, - rip: entry_point.entry_addr.raw_value(), - rbx: PVH_INFO_START.raw_value(), - ..Default::default() - }, - Some(_) => StandardRegisters { - rflags: 0x0000000000000002u64, - rip: entry_point.entry_addr.raw_value(), - rsp: BOOT_STACK_POINTER.raw_value(), - rsi: ZERO_PAGE_START.raw_value(), - ..Default::default() - }, + let mut regs = vcpu.create_standard_regs(); + match entry_point.setup_header { + None => { + regs.set_rflags(0x0000000000000002u64); + regs.set_rip(entry_point.entry_addr.raw_value()); + regs.set_rbx(PVH_INFO_START.raw_value()); + } + Some(_) => { + regs.set_rflags(0x0000000000000002u64); + regs.set_rip(entry_point.entry_addr.raw_value()); + regs.set_rsp(BOOT_STACK_POINTER.raw_value()); + regs.set_rsi(ZERO_PAGE_START.raw_value()); + } }; vcpu.set_regs(®s).map_err(Error::SetBaseRegisters) } diff --git a/hypervisor/Cargo.toml b/hypervisor/Cargo.toml index a82280488..6e03df0b6 100644 --- a/hypervisor/Cargo.toml +++ b/hypervisor/Cargo.toml @@ -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 } diff --git a/hypervisor/src/arch/x86/emulator/mod.rs b/hypervisor/src/arch/x86/emulator/mod.rs index d08ab5b90..71e375533 100644 --- a/hypervisor/src/arch/x86/emulator/mod.rs +++ b/hypervisor/src/arch/x86/emulator/mod.rs @@ -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 { 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 { @@ -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(); diff --git a/hypervisor/src/arch/x86/mod.rs b/hypervisor/src/arch/x86/mod.rs index 385772a0c..d9832b296 100644 --- a/hypervisor/src/arch/x86/mod.rs +++ b/hypervisor/src/arch/x86/mod.rs @@ -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, diff --git a/hypervisor/src/cpu.rs b/hypervisor/src/cpu.rs index 4d1cd784f..4e5312fdd 100644 --- a/hypervisor/src/cpu.rs +++ b/hypervisor/src/cpu.rs @@ -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; diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index ac6d1472f..0d99bd65d 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -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, diff --git a/hypervisor/src/kvm/x86_64/mod.rs b/hypervisor/src/kvm/x86_64/mod.rs index 77a37c3f7..2aecc65c5 100644 --- a/hypervisor/src/kvm/x86_64/mod.rs +++ b/hypervisor/src/kvm/x86_64/mod.rs @@ -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, } -impl From 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 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 for kvm_segment { fn from(s: SegmentRegister) -> Self { Self { diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 54329d382..62e0dfa5f 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -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 { + fn get_regs(&self) -> cpu::Result { 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) diff --git a/hypervisor/src/mshv/x86_64/mod.rs b/hypervisor/src/mshv/x86_64/mod.rs index 45a97b84a..07576004e 100644 --- a/hypervisor/src/mshv/x86_64/mod.rs +++ b/hypervisor/src/mshv/x86_64/mod.rs @@ -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 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 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 for MshvSegmentRegister { fn from(s: SegmentRegister) -> Self { Self { diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 7e2752fe6..aa149f60f 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -51,7 +51,7 @@ use hypervisor::arch::x86::CpuIdEntry; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] use hypervisor::arch::x86::MsrEntry; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] -use hypervisor::arch::x86::{SpecialRegisters, StandardRegisters}; +use hypervisor::arch::x86::SpecialRegisters; #[cfg(target_arch = "aarch64")] use hypervisor::kvm::kvm_bindings; #[cfg(all(target_arch = "aarch64", feature = "kvm"))] @@ -62,6 +62,8 @@ use hypervisor::kvm::{TdxExitDetails, TdxExitStatus}; use hypervisor::CpuVendor; #[cfg(feature = "kvm")] use hypervisor::HypervisorType; +#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] +use hypervisor::StandardRegisters; use hypervisor::{CpuState, HypervisorCpuError, VmExit, VmOps}; use libc::{c_void, siginfo_t}; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] @@ -1595,6 +1597,15 @@ impl CpuManager { 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")] fn get_regs(&self, cpu_id: u8) -> Result { self.vcpus[usize::from(cpu_id)] @@ -2331,14 +2342,28 @@ impl Debuggable for CpuManager { .get_regs(cpu_id as u8) .map_err(DebuggableError::ReadRegs)?; let regs = [ - gregs.rax, gregs.rbx, gregs.rcx, gregs.rdx, gregs.rsi, gregs.rdi, gregs.rbp, gregs.rsp, - gregs.r8, gregs.r9, gregs.r10, gregs.r11, gregs.r12, gregs.r13, gregs.r14, gregs.r15, + gregs.get_rax(), + 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. // https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml - let eflags = gregs.rflags as u32; - let rip = gregs.rip; + let eflags = gregs.get_rflags() as u32; + let rip = gregs.get_rip(); // Segment registers: CS, SS, DS, ES, FS, GS let sregs = self @@ -2386,27 +2411,26 @@ impl Debuggable for CpuManager { let orig_gregs = self .get_regs(cpu_id as u8) .map_err(DebuggableError::ReadRegs)?; - let gregs = StandardRegisters { - rax: regs.regs[0], - rbx: regs.regs[1], - rcx: regs.regs[2], - rdx: regs.regs[3], - rsi: regs.regs[4], - rdi: regs.regs[5], - rbp: regs.regs[6], - rsp: regs.regs[7], - r8: regs.regs[8], - r9: regs.regs[9], - r10: regs.regs[10], - r11: regs.regs[11], - r12: regs.regs[12], - r13: regs.regs[13], - r14: regs.regs[14], - r15: regs.regs[15], - rip: regs.rip, - // Update the lower 32-bit of rflags. - rflags: (orig_gregs.rflags & !(u32::MAX as u64)) | (regs.eflags as u64), - }; + let mut gregs = self.create_standard_regs(cpu_id as u8); + gregs.set_rax(regs.regs[0]); + gregs.set_rbx(regs.regs[1]); + gregs.set_rcx(regs.regs[2]); + gregs.set_rdx(regs.regs[3]); + gregs.set_rsi(regs.regs[4]); + gregs.set_rdi(regs.regs[5]); + gregs.set_rbp(regs.regs[6]); + gregs.set_rsp(regs.regs[7]); + gregs.set_r8(regs.regs[8]); + gregs.set_r9(regs.regs[9]); + gregs.set_r10(regs.regs[10]); + gregs.set_r11(regs.regs[11]); + gregs.set_r12(regs.regs[12]); + gregs.set_r13(regs.regs[13]); + gregs.set_r14(regs.regs[14]); + gregs.set_r15(regs.regs[15]); + gregs.set_rip(regs.rip); + // Update the lower 32-bit of rflags. + gregs.set_rflags((orig_gregs.get_rflags() & !(u32::MAX as u64)) | (regs.eflags as u64)); self.set_regs(cpu_id as u8, &gregs) .map_err(DebuggableError::WriteRegs)?; @@ -2566,11 +2590,24 @@ impl CpuElf64Writable for CpuManager { .map_err(|_e| GuestDebuggableError::Coredump(anyhow!("get regs failed")))?; let regs1 = [ - gregs.r15, gregs.r14, gregs.r13, gregs.r12, gregs.rbp, gregs.rbx, gregs.r11, - gregs.r10, + gregs.get_r15(), + gregs.get_r14(), + gregs.get_r13(), + gregs.get_r12(), + gregs.get_rbp(), + gregs.get_rbx(), + gregs.get_r11(), + gregs.get_r10(), ]; 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)] @@ -2582,8 +2619,8 @@ impl CpuElf64Writable for CpuManager { debug!( "rip 0x{:x} rsp 0x{:x} gs 0x{:x} cs 0x{:x} ss 0x{:x} ds 0x{:x}", - gregs.rip, - gregs.rsp, + gregs.get_rip(), + gregs.get_rsp(), sregs.gs.base, sregs.cs.selector, sregs.ss.selector, @@ -2593,10 +2630,10 @@ impl CpuElf64Writable for CpuManager { let regs = X86_64UserRegs { regs1, regs2, - rip: gregs.rip, + rip: gregs.get_rip(), cs: sregs.cs.selector as u64, - eflags: gregs.rflags, - rsp: gregs.rsp, + eflags: gregs.get_rflags(), + rsp: gregs.get_rsp(), ss: sregs.ss.selector as u64, fs_base: sregs.fs.base, gs_base: sregs.gs.base, @@ -2655,13 +2692,25 @@ impl CpuElf64Writable for CpuManager { .map_err(|_e| GuestDebuggableError::Coredump(anyhow!("get regs failed")))?; let regs1 = [ - gregs.rax, gregs.rbx, gregs.rcx, gregs.rdx, gregs.rsi, gregs.rdi, gregs.rsp, - gregs.rbp, + gregs.get_rax(), + gregs.get_rbx(), + gregs.get_rcx(), + gregs.get_rdx(), + gregs.get_rsi(), + gregs.get_rdi(), + gregs.get_rsp(), + gregs.get_rbp(), ]; let regs2 = [ - gregs.r8, gregs.r9, gregs.r10, gregs.r11, gregs.r12, gregs.r13, gregs.r14, - gregs.r15, + gregs.get_r8(), + 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)] @@ -2700,8 +2749,8 @@ impl CpuElf64Writable for CpuManager { size: size_of::() as u32, regs1, regs2, - rip: gregs.rip, - rflags: gregs.rflags, + rip: gregs.get_rip(), + rflags: gregs.get_rflags(), cs, ds, es, @@ -2737,7 +2786,8 @@ mod tests { use arch::layout::ZERO_PAGE_START; use arch::x86_64::interrupts::*; 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; #[test] @@ -2822,17 +2872,15 @@ mod tests { let vm = hv.create_vm().expect("new VM fd creation failed"); let vcpu = vm.create_vcpu(0, None).unwrap(); - let expected_regs: StandardRegisters = StandardRegisters { - rflags: 0x0000000000000002u64, - rbx: arch::layout::PVH_INFO_START.0, - rip: 1, - ..Default::default() - }; + let mut expected_regs: StandardRegisters = vcpu.create_standard_regs(); + expected_regs.set_rflags(0x0000000000000002u64); + expected_regs.set_rbx(arch::layout::PVH_INFO_START.0); + expected_regs.set_rip(1); setup_regs( &vcpu, arch::EntryPoint { - entry_addr: vm_memory::GuestAddress(expected_regs.rip), + entry_addr: vm_memory::GuestAddress(expected_regs.get_rip()), setup_header: None, }, ) @@ -2848,18 +2896,16 @@ mod tests { let vm = hv.create_vm().expect("new VM fd creation failed"); let vcpu = vm.create_vcpu(0, None).unwrap(); - let expected_regs: StandardRegisters = StandardRegisters { - rflags: 0x0000000000000002u64, - rip: 1, - rsp: BOOT_STACK_POINTER.0, - rsi: ZERO_PAGE_START.0, - ..Default::default() - }; + let mut expected_regs: StandardRegisters = vcpu.create_standard_regs(); + expected_regs.set_rflags(0x0000000000000002u64); + expected_regs.set_rip(1); + expected_regs.set_rsp(BOOT_STACK_POINTER.0); + expected_regs.set_rsi(ZERO_PAGE_START.0); setup_regs( &vcpu, arch::EntryPoint { - entry_addr: vm_memory::GuestAddress(expected_regs.rip), + entry_addr: vm_memory::GuestAddress(expected_regs.get_rip()), setup_header: Some(setup_header { ..Default::default() }), diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index a38d8c4d6..a9f7ce211 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -3236,10 +3236,10 @@ pub fn test_vm() { vcpu.set_sregs(&vcpu_sregs).expect("set sregs failed"); let mut vcpu_regs = vcpu.get_regs().expect("get regs failed"); - vcpu_regs.rip = 0x1000; - vcpu_regs.rax = 2; - vcpu_regs.rbx = 3; - vcpu_regs.rflags = 2; + vcpu_regs.set_rip(0x1000); + vcpu_regs.set_rax(2); + vcpu_regs.set_rbx(3); + vcpu_regs.set_rflags(2); vcpu.set_regs(&vcpu_regs).expect("set regs failed"); loop {