Skip to content

Commit d41a4d9

Browse files
committed
add a way to report a non-fatal error to gdb
- sometimes gdb tries to read from an address where the vcpu translate method fails, so we need to handle that in such a way that the hypervisor handler doesn't crash Signed-off-by: Doru Blânzeanu <[email protected]>
1 parent c601f45 commit d41a4d9

File tree

4 files changed

+68
-13
lines changed

4 files changed

+68
-13
lines changed

src/hyperlight_host/src/error.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,11 @@ pub enum HyperlightError {
275275
#[error("SystemTimeError {0:?}")]
276276
SystemTimeError(#[from] SystemTimeError),
277277

278+
/// Error occurred when translating guest address
279+
#[error("An error occurred when translating guest address: {0:?}")]
280+
#[cfg(gdb)]
281+
TranslateGuestAddress(u64),
282+
278283
/// Error occurred converting a slice to an array
279284
#[error("TryFromSliceError {0:?}")]
280285
TryFromSliceError(#[from] TryFromSliceError),

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ pub enum DebugResponse {
120120
AddSwBreakpoint(bool),
121121
Continue,
122122
DisableDebug,
123+
ErrorOccurred,
123124
GetCodeSectionOffset(u64),
124125
ReadAddr(Vec<u8>),
125126
ReadRegisters(X86_64Regs),

src/hyperlight_host/src/hypervisor/gdb/x86_64_target.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ impl HyperlightSandboxTarget {
8787

8888
match self.send_command(DebugMsg::DisableDebug)? {
8989
DebugResponse::DisableDebug => Ok(()),
90+
DebugResponse::ErrorOccurred => {
91+
log::error!("Error occurred");
92+
Err(GdbTargetError::UnexpectedError)
93+
}
9094
msg => {
9195
log::error!("Unexpected message received: {:?}", msg);
9296
Err(GdbTargetError::UnexpectedMessage)
@@ -129,6 +133,10 @@ impl SingleThreadBase for HyperlightSandboxTarget {
129133

130134
Ok(v.len())
131135
}
136+
DebugResponse::ErrorOccurred => {
137+
log::error!("Error occurred");
138+
Err(TargetError::NonFatal)
139+
}
132140
msg => {
133141
log::error!("Unexpected message received: {:?}", msg);
134142
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
@@ -146,6 +154,10 @@ impl SingleThreadBase for HyperlightSandboxTarget {
146154

147155
match self.send_command(DebugMsg::WriteAddr(gva, v))? {
148156
DebugResponse::WriteAddr => Ok(()),
157+
DebugResponse::ErrorOccurred => {
158+
log::error!("Error occurred");
159+
Err(TargetError::NonFatal)
160+
}
149161
msg => {
150162
log::error!("Unexpected message received: {:?}", msg);
151163
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
@@ -182,6 +194,10 @@ impl SingleThreadBase for HyperlightSandboxTarget {
182194

183195
Ok(())
184196
}
197+
DebugResponse::ErrorOccurred => {
198+
log::error!("Error occurred");
199+
Err(TargetError::NonFatal)
200+
}
185201

186202
msg => {
187203
log::error!("Unexpected message received: {:?}", msg);
@@ -219,6 +235,10 @@ impl SingleThreadBase for HyperlightSandboxTarget {
219235

220236
match self.send_command(DebugMsg::WriteRegisters(regs))? {
221237
DebugResponse::WriteRegisters => Ok(()),
238+
DebugResponse::ErrorOccurred => {
239+
log::error!("Error occurred");
240+
Err(TargetError::NonFatal)
241+
}
222242
msg => {
223243
log::error!("Unexpected message received: {:?}", msg);
224244
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
@@ -240,6 +260,10 @@ impl SectionOffsets for HyperlightSandboxTarget {
240260
text_seg: text,
241261
data_seg: None,
242262
}),
263+
DebugResponse::ErrorOccurred => {
264+
log::error!("Error occurred");
265+
Err(GdbTargetError::UnexpectedError)
266+
}
243267
msg => {
244268
log::error!("Unexpected message received: {:?}", msg);
245269
Err(GdbTargetError::UnexpectedMessage)
@@ -267,6 +291,10 @@ impl HwBreakpoint for HyperlightSandboxTarget {
267291

268292
match self.send_command(DebugMsg::AddHwBreakpoint(addr))? {
269293
DebugResponse::AddHwBreakpoint(rsp) => Ok(rsp),
294+
DebugResponse::ErrorOccurred => {
295+
log::error!("Error occurred");
296+
Err(TargetError::NonFatal)
297+
}
270298
msg => {
271299
log::error!("Unexpected message received: {:?}", msg);
272300
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
@@ -283,6 +311,10 @@ impl HwBreakpoint for HyperlightSandboxTarget {
283311

284312
match self.send_command(DebugMsg::RemoveHwBreakpoint(addr))? {
285313
DebugResponse::RemoveHwBreakpoint(rsp) => Ok(rsp),
314+
DebugResponse::ErrorOccurred => {
315+
log::error!("Error occurred");
316+
Err(TargetError::NonFatal)
317+
}
286318
msg => {
287319
log::error!("Unexpected message received: {:?}", msg);
288320
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
@@ -301,6 +333,10 @@ impl SwBreakpoint for HyperlightSandboxTarget {
301333

302334
match self.send_command(DebugMsg::AddSwBreakpoint(addr))? {
303335
DebugResponse::AddSwBreakpoint(rsp) => Ok(rsp),
336+
DebugResponse::ErrorOccurred => {
337+
log::error!("Error occurred");
338+
Err(TargetError::NonFatal)
339+
}
304340
msg => {
305341
log::error!("Unexpected message received: {:?}", msg);
306342
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
@@ -317,6 +353,10 @@ impl SwBreakpoint for HyperlightSandboxTarget {
317353

318354
match self.send_command(DebugMsg::RemoveSwBreakpoint(addr))? {
319355
DebugResponse::RemoveSwBreakpoint(rsp) => Ok(rsp),
356+
DebugResponse::ErrorOccurred => {
357+
log::error!("Error occurred");
358+
Err(TargetError::NonFatal)
359+
}
320360
msg => {
321361
log::error!("Unexpected message received: {:?}", msg);
322362
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
@@ -342,6 +382,10 @@ impl SingleThreadSingleStep for HyperlightSandboxTarget {
342382
log::debug!("Step");
343383
match self.send_command(DebugMsg::Step)? {
344384
DebugResponse::Step => Ok(()),
385+
DebugResponse::ErrorOccurred => {
386+
log::error!("Error occurred");
387+
Err(GdbTargetError::UnexpectedError)
388+
}
345389
msg => {
346390
log::error!("Unexpected message received: {:?}", msg);
347391
Err(GdbTargetError::UnexpectedMessage)

src/hyperlight_host/src/hypervisor/kvm.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
3939
use crate::mem::ptr::{GuestPtr, RawPtr};
4040
#[cfg(gdb)]
4141
use crate::sandbox::config::DebugInfo;
42+
#[cfg(gdb)]
43+
use crate::HyperlightError;
4244
use crate::{log_then_return, new_error, Result};
4345

4446
/// Return `true` if the KVM API is available, version 12, and has UserMemory capability, or `false` otherwise
@@ -79,7 +81,7 @@ mod debug {
7981
use crate::hypervisor::gdb::{DebugMsg, DebugResponse, VcpuStopReason, X86_64Regs};
8082
use crate::hypervisor::handlers::DbgMemAccessHandlerCaller;
8183
use crate::mem::layout::SandboxMemoryLayout;
82-
use crate::{new_error, Result};
84+
use crate::{new_error, HyperlightError, Result};
8385

8486
/// Software Breakpoint size in memory
8587
pub const SW_BP_SIZE: usize = 1;
@@ -217,19 +219,13 @@ mod debug {
217219

218220
/// Translates the guest address to physical address
219221
fn translate_gva(&self, gva: u64) -> Result<u64> {
220-
let tr = self.vcpu_fd.translate_gva(gva).map_err(|e| {
221-
new_error!(
222-
"Could not translate guest virtual address {:X}: {:?}",
223-
gva,
224-
e
225-
)
226-
})?;
222+
let tr = self
223+
.vcpu_fd
224+
.translate_gva(gva)
225+
.map_err(|_| HyperlightError::TranslateGuestAddress(gva))?;
227226

228227
if tr.valid == 0 {
229-
Err(new_error!(
230-
"Could not translate guest virtual address {:X}",
231-
gva
232-
))
228+
Err(HyperlightError::TranslateGuestAddress(gva))
233229
} else {
234230
Ok(tr.physical_address)
235231
}
@@ -919,7 +915,16 @@ impl Hypervisor for KVMDriver {
919915
// Wait for a message from gdb
920916
let req = self.recv_dbg_msg()?;
921917

922-
let response = self.process_dbg_request(req, dbg_mem_access_fn.clone())?;
918+
let result = self.process_dbg_request(req, dbg_mem_access_fn.clone());
919+
920+
let response = match result {
921+
Ok(response) => response,
922+
// Treat non fatal errors separately so the guest doesn't fail
923+
Err(HyperlightError::TranslateGuestAddress(_)) => DebugResponse::ErrorOccurred,
924+
Err(e) => {
925+
return Err(e);
926+
}
927+
};
923928

924929
// If the command was either step or continue, we need to run the vcpu
925930
let cont = matches!(

0 commit comments

Comments
 (0)