Skip to content

Commit 21b86d5

Browse files
committed
fixup! Implement wasmtime_memory_image APIs
Fixes to some barrier logic, along with some minor formatting nits Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com>
1 parent 030fbb5 commit 21b86d5

1 file changed

Lines changed: 42 additions & 11 deletions

File tree

src/hyperlight_wasm_runtime/src/platform.rs

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,15 @@ pub extern "C" fn wasmtime_init_traps(handler: wasmtime_trap_handler_t) -> i32 {
175175
// Copy a VA range to a new VA. Old and new VA, and len, must be
176176
// page-aligned.
177177
fn copy_va_mapping(base: *const u8, len: usize, to_va: *mut u8, remap_original: bool) {
178+
// TODO: all this barrier code is amd64 specific. It should be
179+
// refactored to use some better architecture-independent APIs.
180+
//
181+
// On amd64, "upgrades" including the first time that a a valid
182+
// translation exists for a VA, only need a light (serialising
183+
// instruction) barrier. Since invlpg is also a barrier, we don't
184+
// even need that, if we did do a downgrade remap just before.
185+
let mut needs_first_valid_exposure_barrier = false;
186+
178187
// TODO: make this more efficient by directly exposing the ability
179188
// to traverse an entire VA range in
180189
// hyperlight_guest_bin::paging::virt_to_phys, and coalescing
@@ -188,18 +197,25 @@ fn copy_va_mapping(base: *const u8, len: usize, to_va: *mut u8, remap_original:
188197
// Skip unmapped pages, since they will be unmapped in
189198
// both the original and the new copy
190199
vmem::MappingKind::Unmapped => continue,
191-
vmem::MappingKind::Basic(bm) if bm.writable => (vmem::MappingKind::Cow(vmem::CowMapping {
192-
readable: bm.readable,
193-
executable: bm.executable,
194-
}), true),
195-
vmem::MappingKind::Basic(bm) => (vmem::MappingKind::Basic(vmem::BasicMapping {
196-
readable: bm.readable,
197-
writable: false,
198-
executable: bm.executable,
199-
}), false),
200+
vmem::MappingKind::Basic(bm) if bm.writable => (
201+
vmem::MappingKind::Cow(vmem::CowMapping {
202+
readable: bm.readable,
203+
executable: bm.executable,
204+
}),
205+
true,
206+
),
207+
vmem::MappingKind::Basic(bm) => (
208+
vmem::MappingKind::Basic(vmem::BasicMapping {
209+
readable: bm.readable,
210+
writable: false,
211+
executable: bm.executable,
212+
}),
213+
false,
214+
),
200215
vmem::MappingKind::Cow(cm) => (vmem::MappingKind::Cow(cm), false),
201216
};
202-
if remap_original && was_writable {
217+
let do_downgrade = remap_original && was_writable;
218+
if do_downgrade {
203219
// If necessary, remap the original page as Cow, instead
204220
// of whatever it is now, to ensure that any more writes to
205221
// that region do not change the image base.
@@ -225,6 +241,21 @@ fn copy_va_mapping(base: *const u8, len: usize, to_va: *mut u8, remap_original:
225241
new_kind,
226242
);
227243
}
244+
if do_downgrade {
245+
// Since we have downgraded a page from writable to CoW we
246+
// need to do an invlpg on it. Because invlpg is a
247+
// serialising instruction, we don't need need the other
248+
// barrier for the new mapping.
249+
unsafe {
250+
core::arch::asm!("invlpg [{}]", in(reg) mapping.virt_base, options(readonly, nostack, preserves_flags));
251+
}
252+
needs_first_valid_exposure_barrier = false;
253+
} else {
254+
needs_first_valid_exposure_barrier = true;
255+
}
256+
}
257+
if needs_first_valid_exposure_barrier {
258+
paging::barrier::first_valid_same_ctx();
228259
}
229260
}
230261

@@ -259,7 +290,7 @@ pub extern "C" fn wasmtime_memory_image_map_at(
259290

260291
#[no_mangle]
261292
pub extern "C" fn wasmtime_memory_image_free(_image: *mut c_void) {
262-
/* This should never be called in practice, because we simple
293+
/* This should never be called in practice, because we simply
263294
* restore the snapshot rather than actually unload/destroy instances */
264295
panic!("wasmtime_memory_image_free");
265296
}

0 commit comments

Comments
 (0)