Skip to content

Commit d4ba66e

Browse files
committed
Separate debugging related methods from Vm trait
Signed-off-by: Ludvig Liljenberg <[email protected]>
1 parent afa720d commit d4ba66e

File tree

7 files changed

+56
-55
lines changed

7 files changed

+56
-55
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ limitations under the License.
1616

1717
//! This file contains architecture specific code for the x86_64
1818
19-
use super::VcpuStopReason;
19+
use super::{DebuggableVm, VcpuStopReason};
2020
use crate::Result;
2121
use crate::hypervisor::regs::CommonRegisters;
22-
use crate::hypervisor::vm::Vm;
2322

2423
// Described in Table 6-1. Exceptions and Interrupts at Page 6-13 Vol. 1
2524
// of Intel 64 and IA-32 Architectures Software Developer's Manual
@@ -53,7 +52,7 @@ pub(crate) const DR6_HW_BP_FLAGS_MASK: u64 = 0x0F << DR6_HW_BP_FLAGS_POS;
5352
/// Determine the reason the vCPU stopped
5453
/// This is done by checking the DR6 register and the exception id
5554
pub(crate) fn vcpu_stop_reason(
56-
vm: &mut dyn Vm,
55+
vm: &mut dyn DebuggableVm,
5756
entrypoint: u64,
5857
dr6: u64,
5958
exception: u32,

src/hyperlight_host/src/hypervisor/gdb/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use x86_64_target::HyperlightSandboxTarget;
3333

3434
use super::InterruptHandle;
3535
use super::regs::CommonRegisters;
36+
use super::vm::Vm;
3637
use crate::hypervisor::regs::CommonFpu;
3738
use crate::mem::layout::SandboxMemoryLayout;
3839
use crate::mem::memory_region::MemoryRegion;
@@ -221,6 +222,26 @@ impl DebugMemoryAccess {
221222
}
222223
}
223224

225+
/// Trait for VMs that support debugging capabilities.
226+
/// This extends the base Vm trait with GDB-specific functionality.
227+
pub(crate) trait DebuggableVm: Vm {
228+
/// Translates a guest virtual address to a guest physical address
229+
fn translate_gva(&self, gva: u64) -> crate::Result<u64>;
230+
231+
/// Enable/disable debugging
232+
fn set_debug(&mut self, enable: bool) -> crate::Result<()>;
233+
234+
/// Enable/disable single stepping
235+
fn set_single_step(&mut self, enable: bool) -> crate::Result<()>;
236+
237+
/// Add a hardware breakpoint at the given address.
238+
/// Must be idempotent.
239+
fn add_hw_breakpoint(&mut self, addr: u64) -> crate::Result<()>;
240+
241+
/// Remove a hardware breakpoint at the given address
242+
fn remove_hw_breakpoint(&mut self, addr: u64) -> crate::Result<()>;
243+
}
244+
224245
/// Defines the possible reasons for which a vCPU can be stopped when debugging
225246
#[derive(Debug)]
226247
pub enum VcpuStopReason {

src/hyperlight_host/src/hypervisor/hyperlight_vm.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ use super::LinuxInterruptHandle;
3434
#[cfg(target_os = "windows")]
3535
use super::WindowsInterruptHandle;
3636
#[cfg(gdb)]
37-
use super::gdb::{DebugCommChannel, DebugMsg, DebugResponse, VcpuStopReason, arch};
37+
use super::gdb::{DebugCommChannel, DebugMsg, DebugResponse, DebuggableVm, VcpuStopReason, arch};
3838
use super::regs::{CommonFpu, CommonRegisters};
39+
#[cfg(not(gdb))]
40+
use super::vm::Vm;
3941
use super::{InterruptHandle, InterruptHandleImpl, get_max_log_level};
4042
use crate::HyperlightError::{ExecutionCanceledByHost, NoHypervisorFound};
4143
#[cfg(crashdump)]
@@ -47,7 +49,7 @@ use crate::hypervisor::hyperv_windows::WhpVm;
4749
#[cfg(kvm)]
4850
use crate::hypervisor::kvm::KvmVm;
4951
use crate::hypervisor::regs::CommonSpecialRegisters;
50-
use crate::hypervisor::vm::{Vm, VmExit};
52+
use crate::hypervisor::vm::VmExit;
5153
#[cfg(target_os = "windows")]
5254
use crate::hypervisor::wrappers::HandleWrapper;
5355
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags, MemoryRegionType};
@@ -66,6 +68,9 @@ use crate::sandbox::uninitialized::SandboxRuntimeConfig;
6668
use crate::{HyperlightError, Result, log_then_return, new_error};
6769

