Skip to content
This repository was archived by the owner on Mar 24, 2022. It is now read-only.

Commit 6557e8e

Browse files
only force an unwind if n>0 host frames are on a guest stack
1 parent f1e6950 commit 6557e8e

2 files changed

Lines changed: 26 additions & 5 deletions

File tree

lucet-runtime/lucet-runtime-internals/src/hostcall_macros.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,16 @@ macro_rules! lucet_hostcalls {
5050
) -> $ret_ty {
5151
$($body)*
5252
}
53-
hostcall_impl(&mut $crate::vmctx::Vmctx::from_raw(vmctx_raw), $( $arg ),*)
53+
54+
#[allow(unused_imports)]
55+
use lucet_runtime_internals::vmctx::VmctxInternal;
56+
$crate::vmctx::Vmctx::from_raw(vmctx_raw).instance_mut().begin_hostcall();
57+
58+
let res = hostcall_impl(&mut $crate::vmctx::Vmctx::from_raw(vmctx_raw), $( $arg ),*);
59+
60+
$crate::vmctx::Vmctx::from_raw(vmctx_raw).instance_mut().end_hostcall();
61+
62+
res
5463
}
5564
)*
5665
}

lucet-runtime/lucet-runtime-internals/src/instance.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ pub struct Instance {
251251
/// The value passed back to the guest when resuming a yielded instance.
252252
pub(crate) resumed_val: Option<Box<dyn Any + 'static>>,
253253

254+
hostcall_count: u64,
255+
254256
/// `_padding` must be the last member of the structure.
255257
/// This marks where the padding starts to make the structure exactly 4096 bytes long.
256258
/// It is also used to compute the size of the structure up to that point, i.e. without padding.
@@ -533,10 +535,7 @@ impl Instance {
533535
/// This function runs the guest code for the WebAssembly `start` section, and running any guest
534536
/// code is potentially unsafe; see [`Instance::run()`](struct.Instance.html#method.run).
535537
pub fn reset(&mut self) -> Result<(), Error> {
536-
// temporary heuristic for whether this should happen upon a reset; in the long term we only
537-
// want to force an unwind if there are hostcall frames present, which we'll need to track
538-
// via the instance
539-
if self.ctx.gpr.rsp != 0 {
538+
if self.hostcall_count > 0 {
540539
self.force_unwind().unwrap();
541540
}
542541
self.alloc.reset_heap(self.module.as_ref())?;
@@ -694,6 +693,14 @@ impl Instance {
694693
self.c_fatal_handler = Some(handler);
695694
}
696695

696+
pub fn begin_hostcall(&mut self) {
697+
self.hostcall_count += 1;
698+
}
699+
700+
pub fn end_hostcall(&mut self) {
701+
self.hostcall_count -= 1;
702+
}
703+
697704
#[inline]
698705
pub fn get_instruction_count(&self) -> u64 {
699706
self.get_instance_implicits().instruction_count
@@ -721,6 +728,7 @@ impl Instance {
721728
signal_handler: Box::new(signal_handler_none) as Box<SignalHandler>,
722729
entrypoint: None,
723730
resumed_val: None,
731+
hostcall_count: 0,
724732
_padding: (),
725733
};
726734
inst.set_globals_ptr(globals_ptr);
@@ -806,6 +814,10 @@ impl Instance {
806814
let mut args_with_vmctx = vec![Val::from(self.alloc.slot().heap)];
807815
args_with_vmctx.extend_from_slice(args);
808816

817+
// when preparing a new context for the guest to run, we must have cleaned up any existing
818+
// host call frames on the stack.
819+
assert_eq!(self.hostcall_count, 0);
820+
809821
HOST_CTX.with(|host_ctx| {
810822
Context::init(
811823
unsafe { self.alloc.stack_u64_mut() },

0 commit comments

Comments
 (0)