Skip to content

Commit fb4990a

Browse files
committed
simplify hw logic
Signed-off-by: Ludvig Liljenberg <[email protected]>
1 parent 6c4ca58 commit fb4990a

File tree

6 files changed

+50
-56
lines changed

6 files changed

+50
-56
lines changed

src/hyperlight_host/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ cfg_aliases = "0.2.1"
116116
built = { version = "0.8.0", optional = true, features = ["chrono", "git2"] }
117117

118118
[features]
119-
default = ["kvm", "mshv2", "seccomp", "build-metadata", "gdb"]
119+
default = ["kvm", "mshv2", "seccomp", "build-metadata"]
120120
seccomp = ["dep:seccompiler"]
121121
function_call_metrics = []
122122
executable_heap = []

src/hyperlight_host/src/hypervisor/gdb/arch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub(crate) const SW_BP_OP: u8 = 0xCC;
3737
/// Software Breakpoint written to memory
3838
pub(crate) const SW_BP: [u8; SW_BP_SIZE] = [SW_BP_OP];
3939
// /// Maximum number of supported hardware breakpoints
40-
// pub(crate) const MAX_NO_OF_HW_BP: usize = 4;
40+
pub(crate) const MAX_NO_OF_HW_BP: usize = 4;
4141

4242
/// Check page 19-4 Vol. 3B of Intel 64 and IA-32
4343
/// Architectures Software Developer's Manual

src/hyperlight_host/src/hypervisor/hyperlight_vm.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,16 @@ use super::mshv::MshvVm;
3434
use super::regs::{
3535
CommonFpu, CommonRegisters, FP_CONTROL_WORD_DEFAULT, FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT,
3636
};
37-
use super::vm::{DebugExit, HyperlightExit, Vm};
37+
use super::vm::{HyperlightExit, Vm};
3838
use super::{
3939
HyperlightVm, CR0_AM, CR0_ET, CR0_MP, CR0_NE, CR0_PE, CR0_PG, CR0_WP, CR4_OSFXSR,
4040
CR4_OSXMMEXCPT, CR4_PAE, EFER_LMA, EFER_LME, EFER_NX, EFER_SCE,
4141
};
4242
#[cfg(crashdump)]
4343
use crate::hypervisor::crashdump;
4444
use crate::hypervisor::hypervisor_handler::HypervisorHandler;
45+
#[cfg(gdb)]
46+
use crate::hypervisor::vm::DebugExit;
4547
#[cfg(target_os = "windows")]
4648
use crate::hypervisor::whp::WhpVm;
4749
#[cfg(target_os = "windows")]

src/hyperlight_host/src/hypervisor/kvm.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ use kvm_ioctls::{Kvm, VcpuExit, VcpuFd, VmFd};
2626
use tracing::{instrument, Span};
2727

2828
use super::regs::{CommonFpu, CommonRegisters, CommonSpecialRegisters};
29-
use super::vm::{DebugExit, HyperlightExit, Vm};
29+
use super::vm::{HyperlightExit, Vm};
30+
#[cfg(gdb)]
31+
use crate::hypervisor::vm::DebugExit;
3032
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
3133
use crate::{log_then_return, new_error, Result};
3234

