mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-11-04 19:11:11 +00:00
vmm: Enable gdbstub
on AArch64
The `gva_translate` function is still missing, it will be added with a separate commit. Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
parent
baa58ad8bf
commit
5febdec81a
@ -32,8 +32,12 @@ use anyhow::anyhow;
|
|||||||
use arch::EntryPoint;
|
use arch::EntryPoint;
|
||||||
use arch::NumaNodes;
|
use arch::NumaNodes;
|
||||||
use devices::interrupt_controller::InterruptController;
|
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"))]
|
#[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")]
|
#[cfg(feature = "guest_debug")]
|
||||||
use hypervisor::arch::x86::msr_index;
|
use hypervisor::arch::x86::msr_index;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -133,7 +137,7 @@ pub enum Error {
|
|||||||
#[error("Error initializing PMU: {0}")]
|
#[error("Error initializing PMU: {0}")]
|
||||||
InitPmu(#[source] hypervisor::HypervisorCpuError),
|
InitPmu(#[source] hypervisor::HypervisorCpuError),
|
||||||
|
|
||||||
#[cfg(all(target_arch = "x86_64", feature = "gdb"))]
|
#[cfg(feature = "gdb")]
|
||||||
#[error("Error during CPU debug: {0}")]
|
#[error("Error during CPU debug: {0}")]
|
||||||
CpuDebug(#[source] hypervisor::HypervisorCpuError),
|
CpuDebug(#[source] hypervisor::HypervisorCpuError),
|
||||||
|
|
||||||
@ -950,7 +954,7 @@ impl CpuManager {
|
|||||||
// vcpu.run() returns false on a triple-fault so trigger a reset
|
// vcpu.run() returns false on a triple-fault so trigger a reset
|
||||||
match vcpu.run() {
|
match vcpu.run() {
|
||||||
Ok(run) => match run {
|
Ok(run) => match run {
|
||||||
#[cfg(all(target_arch = "x86_64", feature = "kvm"))]
|
#[cfg(feature = "kvm")]
|
||||||
VmExit::Debug => {
|
VmExit::Debug => {
|
||||||
info!("VmExit::Debug");
|
info!("VmExit::Debug");
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
@ -1436,7 +1440,7 @@ impl CpuManager {
|
|||||||
pptt
|
pptt
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(target_arch = "x86_64", feature = "gdb"))]
|
#[cfg(feature = "gdb")]
|
||||||
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)]
|
||||||
.lock()
|
.lock()
|
||||||
@ -1446,7 +1450,7 @@ impl CpuManager {
|
|||||||
.map_err(Error::CpuDebug)
|
.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<()> {
|
fn set_regs(&self, cpu_id: u8, regs: &StandardRegisters) -> Result<()> {
|
||||||
self.vcpus[usize::from(cpu_id)]
|
self.vcpus[usize::from(cpu_id)]
|
||||||
.lock()
|
.lock()
|
||||||
@ -1486,6 +1490,11 @@ impl CpuManager {
|
|||||||
.map_err(Error::TranslateVirtualAddress)?;
|
.map_err(Error::TranslateVirtualAddress)?;
|
||||||
Ok(gpa)
|
Ok(gpa)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "aarch64", feature = "gdb"))]
|
||||||
|
fn translate_gva(&self, cpu_id: u8, gva: u64) -> Result<u64> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Cpu {
|
struct Cpu {
|
||||||
@ -1931,7 +1940,7 @@ impl Debuggable for CpuManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
fn read_regs(&self, cpu_id: usize) -> std::result::Result<X86_64CoreRegs, DebuggableError> {
|
fn read_regs(&self, cpu_id: usize) -> std::result::Result<CoreRegs, DebuggableError> {
|
||||||
// General registers: RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, r8-r15
|
// General registers: RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, r8-r15
|
||||||
let gregs = self
|
let gregs = self
|
||||||
.get_regs(cpu_id as u8)
|
.get_regs(cpu_id as u8)
|
||||||
@ -1961,7 +1970,7 @@ impl Debuggable for CpuManager {
|
|||||||
|
|
||||||
// TODO: Add other registers
|
// TODO: Add other registers
|
||||||
|
|
||||||
Ok(X86_64CoreRegs {
|
Ok(CoreRegs {
|
||||||
regs,
|
regs,
|
||||||
eflags,
|
eflags,
|
||||||
rip,
|
rip,
|
||||||
@ -1970,11 +1979,24 @@ impl Debuggable for CpuManager {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
fn read_regs(&self, cpu_id: usize) -> std::result::Result<CoreRegs, DebuggableError> {
|
||||||
|
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")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
fn write_regs(
|
fn write_regs(
|
||||||
&self,
|
&self,
|
||||||
cpu_id: usize,
|
cpu_id: usize,
|
||||||
regs: &X86_64CoreRegs,
|
regs: &CoreRegs,
|
||||||
) -> std::result::Result<(), DebuggableError> {
|
) -> std::result::Result<(), DebuggableError> {
|
||||||
let orig_gregs = self
|
let orig_gregs = self
|
||||||
.get_regs(cpu_id as u8)
|
.get_regs(cpu_id as u8)
|
||||||
@ -2024,7 +2046,26 @@ impl Debuggable for CpuManager {
|
|||||||
Ok(())
|
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(
|
fn read_mem(
|
||||||
&self,
|
&self,
|
||||||
cpu_id: usize,
|
cpu_id: usize,
|
||||||
@ -2055,7 +2096,6 @@ impl Debuggable for CpuManager {
|
|||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
fn write_mem(
|
fn write_mem(
|
||||||
&self,
|
&self,
|
||||||
cpu_id: usize,
|
cpu_id: usize,
|
||||||
|
@ -24,6 +24,10 @@ use gdbstub::{
|
|||||||
Target, TargetError, TargetResult,
|
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")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use gdbstub_arch::x86::reg::X86_64CoreRegs as CoreRegs;
|
use gdbstub_arch::x86::reg::X86_64CoreRegs as CoreRegs;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[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 std::{os::unix::net::UnixListener, sync::mpsc};
|
||||||
use vm_memory::{GuestAddress, GuestMemoryError};
|
use vm_memory::{GuestAddress, GuestMemoryError};
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
type ArchUsize = u64;
|
type ArchUsize = u64;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -121,7 +124,6 @@ pub struct GdbStub {
|
|||||||
gdb_sender: mpsc::Sender<GdbRequest>,
|
gdb_sender: mpsc::Sender<GdbRequest>,
|
||||||
gdb_event: vmm_sys_util::eventfd::EventFd,
|
gdb_event: vmm_sys_util::eventfd::EventFd,
|
||||||
vm_event: vmm_sys_util::eventfd::EventFd,
|
vm_event: vmm_sys_util::eventfd::EventFd,
|
||||||
|
|
||||||
hw_breakpoints: Vec<GuestAddress>,
|
hw_breakpoints: Vec<GuestAddress>,
|
||||||
single_step: bool,
|
single_step: bool,
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,10 @@ use devices::gic::GIC_V3_ITS_SNAPSHOT_ID;
|
|||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use devices::interrupt_controller::{self, InterruptController};
|
use devices::interrupt_controller::{self, InterruptController};
|
||||||
use devices::AcpiNotificationFlags;
|
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"))]
|
#[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 hypervisor::{HypervisorVmError, VmOps};
|
||||||
use linux_loader::cmdline::Cmdline;
|
use linux_loader::cmdline::Cmdline;
|
||||||
#[cfg(feature = "guest_debug")]
|
#[cfg(feature = "guest_debug")]
|
||||||
@ -2522,7 +2524,7 @@ impl Vm {
|
|||||||
self.memory_manager.lock().unwrap().snapshot_data()
|
self.memory_manager.lock().unwrap().snapshot_data()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(target_arch = "x86_64", feature = "gdb"))]
|
#[cfg(feature = "gdb")]
|
||||||
pub fn debug_request(
|
pub fn debug_request(
|
||||||
&mut self,
|
&mut self,
|
||||||
gdb_request: &GdbRequestPayload,
|
gdb_request: &GdbRequestPayload,
|
||||||
@ -2973,14 +2975,14 @@ impl Debuggable for Vm {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_regs(&self, cpu_id: usize) -> std::result::Result<X86_64CoreRegs, DebuggableError> {
|
fn read_regs(&self, cpu_id: usize) -> std::result::Result<CoreRegs, DebuggableError> {
|
||||||
self.cpu_manager.lock().unwrap().read_regs(cpu_id)
|
self.cpu_manager.lock().unwrap().read_regs(cpu_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_regs(
|
fn write_regs(
|
||||||
&self,
|
&self,
|
||||||
cpu_id: usize,
|
cpu_id: usize,
|
||||||
regs: &X86_64CoreRegs,
|
regs: &CoreRegs,
|
||||||
) -> std::result::Result<(), DebuggableError> {
|
) -> std::result::Result<(), DebuggableError> {
|
||||||
self.cpu_manager.lock().unwrap().write_regs(cpu_id, regs)
|
self.cpu_manager.lock().unwrap().write_regs(cpu_id, regs)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user