From 8b40213fc17a9f99e8465c20240dddaf5f0e0a88 Mon Sep 17 00:00:00 2001 From: Lucy Menon <168595099+syntactically@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:38:19 +0000 Subject: [PATCH 1/4] Add git dependencies on hyperlight for development The core hyperlight libraries now have both version and git keys in Cargo.toml, allowing us to develop against upstream hyperlight HEAD. Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com> --- Cargo.lock | 103 ++++++++++++++++++++------- Cargo.toml | 2 +- src/hyperlight_wasm/Cargo.toml | 2 +- src/hyperlight_wasm_macro/Cargo.lock | 2 - src/hyperlight_wasm_macro/Cargo.toml | 2 +- src/wasm_runtime/Cargo.lock | 12 ++-- src/wasm_runtime/Cargo.toml | 6 +- 7 files changed, 87 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4ee440..1b6b5ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,6 +322,22 @@ dependencies = [ "serde", ] +[[package]] +name = "cargo-util-schemas" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63d2780ac94487eb9f1fea7b0d56300abc9eb488800854ca217f102f5caccca" +dependencies = [ + "semver", + "serde", + "serde-untagged", + "serde-value", + "thiserror 1.0.69", + "toml 0.8.23", + "unicode-xid", + "url", +] + [[package]] name = "cargo_metadata" version = "0.19.2" @@ -687,19 +703,6 @@ dependencies = [ "itertools 0.10.5", ] -[[package]] -name = "crossbeam" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -1249,8 +1252,7 @@ dependencies = [ [[package]] name = "hyperlight-common" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b9232222e023b84c7c10bdb67327f503567a1a5ff68db935683af0147d73ba" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=ea6fa8f#ea6fa8f16dae2325d94af39eb6ac3b441b24dcac" dependencies = [ "anyhow", "flatbuffers", @@ -1262,8 +1264,7 @@ dependencies = [ [[package]] name = "hyperlight-component-macro" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bc0fc7f0d77ab2c16277da4efb58fa99c56f607f9407fd5c0490909c327facd" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=ea6fa8f#ea6fa8f16dae2325d94af39eb6ac3b441b24dcac" dependencies = [ "env_logger", "hyperlight-component-util", @@ -1278,8 +1279,7 @@ dependencies = [ [[package]] name = "hyperlight-component-util" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88137b20c4761f4b309d36b22574e2283745afad5959df7ecc5928557417d098" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=ea6fa8f#ea6fa8f16dae2325d94af39eb6ac3b441b24dcac" dependencies = [ "itertools 0.14.0", "log", @@ -1293,15 +1293,13 @@ dependencies = [ [[package]] name = "hyperlight-host" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cb5d2db5c1325df0c1042680ccbff16958105a2842140736ac463d67df89fba" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=ea6fa8f#ea6fa8f16dae2325d94af39eb6ac3b441b24dcac" dependencies = [ "anyhow", "bitflags 2.9.1", "cfg-if", "cfg_aliases", "chrono", - "crossbeam", "crossbeam-channel", "elfcore", "flatbuffers", @@ -1331,7 +1329,7 @@ dependencies = [ "vmm-sys-util", "windows", "windows-result", - "windows-sys 0.59.0", + "windows-sys 0.60.2", "windows-version", ] @@ -1358,7 +1356,7 @@ dependencies = [ "once_cell", "page_size", "tar", - "toml", + "toml 0.9.0", "tracing", "windows", ] @@ -2620,6 +2618,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + [[package]] name = "serde_spanned" version = "1.0.0" @@ -2875,6 +2882,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit", +] + [[package]] name = "toml" version = "0.9.0" @@ -2883,13 +2902,22 @@ checksum = "f271e09bde39ab52250160a67e88577e0559ad77e9085de6e9051a2c4353f8f8" dependencies = [ "indexmap", "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 1.0.0", + "toml_datetime 0.7.0", "toml_parser", "toml_writer", "winnow", ] +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + [[package]] name = "toml_datetime" version = "0.7.0" @@ -2899,6 +2927,20 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_write", + "winnow", +] + [[package]] name = "toml_parser" version = "1.0.0" @@ -2908,6 +2950,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "toml_writer" version = "1.0.0" @@ -3747,6 +3795,9 @@ name = "winnow" version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" +dependencies = [ + "memchr", +] [[package]] name = "wit-bindgen-rt" diff --git a/Cargo.toml b/Cargo.toml index 633f05f..f7f662b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,4 @@ repository = "https://github.com/hyperlight-dev/hyperlight-wasm" readme = "README.md" [workspace.dependencies] -hyperlight-host = { version = "0.7.0", default-features = false, features = ["executable_heap", "init-paging"] } +hyperlight-host = { version = "0.7.0", git = "https://github.com/hyperlight-dev/hyperlight", rev = "ea6fa8f", default-features = false, features = ["executable_heap", "init-paging"] } diff --git a/src/hyperlight_wasm/Cargo.toml b/src/hyperlight_wasm/Cargo.toml index 14c142f..96e988d 100644 --- a/src/hyperlight_wasm/Cargo.toml +++ b/src/hyperlight_wasm/Cargo.toml @@ -58,7 +58,7 @@ windows = { version = "0.61", features = ["Win32_System_Threading"] } page_size = "0.6.0" [dev-dependencies] -hyperlight-component-macro = "0.7.0" +hyperlight-component-macro = { version = "0.7.0", git = "https://github.com/hyperlight-dev/hyperlight", rev = "ea6fa8f" } examples_common = { path = "../examples_common" } criterion = { version = "0.6.0", features = ["html_reports"] } crossbeam-queue = "0.3" diff --git a/src/hyperlight_wasm_macro/Cargo.lock b/src/hyperlight_wasm_macro/Cargo.lock index 3d2934b..2ad9117 100644 --- a/src/hyperlight_wasm_macro/Cargo.lock +++ b/src/hyperlight_wasm_macro/Cargo.lock @@ -39,8 +39,6 @@ dependencies = [ [[package]] name = "hyperlight-component-util" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88137b20c4761f4b309d36b22574e2283745afad5959df7ecc5928557417d098" dependencies = [ "itertools", "log", diff --git a/src/hyperlight_wasm_macro/Cargo.toml b/src/hyperlight_wasm_macro/Cargo.toml index 275eab5..bb9eb05 100644 --- a/src/hyperlight_wasm_macro/Cargo.toml +++ b/src/hyperlight_wasm_macro/Cargo.toml @@ -17,4 +17,4 @@ proc-macro2 = { version = "1.0.93" } syn = { version = "2.0.96" } itertools = { version = "0.14.0" } prettyplease = { version = "0.2.31" } -hyperlight-component-util = { version = "0.7.0" } +hyperlight-component-util = { version = "0.7.0", git = "https://github.com/hyperlight-dev/hyperlight", rev = "ea6fa8f" } diff --git a/src/wasm_runtime/Cargo.lock b/src/wasm_runtime/Cargo.lock index b5739be..a80dd4a 100644 --- a/src/wasm_runtime/Cargo.lock +++ b/src/wasm_runtime/Cargo.lock @@ -601,8 +601,7 @@ dependencies = [ [[package]] name = "hyperlight-common" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b9232222e023b84c7c10bdb67327f503567a1a5ff68db935683af0147d73ba" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=ea6fa8f#ea6fa8f16dae2325d94af39eb6ac3b441b24dcac" dependencies = [ "anyhow", "flatbuffers", @@ -613,8 +612,7 @@ dependencies = [ [[package]] name = "hyperlight-component-util" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88137b20c4761f4b309d36b22574e2283745afad5959df7ecc5928557417d098" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=ea6fa8f#ea6fa8f16dae2325d94af39eb6ac3b441b24dcac" dependencies = [ "itertools", "log", @@ -628,8 +626,7 @@ dependencies = [ [[package]] name = "hyperlight-guest" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9f007acee89f791a645acd7ae517190bd2bd2e4e24ede531e8d9b70c898c65" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=ea6fa8f#ea6fa8f16dae2325d94af39eb6ac3b441b24dcac" dependencies = [ "anyhow", "hyperlight-common", @@ -639,8 +636,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-bin" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e125eb8b36a7f8909c8efea4e37ebb5306307fc3e20a0d2b533a40441785e34" +source = "git+https://github.com/hyperlight-dev/hyperlight?rev=ea6fa8f#ea6fa8f16dae2325d94af39eb6ac3b441b24dcac" dependencies = [ "buddy_system_allocator", "cc", diff --git a/src/wasm_runtime/Cargo.toml b/src/wasm_runtime/Cargo.toml index 2346ab9..a45bd2e 100644 --- a/src/wasm_runtime/Cargo.toml +++ b/src/wasm_runtime/Cargo.toml @@ -11,9 +11,9 @@ doctest = false bench = false [dependencies] -hyperlight-common = { version = "0.7.0", default-features = false } -hyperlight-guest-bin = { version = "0.7.0", features = [ "printf" ] } -hyperlight-guest = { version = "0.7.0" } +hyperlight-common = { version = "0.7.0", git = "https://github.com/hyperlight-dev/hyperlight", rev = "ea6fa8f", default-features = false } +hyperlight-guest-bin = { version = "0.7.0", git = "https://github.com/hyperlight-dev/hyperlight", rev = "ea6fa8f", features = [ "printf" ] } +hyperlight-guest = { version = "0.7.0", git = "https://github.com/hyperlight-dev/hyperlight", rev = "ea6fa8f" } wasmtime = { version = "34.0.1", default-features = false, features = [ "runtime", "custom-virtual-memory", "custom-native-signals", "component-model" ] } hyperlight-wasm-macro = { path = "../hyperlight_wasm_macro" } spin = "0.9.8" From 917a1da3e9e34191ffe4cdc711ecdbfcc5766603 Mon Sep 17 00:00:00 2001 From: Lucy Menon <168595099+syntactically@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:45:06 +0000 Subject: [PATCH 2/4] 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> --- src/wasm_runtime/src/component.rs | 4 +++ src/wasm_runtime/src/module.rs | 4 ++- src/wasm_runtime/src/platform.rs | 50 +++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/wasm_runtime/src/component.rs b/src/wasm_runtime/src/component.rs index 7fa5dff..0d01c47 100644 --- a/src/wasm_runtime/src/component.rs +++ b/src/wasm_runtime/src/component.rs @@ -33,6 +33,8 @@ use spin::Mutex; use wasmtime::component::{Component, Instance, Linker}; use wasmtime::{Config, Engine, Store}; +use crate::platform; + static CUR_ENGINE: Mutex> = Mutex::new(None); static CUR_LINKER: Mutex>> = Mutex::new(None); static CUR_STORE: Mutex>> = Mutex::new(None); @@ -74,6 +76,8 @@ fn load_wasm_module(function_call: &FunctionCall) -> Result> { #[no_mangle] pub extern "C" fn hyperlight_main() { + platform::register_page_fault_handler(); + let mut config = Config::new(); config.memory_reservation(0); config.memory_guard_size(0); diff --git a/src/wasm_runtime/src/module.rs b/src/wasm_runtime/src/module.rs index b5e3691..ad0611a 100644 --- a/src/wasm_runtime/src/module.rs +++ b/src/wasm_runtime/src/module.rs @@ -32,7 +32,7 @@ use hyperlight_guest_bin::host_comm::print_output_with_host_print; use spin::Mutex; use wasmtime::{Config, Engine, Linker, Module, Store, Val}; -use crate::{hostfuncs, marshal, wasip1}; +use crate::{hostfuncs, marshal, platform, wasip1}; static CUR_ENGINE: Mutex> = Mutex::new(None); static CUR_LINKER: Mutex>> = Mutex::new(None); @@ -141,6 +141,8 @@ fn load_wasm_module(function_call: &FunctionCall) -> Result> { #[no_mangle] #[allow(clippy::fn_to_numeric_cast)] // GuestFunctionDefinition expects a function pointer as i64 pub extern "C" fn hyperlight_main() { + platform::register_page_fault_handler(); + register_function(GuestFunctionDefinition::new( "PrintOutput".to_string(), vec![ParameterType::String], diff --git a/src/wasm_runtime/src/platform.rs b/src/wasm_runtime/src/platform.rs index 6973950..5491057 100644 --- a/src/wasm_runtime/src/platform.rs +++ b/src/wasm_runtime/src/platform.rs @@ -16,7 +16,9 @@ limitations under the License. use alloc::alloc::{alloc, dealloc, Layout}; use core::ffi::c_void; -use core::sync::atomic::{AtomicPtr, Ordering}; +use core::sync::atomic::{AtomicPtr, AtomicU64, Ordering}; + +use hyperlight_guest_bin::exceptions::handler; // Wasmtime Embedding Interface @@ -64,10 +66,52 @@ pub extern "C" fn wasmtime_page_size() -> usize { #[allow(non_camel_case_types)] // we didn't choose the name! type wasmtime_trap_handler_t = extern "C" fn(ip: usize, fp: usize, has_faulting_addr: bool, faulting_addr: usize); +static WASMTIME_REQUESTED_TRAP_HANDLER: AtomicU64 = AtomicU64::new(0); +fn wasmtime_trap_handler( + exception_number: u64, + info: *mut handler::ExceptionInfo, + ctx: *mut handler::Context, + _page_fault_address: u64, +) -> bool { + let requested_handler = WASMTIME_REQUESTED_TRAP_HANDLER.load(Ordering::Relaxed); + if requested_handler != 0 { + #[allow(clippy::collapsible_if)] // We will add more cases + if exception_number == 6 { + // #UD + // we assume that handle_trap always longjmp's away, so don't bother + // setting up a terribly proper stack frame + unsafe { + let orig_rip = (&raw mut (*info).rip).read_volatile(); + (&raw mut (*info).rip).write_volatile(requested_handler); + // TODO: This only works on amd64 sysv + (&raw mut (*ctx).gprs[9]).write_volatile(orig_rip); + let orig_rbp = (&raw mut (*ctx).gprs[8]).read_volatile(); + (&raw mut (*ctx).gprs[10]).write_volatile(orig_rbp); + (&raw mut (*ctx).gprs[11]).write_volatile(0); + (&raw mut (*ctx).gprs[12]).write_volatile(0); + } + return true; + } + // TODO: Add handlers for any other traps that wasmtime needs + } + false +} -// TODO: Correctly handle traps. #[no_mangle] -pub extern "C" fn wasmtime_init_traps(_handler: wasmtime_trap_handler_t) -> i32 { +pub extern "C" fn wasmtime_init_traps(handler: wasmtime_trap_handler_t) -> i32 { + WASMTIME_REQUESTED_TRAP_HANDLER.store(handler as usize as u64, Ordering::Relaxed); + // On amd64, vector 6 is #UD + // See AMD64 Architecture Programmer's Manual, Volume 2 + // §8.2 Vectors, p. 245 + // Table 8-1: Interrupt Vector Source and Cause + handler::handlers[6].store(wasmtime_trap_handler as usize as u64, Ordering::Release); + // TODO: Add handlers for any other traps that wasmtime needs, + // probably including at least some floating-point + // exceptions + // TODO: Ensure that invalid accesses to mprotect()'d regions also + // need to trap, although those will need to go through the + // page fault handler instead of using this handler that + // takes over the exception. 0 } From 3b2330b3ddea1c88f3136bc97a8756c775e9ca14 Mon Sep 17 00:00:00 2001 From: Lucy Menon <168595099+syntactically@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:53:09 +0000 Subject: [PATCH 3/4] Support loading a wasm module/component via direct mapping This adds support for directly mapping a host buffer containing a wasm module/component into the guest, enabling the use of mmap() on the host to share a single module/component across multiple sandboxes. Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com> --- flake.lock | 44 ++++++++++ flake.nix | 83 +++++++++++++++++++ .../src/sandbox/wasm_sandbox.rs | 83 +++++++++++++++---- src/wasm_runtime/src/component.rs | 44 ++++++++-- src/wasm_runtime/src/module.rs | 24 ++++++ src/wasm_runtime/src/platform.rs | 32 +++++++ 6 files changed, 289 insertions(+), 21 deletions(-) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..cc23356 --- /dev/null +++ b/flake.lock @@ -0,0 +1,44 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1727634051, + "narHash": "sha256-S5kVU7U82LfpEukbn/ihcyNt2+EvG7Z5unsKW9H/yFA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "06cf0e1da4208d3766d898b7fdab6513366d45b9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-mozilla": { + "locked": { + "lastModified": 1704373101, + "narHash": "sha256-+gi59LRWRQmwROrmE1E2b3mtocwueCQqZ60CwLG+gbg=", + "owner": "mozilla", + "repo": "nixpkgs-mozilla", + "rev": "9b11a87c0cc54e308fa83aac5b4ee1816d5418a2", + "type": "github" + }, + "original": { + "owner": "mozilla", + "ref": "master", + "repo": "nixpkgs-mozilla", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "nixpkgs-mozilla": "nixpkgs-mozilla" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..f31bff6 --- /dev/null +++ b/flake.nix @@ -0,0 +1,83 @@ +{ + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + inputs.nixpkgs-mozilla.url = "github:mozilla/nixpkgs-mozilla/master"; + outputs = { self, nixpkgs, nixpkgs-mozilla, ... } @ inputs: +let token = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IktRMnRBY3JFN2xCYVZWR0JtYzVGb2JnZEpvNCIsImtpZCI6IktRMnRBY3JFN2xCYVZWR0JtYzVGb2JnZEpvNCJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83MmY5ODhiZi04NmYxLTQxYWYtOTFhYi0yZDdjZDAxMWRiNDcvIiwiaWF0IjoxNzIyODc3MzM2LCJuYmYiOjE3MjI4NzczMzYsImV4cCI6MTcyMjg4MjAyOCwiX2NsYWltX25hbWVzIjp7Imdyb3VwcyI6InNyYzEifSwiX2NsYWltX3NvdXJjZXMiOnsic3JjMSI6eyJlbmRwb2ludCI6Imh0dHBzOi8vZ3JhcGgud2luZG93cy5uZXQvNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3L3VzZXJzLzFkNDgzMWMxLWVhYTgtNGY2OS1hZTVjLTE4MTQwMjBlZTJlYy9nZXRNZW1iZXJPYmplY3RzIn19LCJhY3IiOiIxIiwiYWlvIjoiQVZRQXEvOFhBQUFBK3V0TC9hdXdsU1ppQXp1T1pjdk14aERWay9lTlJaR0tiSFNOTjZXcS9VRTlRZGJTOEdmeWFadDUyM2dsT3FOZVdDckVkQ2E1RFV5c2lHcTdJK1ZMTzJoYW9UVzJ6MFhzVm1VTEMwK1RHUGs9IiwiYW1yIjpbInB3ZCIsInJzYSIsIm1mYSJdLCJhcHBpZCI6IjA0YjA3Nzk1LThkZGItNDYxYS1iYmVlLTAyZjllMWJmN2I0NiIsImFwcGlkYWNyIjoiMCIsImNhcG9saWRzX2xhdGViaW5kIjpbIjI5Mzk5Y2Y5LTliNmItNDIwNS1iNWIzLTEzYTEzNGU5YjIzMyJdLCJkZXZpY2VpZCI6IjVmZThlYWYzLTYzYWUtNGY3Ny1hMDkxLTI4MzcxZTRlZmRlMyIsImZhbWlseV9uYW1lIjoiTWVub24iLCJnaXZlbl9uYW1lIjoiTHVjeSIsImlkdHlwIjoidXNlciIsImlwYWRkciI6IjkyLjQwLjE3MC4yMjAiLCJuYW1lIjoiTHVjeSBNZW5vbiIsIm9pZCI6IjFkNDgzMWMxLWVhYTgtNGY2OS1hZTVjLTE4MTQwMjBlZTJlYyIsIm9ucHJlbV9zaWQiOiJTLTEtNS0yMS0yMTI3NTIxMTg0LTE2MDQwMTI5MjAtMTg4NzkyNzUyNy03ODMzODE4MyIsInB1aWQiOiIxMDAzMjAwM0FBNkI0MTNFIiwicmgiOiIwLkFSb0F2NGo1Y3ZHR3IwR1JxeTE4MEJIYlIwWklmM2tBdXRkUHVrUGF3ZmoyTUJNYUFIUS4iLCJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLCJzdWIiOiJ0bmo3a0hTb1ZIM3V6eGVsYkVfNnRFSEVoaDRBaWVtTGZ4aThDNld1NzBvIiwidGlkIjoiNzJmOTg4YmYtODZmMS00MWFmLTkxYWItMmQ3Y2QwMTFkYjQ3IiwidW5pcXVlX25hbWUiOiJtZW5vbmx1Y3lAbWljcm9zb2Z0LmNvbSIsInVwbiI6Im1lbm9ubHVjeUBtaWNyb3NvZnQuY29tIiwidXRpIjoiaFRXM0lFVmtCRXVaWFRTSnoxNW1BQSIsInZlciI6IjEuMCIsIndpZHMiOlsiYjc5ZmJmNGQtM2VmOS00Njg5LTgxNDMtNzZiMTk0ZTg1NTA5Il0sInhtc19jYWUiOiIxIiwieG1zX2NjIjpbIkNQMSJdLCJ4bXNfZmlsdGVyX2luZGV4IjpbIjI2Il0sInhtc19pZHJlbCI6IjI2IDEiLCJ4bXNfcmQiOiIwLjQyTGxZQlJpbEFJQSIsInhtc19zc20iOiIxIiwieG1zX3RjZHQiOjEyODkyNDE1NDd9.t5d56DG8TDlkLYJPIVHFcftn4PbrPOhzwIQoyJRqe4s1VVgscqhNQH4PYqPjizkHy76lZM0cI6a3lrRfVbr1wXBDk82jLyxQ_AXR0yMN4RmrrTRK5M5p5sKHtXq85rTohHl2RSeu7VsWNNBVMsy1Efh6UN095zFZvzntbn-N2JXjloprrz5JcHb1hasT9-o_tsebIM2jefbj7ggpuiGRcbYM3i5mgLVGd19gYzlpAq7YyiE-SvHtLu3cSSms4KwDeoi3QpZiV_5ok1dsZxaonGplaqXeE_pRM92JCvk1paahCKNmrOjZPcJ4hXUlH4q7OY2Hm6MY4GKcTG_xXXoWaQ"; in +{ + devShells.x86_64-linux.default = with import nixpkgs { system = "x86_64-linux"; overlays = [ (import (nixpkgs-mozilla + "/rust-overlay.nix")) ]; }; let + stable = rustChannelOf { + date = "2025-02-20"; + channel = "stable"; + sha256 = "sha256-AJ6LX/Q/Er9kS15bn9iflkUwcgYqRQxiOIL2ToVAXaU="; + }; + nightly = rustChannelOf { + date = "2025-06-04"; + channel = "nightly"; + sha256 = "sha256-eFuFA5spScrde7b7lSV5QAND1m0+Ds6gbVODfDE3scg="; + }; + rust_stable = stable.rust.override { + targets = [ "x86_64-unknown-linux-gnu" "x86_64-pc-windows-msvc" "x86_64-unknown-none" "wasm32-wasip1" "wasm32-unknown-unknown" ]; + }; + rust_nightly = nightly.rust.override { + targets = [ "x86_64-unknown-linux-gnu" "x86_64-pc-windows-msvc" "x86_64-unknown-none" "wasm32-wasip1" "wasm32-unknown-unknown" ]; + }; + rust-platform = makeRustPlatform { + cargo = rust_stable; + rustc = rust_stable; + }; + in ((rust-platform.buildRustPackage.override { stdenv = clangStdenv; }) rec { + pname = "hyperlight"; + version = "0.0.0"; + src = lib.cleanSource ./.; + #cargoHash = lib.fakeHash; + #cargoHash = "sha256-Z4dkYH1BBSUpqiHETkIi+i13FD1q5CyB0NuGHUxhLm0="; + cargoHash = "sha256-CsHcz91S5NHdoHgQVLFizyd5rUXMlMDHEN67JrQ6Xls="; + nativeBuildInputs = [ + azure-cli + just + dotnet-sdk_6 + clang + llvmPackages_18.llvm + gh + lld + valgrind + pkg-config + ffmpeg + mkvtoolnix + wasm-tools + nodejs # todo - just for now + cargo-component + wasm-tools + ]; + buildInputs = [ + pango + cairo + openssl + ]; + auditable = false; + depsExtraArgs = { + CARGO_REGISTRIES_HYPERLIGHT_REDIST_TOKEN = token; + CARGO_REGISTRIES_HYPERLIGHT_PACKAGES_TOKEN = token; + }; + KVM_SHOULD_BE_PRESENT = "true"; + LIBCLANG_PATH = "${pkgs.llvmPackages_18.libclang.lib}/lib"; + RUST_NIGHTLY = "${rust_nightly}"; + shellHook = '' + rustc_nightly() { + (export PATH="${rust_nightly}/bin/:$PATH"; ${rust_nightly}/bin/rustc "$@") + } + rustc_stable() { + (export PATH="${rust_stable}/bin/:$PATH"; ${rust_stable}/bin/rustc "$@") + } + cargo_nightly() { + (export PATH="${rust_nightly}/bin/:$PATH"; ${rust_nightly}/bin/cargo "$@") + } + cargo_stable() { + (export PATH="${rust_stable}/bin/:$PATH"; ${rust_stable}/bin/cargo "$@") + } + ''; + }).overrideAttrs(oA: { + hardeningDisable = [ "all" ]; + }); + }; +} diff --git a/src/hyperlight_wasm/src/sandbox/wasm_sandbox.rs b/src/hyperlight_wasm/src/sandbox/wasm_sandbox.rs index 43204a2..d9bf176 100644 --- a/src/hyperlight_wasm/src/sandbox/wasm_sandbox.rs +++ b/src/hyperlight_wasm/src/sandbox/wasm_sandbox.rs @@ -17,6 +17,7 @@ limitations under the License. use std::path::Path; use hyperlight_host::func::call_ctx::MultiUseGuestCallContext; +use hyperlight_host::mem::memory_region::{MemoryRegion, MemoryRegionFlags, MemoryRegionType}; use hyperlight_host::sandbox::Callable; use hyperlight_host::sandbox_state::sandbox::{EvolvableSandbox, Sandbox}; use hyperlight_host::sandbox_state::transition::MultiUseContextCallback; @@ -42,6 +43,7 @@ pub struct WasmSandbox { impl Sandbox for WasmSandbox {} +const MAPPED_BINARY_VA: u64 = 0x1_0000_0000u64; impl WasmSandbox { /// Create a new WasmSandBox from a `MultiUseSandbox`. /// This function should be used to create a new `WasmSandbox` from a ProtoWasmSandbox. @@ -59,23 +61,60 @@ impl WasmSandbox { /// Before you can call guest functions in the sandbox, you must call /// this function and use the returned value to call guest functions. pub fn load_module(self, file: impl AsRef) -> Result { - let wasm_bytes = std::fs::read(file)?; - self.load_module_inner(wasm_bytes) + let func = Box::new(move |call_ctx: &mut MultiUseGuestCallContext| { + if let Ok(len) = call_ctx.map_file_cow(file.as_ref(), MAPPED_BINARY_VA) { + call_ctx.call("LoadWasmModulePhys", (MAPPED_BINARY_VA, len)) + } else { + let wasm_bytes = std::fs::read(file)?; + Self::load_module_from_buffer_transition_func(wasm_bytes)(call_ctx) + } + }); + self.load_module_inner(func) } - /// Load a Wasm module from a buffer of bytes into the sandbox and return a `LoadedWasmSandbox` - /// able to execute code in the loaded Wasm Module. + /// Load a Wasm module that is currently present in a buffer in + /// host memory, by mapping the host memory directly into the + /// sandbox. /// - /// Before you can call guest functions in the sandbox, you must call - /// this function and use the returned value to call guest functions. - pub fn load_module_from_buffer(self, buffer: &[u8]) -> Result { - self.load_module_inner(buffer.to_vec()) + /// Depending on the host platform, there are likely alignment + /// requirements of at least one page for base and len + /// + /// # Safety + /// It is the caller's responsibility to ensure that the host side + /// of the region remains intact and is not written to until the + /// produced LoadedWasmSandbox is discarded or devolved. + pub unsafe fn load_module_by_mapping( + self, + base: *mut libc::c_void, + len: usize, + ) -> Result { + let func = Box::new(move |call_ctx: &mut MultiUseGuestCallContext| { + let guest_base: usize = MAPPED_BINARY_VA as usize; + let rgn = MemoryRegion { + host_region: base as usize..base.wrapping_add(len) as usize, + guest_region: guest_base..guest_base + len, + flags: MemoryRegionFlags::READ | MemoryRegionFlags::EXECUTE, + region_type: MemoryRegionType::Heap, + }; + if let Ok(()) = unsafe { call_ctx.map_region(&rgn) } { + call_ctx.call("LoadWasmModulePhys", (MAPPED_BINARY_VA, len as u64)) + } else { + let wasm_bytes = + unsafe { std::slice::from_raw_parts(base as *const u8, len).to_vec() }; + Self::load_module_from_buffer_transition_func(wasm_bytes)(call_ctx) + } + }); + self.load_module_inner(func) } - fn load_module_inner(mut self, wasm_bytes: Vec) -> Result { - let func = Box::new(move |call_ctx: &mut MultiUseGuestCallContext| { - let len = wasm_bytes.len() as i32; - let res: i32 = call_ctx.call("LoadWasmModule", (wasm_bytes, len))?; + // todo: take a slice rather than a vec (requires somewhat + // refactoring the flatbuffers stuff maybe) + fn load_module_from_buffer_transition_func( + buffer: Vec, + ) -> impl FnOnce(&mut MultiUseGuestCallContext) -> Result<()> { + move |call_ctx: &mut MultiUseGuestCallContext| { + let len = buffer.len() as i32; + let res: i32 = call_ctx.call("LoadWasmModule", (buffer, len))?; if res != 0 { return Err(new_error!( "LoadWasmModule Failed with error code {:?}", @@ -83,10 +122,26 @@ impl WasmSandbox { )); } Ok(()) - }); + } + } - let transition_func = MultiUseContextCallback::from(func); + /// Load a Wasm module from a buffer of bytes into the sandbox and return a `LoadedWasmSandbox` + /// able to execute code in the loaded Wasm Module. + /// + /// Before you can call guest functions in the sandbox, you must call + /// this function and use the returned value to call guest functions. + pub fn load_module_from_buffer(self, buffer: &[u8]) -> Result { + // TODO: get rid of this clone + let func = Self::load_module_from_buffer_transition_func(buffer.to_vec()); + self.load_module_inner(func) + } + + fn load_module_inner Result<()>>( + mut self, + func: F, + ) -> Result { + let transition_func = MultiUseContextCallback::from(func); match self.inner.take() { Some(sbox) => { let new_sbox: MultiUseSandbox = sbox.evolve(transition_func)?; diff --git a/src/wasm_runtime/src/component.rs b/src/wasm_runtime/src/component.rs index 0d01c47..1b12c60 100644 --- a/src/wasm_runtime/src/component.rs +++ b/src/wasm_runtime/src/component.rs @@ -47,6 +47,17 @@ fn init_wasm_runtime(_function_call: &FunctionCall) -> Result> { Ok(get_flatbuffer_result::(0)) } +fn load_component_common(engine: &Engine, component: Component) -> Result<()> { + let mut store = Store::new(engine, ()); + let instance = (*CUR_LINKER.lock()) + .as_ref() + .unwrap() + .instantiate(&mut store, &component)?; + *CUR_STORE.lock() = Some(store); + *CUR_INSTANCE.lock() = Some(instance); + Ok(()) +} + fn load_wasm_module(function_call: &FunctionCall) -> Result> { if let ( ParameterValue::VecBytes(ref wasm_bytes), @@ -58,13 +69,7 @@ fn load_wasm_module(function_call: &FunctionCall) -> Result> { &*CUR_ENGINE.lock(), ) { let component = unsafe { Component::deserialize(engine, wasm_bytes)? }; - let mut store = Store::new(engine, ()); - let instance = (*CUR_LINKER.lock()) - .as_ref() - .unwrap() - .instantiate(&mut store, &component)?; - *CUR_STORE.lock() = Some(store); - *CUR_INSTANCE.lock() = Some(instance); + load_component_common(engine, component)?; Ok(get_flatbuffer_result::(0)) } else { Err(HyperlightGuestError::new( @@ -74,6 +79,24 @@ fn load_wasm_module(function_call: &FunctionCall) -> Result> { } } +fn load_wasm_module_phys(function_call: &FunctionCall) -> Result> { + if let (ParameterValue::ULong(ref phys), ParameterValue::ULong(ref len), Some(ref engine)) = ( + &function_call.parameters.as_ref().unwrap()[0], + &function_call.parameters.as_ref().unwrap()[1], + &*CUR_ENGINE.lock(), + ) { + let component = + unsafe { Component::deserialize_raw(engine, platform::map_buffer(*phys, *len))? }; + load_component_common(engine, component)?; + Ok(get_flatbuffer_result::<()>(())) + } else { + Err(HyperlightGuestError::new( + ErrorCode::GuestFunctionParameterTypeMismatch, + "Invalid parameters passed to LoadWasmModulePhys".to_string(), + )) + } +} + #[no_mangle] pub extern "C" fn hyperlight_main() { platform::register_page_fault_handler(); @@ -83,6 +106,7 @@ pub extern "C" fn hyperlight_main() { config.memory_guard_size(0); config.memory_reservation_for_growth(0); config.guard_before_linear_memory(false); + config.with_custom_code_memory(Some(alloc::sync::Arc::new(platform::WasmtimeCodeMemory {}))); let engine = Engine::new(&config).unwrap(); let linker = Linker::new(&engine); *CUR_ENGINE.lock() = Some(engine); @@ -102,6 +126,12 @@ pub extern "C" fn hyperlight_main() { ReturnType::Int, load_wasm_module as usize, )); + register_function(GuestFunctionDefinition::new( + "LoadWasmModulePhys".to_string(), + vec![ParameterType::ULong, ParameterType::ULong], + ReturnType::Void, + load_wasm_module_phys as usize, + )); } #[no_mangle] diff --git a/src/wasm_runtime/src/module.rs b/src/wasm_runtime/src/module.rs index ad0611a..c5bb1b8 100644 --- a/src/wasm_runtime/src/module.rs +++ b/src/wasm_runtime/src/module.rs @@ -93,6 +93,7 @@ fn init_wasm_runtime() -> Result> { config.memory_guard_size(0); config.memory_reservation_for_growth(0); config.guard_before_linear_memory(false); + config.with_custom_code_memory(Some(alloc::sync::Arc::new(platform::WasmtimeCodeMemory {}))); let engine = Engine::new(&config)?; let mut linker = Linker::new(&engine); wasip1::register_handlers(&mut linker)?; @@ -138,6 +139,23 @@ fn load_wasm_module(function_call: &FunctionCall) -> Result> { } } +fn load_wasm_module_phys(function_call: &FunctionCall) -> Result> { + if let (ParameterValue::ULong(ref phys), ParameterValue::ULong(ref len), Some(ref engine)) = ( + &function_call.parameters.as_ref().unwrap()[0], + &function_call.parameters.as_ref().unwrap()[1], + &*CUR_ENGINE.lock(), + ) { + let module = unsafe { Module::deserialize_raw(engine, platform::map_buffer(*phys, *len))? }; + *CUR_MODULE.lock() = Some(module); + Ok(get_flatbuffer_result::<()>(())) + } else { + Err(HyperlightGuestError::new( + ErrorCode::GuestFunctionParameterTypeMismatch, + "Invalid parameters passed to LoadWasmModulePhys".to_string(), + )) + } +} + #[no_mangle] #[allow(clippy::fn_to_numeric_cast)] // GuestFunctionDefinition expects a function pointer as i64 pub extern "C" fn hyperlight_main() { @@ -163,4 +181,10 @@ pub extern "C" fn hyperlight_main() { ReturnType::Int, load_wasm_module as usize, )); + register_function(GuestFunctionDefinition::new( + "LoadWasmModulePhys".to_string(), + vec![ParameterType::ULong, ParameterType::ULong], + ReturnType::Void, + load_wasm_module_phys as usize, + )); } diff --git a/src/wasm_runtime/src/platform.rs b/src/wasm_runtime/src/platform.rs index 5491057..f378877 100644 --- a/src/wasm_runtime/src/platform.rs +++ b/src/wasm_runtime/src/platform.rs @@ -16,6 +16,7 @@ limitations under the License. use alloc::alloc::{alloc, dealloc, Layout}; use core::ffi::c_void; +use core::ptr::NonNull; use core::sync::atomic::{AtomicPtr, AtomicU64, Ordering}; use hyperlight_guest_bin::exceptions::handler; @@ -155,3 +156,34 @@ pub extern "C" fn wasmtime_tls_get() -> *mut u8 { pub extern "C" fn wasmtime_tls_set(ptr: *mut u8) { FAKE_TLS.store(ptr, Ordering::Release) } + +pub struct WasmtimeCodeMemory {} +// TODO: Actually change the page tables for W^X +impl wasmtime::CustomCodeMemory for WasmtimeCodeMemory { + fn required_alignment(&self) -> usize { + unsafe { hyperlight_guest_bin::OS_PAGE_SIZE as usize } + } + fn publish_executable( + &self, + _ptr: *const u8, + _len: usize, + ) -> core::result::Result<(), wasmtime::Error> { + Ok(()) + } + fn unpublish_executable( + &self, + _ptr: *const u8, + _len: usize, + ) -> core::result::Result<(), wasmtime::Error> { + Ok(()) + } +} + +pub(crate) unsafe fn map_buffer(phys: u64, len: u64) -> NonNull<[u8]> { + // TODO: Use a VA allocator + let virt = phys as *mut u8; + unsafe { + paging::map_region(phys, virt, len); + NonNull::new_unchecked(core::ptr::slice_from_raw_parts_mut(virt, len as usize)) + } +} From 2a168d199415892a1ec1fe4e373bde9a6264426b Mon Sep 17 00:00:00 2001 From: Lucy Menon <168595099+syntactically@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:55:49 +0000 Subject: [PATCH 4/4] Begin to enable virtual memory in wasmtime There is a big caveat here, which is that wasmtime's mprotect calls are ignored, so this sandbox is very unsound: a wasm module can take over the entire guest easily Signed-off-by: Lucy Menon <168595099+syntactically@users.noreply.github.com> --- src/hyperlight_wasm_aot/src/main.rs | 4 -- src/wasm_runtime/src/component.rs | 4 -- src/wasm_runtime/src/module.rs | 4 -- src/wasm_runtime/src/platform.rs | 80 +++++++++++++++++++++++------ 4 files changed, 65 insertions(+), 27 deletions(-) diff --git a/src/hyperlight_wasm_aot/src/main.rs b/src/hyperlight_wasm_aot/src/main.rs index a94cd9c..2f01d3d 100644 --- a/src/hyperlight_wasm_aot/src/main.rs +++ b/src/hyperlight_wasm_aot/src/main.rs @@ -150,9 +150,5 @@ fn main() { fn get_config() -> Config { let mut config = Config::new(); config.target("x86_64-unknown-none").unwrap(); - config.memory_reservation(0); - config.memory_reservation_for_growth(0); - config.memory_guard_size(0); - config.guard_before_linear_memory(false); config } diff --git a/src/wasm_runtime/src/component.rs b/src/wasm_runtime/src/component.rs index 1b12c60..c14f8cb 100644 --- a/src/wasm_runtime/src/component.rs +++ b/src/wasm_runtime/src/component.rs @@ -102,10 +102,6 @@ pub extern "C" fn hyperlight_main() { platform::register_page_fault_handler(); let mut config = Config::new(); - config.memory_reservation(0); - config.memory_guard_size(0); - config.memory_reservation_for_growth(0); - config.guard_before_linear_memory(false); config.with_custom_code_memory(Some(alloc::sync::Arc::new(platform::WasmtimeCodeMemory {}))); let engine = Engine::new(&config).unwrap(); let linker = Linker::new(&engine); diff --git a/src/wasm_runtime/src/module.rs b/src/wasm_runtime/src/module.rs index c5bb1b8..c9aec48 100644 --- a/src/wasm_runtime/src/module.rs +++ b/src/wasm_runtime/src/module.rs @@ -89,10 +89,6 @@ pub fn guest_dispatch_function(function_call: &FunctionCall) -> Result> fn init_wasm_runtime() -> Result> { let mut config = Config::new(); - config.memory_reservation(0); - config.memory_guard_size(0); - config.memory_reservation_for_growth(0); - config.guard_before_linear_memory(false); config.with_custom_code_memory(Some(alloc::sync::Arc::new(platform::WasmtimeCodeMemory {}))); let engine = Engine::new(&config)?; let mut linker = Linker::new(&engine); diff --git a/src/wasm_runtime/src/platform.rs b/src/wasm_runtime/src/platform.rs index f378877..df15ede 100644 --- a/src/wasm_runtime/src/platform.rs +++ b/src/wasm_runtime/src/platform.rs @@ -14,41 +14,91 @@ See the License for the specific language governing permissions and limitations under the License. */ -use alloc::alloc::{alloc, dealloc, Layout}; use core::ffi::c_void; use core::ptr::NonNull; use core::sync::atomic::{AtomicPtr, AtomicU64, Ordering}; use hyperlight_guest_bin::exceptions::handler; +use hyperlight_guest_bin::paging; + +// Extremely stupid virtual address allocator +// 0x1_0000_0000 is where the module is +// we start at +// 0x100_0000_0000 and go up from there +static FIRST_VADDR: AtomicU64 = AtomicU64::new(0x100_0000_0000u64); +fn page_fault_handler( + _exception_number: u64, + info: *mut handler::ExceptionInfo, + _ctx: *mut handler::Context, + page_fault_address: u64, +) -> bool { + let error_code = unsafe { (&raw const (*info).error_code).read_volatile() }; + // TODO: check if this is a guard-region trap (which can't happen + // right now since we don't actually set the permissions properly + // in mprotect) + + // TODO: replace this with some generic virtual memory area data + // structure in hyperlight core + if (error_code & 0x1) == 0x0 && page_fault_address >= 0x100_0000_0000u64 { + unsafe { + let phys_page = paging::alloc_phys_pages(1); + let virt_base = (page_fault_address & !0xFFF) as *mut u8; + paging::map_region( + phys_page, + virt_base, + hyperlight_guest_bin::OS_PAGE_SIZE as u64, + ); + virt_base.write_bytes(0u8, hyperlight_guest_bin::OS_PAGE_SIZE as usize); + } + return true; // Try again! + } + false +} +pub(crate) fn register_page_fault_handler() { + // On amd64, vector 14 is #PF + // See AMD64 Architecture Programmer's Manual, Volume 2 + // §8.2 Vectors, p. 245 + // Table 8-1: Interrupt Vector Source and Cause + handler::handlers[14].store(page_fault_handler as usize as u64, Ordering::Release); +} // Wasmtime Embedding Interface -/* We don't have proper support for lazy committing an mmap region, or - * for setting up guard pages, because the guest doesn't have an * - * appropriate interrupt handler yet. Consequently, we configure - * wasmtime not to use any guard region, and precommit memory. */ +/* We don't actually have any sensible virtual memory areas, so + * we just give out virtual addresses very coarsely with + * probably-more-than-enough space between them, and take over + * page-fault handling to hardcoded check if memory is in this region + * (see above) */ #[no_mangle] -pub extern "C" fn wasmtime_mmap_new(size: usize, _prot_flags: u32, ret: &mut *mut u8) -> i32 { - *ret = unsafe { alloc(Layout::from_size_align(size, 0x1000).unwrap()) }; +pub extern "C" fn wasmtime_mmap_new(_size: usize, _prot_flags: u32, ret: &mut *mut u8) -> i32 { + if _size > 0x100_0000_0000 { + panic!("wasmtime_mmap_{:x} {:x}", _size, _prot_flags); + } + *ret = FIRST_VADDR.fetch_add(0x100_0000_0000, Ordering::Relaxed) as *mut u8; 0 } -/* Because of the precommitted memory strategy, we can't generally - * support remap */ +/* Remap is only used for changing the region size (which is presently + * a no-op, since we just hand out very large regions and treat them all + * the same), or possibly for changing permissions, which will be a no-op + * as we don't properly implement permissions at the moment. */ #[no_mangle] pub extern "C" fn wasmtime_mmap_remap(addr: *mut u8, size: usize, prot_flags: u32) -> i32 { - panic!( - "wasmtime_mmap_remap {:x} {:x} {:x}", - addr as usize, size, prot_flags - ); + if size > 0x100_0000_0000 { + panic!( + "wasmtime_mmap_remap {:x} {:x} {:x}", + addr as usize, size, prot_flags + ); + } + 0 } #[no_mangle] -pub extern "C" fn wasmtime_munmap(ptr: *mut u8, size: usize) -> i32 { - unsafe { dealloc(ptr, Layout::from_size_align(size, 0x1000).unwrap()) }; +pub extern "C" fn wasmtime_munmap(_ptr: *mut u8, _size: usize) -> i32 { 0 } +/* TODO: implement permissions properly */ #[no_mangle] pub extern "C" fn wasmtime_mprotect(_ptr: *mut u8, _size: usize, prot_flags: u32) -> i32 { /* currently all memory is allocated RWX; we assume that