6870
pub(crate) struct HyperlightVm {
71+
#[cfg(gdb)]
72+
vm: Box<dyn DebuggableVm>,
73+
#[cfg(not(gdb))]
6974
vm: Box<dyn Vm>,
7075
page_size: usize,
7176
entrypoint: u64,
@@ -105,8 +110,13 @@ impl HyperlightVm {
105110
#[cfg(crashdump)] rt_cfg: SandboxRuntimeConfig,
106111
#[cfg(feature = "mem_profile")] trace_info: MemTraceInfo,
107112
) -> Result<Self> {
113+
#[cfg(gdb)]
114+
type VmType = Box<dyn DebuggableVm>;
115+
#[cfg(not(gdb))]
116+
type VmType = Box<dyn Vm>;
117+
108118
#[allow(unused_mut)] // needs to be mutable when gdb is enabled
109-
let mut vm: Box<dyn Vm> = match get_available_hypervisor() {
119+
let mut vm: VmType = match get_available_hypervisor() {
110120
#[cfg(kvm)]
111121
Some(HypervisorType::Kvm) => Box::new(KvmVm::new()?),
112122
#[cfg(mshv3)]

src/hyperlight_host/src/hypervisor/hyperv_linux.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ use mshv_bindings::{
3030
use mshv_ioctls::{Mshv, VcpuFd, VmFd};
3131
use tracing::{Span, instrument};
3232

33+
#[cfg(gdb)]
34+
use crate::hypervisor::gdb::DebuggableVm;
3335
use crate::hypervisor::regs::{CommonFpu, CommonRegisters, CommonSpecialRegisters};
3436
use crate::hypervisor::vm::{Vm, VmExit};
3537
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
@@ -202,10 +204,10 @@ impl Vm for MshvVm {
202204
};
203205
Ok(result)
204206
}
207+
}
205208

206-
// -- DEBUGGING RELATED BELOW ---
207-
208-
#[cfg(gdb)]
209+
#[cfg(gdb)]
210+
impl DebuggableVm for MshvVm {
209211
fn translate_gva(&self, gva: u64) -> Result<u64> {
210212
use mshv_bindings::{HV_TRANSLATE_GVA_VALIDATE_READ, HV_TRANSLATE_GVA_VALIDATE_WRITE};
211213

@@ -220,7 +222,6 @@ impl Vm for MshvVm {
220222
Ok(addr)
221223
}
222224

223-
#[cfg(gdb)]
224225
fn set_debug(&mut self, enabled: bool) -> Result<()> {
225226
use mshv_bindings::{
226227
HV_INTERCEPT_ACCESS_MASK_EXECUTE, hv_intercept_parameters,
@@ -259,7 +260,6 @@ impl Vm for MshvVm {
259260
Ok(())
260261
}
261262

262-
#[cfg(gdb)]
263263
fn set_single_step(&mut self, enable: bool) -> Result<()> {
264264
let mut regs = self.regs()?;
265265
if enable {
@@ -271,7 +271,6 @@ impl Vm for MshvVm {
271271
Ok(())
272272
}
273273

274-
#[cfg(gdb)]
275274
fn add_hw_breakpoint(&mut self, addr: u64) -> Result<()> {
276275
use crate::hypervisor::gdb::arch::MAX_NO_OF_HW_BP;
277276
use crate::new_error;
@@ -310,7 +309,6 @@ impl Vm for MshvVm {
310309
Ok(())
311310
}
312311

313-
#[cfg(gdb)]
314312
fn remove_hw_breakpoint(&mut self, addr: u64) -> Result<()> {
315313
use crate::new_error;
316314

src/hyperlight_host/src/hypervisor/hyperv_windows.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ use super::vm::{Vm, VmExit};
3434
#[cfg(not(gdb))]
3535
use super::vm::{Vm, VmExit};
3636
use super::wrappers::HandleWrapper;
37+
#[cfg(gdb)]
38+
use crate::hypervisor::gdb::DebuggableVm;
3739
use crate::hypervisor::regs::{CommonFpu, CommonRegisters, CommonSpecialRegisters};
3840
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
3941
use crate::{Result, log_then_return, new_error};
@@ -471,7 +473,14 @@ impl Vm for WhpVm {
471473
Ok(result)
472474
}
473475

474-
#[cfg(gdb)]
476+
/// Mark that initial memory setup is complete. After this, map_memory will fail.
477+
fn complete_initial_memory_setup(&mut self) {
478+
self.initial_memory_setup_done = true;
479+
}
480+
}
481+
482+
#[cfg(gdb)]
483+
impl DebuggableVm for WhpVm {
475484
fn translate_gva(&self, gva: u64) -> Result<u64> {
476485
let mut gpa = 0;
477486
let mut result = WHV_TRANSLATE_GVA_RESULT::default();
@@ -494,7 +503,6 @@ impl Vm for WhpVm {
494503
Ok(gpa)
495504
}
496505

497-
#[cfg(gdb)]
498506
fn set_debug(&mut self, enable: bool) -> Result<()> {
499507
if enable {
500508
// Set the extended VM exits property to enable extended VM exits
@@ -527,7 +535,6 @@ impl Vm for WhpVm {
527535
Ok(())
528536
}
529537

530-
#[cfg(gdb)]
531538
fn set_single_step(&mut self, enable: bool) -> Result<()> {
532539
let mut regs = self.regs()?;
533540
if enable {
@@ -539,7 +546,6 @@ impl Vm for WhpVm {
539546
Ok(())
540547
}
541548

542-
#[cfg(gdb)]
543549
fn add_hw_breakpoint(&mut self, addr: u64) -> Result<()> {
544550
use crate::hypervisor::gdb::arch::MAX_NO_OF_HW_BP;
545551

@@ -599,7 +605,6 @@ impl Vm for WhpVm {
599605
Ok(())
600606
}
601607

602-
#[cfg(gdb)]
603608
fn remove_hw_breakpoint(&mut self, addr: u64) -> Result<()> {
604609
// Get current debug registers
605610
const LEN: usize = 6;
@@ -651,11 +656,6 @@ impl Vm for WhpVm {
651656
Err(new_error!("Tried to remove non-existing hw-breakpoint"))
652657
}
653658
}
654-
655-
/// Mark that initial memory setup is complete. After this, map_memory will fail.
656-
fn complete_initial_memory_setup(&mut self) {
657-
self.initial_memory_setup_done = true;
658-
}
659659
}
660660

661661
impl Drop for WhpVm {

src/hyperlight_host/src/hypervisor/kvm.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ use kvm_ioctls::Cap::UserMemory;
2323
use kvm_ioctls::{Kvm, VcpuExit, VcpuFd, VmFd};
2424
use tracing::{Span, instrument};
2525

26+
#[cfg(gdb)]
27+
use crate::hypervisor::gdb::DebuggableVm;
2628
use crate::hypervisor::regs::{CommonFpu, CommonRegisters, CommonSpecialRegisters};
2729
use crate::hypervisor::vm::{Vm, VmExit};
2830
use crate::mem::memory_region::MemoryRegion;
@@ -161,10 +163,10 @@ impl Vm for KvmVm {
161163
))),
162164
}
163165
}
166+
}
164167

165-
// --- DEBUGGING RELATED BELOW ---
166-
167-
#[cfg(gdb)]
168+
#[cfg(gdb)]
169+
impl DebuggableVm for KvmVm {
168170
fn translate_gva(&self, gva: u64) -> Result<u64> {
169171
use crate::HyperlightError;
170172

@@ -176,7 +178,6 @@ impl Vm for KvmVm {
176178
}
177179
}
178180

179-
#[cfg(gdb)]
180181
fn set_debug(&mut self, enable: bool) -> Result<()> {
181182
use kvm_bindings::{KVM_GUESTDBG_ENABLE, KVM_GUESTDBG_USE_HW_BP, KVM_GUESTDBG_USE_SW_BP};
182183

@@ -192,7 +193,6 @@ impl Vm for KvmVm {
192193
Ok(())
193194
}
194195

195-
#[cfg(gdb)]
196196
fn set_single_step(&mut self, enable: bool) -> Result<()> {
197197
use kvm_bindings::KVM_GUESTDBG_SINGLESTEP;
198198

@@ -213,7 +213,6 @@ impl Vm for KvmVm {
213213
Ok(())
214214
}
215215

216-
#[cfg(gdb)]
217216
fn add_hw_breakpoint(&mut self, addr: u64) -> Result<()> {
218217
use crate::hypervisor::gdb::arch::MAX_NO_OF_HW_BP;
219218
use crate::new_error;
@@ -238,7 +237,6 @@ impl Vm for KvmVm {
238237
Ok(())
239238
}
240239

241-
#[cfg(gdb)]
242240
fn remove_hw_breakpoint(&mut self, addr: u64) -> Result<()> {
243241
use crate::new_error;
244242

src/hyperlight_host/src/hypervisor/vm.rs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -59,31 +59,6 @@ pub(crate) trait Vm: Send + Sync + Debug {
5959
/// Runs the vCPU until it exits
6060
fn run_vcpu(&mut self) -> Result<VmExit>;
6161

62-
// --------------------------
63-
// --- DEBUGGING BELOW ------
64-
// --------------------------
65-
66-
/// Translates a guest virtual address to a guest physical address
67-
#[cfg(gdb)]
68-
fn translate_gva(&self, gva: u64) -> Result<u64>;
69-
70-
/// Enable/disable debugging
71-
#[cfg(gdb)]
72-
fn set_debug(&mut self, enable: bool) -> Result<()>;
73-
74-
/// Enable/disable single stepping
75-
#[cfg(gdb)]
76-
fn set_single_step(&mut self, enable: bool) -> Result<()>;
77-
78-
/// Add a hardware breakpoint at the given address.
79-
/// Must be idempotent.
80-
#[cfg(gdb)]
81-
fn add_hw_breakpoint(&mut self, addr: u64) -> Result<()>;
82-
83-
/// Remove a hardware breakpoint at the given address
84-
#[cfg(gdb)]
85-
fn remove_hw_breakpoint(&mut self, addr: u64) -> Result<()>;
86-
8762
/// Get partition handle
8863
#[cfg(target_os = "windows")]
8964
fn partition_handle(&self) -> windows::Win32::System::Hypervisor::WHV_PARTITION_HANDLE;

0 commit comments

Comments
 (0)