mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-08 22:05:20 +00:00
vmm: Restrict the maximum number of HW breakpoints
Set the maximum number of HW breakpoints according to the value returned from `Hypervisor::get_guest_debug_hw_bps()`. Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
parent
223b1f6c51
commit
d66d64c325
@ -1605,13 +1605,6 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
addrs: &[vm_memory::GuestAddress],
|
addrs: &[vm_memory::GuestAddress],
|
||||||
singlestep: bool,
|
singlestep: bool,
|
||||||
) -> cpu::Result<()> {
|
) -> cpu::Result<()> {
|
||||||
if addrs.len() > 4 {
|
|
||||||
return Err(cpu::HypervisorCpuError::SetDebugRegs(anyhow!(
|
|
||||||
"Support 4 breakpoints at most but {} addresses are passed",
|
|
||||||
addrs.len()
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut dbg = kvm_guest_debug {
|
let mut dbg = kvm_guest_debug {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
control: KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP,
|
control: KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP,
|
||||||
@ -1623,6 +1616,9 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
dbg.control |= KVM_GUESTDBG_SINGLESTEP;
|
dbg.control |= KVM_GUESTDBG_SINGLESTEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the debug registers.
|
||||||
|
// Here we assume that the number of addresses do not exceed what
|
||||||
|
// `Hypervisor::get_guest_debug_hw_bps()` specifies.
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
{
|
{
|
||||||
// Set bits 9 and 10.
|
// Set bits 9 and 10.
|
||||||
|
@ -133,12 +133,13 @@ impl 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: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
gdb_sender,
|
gdb_sender,
|
||||||
gdb_event,
|
gdb_event,
|
||||||
vm_event,
|
vm_event,
|
||||||
hw_breakpoints: Default::default(),
|
hw_breakpoints: Vec::with_capacity(hw_breakpoints),
|
||||||
single_step: false,
|
single_step: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -383,9 +384,12 @@ impl HwBreakpoint for GdbStub {
|
|||||||
addr: <Self::Arch as Arch>::Usize,
|
addr: <Self::Arch as Arch>::Usize,
|
||||||
_kind: <Self::Arch as Arch>::BreakpointKind,
|
_kind: <Self::Arch as Arch>::BreakpointKind,
|
||||||
) -> TargetResult<bool, Self> {
|
) -> TargetResult<bool, Self> {
|
||||||
// If we already have 4 breakpoints, we cannot set a new one.
|
// If the HW breakpoints reach the limit, no more can be added.
|
||||||
if self.hw_breakpoints.len() >= 4 {
|
if self.hw_breakpoints.len() >= self.hw_breakpoints.capacity() {
|
||||||
error!("Not allowed to set more than 4 HW breakpoints");
|
error!(
|
||||||
|
"Not allowed to set more than {} HW breakpoints",
|
||||||
|
self.hw_breakpoints.capacity()
|
||||||
|
);
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +272,8 @@ pub fn start_vmm_thread(
|
|||||||
seccomp_action: &SeccompAction,
|
seccomp_action: &SeccompAction,
|
||||||
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
) -> Result<thread::JoinHandle<Result<()>>> {
|
) -> Result<thread::JoinHandle<Result<()>>> {
|
||||||
|
#[cfg(feature = "gdb")]
|
||||||
|
let gdb_hw_breakpoints = hypervisor.get_guest_debug_hw_bps();
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
let (gdb_sender, gdb_receiver) = std::sync::mpsc::channel();
|
let (gdb_sender, gdb_receiver) = std::sync::mpsc::channel();
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
@ -344,7 +346,12 @@ pub fn start_vmm_thread(
|
|||||||
|
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
if let Some(debug_path) = debug_path {
|
if let Some(debug_path) = debug_path {
|
||||||
let target = gdb::GdbStub::new(gdb_sender, gdb_debug_event, gdb_vm_debug_event);
|
let target = gdb::GdbStub::new(
|
||||||
|
gdb_sender,
|
||||||
|
gdb_debug_event,
|
||||||
|
gdb_vm_debug_event,
|
||||||
|
gdb_hw_breakpoints,
|
||||||
|
);
|
||||||
thread::Builder::new()
|
thread::Builder::new()
|
||||||
.name("gdb".to_owned())
|
.name("gdb".to_owned())
|
||||||
.spawn(move || gdb::gdb_thread(target, &debug_path))
|
.spawn(move || gdb::gdb_thread(target, &debug_path))
|
||||||
|
Loading…
Reference in New Issue
Block a user