hyperlight_guest_bin/exceptions/
handler.rs1use alloc::format;
18use core::ffi::c_char;
19
20use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
21use hyperlight_common::outb::Exception;
22use hyperlight_guest::exit::abort_with_code_and_message;
23
24#[repr(C)]
31pub struct ExceptionInfo {
32 pub error_code: u64,
33 pub rip: u64,
34 pub cs: u64,
35 pub rflags: u64,
36 pub rsp: u64,
37 pub ss: u64,
38}
39const _: () = assert!(core::mem::offset_of!(ExceptionInfo, rip) == 8);
40const _: () = assert!(core::mem::offset_of!(ExceptionInfo, rsp) == 32);
41
42#[repr(C)]
43pub struct Context {
45 pub segments: [u64; 3],
47 pub fxsave: [u8; 512],
48 pub ds: u64,
49 pub gprs: [u64; 15],
52}
53const _: () = assert!(size_of::<Context>() == 152 + 512);
54
55pub static HANDLERS: [core::sync::atomic::AtomicU64; 31] =
58 [const { core::sync::atomic::AtomicU64::new(0) }; 31];
59pub type HandlerT = fn(n: u64, info: *mut ExceptionInfo, ctx: *mut Context, pf_addr: u64) -> bool;
60
61#[unsafe(no_mangle)]
63pub extern "C" fn hl_exception_handler(
64 stack_pointer: u64,
65 exception_number: u64,
66 page_fault_address: u64,
67) {
68 hyperlight_guest_tracing::trace!("> hl_exception_handler");
73
74 let ctx = stack_pointer as *mut Context;
75 let exn_info = (stack_pointer + size_of::<Context>() as u64) as *mut ExceptionInfo;
76
77 let exception = Exception::try_from(exception_number as u8).expect("Invalid exception number");
78
79 let saved_rip = unsafe { (&raw const (*exn_info).rip).read_volatile() };
80 let error_code = unsafe { (&raw const (*exn_info).error_code).read_volatile() };
81
82 let msg = format!(
83 "Exception vector: {:#}\n\
84 Faulting Instruction: {:#x}\n\
85 Page Fault Address: {:#x}\n\
86 Error code: {:#x}\n\
87 Stack Pointer: {:#x}",
88 exception_number, saved_rip, page_fault_address, error_code, stack_pointer
89 );
90
91 if exception_number < 31 {
95 let handler =
96 HANDLERS[exception_number as usize].load(core::sync::atomic::Ordering::Acquire);
97 if handler != 0
98 && unsafe {
99 core::mem::transmute::<u64, fn(u64, *mut ExceptionInfo, *mut Context, u64) -> bool>(
100 handler,
101 )(exception_number, exn_info, ctx, page_fault_address)
102 }
103 {
104 hyperlight_guest_tracing::trace!("< hl_exception_handler");
105 return;
106 }
107 }
108
109 unsafe {
110 abort_with_code_and_message(
111 &[ErrorCode::GuestError as u8, exception as u8],
112 msg.as_ptr() as *const c_char,
113 );
114 }
115}