@@ -16,7 +16,9 @@ limitations under the License.
1616
1717use alloc:: alloc:: { alloc, dealloc, Layout } ;
1818use core:: ffi:: c_void;
19- use core:: sync:: atomic:: { AtomicPtr , Ordering } ;
19+ use core:: sync:: atomic:: { AtomicPtr , AtomicU64 , Ordering } ;
20+
21+ use hyperlight_guest_bin:: exceptions:: handler;
2022
2123// Wasmtime Embedding Interface
2224
@@ -64,10 +66,52 @@ pub extern "C" fn wasmtime_page_size() -> usize {
6466#[ allow( non_camel_case_types) ] // we didn't choose the name!
6567type wasmtime_trap_handler_t =
6668 extern "C" fn ( ip : usize , fp : usize , has_faulting_addr : bool , faulting_addr : usize ) ;
69+ static WASMTIME_REQUESTED_TRAP_HANDLER : AtomicU64 = AtomicU64 :: new ( 0 ) ;
70+ fn wasmtime_trap_handler (
71+ exception_number : u64 ,
72+ info : * mut handler:: ExceptionInfo ,
73+ ctx : * mut handler:: Context ,
74+ _page_fault_address : u64 ,
75+ ) -> bool {
76+ let requested_handler = WASMTIME_REQUESTED_TRAP_HANDLER . load ( Ordering :: Relaxed ) ;
77+ if requested_handler != 0 {
78+ #[ allow( clippy:: collapsible_if) ] // We will add more cases
79+ if exception_number == 6 {
80+ // #UD
81+ // we assume that handle_trap always longjmp's away, so don't bother
82+ // setting up a terribly proper stack frame
83+ unsafe {
84+ let orig_rip = ( & raw mut ( * info) . rip ) . read_volatile ( ) ;
85+ ( & raw mut ( * info) . rip ) . write_volatile ( requested_handler) ;
86+ // TODO: This only works on amd64 sysv
87+ ( & raw mut ( * ctx) . gprs [ 9 ] ) . write_volatile ( orig_rip) ;
88+ let orig_rbp = ( & raw mut ( * ctx) . gprs [ 8 ] ) . read_volatile ( ) ;
89+ ( & raw mut ( * ctx) . gprs [ 10 ] ) . write_volatile ( orig_rbp) ;
90+ ( & raw mut ( * ctx) . gprs [ 11 ] ) . write_volatile ( 0 ) ;
91+ ( & raw mut ( * ctx) . gprs [ 12 ] ) . write_volatile ( 0 ) ;
92+ }
93+ return true ;
94+ }
95+ // TODO: Add handlers for any other traps that wasmtime needs
96+ }
97+ false
98+ }
6799
68- // TODO: Correctly handle traps.
69100#[ no_mangle]
70- pub extern "C" fn wasmtime_init_traps ( _handler : wasmtime_trap_handler_t ) -> i32 {
101+ pub extern "C" fn wasmtime_init_traps ( handler : wasmtime_trap_handler_t ) -> i32 {
102+ WASMTIME_REQUESTED_TRAP_HANDLER . store ( handler as usize as u64 , Ordering :: Relaxed ) ;
103+ // On amd64, vector 6 is #UD
104+ // See AMD64 Architecture Programmer's Manual, Volume 2
105+ // §8.2 Vectors, p. 245
106+ // Table 8-1: Interrupt Vector Source and Cause
107+ handler:: handlers[ 6 ] . store ( wasmtime_trap_handler as usize as u64 , Ordering :: Release ) ;
108+ // TODO: Add handlers for any other traps that wasmtime needs,
109+ // probably including at least some floating-point
110+ // exceptions
111+ // TODO: Ensure that invalid accesses to mprotect()'d regions also
112+ // need to trap, although those will need to go through the
113+ // page fault handler instead of using this handler that
114+ // takes over the exception.
71115 0
72116}
73117
0 commit comments