@@ -16,7 +16,7 @@ use core::mem::{self, MaybeUninit};
1616use core:: ops:: Range ;
1717use core:: ptr:: { self , NonNull } ;
1818use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
19- use rustix:: mm:: { MapFlags , ProtFlags , mmap_anonymous, munmap} ;
19+ use rustix:: mm:: { MapFlags , MprotectFlags , ProtFlags , mmap_anonymous, mprotect , munmap} ;
2020use rustix:: param:: page_size;
2121use wasmtime_environ:: {
2222 BuiltinFunctionIndex , DefinedGlobalIndex , DefinedMemoryIndex , DefinedTableIndex ,
@@ -1227,6 +1227,20 @@ impl VMStoreContext {
12271227 ret
12281228 }
12291229
1230+ /// Twiddles MMU access control bits such that reads from the interrupt page
1231+ /// will cause a segfault. This effectively ends the epoch, as running wasm
1232+ /// will soon execute such reads.
1233+ pub fn protect_interrupt_page ( & self ) {
1234+ if let Some ( page_ptr) = self . epoch_interrupt_page_ptr {
1235+ unsafe {
1236+ mprotect ( page_ptr. as_ptr ( ) , page_size ( ) , MprotectFlags :: empty ( ) )
1237+ . expect ( "any error from mprotect is a programming error" )
1238+ }
1239+ } else {
1240+ panic ! ( "called protect_interrupt_page though epoch-interruption-via-mmu was not on" )
1241+ }
1242+ }
1243+
12301244 /// Disposes of any allocated epoch interrupt page. This must be called if
12311245 /// [`VMStoreContext::with_interrupt_page()`] was used to construct this
12321246 /// instance, lest we leak a page.
0 commit comments