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:
Michael Zhao 2022-08-23 12:00:37 +08:00 committed by Sebastien Boeuf
parent 223b1f6c51
commit d66d64c325
3 changed files with 19 additions and 12 deletions

View File

@ -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.

View File

@ -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);
} }

View File

@ -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))