diff --git a/CHANGELOG.md b/CHANGELOG.md index fa70855d7..c095f6de1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). * A new sandbox writes only the guest code, PEB and init data into its memory. The host populates other pages on first guest touch, which speeds up sandbox creation. +* Use `talc` as the guest heap allocator. Guest init writes only the start and + end of the heap, which speeds up sandbox creation. * **Breaking:** The transport arena sits one unmapped guard page below the reserved scratch-top pages, at an address independent of the scratch size, and the page tables at the scratch base. The guest's page allocator stops at the arena GPA the host publishes in the scratch-top metadata, so guests must be rebuilt. `hyperlight_common::layout::scratch_allocator_limit_gpa` is renamed `scratch_reserved_top_gpa`, the start of the reserved pages. An allocator that stops there runs into the arena. The minimum scratch size grows by that guard page. Snapshot ABI 7: existing snapshots must be regenerated. diff --git a/Cargo.lock b/Cargo.lock index f53387d63..474e4096f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,6 +42,12 @@ dependencies = [ "cc", ] +[[package]] +name = "allocator-api2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c880a97d28a3681c0267bd29cff89621202715b065127cd445fa0f0fe0aa2880" + [[package]] name = "android_system_properties" version = "0.1.6" @@ -305,15 +311,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "buddy_system_allocator" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1af5a01adeeade54c9f5060300227a8ee64c05b6376f28e9b8ee3b72dd2056f" -dependencies = [ - "spin 0.10.1", -] - [[package]] name = "built" version = "0.8.1" @@ -1708,7 +1705,7 @@ dependencies = [ "quickcheck", "rand 0.10.3", "smallvec", - "spin 0.12.3", + "spin", "thiserror", "tracing", "tracing-core", @@ -1770,7 +1767,6 @@ dependencies = [ name = "hyperlight-guest-bin" version = "0.18.0" dependencies = [ - "buddy_system_allocator", "flatbuffers", "hyperlight-common", "hyperlight-guest", @@ -1779,7 +1775,8 @@ dependencies = [ "hyperlight-libc", "linkme", "log", - "spin 0.12.3", + "spin", + "talc", "tracing", ] @@ -1798,7 +1795,7 @@ name = "hyperlight-guest-tracing" version = "0.18.0" dependencies = [ "hyperlight-common", - "spin 0.12.3", + "spin", "tracing", "tracing-core", ] @@ -3767,12 +3764,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "spin" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3" - [[package]] name = "spin" version = "0.12.3" @@ -3876,6 +3867,16 @@ dependencies = [ "version-compare", ] +[[package]] +name = "talc" +version = "5.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53f8ad14fa1c1b8635114abf9721076fe1e869572a5f26a52690f407292c80dc" +dependencies = [ + "allocator-api2", + "lock_api", +] + [[package]] name = "target-lexicon" version = "0.13.5" diff --git a/src/hyperlight_guest_bin/Cargo.toml b/src/hyperlight_guest_bin/Cargo.toml index 6c6f86efe..0b9fe2196 100644 --- a/src/hyperlight_guest_bin/Cargo.toml +++ b/src/hyperlight_guest_bin/Cargo.toml @@ -25,7 +25,7 @@ hyperlight-common = { workspace = true, default-features = false } hyperlight-guest-tracing = { workspace = true, default-features = false } hyperlight-guest-macro = { workspace = true, default-features = false, optional = true } hyperlight-libc = { workspace = true, default-features = false, optional = true } -buddy_system_allocator = "0.13.0" +talc = { version = "5.1.1", default-features = false } log = { version = "0.4", default-features = false } linkme = { version = "0.3.36", optional = true } spin = "0.12.0" diff --git a/src/hyperlight_guest_bin/src/lib.rs b/src/hyperlight_guest_bin/src/lib.rs index 7df64cefc..c253fac20 100644 --- a/src/hyperlight_guest_bin/src/lib.rs +++ b/src/hyperlight_guest_bin/src/lib.rs @@ -8,7 +8,6 @@ extern crate alloc; use core::fmt::Write; use arch::dispatch::dispatch_function; -use buddy_system_allocator::LockedHeap; use guest_function::register::GuestFunctionRegister; use guest_logger::init_logger; use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode; @@ -18,6 +17,8 @@ use hyperlight_common::mem::HyperlightPEB; use hyperlight_common::outb::OutBAction; use hyperlight_guest::exit::write_abort; use hyperlight_guest::guest_handle::handle::GuestHandle; +use talc::TalcLock; +use talc::source::Manual; // === Modules === #[cfg_attr(target_arch = "x86_64", path = "arch/amd64/mod.rs")] @@ -50,10 +51,12 @@ mod init; pub use hyperlight_libc as libc; // Globals +type GuestHeap = TalcLock, Manual>; + #[cfg(all(feature = "mem_profile", target_arch = "x86_64"))] -struct ProfiledLockedHeap(LockedHeap); +struct ProfiledLockedHeap(GuestHeap); #[cfg(all(feature = "mem_profile", target_arch = "x86_64"))] -unsafe impl alloc::alloc::GlobalAlloc for ProfiledLockedHeap { +unsafe impl alloc::alloc::GlobalAlloc for ProfiledLockedHeap { unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 { let addr = unsafe { self.0.alloc(layout) }; unsafe { @@ -107,11 +110,10 @@ unsafe impl alloc::alloc::GlobalAlloc for ProfiledLockedHeap // === Globals === #[cfg(not(all(feature = "mem_profile", target_arch = "x86_64")))] #[global_allocator] -pub(crate) static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::empty(); +pub(crate) static HEAP_ALLOCATOR: GuestHeap = GuestHeap::new(Manual); #[cfg(all(feature = "mem_profile", target_arch = "x86_64"))] #[global_allocator] -pub(crate) static HEAP_ALLOCATOR: ProfiledLockedHeap<32> = - ProfiledLockedHeap(LockedHeap::<32>::empty()); +pub(crate) static HEAP_ALLOCATOR: ProfiledLockedHeap = ProfiledLockedHeap(GuestHeap::new(Manual)); pub static mut GUEST_HANDLE: GuestHandle = GuestHandle::new(); pub(crate) static mut REGISTERED_GUEST_FUNCTIONS: GuestFunctionRegister = @@ -268,10 +270,13 @@ pub(crate) extern "C" fn generic_init( let heap_allocator = &HEAP_ALLOCATOR; #[cfg(all(feature = "mem_profile", target_arch = "x86_64"))] let heap_allocator = &HEAP_ALLOCATOR.0; + // SAFETY: the host reserves the PEB heap range for the guest heap, and + // init claims it once. Only this allocator writes to it. heap_allocator .try_lock() .expect("Failed to access HEAP_ALLOCATOR") - .init(heap_start, heap_size); + .claim(heap_start as *mut u8, heap_size) + .expect("Failed to claim guest heap"); peb_ptr }; diff --git a/src/tests/rust_guests/Cargo.lock b/src/tests/rust_guests/Cargo.lock index 14c069827..4d2223cb7 100644 --- a/src/tests/rust_guests/Cargo.lock +++ b/src/tests/rust_guests/Cargo.lock @@ -11,6 +11,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c880a97d28a3681c0267bd29cff89621202715b065127cd445fa0f0fe0aa2880" + [[package]] name = "anstream" version = "1.0.0" @@ -79,15 +85,6 @@ version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" -[[package]] -name = "buddy_system_allocator" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1af5a01adeeade54c9f5060300227a8ee64c05b6376f28e9b8ee3b72dd2056f" -dependencies = [ - "spin 0.10.1", -] - [[package]] name = "bumpalo" version = "3.20.3" @@ -245,7 +242,7 @@ dependencies = [ "flatbuffers", "log", "smallvec", - "spin 0.12.3", + "spin", "thiserror", "tracing-core", ] @@ -296,7 +293,6 @@ dependencies = [ name = "hyperlight-guest-bin" version = "0.18.0" dependencies = [ - "buddy_system_allocator", "flatbuffers", "hyperlight-common", "hyperlight-guest", @@ -304,7 +300,8 @@ dependencies = [ "hyperlight-guest-tracing", "linkme", "log", - "spin 0.12.3", + "spin", + "talc", "tracing", ] @@ -323,7 +320,7 @@ name = "hyperlight-guest-tracing" version = "0.18.0" dependencies = [ "hyperlight-common", - "spin 0.12.3", + "spin", "tracing", "tracing-core", ] @@ -630,12 +627,6 @@ version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" -[[package]] -name = "spin" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3" - [[package]] name = "spin" version = "0.12.3" @@ -667,6 +658,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "talc" +version = "5.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53f8ad14fa1c1b8635114abf9721076fe1e869572a5f26a52690f407292c80dc" +dependencies = [ + "allocator-api2", + "lock_api", +] + [[package]] name = "thiserror" version = "2.0.20" @@ -915,7 +916,7 @@ dependencies = [ "hyperlight-component-macro", "hyperlight-guest", "hyperlight-guest-bin", - "spin 0.12.3", + "spin", ] [[package]]