Skip to content

Commit

Permalink
add a way to signal a non fatal error on the hypervisor side
Browse files Browse the repository at this point in the history
- when using visual studio code, sometimes it requests to read from
  unexpected addresses which can cause an error on the hypervisor side.
  This fix signals this to the gdb thread which marks it as a non-fatal
  error

Signed-off-by: Doru Blânzeanu <[email protected]>
  • Loading branch information
dblnz committed Feb 5, 2025
1 parent 6cc6184 commit 98ac60e
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 14 deletions.
5 changes: 5 additions & 0 deletions src/hyperlight_host/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,11 @@ pub enum HyperlightError {
#[error("SystemTimeError {0:?}")]
SystemTimeError(#[from] SystemTimeError),

/// Error occurred when translating guest address
#[error("An error occurred when translating guest address: {0:?}")]
#[cfg(gdb)]
TranslateGuestAddress(u64),

/// Error occurred converting a slice to an array
#[error("TryFromSliceError {0:?}")]
TryFromSliceError(#[from] TryFromSliceError),
Expand Down
1 change: 1 addition & 0 deletions src/hyperlight_host/src/hypervisor/gdb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ pub enum DebugResponse {
AddSwBreakpoint(bool),
Continue,
DisableDebug,
ErrorOccurred,
GetCodeSectionOffset(u64),
ReadAddr(Vec<u8>),
ReadRegisters(X86_64Regs),
Expand Down
45 changes: 44 additions & 1 deletion src/hyperlight_host/src/hypervisor/gdb/x86_64_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ impl HyperlightSandboxTarget {

match self.send_command(DebugMsg::DisableDebug)? {
DebugResponse::DisableDebug => Ok(()),
DebugResponse::ErrorOccurred => {
log::error!("Error occurred");
Err(GdbTargetError::UnexpectedError)
}
msg => {
log::error!("Unexpected message received: {:?}", msg);
Err(GdbTargetError::UnexpectedMessage)
Expand Down Expand Up @@ -134,6 +138,10 @@ impl SingleThreadBase for HyperlightSandboxTarget {

Ok(v.len())
}
DebugResponse::ErrorOccurred => {
log::error!("Error occurred");
Err(TargetError::NonFatal)
}
msg => {
log::error!("Unexpected message received: {:?}", msg);
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
Expand All @@ -151,6 +159,10 @@ impl SingleThreadBase for HyperlightSandboxTarget {

match self.send_command(DebugMsg::WriteAddr(gva, v))? {
DebugResponse::WriteAddr => Ok(()),
DebugResponse::ErrorOccurred => {
log::error!("Error occurred");
Err(TargetError::NonFatal)
}
msg => {
log::error!("Unexpected message received: {:?}", msg);
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
Expand Down Expand Up @@ -188,6 +200,10 @@ impl SingleThreadBase for HyperlightSandboxTarget {

Ok(())
}
DebugResponse::ErrorOccurred => {
log::error!("Error occurred");
Err(TargetError::NonFatal)
}

msg => {
log::error!("Unexpected message received: {:?}", msg);
Expand Down Expand Up @@ -225,6 +241,10 @@ impl SingleThreadBase for HyperlightSandboxTarget {

match self.send_command(DebugMsg::WriteRegisters(regs))? {
DebugResponse::WriteRegisters => Ok(()),
DebugResponse::ErrorOccurred => {
log::error!("Error occurred");
Err(TargetError::NonFatal)
}
msg => {
log::error!("Unexpected message received: {:?}", msg);
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
Expand All @@ -246,6 +266,10 @@ impl SectionOffsets for HyperlightSandboxTarget {
text_seg: text,
data_seg: None,
}),
DebugResponse::ErrorOccurred => {
log::error!("Error occurred");
Err(GdbTargetError::UnexpectedError)
}
msg => {
log::error!("Unexpected message received: {:?}", msg);
Err(GdbTargetError::UnexpectedMessage)
Expand Down Expand Up @@ -273,6 +297,10 @@ impl HwBreakpoint for HyperlightSandboxTarget {

match self.send_command(DebugMsg::AddHwBreakpoint(addr))? {
DebugResponse::AddHwBreakpoint(rsp) => Ok(rsp),
DebugResponse::ErrorOccurred => {
log::error!("Error occurred");
Err(TargetError::NonFatal)
}
msg => {
log::error!("Unexpected message received: {:?}", msg);
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
Expand All @@ -289,6 +317,10 @@ impl HwBreakpoint for HyperlightSandboxTarget {

match self.send_command(DebugMsg::RemoveHwBreakpoint(addr))? {
DebugResponse::RemoveHwBreakpoint(rsp) => Ok(rsp),
DebugResponse::ErrorOccurred => {
log::error!("Error occurred");
Err(TargetError::NonFatal)
}
msg => {
log::error!("Unexpected message received: {:?}", msg);
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
Expand All @@ -307,6 +339,10 @@ impl SwBreakpoint for HyperlightSandboxTarget {

match self.send_command(DebugMsg::AddSwBreakpoint(addr))? {
DebugResponse::AddSwBreakpoint(rsp) => Ok(rsp),
DebugResponse::ErrorOccurred => {
log::error!("Error occurred");
Err(TargetError::NonFatal)
}
msg => {
log::error!("Unexpected message received: {:?}", msg);
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
Expand All @@ -323,6 +359,10 @@ impl SwBreakpoint for HyperlightSandboxTarget {

match self.send_command(DebugMsg::RemoveSwBreakpoint(addr))? {
DebugResponse::RemoveSwBreakpoint(rsp) => Ok(rsp),
DebugResponse::ErrorOccurred => {
log::error!("Error occurred");
Err(TargetError::NonFatal)
}
msg => {
log::error!("Unexpected message received: {:?}", msg);
Err(TargetError::Fatal(GdbTargetError::UnexpectedMessage))
Expand All @@ -348,9 +388,12 @@ impl SingleThreadSingleStep for HyperlightSandboxTarget {
log::debug!("Step");
match self.send_command(DebugMsg::Step)? {
DebugResponse::Step => Ok(()),
DebugResponse::ErrorOccurred => {
log::error!("Error occurred");
Err(GdbTargetError::UnexpectedError)
}
msg => {
log::error!("Unexpected message received: {:?}", msg);

Err(GdbTargetError::UnexpectedMessage)
}
}
Expand Down
31 changes: 18 additions & 13 deletions src/hyperlight_host/src/hypervisor/kvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
use crate::mem::ptr::{GuestPtr, RawPtr};
#[cfg(gdb)]
use crate::sandbox::uninitialized::DebugInfo;
#[cfg(gdb)]
use crate::HyperlightError;
use crate::{log_then_return, new_error, Result};

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

/// Software Breakpoint size in memory
pub const SW_BP_SIZE: usize = 1;
Expand Down Expand Up @@ -208,19 +210,13 @@ mod debug {

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

if tr.valid == 0 {
Err(new_error!(
"Could not translate guest virtual address {:X}",
gva
))
Err(HyperlightError::TranslateGuestAddress(gva))
} else {
Ok(tr.physical_address)
}
Expand Down Expand Up @@ -916,7 +912,16 @@ impl Hypervisor for KVMDriver {
// Wait for a message from gdb
let req = self.recv_dbg_msg()?;

let response = self.process_dbg_request(req, dbg_mem_access_fn.clone())?;
let result = self.process_dbg_request(req, dbg_mem_access_fn.clone());

let response = match result {
Ok(response) => response,
// Treat non fatal errors separately so the guest doesn't fail
Err(HyperlightError::TranslateGuestAddress(_)) => DebugResponse::ErrorOccurred,
Err(e) => {
return Err(e);
}
};

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

0 comments on commit 98ac60e

Please sign in to comment.