Skip to content

Commit 8d64112

Browse files
committed
dbg: mshv guest debugging support for memory inspection
Signed-off-by: Doru Blânzeanu <[email protected]>
1 parent 19d8134 commit 8d64112

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

src/hyperlight_host/src/hypervisor/gdb/hyp_debug.rs

+26
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,8 @@ pub mod kvm {
492492

493493
#[cfg(mshv)]
494494
pub mod mshv {
495+
use std::collections::HashMap;
496+
495497
use mshv_bindings::{
496498
DebugRegisters, StandardRegisters, HV_TRANSLATE_GVA_VALIDATE_READ,
497499
HV_TRANSLATE_GVA_VALIDATE_WRITE,
@@ -508,6 +510,9 @@ pub mod mshv {
508510

509511
/// Array of addresses for HW breakpoints
510512
hw_breakpoints: Vec<u64>,
513+
/// Saves the bytes modified to enable SW breakpoints
514+
sw_breakpoints: HashMap<u64, [u8; SW_BP_SIZE]>,
515+
511516
/// Debug registers
512517
pub dbg_cfg: DebugRegisters,
513518
}
@@ -517,6 +522,7 @@ pub mod mshv {
517522
Self {
518523
single_step: false,
519524
hw_breakpoints: vec![],
525+
sw_breakpoints: HashMap::new(),
520526
dbg_cfg: DebugRegisters::default(),
521527
}
522528
}
@@ -621,6 +627,14 @@ pub mod mshv {
621627
return Ok(VcpuStopReason::HwBp);
622628
}
623629

630+
// mshv does not provide a way to specify which exception triggered the
631+
// vCPU exit as the mshv intercepts both #DB and #BP
632+
// We check against the SW breakpoints Hashmap to detect whether the
633+
// vCPU exited due to a SW breakpoint
634+
if self.sw_breakpoints.contains_key(&gpa) {
635+
return Ok(VcpuStopReason::SwBp);
636+
}
637+
624638
Ok(VcpuStopReason::Unknown)
625639
}
626640
}
@@ -715,4 +729,16 @@ pub mod mshv {
715729
.map_err(|e| new_error!("Could not write guest registers: {:?}", e))
716730
}
717731
}
732+
733+
impl GuestMemoryDebug for MshvDebug {
734+
fn is_sw_breakpoint(&self, addr: &u64) -> bool {
735+
self.sw_breakpoints.contains_key(addr)
736+
}
737+
fn save_sw_breakpoint_data(&mut self, addr: u64, data: [u8; 1]) {
738+
_ = self.sw_breakpoints.insert(addr, data);
739+
}
740+
fn delete_sw_breakpoint_data(&mut self, addr: &u64) -> Option<[u8; 1]> {
741+
self.sw_breakpoints.remove(addr)
742+
}
743+
}
718744
}

src/hyperlight_host/src/hypervisor/hyperv_linux.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ mod debug {
7272
use std::sync::{Arc, Mutex};
7373

7474
use super::{HypervLinuxDriver, *};
75-
use crate::hypervisor::gdb::{DebugMsg, DebugResponse, VcpuStopReason, X86_64Regs};
75+
use crate::hypervisor::gdb::{
76+
DebugMsg, DebugResponse, GuestMemoryDebug, VcpuStopReason, X86_64Regs,
77+
};
7678
use crate::hypervisor::handlers::DbgMemAccessHandlerCaller;
7779
use crate::{new_error, Result};
7880

@@ -112,6 +114,9 @@ mod debug {
112114

113115
Ok(DebugResponse::AddHwBreakpoint(res))
114116
}
117+
DebugMsg::AddSwBreakpoint(addr) => debug
118+
.add_sw_breakpoint(&self.vcpu_fd, addr, dbg_mem_access_fn)
119+
.map(DebugResponse::AddSwBreakpoint),
115120
DebugMsg::Continue => {
116121
debug.set_single_step(&self.vcpu_fd, false)?;
117122
Ok(DebugResponse::Continue)
@@ -131,6 +136,13 @@ mod debug {
131136

132137
Ok(DebugResponse::GetCodeSectionOffset(offset as u64))
133138
}
139+
DebugMsg::ReadAddr(addr, len) => {
140+
let mut data = vec![0u8; len];
141+
142+
debug.read_addrs(&self.vcpu_fd, addr, &mut data, dbg_mem_access_fn)?;
143+
144+
Ok(DebugResponse::ReadAddr(data))
145+
}
134146
DebugMsg::ReadRegisters => {
135147
let mut regs = X86_64Regs::default();
136148
debug.read_regs(&self.vcpu_fd, &mut regs)?;
@@ -144,16 +156,23 @@ mod debug {
144156

145157
Ok(DebugResponse::RemoveHwBreakpoint(res))
146158
}
159+
DebugMsg::RemoveSwBreakpoint(addr) => debug
160+
.remove_sw_breakpoint(&self.vcpu_fd, addr, dbg_mem_access_fn)
161+
.map(DebugResponse::RemoveSwBreakpoint),
147162
DebugMsg::Step => {
148163
debug.set_single_step(&self.vcpu_fd, true)?;
149164
Ok(DebugResponse::Step)
150165
}
166+
DebugMsg::WriteAddr(addr, data) => {
167+
debug.write_addrs(&self.vcpu_fd, addr, &data, dbg_mem_access_fn)?;
168+
169+
Ok(DebugResponse::WriteAddr)
170+
}
151171
DebugMsg::WriteRegisters(regs) => {
152172
debug.write_regs(&self.vcpu_fd, &regs)?;
153173

154174
Ok(DebugResponse::WriteRegisters)
155175
}
156-
_ => Err(new_error!("Not yet implemented")),
157176
}
158177
} else {
159178
Err(new_error!("Debugging is not enabled"))

0 commit comments

Comments
 (0)