diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index e2584fccb..862906daf 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -1605,13 +1605,6 @@ impl cpu::Vcpu for KvmVcpu { addrs: &[vm_memory::GuestAddress], singlestep: bool, ) -> 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 { #[cfg(target_arch = "x86_64")] control: KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP, @@ -1623,6 +1616,9 @@ impl cpu::Vcpu for KvmVcpu { 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")] { // Set bits 9 and 10. diff --git a/vmm/src/gdb.rs b/vmm/src/gdb.rs index d60a7daaf..a708eb4e6 100644 --- a/vmm/src/gdb.rs +++ b/vmm/src/gdb.rs @@ -133,12 +133,13 @@ impl GdbStub { gdb_sender: mpsc::Sender, gdb_event: vmm_sys_util::eventfd::EventFd, vm_event: vmm_sys_util::eventfd::EventFd, + hw_breakpoints: usize, ) -> Self { Self { gdb_sender, gdb_event, vm_event, - hw_breakpoints: Default::default(), + hw_breakpoints: Vec::with_capacity(hw_breakpoints), single_step: false, } } @@ -383,9 +384,12 @@ impl HwBreakpoint for GdbStub { addr: ::Usize, _kind: ::BreakpointKind, ) -> TargetResult { - // If we already have 4 breakpoints, we cannot set a new one. - if self.hw_breakpoints.len() >= 4 { - error!("Not allowed to set more than 4 HW breakpoints"); + // If the HW breakpoints reach the limit, no more can be added. + if self.hw_breakpoints.len() >= self.hw_breakpoints.capacity() { + error!( + "Not allowed to set more than {} HW breakpoints", + self.hw_breakpoints.capacity() + ); return Ok(false); } diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index a114488b3..02285dfc6 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -272,6 +272,8 @@ pub fn start_vmm_thread( seccomp_action: &SeccompAction, hypervisor: Arc, ) -> Result>> { + #[cfg(feature = "gdb")] + let gdb_hw_breakpoints = hypervisor.get_guest_debug_hw_bps(); #[cfg(feature = "gdb")] let (gdb_sender, gdb_receiver) = std::sync::mpsc::channel(); #[cfg(feature = "gdb")] @@ -344,7 +346,12 @@ pub fn start_vmm_thread( #[cfg(feature = "gdb")] 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() .name("gdb".to_owned()) .spawn(move || gdb::gdb_thread(target, &debug_path))