@@ -224,27 +226,21 @@ impl Vm for KvmVm {
224226

225227
#[cfg(gdb)]
226228
fn add_hw_breakpoint(&mut self, addr: u64) -> Result<()> {
229+
use crate::hypervisor::gdb::arch::MAX_NO_OF_HW_BP;
227230
use crate::new_error;
228231

229-
let dr7 = self.debug.regs.arch.debugreg[7];
232+
// Find the first available LOCAL (L0–L3) slot
233+
let i = (0..MAX_NO_OF_HW_BP)
234+
.position(|i| self.debug.regs.arch.debugreg[7] & (1 << (i * 2)) == 0)
235+
.ok_or_else(|| new_error!("Tried to add more than 4 hardware breakpoints"))?;
230236

231-
// count only LOCAL (L0, L1, L2, L3) enable bits
232-
let num_hw_breakpoints = [0, 2, 4, 6]
233-
.iter()
234-
.filter(|&&bit| (dr7 & (1 << bit)) != 0)
235-
.count();
237+
// Assign to corresponding debug register
238+
self.debug.regs.arch.debugreg[i] = addr;
236239

237-
if num_hw_breakpoints >= 4 {
238-
return Err(new_error!("Tried to add more than 4 hardware breakpoints"));
239-
}
240-
241-
// find the first available LOCAL, and then enable it
242-
let available_debug_register_idx = (0..4).find(|&i| (dr7 & (1 << (i * 2))) == 0).unwrap(); // safe because of the check above
243-
self.debug.regs.arch.debugreg[available_debug_register_idx] = addr;
244-
self.debug.regs.arch.debugreg[7] |= 1 << (available_debug_register_idx * 2);
240+
// Enable LOCAL bit
241+
self.debug.regs.arch.debugreg[7] |= 1 << (i * 2);
245242

246243
self.vcpu_fd.set_guest_debug(&self.debug.regs)?;
247-
248244
Ok(())
249245
}
250246

@@ -258,8 +254,9 @@ impl Vm for KvmVm {
258254
.position(|&a| a == addr)
259255
.ok_or_else(|| new_error!("Tried to remove non-existing hw-breakpoint"))?;
260256

261-
// Clear the address and disable the corresponding bit
257+
// Clear the address
262258
self.debug.regs.arch.debugreg[index] = 0;
259+
// Disable LOCAL bit
263260
self.debug.regs.arch.debugreg[7] &= !(1 << (index * 2));
264261

265262
self.vcpu_fd.set_guest_debug(&self.debug.regs)?;

src/hyperlight_host/src/hypervisor/mshv.rs

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use tracing::{instrument, Span};
5353
use super::handlers::DbgMemAccessHandlerCaller;
5454
use super::regs::{CommonFpu, CommonRegisters, CommonSpecialRegisters};
5555
use super::vm::{HyperlightExit, Vm};
56+
#[cfg(gdb)]
5657
use crate::hypervisor::vm::DebugExit;
5758
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
5859
use crate::{log_then_return, new_error, Result};
@@ -334,57 +335,50 @@ impl Vm for MshvVm {
334335

335336
#[cfg(gdb)]
336337
fn add_hw_breakpoint(&mut self, addr: u64) -> Result<()> {
338+
use crate::hypervisor::gdb::arch::MAX_NO_OF_HW_BP;
337339
use crate::new_error;
338340

339-
let dr7 = self.debug.regs.dr7;
340-
// count only LOCAL (L0, L1, L2, L3) enable bits
341-
let num_hw_breakpoints = [0, 2, 4, 6]
342-
.iter()
343-
.filter(|&&bit| (dr7 & (1 << bit)) != 0)
344-
.count();
341+
// Find the first available LOCAL (L0–L3) slot
342+
let i = (0..MAX_NO_OF_HW_BP)
343+
.position(|i| self.debug.regs.dr7 & (1 << (i * 2)) == 0)
344+
.ok_or_else(|| new_error!("Tried to add more than 4 hardware breakpoints"))?;
345345

346-
if num_hw_breakpoints >= 4 {
347-
return Err(new_error!("Tried to add more than 4 hardware breakpoints"));
348-
}
346+
// Assign to corresponding debug register
347+
*[
348+
&mut self.debug.regs.dr0,
349+
&mut self.debug.regs.dr1,
350+
&mut self.debug.regs.dr2,
351+
&mut self.debug.regs.dr3,
352+
][i] = addr;
349353

350-
// find the first available LOCAL, and then enable it
351-
let available_debug_register_idx = (0..4).find(|&i| (dr7 & (1 << (i * 2))) == 0).unwrap(); // safe because of the check above
352-
match available_debug_register_idx {
353-
0 => self.debug.regs.dr0 = addr,
354-
1 => self.debug.regs.dr1 = addr,
355-
2 => self.debug.regs.dr2 = addr,
356-
3 => self.debug.regs.dr3 = addr,
357-
_ => unreachable!(),
358-
}
359-
self.debug.regs.dr7 |= 1 << (available_debug_register_idx * 2);
354+
// Enable LOCAL bit
355+
self.debug.regs.dr7 |= 1 << (i * 2);
360356

361357
self.vcpu_fd.set_debug_regs(&self.debug.regs)?;
362-
363358
Ok(())
364359
}
365360

366361
#[cfg(gdb)]
367362
fn remove_hw_breakpoint(&mut self, addr: u64) -> Result<()> {
368363
use crate::new_error;
369364

370-
if self.debug.regs.dr0 == addr {
371-
self.debug.regs.dr0 = 0;
372-
self.debug.regs.dr7 &= !(1 << 0);
373-
} else if self.debug.regs.dr1 == addr {
374-
self.debug.regs.dr1 = 0;
375-
self.debug.regs.dr7 &= !(1 << 2);
376-
} else if self.debug.regs.dr2 == addr {
377-
self.debug.regs.dr2 = 0;
378-
self.debug.regs.dr7 &= !(1 << 4);
379-
} else if self.debug.regs.dr3 == addr {
380-
self.debug.regs.dr3 = 0;
381-
self.debug.regs.dr7 &= !(1 << 6);
365+
let regs = [
366+
&mut self.debug.regs.dr0,
367+
&mut self.debug.regs.dr1,
368+
&mut self.debug.regs.dr2,
369+
&mut self.debug.regs.dr3,
370+
];
371+
372+
if let Some(i) = regs.iter().position(|&&mut reg| reg == addr) {
373+
// Clear the address
374+
*regs[i] = 0;
375+
// Disable LOCAL bit
376+
self.debug.regs.dr7 &= !(1 << (i * 2));
377+
self.vcpu_fd.set_debug_regs(&self.debug.regs)?;
378+
Ok(())
382379
} else {
383-
return Err(new_error!("Tried to remove non-existing hw-breakpoint"));
380+
Err(new_error!("Tried to remove non-existing hw-breakpoint"))
384381
}
385-
386-
self.vcpu_fd.set_debug_regs(&self.debug.regs)?;
387-
Ok(())
388382
}
389383

390384
#[cfg(gdb)]

src/hyperlight_host/src/hypervisor/vm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub(crate) trait Vm: Send + Sync + Debug {
7979
}
8080

8181
#[derive(Debug)]
82+
#[cfg(gdb)]
8283
pub(super) enum DebugExit {
8384
/// The vCPU has exited due to a debug event (usually breakpoint)
8485
Debug { dr6: u64, exception: u32 },

0 commit comments

Comments
 (0)