Skip to content

Commit 8602907

Browse files
committed
Refactor 'run'
Signed-off-by: Ludvig Liljenberg <[email protected]>
1 parent bb0d9a7 commit 8602907

File tree

14 files changed

+956
-1718
lines changed

14 files changed

+956
-1718
lines changed

src/hyperlight_host/src/hypervisor/crashdump.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use elfcore::{
2323
ReadProcessMemory, ThreadView, VaProtection, VaRegion,
2424
};
2525

26-
use super::Hypervisor;
2726
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
2827
use crate::{Result, new_error};
2928

@@ -262,12 +261,7 @@ impl ReadProcessMemory for GuestMemReader {
262261
///
263262
/// # Returns
264263
/// * `Result<()>`: Success or error
265-
pub(crate) fn generate_crashdump(hv: &dyn Hypervisor) -> Result<()> {
266-
// Get crash context from hypervisor
267-
let ctx = hv
268-
.crashdump_context()
269-
.map_err(|e| new_error!("Failed to get crashdump context: {:?}", e))?;
270-
264+
pub(crate) fn generate_crashdump(ctx: Option<CrashDumpContext>) -> Result<()> {
271265
// Get env variable for core dump directory
272266
let core_dump_dir = std::env::var("HYPERLIGHT_CORE_DUMP_DIR").ok();
273267

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

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ limitations under the License.
1616

1717
//! This file contains architecture specific code for the x86_64
1818
19-
use std::collections::HashMap;
20-
2119
use super::VcpuStopReason;
20+
use crate::Result;
2221

2322
// Described in Table 6-1. Exceptions and Interrupts at Page 6-13 Vol. 1
2423
// of Intel 64 and IA-32 Architectures Software Developer's Manual
@@ -51,61 +50,50 @@ pub(crate) const DR6_HW_BP_FLAGS_MASK: u64 = 0x0F << DR6_HW_BP_FLAGS_POS;
5150

5251
/// Determine the reason the vCPU stopped
5352
/// This is done by checking the DR6 register and the exception id
54-
/// NOTE: Additional checks are done for the entrypoint, stored hw_breakpoints
55-
/// and sw_breakpoints to ensure the stop reason is valid with internal state
5653
pub(crate) fn vcpu_stop_reason(
57-
single_step: bool,
5854
rip: u64,
59-
dr6: u64,
6055
entrypoint: u64,
56+
dr6: u64,
6157
exception: u32,
62-
hw_breakpoints: &[u64],
63-
sw_breakpoints: &HashMap<u64, [u8; SW_BP_SIZE]>,
64-
) -> VcpuStopReason {
58+
) -> Result<VcpuStopReason> {
6559
if DB_EX_ID == exception {
6660
// If the BS flag in DR6 register is set, it means a single step
6761
// instruction triggered the exit
6862
// Check page 19-4 Vol. 3B of Intel 64 and IA-32
6963
// Architectures Software Developer's Manual
70-
if dr6 & DR6_BS_FLAG_MASK != 0 && single_step {
71-
return VcpuStopReason::DoneStep;
64+
if dr6 & DR6_BS_FLAG_MASK != 0 {
65+
return Ok(VcpuStopReason::DoneStep);
7266
}
7367

7468
// If any of the B0-B3 flags in DR6 register is set, it means a
7569
// hardware breakpoint triggered the exit
7670
// Check page 19-4 Vol. 3B of Intel 64 and IA-32
7771
// Architectures Software Developer's Manual
78-
if DR6_HW_BP_FLAGS_MASK & dr6 != 0 && hw_breakpoints.contains(&rip) {
72+
if DR6_HW_BP_FLAGS_MASK & dr6 != 0 {
7973
if rip == entrypoint {
80-
return VcpuStopReason::EntryPointBp;
74+
return Ok(VcpuStopReason::EntryPointBp);
8175
}
82-
return VcpuStopReason::HwBp;
76+
return Ok(VcpuStopReason::HwBp);
8377
}
8478
}
8579

86-
if BP_EX_ID == exception && sw_breakpoints.contains_key(&rip) {
87-
return VcpuStopReason::SwBp;
80+
if BP_EX_ID == exception {
81+
return Ok(VcpuStopReason::SwBp);
8882
}
8983

9084
// Log an error and provide internal debugging info
9185
log::error!(
9286
r"The vCPU exited because of an unknown reason:
93-
single_step: {:?}
9487
rip: {:?}
9588
dr6: {:?}
9689
entrypoint: {:?}
9790
exception: {:?}
98-
hw_breakpoints: {:?}
99-
sw_breakpoints: {:?}
10091
",
101-
single_step,
10292
rip,
10393
dr6,
10494
entrypoint,
10595
exception,
106-
hw_breakpoints,
107-
sw_breakpoints,
10896
);
10997

110-
VcpuStopReason::Unknown
98+
Ok(VcpuStopReason::Unknown)
11199
}

src/hyperlight_host/src/hypervisor/gdb/hyperv_debug.rs

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

1717
use std::collections::HashMap;
1818

19-
use windows::Win32::System::Hypervisor::WHV_VP_EXCEPTION_CONTEXT;
20-
21-
use super::arch::{MAX_NO_OF_HW_BP, vcpu_stop_reason};
22-
use super::{GuestDebug, SW_BP_SIZE, VcpuStopReason};
19+
use super::arch::MAX_NO_OF_HW_BP;
20+
use super::{GuestDebug, SW_BP_SIZE};
2321
use crate::hypervisor::regs::{CommonFpu, CommonRegisters};
2422
use crate::hypervisor::windows_hypervisor_platform::VMProcessor;
2523
use crate::hypervisor::wrappers::WHvDebugRegisters;
@@ -52,15 +50,6 @@ impl HypervDebug {
5250
}
5351
}
5452

55-
/// Returns the instruction pointer from the stopped vCPU
56-
fn get_instruction_pointer(&self, vcpu_fd: &VMProcessor) -> Result<u64> {
57-
let regs = vcpu_fd
58-
.regs()
59-
.map_err(|e| new_error!("Could not retrieve registers from vCPU: {:?}", e))?;
60-
61-
Ok(regs.rip)
62-
}
63-
6453
/// This method sets the kvm debugreg fields to enable breakpoints at
6554
/// specific addresses
6655
///
@@ -120,42 +109,6 @@ impl HypervDebug {
120109

121110
Ok(())
122111
}
123-
124-
/// Get the reason the vCPU has stopped
125-
pub(crate) fn get_stop_reason(
126-
&mut self,
127-
vcpu_fd: &VMProcessor,
128-
exception: WHV_VP_EXCEPTION_CONTEXT,
129-
entrypoint: u64,
130-
) -> Result<VcpuStopReason> {
131-
let rip = self.get_instruction_pointer(vcpu_fd)?;
132-
let rip = self.translate_gva(vcpu_fd, rip)?;
133-
134-
let debug_regs = vcpu_fd
135-
.get_debug_regs()
136-
.map_err(|e| new_error!("Could not retrieve registers from vCPU: {:?}", e))?;
137-
138-
// Check if the vCPU stopped because of a hardware breakpoint
139-
let reason = vcpu_stop_reason(
140-
self.single_step,
141-
rip,
142-
debug_regs.dr6,
143-
entrypoint,
144-
exception.ExceptionType as u32,
145-
&self.hw_breakpoints,
146-
&self.sw_breakpoints,
147-
);
148-
149-
if let VcpuStopReason::EntryPointBp = reason {
150-
// In case the hw breakpoint is the entry point, remove it to
151-
// avoid hanging here as gdb does not remove breakpoints it
152-
// has not set.
153-
// Gdb expects the target to be stopped when connected.
154-
self.remove_hw_breakpoint(vcpu_fd, entrypoint)?;
155-
}
156-
157-
Ok(reason)
158-
}
159112
}
160113

161114
impl GuestDebug for HypervDebug {

src/hyperlight_host/src/hypervisor/gdb/kvm_debug.rs

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ use std::collections::HashMap;
1818

1919
use kvm_bindings::{
2020
KVM_GUESTDBG_ENABLE, KVM_GUESTDBG_SINGLESTEP, KVM_GUESTDBG_USE_HW_BP, KVM_GUESTDBG_USE_SW_BP,
21-
kvm_debug_exit_arch, kvm_guest_debug,
21+
kvm_guest_debug,
2222
};
2323
use kvm_ioctls::VcpuFd;
2424

25-
use super::arch::{MAX_NO_OF_HW_BP, SW_BP_SIZE, vcpu_stop_reason};
26-
use super::{GuestDebug, VcpuStopReason};
25+
use super::GuestDebug;
26+
use super::arch::{MAX_NO_OF_HW_BP, SW_BP_SIZE};
2727
use crate::hypervisor::regs::{CommonFpu, CommonRegisters};
2828
use crate::{HyperlightError, Result, new_error};
2929

@@ -59,15 +59,6 @@ impl KvmDebug {
5959
}
6060
}
6161

62-
/// Returns the instruction pointer from the stopped vCPU
63-
fn get_instruction_pointer(&self, vcpu_fd: &VcpuFd) -> Result<u64> {
64-
let regs = vcpu_fd
65-
.get_regs()
66-
.map_err(|e| new_error!("Could not retrieve registers from vCPU: {:?}", e))?;
67-
68-
Ok(regs.rip)
69-
}
70-
7162
/// This method sets the kvm debugreg fields to enable breakpoints at
7263
/// specific addresses
7364
///
@@ -106,38 +97,6 @@ impl KvmDebug {
10697

10798
Ok(())
10899
}
109-
110-
/// Get the reason the vCPU has stopped
111-
pub(crate) fn get_stop_reason(
112-
&mut self,
113-
vcpu_fd: &VcpuFd,
114-
debug_exit: kvm_debug_exit_arch,
115-
entrypoint: u64,
116-
) -> Result<VcpuStopReason> {
117-
let rip = self.get_instruction_pointer(vcpu_fd)?;
118-
let rip = self.translate_gva(vcpu_fd, rip)?;
119-
120-
// Check if the vCPU stopped because of a hardware breakpoint
121-
let reason = vcpu_stop_reason(
122-
self.single_step,
123-
rip,
124-
debug_exit.dr6,
125-
entrypoint,
126-
debug_exit.exception,
127-
&self.hw_breakpoints,
128-
&self.sw_breakpoints,
129-
);
130-
131-
if let VcpuStopReason::EntryPointBp = reason {
132-
// In case the hw breakpoint is the entry point, remove it to
133-
// avoid hanging here as gdb does not remove breakpoints it
134-
// has not set.
135-
// Gdb expects the target to be stopped when connected.
136-
self.remove_hw_breakpoint(vcpu_fd, entrypoint)?;
137-
}
138-
139-
Ok(reason)
140-
}
141100
}
142101

143102
impl GuestDebug for KvmDebug {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
mod arch;
17+
pub(crate) mod arch;
1818
mod event_loop;
1919
#[cfg(target_os = "windows")]
2020
mod hyperv_debug;
@@ -235,7 +235,7 @@ impl DebugMemoryAccess {
235235
}
236236

237237
/// Defines the possible reasons for which a vCPU can be stopped when debugging
238-
#[derive(Debug)]
238+
#[derive(Debug, PartialEq, Eq)]
239239
pub enum VcpuStopReason {
240240
Crash,
241241
DoneStep,

src/hyperlight_host/src/hypervisor/gdb/mshv_debug.rs

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use mshv_bindings::{
2626
};
2727
use mshv_ioctls::VcpuFd;
2828

29-
use super::arch::{MAX_NO_OF_HW_BP, SW_BP_SIZE, vcpu_stop_reason};
30-
use super::{GuestDebug, VcpuStopReason};
29+
use super::GuestDebug;
30+
use super::arch::{MAX_NO_OF_HW_BP, SW_BP_SIZE};
3131
use crate::hypervisor::regs::{CommonFpu, CommonRegisters};
3232
use crate::{HyperlightError, Result, new_error};
3333

@@ -55,15 +55,6 @@ impl MshvDebug {
5555
}
5656
}
5757

58-
/// Returns the instruction pointer from the stopped vCPU
59-
fn get_instruction_pointer(&self, vcpu_fd: &VcpuFd) -> Result<u64> {
60-
let regs = vcpu_fd
61-
.get_regs()
62-
.map_err(|e| new_error!("Could not retrieve registers from vCPU: {:?}", e))?;
63-
64-
Ok(regs.rip)
65-
}
66-
6758
/// This method sets the vCPU debug register fields to enable breakpoints at
6859
/// specific addresses
6960
///
@@ -121,44 +112,6 @@ impl MshvDebug {
121112

122113
Ok(())
123114
}
124-
125-
/// Returns the vCPU stop reason
126-
pub(crate) fn get_stop_reason(
127-
&mut self,
128-
vcpu_fd: &VcpuFd,
129-
exception: u16,
130-
entrypoint: u64,
131-
) -> Result<VcpuStopReason> {
132-
let regs = vcpu_fd
133-
.get_debug_regs()
134-
.map_err(|e| new_error!("Cannot retrieve debug registers from vCPU: {}", e))?;
135-
136-
// DR6 register contains debug state related information
137-
let debug_status = regs.dr6;
138-
139-
let rip = self.get_instruction_pointer(vcpu_fd)?;
140-
let rip = self.translate_gva(vcpu_fd, rip)?;
141-
142-
let reason = vcpu_stop_reason(
143-
self.single_step,
144-
rip,
145-
debug_status,
146-
entrypoint,
147-
exception as u32,
148-
&self.hw_breakpoints,
149-
&self.sw_breakpoints,
150-
);
151-
152-
if let VcpuStopReason::EntryPointBp = reason {
153-
// In case the hw breakpoint is the entry point, remove it to
154-
// avoid hanging here as gdb does not remove breakpoints it
155-
// has not set.
156-
// Gdb expects the target to be stopped when connected.
157-
self.remove_hw_breakpoint(vcpu_fd, entrypoint)?;
158-
}
159-
160-
Ok(reason)
161-
}
162115
}
163116

164117
impl GuestDebug for MshvDebug {

0 commit comments

Comments
 (0)