Skip to content

Commit 917a1da

Browse files
committed
wasmtime platform: make init_traps catch #UD
This makes wasmtime_init_traps actually register an exception handler, and adds handling for #UD to recognize it as a trap that should be forwraded to wasmtime. More traps will need to be added in the future in order to ensure correctness. Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com>
1 parent 8b40213 commit 917a1da

3 files changed

Lines changed: 54 additions & 4 deletions

File tree

src/wasm_runtime/src/component.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ use spin::Mutex;
3333
use wasmtime::component::{Component, Instance, Linker};
3434
use wasmtime::{Config, Engine, Store};
3535

36+
use crate::platform;
37+
3638
static CUR_ENGINE: Mutex<Option<Engine>> = Mutex::new(None);
3739
static CUR_LINKER: Mutex<Option<Linker<()>>> = Mutex::new(None);
3840
static CUR_STORE: Mutex<Option<Store<()>>> = Mutex::new(None);
@@ -74,6 +76,8 @@ fn load_wasm_module(function_call: &FunctionCall) -> Result<Vec<u8>> {
7476

7577
#[no_mangle]
7678
pub extern "C" fn hyperlight_main() {
79+
platform::register_page_fault_handler();
80+
7781
let mut config = Config::new();
7882
config.memory_reservation(0);
7983
config.memory_guard_size(0);

src/wasm_runtime/src/module.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use hyperlight_guest_bin::host_comm::print_output_with_host_print;
3232
use spin::Mutex;
3333
use wasmtime::{Config, Engine, Linker, Module, Store, Val};
3434

35-
use crate::{hostfuncs, marshal, wasip1};
35+
use crate::{hostfuncs, marshal, platform, wasip1};
3636

3737
static CUR_ENGINE: Mutex<Option<Engine>> = Mutex::new(None);
3838
static CUR_LINKER: Mutex<Option<Linker<()>>> = Mutex::new(None);
@@ -141,6 +141,8 @@ fn load_wasm_module(function_call: &FunctionCall) -> Result<Vec<u8>> {
141141
#[no_mangle]
142142
#[allow(clippy::fn_to_numeric_cast)] // GuestFunctionDefinition expects a function pointer as i64
143143
pub extern "C" fn hyperlight_main() {
144+
platform::register_page_fault_handler();
145+
144146
register_function(GuestFunctionDefinition::new(
145147
"PrintOutput".to_string(),
146148
vec![ParameterType::String],

src/wasm_runtime/src/platform.rs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ limitations under the License.
1616

1717
use alloc::alloc::{alloc, dealloc, Layout};
1818
use 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!
6567
type 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

Comments
 (0)