diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index a78c17a91..f2b5242fb 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -32,8 +32,12 @@ use anyhow::anyhow; use arch::EntryPoint; use arch::NumaNodes; use devices::interrupt_controller::InterruptController; +#[cfg(all(target_arch = "aarch64", feature = "gdb"))] +use gdbstub_arch::aarch64::reg::AArch64CoreRegs as CoreRegs; #[cfg(all(target_arch = "x86_64", feature = "gdb"))] -use gdbstub_arch::x86::reg::{X86SegmentRegs, X86_64CoreRegs}; +use gdbstub_arch::x86::reg::{X86SegmentRegs, X86_64CoreRegs as CoreRegs}; +#[cfg(all(target_arch = "aarch64", feature = "gdb"))] +use hypervisor::aarch64::StandardRegisters; #[cfg(feature = "guest_debug")] use hypervisor::arch::x86::msr_index; #[cfg(target_arch = "x86_64")] @@ -133,7 +137,7 @@ pub enum Error { #[error("Error initializing PMU: {0}")] InitPmu(#[source] hypervisor::HypervisorCpuError), - #[cfg(all(target_arch = "x86_64", feature = "gdb"))] + #[cfg(feature = "gdb")] #[error("Error during CPU debug: {0}")] CpuDebug(#[source] hypervisor::HypervisorCpuError), @@ -950,7 +954,7 @@ impl CpuManager { // vcpu.run() returns false on a triple-fault so trigger a reset match vcpu.run() { Ok(run) => match run { - #[cfg(all(target_arch = "x86_64", feature = "kvm"))] + #[cfg(feature = "kvm")] VmExit::Debug => { info!("VmExit::Debug"); #[cfg(feature = "gdb")] @@ -1436,7 +1440,7 @@ impl CpuManager { pptt } - #[cfg(all(target_arch = "x86_64", feature = "gdb"))] + #[cfg(feature = "gdb")] fn get_regs(&self, cpu_id: u8) -> Result { self.vcpus[usize::from(cpu_id)] .lock() @@ -1446,7 +1450,7 @@ impl CpuManager { .map_err(Error::CpuDebug) } - #[cfg(all(target_arch = "x86_64", feature = "gdb"))] + #[cfg(feature = "gdb")] fn set_regs(&self, cpu_id: u8, regs: &StandardRegisters) -> Result<()> { self.vcpus[usize::from(cpu_id)] .lock() @@ -1486,6 +1490,11 @@ impl CpuManager { .map_err(Error::TranslateVirtualAddress)?; Ok(gpa) } + + #[cfg(all(target_arch = "aarch64", feature = "gdb"))] + fn translate_gva(&self, cpu_id: u8, gva: u64) -> Result { + unimplemented!() + } } struct Cpu { @@ -1931,7 +1940,7 @@ impl Debuggable for CpuManager { } #[cfg(target_arch = "x86_64")] - fn read_regs(&self, cpu_id: usize) -> std::result::Result { + fn read_regs(&self, cpu_id: usize) -> std::result::Result { // General registers: RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, r8-r15 let gregs = self .get_regs(cpu_id as u8) @@ -1961,7 +1970,7 @@ impl Debuggable for CpuManager { // TODO: Add other registers - Ok(X86_64CoreRegs { + Ok(CoreRegs { regs, eflags, rip, @@ -1970,11 +1979,24 @@ impl Debuggable for CpuManager { }) } + #[cfg(target_arch = "aarch64")] + fn read_regs(&self, cpu_id: usize) -> std::result::Result { + let gregs = self + .get_regs(cpu_id as u8) + .map_err(DebuggableError::ReadRegs)?; + Ok(CoreRegs { + x: gregs.regs.regs, + sp: gregs.regs.sp, + pc: gregs.regs.pc, + ..Default::default() + }) + } + #[cfg(target_arch = "x86_64")] fn write_regs( &self, cpu_id: usize, - regs: &X86_64CoreRegs, + regs: &CoreRegs, ) -> std::result::Result<(), DebuggableError> { let orig_gregs = self .get_regs(cpu_id as u8) @@ -2024,7 +2046,26 @@ impl Debuggable for CpuManager { Ok(()) } - #[cfg(target_arch = "x86_64")] + #[cfg(target_arch = "aarch64")] + fn write_regs( + &self, + cpu_id: usize, + regs: &CoreRegs, + ) -> std::result::Result<(), DebuggableError> { + let mut gregs = self + .get_regs(cpu_id as u8) + .map_err(DebuggableError::ReadRegs)?; + + gregs.regs.regs = regs.x; + gregs.regs.sp = regs.sp; + gregs.regs.pc = regs.pc; + + self.set_regs(cpu_id as u8, &gregs) + .map_err(DebuggableError::WriteRegs)?; + + Ok(()) + } + fn read_mem( &self, cpu_id: usize, @@ -2055,7 +2096,6 @@ impl Debuggable for CpuManager { Ok(buf) } - #[cfg(target_arch = "x86_64")] fn write_mem( &self, cpu_id: usize, diff --git a/vmm/src/gdb.rs b/vmm/src/gdb.rs index 440362f69..d60a7daaf 100644 --- a/vmm/src/gdb.rs +++ b/vmm/src/gdb.rs @@ -24,6 +24,10 @@ use gdbstub::{ Target, TargetError, TargetResult, }, }; +#[cfg(target_arch = "aarch64")] +use gdbstub_arch::aarch64::reg::AArch64CoreRegs as CoreRegs; +#[cfg(target_arch = "aarch64")] +use gdbstub_arch::aarch64::AArch64 as GdbArch; #[cfg(target_arch = "x86_64")] use gdbstub_arch::x86::reg::X86_64CoreRegs as CoreRegs; #[cfg(target_arch = "x86_64")] @@ -31,7 +35,6 @@ use gdbstub_arch::x86::X86_64_SSE as GdbArch; use std::{os::unix::net::UnixListener, sync::mpsc}; use vm_memory::{GuestAddress, GuestMemoryError}; -#[cfg(target_arch = "x86_64")] type ArchUsize = u64; #[derive(Debug)] @@ -121,7 +124,6 @@ pub struct GdbStub { gdb_sender: mpsc::Sender, gdb_event: vmm_sys_util::eventfd::EventFd, vm_event: vmm_sys_util::eventfd::EventFd, - hw_breakpoints: Vec, single_step: bool, } diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index cdb3631da..77654fa2a 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -51,8 +51,10 @@ use devices::gic::GIC_V3_ITS_SNAPSHOT_ID; #[cfg(target_arch = "aarch64")] use devices::interrupt_controller::{self, InterruptController}; use devices::AcpiNotificationFlags; +#[cfg(all(target_arch = "aarch64", feature = "gdb"))] +use gdbstub_arch::aarch64::reg::AArch64CoreRegs as CoreRegs; #[cfg(all(target_arch = "x86_64", feature = "gdb"))] -use gdbstub_arch::x86::reg::X86_64CoreRegs; +use gdbstub_arch::x86::reg::X86_64CoreRegs as CoreRegs; use hypervisor::{HypervisorVmError, VmOps}; use linux_loader::cmdline::Cmdline; #[cfg(feature = "guest_debug")] @@ -2522,7 +2524,7 @@ impl Vm { self.memory_manager.lock().unwrap().snapshot_data() } - #[cfg(all(target_arch = "x86_64", feature = "gdb"))] + #[cfg(feature = "gdb")] pub fn debug_request( &mut self, gdb_request: &GdbRequestPayload, @@ -2973,14 +2975,14 @@ impl Debuggable for Vm { Ok(()) } - fn read_regs(&self, cpu_id: usize) -> std::result::Result { + fn read_regs(&self, cpu_id: usize) -> std::result::Result { self.cpu_manager.lock().unwrap().read_regs(cpu_id) } fn write_regs( &self, cpu_id: usize, - regs: &X86_64CoreRegs, + regs: &CoreRegs, ) -> std::result::Result<(), DebuggableError> { self.cpu_manager.lock().unwrap().write_regs(cpu_id, regs) }