Skip to content

Commit 66e7f0b

Browse files
authored
Merge branch 'main' into update-windows-crates
2 parents f3f4217 + 003bc16 commit 66e7f0b

File tree

16 files changed

+56
-448
lines changed

16 files changed

+56
-448
lines changed

docs/glossary.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ This is an application that consumes the Hyperlight library, in order to execute
2222

2323
## Host
2424

25-
Host is the machine on which the [host application](#host-application) is are running. A host could be a bare metal or virtual machine, when the host is a virtual machine, the nested virtualization is required to run Hyperlight.
25+
Host is the machine on which the [host application](#host-application) is running. A host could be a bare metal or virtual machine, when the host is a virtual machine, the nested virtualization is required to run Hyperlight.
2626

2727
## Hypervisor
2828

@@ -46,7 +46,7 @@ MSHV stands for Microsoft Hypervisor and is the name commonly used for Hyper-V w
4646

4747
## Guest
4848

49-
A guest is a standalone executable binary that is executed inside a hypervisor [micro virtual machine](#micro-virtual-machine). By having purpose-fit guests binaries, as opposed to running a full operating system, is how Hyperlight achieves low-latency startup times of workloads, since it doesn't need to first boot an entire operating system before executing the workload.
49+
A guest is a standalone executable binary that is executed inside a hypervisor [micro virtual machine](#micro-virtual-machine). By having purpose-fit guests binaries, as opposed to running a full operating system, Hyperlight achieves low-latency startup times of workloads, since it doesn't need to first boot an entire operating system before executing the workload.
5050

5151
The interface that a guest must implement is specific to the associated [host](#host) and the type of workloads that it may be specialized for executing, such as WebAssembly Modules (Wasm), or a specific language.
5252

docs/security.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ A primary goal of Hyperlight is to safely execute untrusted or unsafe code.
44

55
## Threat Model
66

7-
Hyperlight assumes that guest binaries are untrusted, and are running arbitrary, potentially malicious code. Despite this, the host should never be compromised. This documents outlines some of the steps Hyperlight takes to uphold this strong security guarantee.
7+
Hyperlight assumes that guest binaries are untrusted, and are running arbitrary, potentially malicious code. Despite this, the host should never be compromised. This document outlines some of the steps Hyperlight takes to uphold this strong security guarantee.
88

99
### Hypervisor Isolation
1010

11-
Hyperlight runs all guest code inside a Virtual Machine, Each VM only has access to a very specific, small (by default) pre-allocated memory buffer in the host's process, no dynamic memory allocations are allowed. As a result, any attempt by the guest to read or write to memory anywhere outside of that particular buffer is caught by the hypervisor. Similarly, the guest VM does not have any access to devices since non are provided by the hyperlight host library, therefore there is no file, network, etc. access available to guest code.
11+
Hyperlight runs all guest code inside a Virtual Machine, Each VM only has access to a very specific, small (by default) pre-allocated memory buffer in the host's process, no dynamic memory allocations are allowed. As a result, any attempt by the guest to read or write to memory anywhere outside of that particular buffer is caught by the hypervisor. Similarly, the guest VM does not have any access to devices since none are provided by the hyperlight host library, therefore there is no file, network, etc. access available to guest code.
1212

1313
### Host-Guest Communication (Serialization and Deserialization)
1414

src/hyperlight_host/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ hyperlight-common = { workspace = true, default-features = true }
4242
vmm-sys-util = "0.12.1"
4343
crossbeam = "0.8.0"
4444
crossbeam-channel = "0.5.14"
45-
thiserror = "2.0.10"
45+
thiserror = "2.0.11"
4646
prometheus = "0.13.3"
4747
strum = { version = "0.26", features = ["derive"] }
4848
tempfile = { version = "3.15", optional = true }
@@ -96,7 +96,7 @@ opentelemetry = "0.27.0"
9696
opentelemetry-otlp = { version = "0.27.0", features = ["default"] }
9797
opentelemetry-semantic-conventions = "0.27.0"
9898
opentelemetry_sdk = { version = "0.27.0", features = ["rt-tokio"] }
99-
tokio = { version = "1.42.0", features = ["full"] }
99+
tokio = { version = "1.43.0", features = ["full"] }
100100
criterion = "0.5.1"
101101
tracing-chrome = "0.7.2"
102102

src/hyperlight_host/examples/chrome-tracing/main.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ fn main() -> Result<()> {
3636
let usandbox =
3737
UninitializedSandbox::new(GuestBinary::FilePath(simple_guest_path), None, None, None)?;
3838

39-
// NOTE: if replacing MultiUseSandbox with SingleUseSandbox, the function call will take ~50x longer because the drop
40-
// happens inside `call_guest_function_by_name` rather than at the end of of this `main` block.
41-
4239
let mut sbox = usandbox
4340
.evolve(Noop::<UninitializedSandbox, MultiUseSandbox>::default())
4441
.unwrap();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
set -Eeuo pipefail
3+
kernel_version=$(uname -r)
4+
if [[ "$kernel_version" == 6.* ]]; then
5+
if [[ $(cat /sys/devices/system/cpu/vulnerabilities/itlb_multihit) == "Not affected" ]]; then
6+
KVM_VENDOR_MOD=$(lsmod |grep -P "^kvm_(amd|intel)" | awk '{print $1}')
7+
sudo modprobe -r $KVM_VENDOR_MOD kvm
8+
sudo modprobe kvm nx_huge_pages=never
9+
sudo modprobe $KVM_VENDOR_MOD
10+
fi
11+
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
12+
sudo mount -o remount,favordynmods /sys/fs/cgroup
13+
fi
14+
fi

src/hyperlight_host/src/func/call_ctx.rs

Lines changed: 2 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use hyperlight_common::flatbuffer_wrappers::function_types::{
2020
use tracing::{instrument, Span};
2121

2222
use super::guest_dispatch::call_function_on_guest;
23-
use crate::{MultiUseSandbox, Result, SingleUseSandbox};
23+
use crate::{MultiUseSandbox, Result};
2424
/// A context for calling guest functions.
2525
///
2626
/// Takes ownership of an existing `MultiUseSandbox`.
@@ -99,100 +99,6 @@ impl MultiUseGuestCallContext {
9999
}
100100
}
101101

102-
/// A context for calling guest functions. Can only be created from an existing
103-
/// `SingleUseSandbox`, and once created, guest functions against that sandbox
104-
/// can be made from this until it is dropped.
105-
#[derive(Debug)]
106-
pub struct SingleUseGuestCallContext {
107-
sbox: SingleUseSandbox,
108-
}
109-
110-
impl SingleUseGuestCallContext {
111-
/// Take ownership of a `SingleUseSandbox` and
112-
/// return a new `SingleUseGuestCallContext` instance.
113-
///
114-
#[instrument(skip_all, parent = Span::current())]
115-
pub(crate) fn start(sbox: SingleUseSandbox) -> Self {
116-
Self { sbox }
117-
}
118-
119-
/// Call the guest function called `func_name` with the given arguments
120-
/// `args`, and expect the return value have the same type as
121-
/// `func_ret_type`.
122-
///
123-
/// Once the call is complete, the 'SingleUseSandbox' will no longer be useable and a new one will need to be created.
124-
///
125-
/// Rather than call this method directly, consider using the `call_guest_function_by_name` method on the `SingleUseSandbox`
126-
127-
#[instrument(err(Debug),skip(self, args),parent = Span::current())]
128-
pub(crate) fn call(
129-
mut self,
130-
func_name: &str,
131-
func_ret_type: ReturnType,
132-
args: Option<Vec<ParameterValue>>,
133-
) -> Result<ReturnValue> {
134-
self.call_internal(func_name, func_ret_type, args)
135-
}
136-
137-
// Internal call function that takes a mutable reference to self
138-
// This function allows a SingleUseMultiGuestCallContext to be used to make multiple calls to guest functions
139-
// before it is no longer usable.
140-
#[instrument(skip_all, parent = Span::current())]
141-
fn call_internal(
142-
&mut self,
143-
func_name: &str,
144-
func_ret_type: ReturnType,
145-
args: Option<Vec<ParameterValue>>,
146-
) -> Result<ReturnValue> {
147-
// We are guaranteed to be holding a lock now, since `self` can't
148-
// exist without doing so. since GuestCallContext is effectively
149-
// !Send (and !Sync), we also don't need to worry about
150-
// synchronization
151-
152-
call_function_on_guest(&mut self.sbox, func_name, func_ret_type, args)
153-
}
154-
155-
/// This function allows for a `SingleUseSandbox` to be used to make multiple calls to guest functions before it is dropped.
156-
///
157-
/// The function is passed a callback function that it then callsd with a reference to a 'SingleUseMultiGuestCallContext'
158-
/// that can be used to make multiple calls to guest functions.
159-
///
160-
pub fn call_from_func<
161-
Fn: FnOnce(&mut SingleUseMultiGuestCallContext) -> Result<ReturnValue>,
162-
>(
163-
self,
164-
f: Fn,
165-
) -> Result<ReturnValue> {
166-
let mut ctx = SingleUseMultiGuestCallContext::new(self);
167-
f(&mut ctx)
168-
}
169-
}
170-
171-
/// A context for making multiple calls to guest functions in a SingleUseSandbox. Can only be created
172-
/// from an existing SingleUseGuestCallContext using the `call_using_closure` method.
173-
/// Once created, calls to guest functions may be made through this context until it is dropped.
174-
/// Once dropped the underlying `SingleUseGuestCallContext` and associated `SingleUseSandbox` will be dropped
175-
pub struct SingleUseMultiGuestCallContext {
176-
call_context: SingleUseGuestCallContext,
177-
}
178-
179-
impl SingleUseMultiGuestCallContext {
180-
fn new(call_context: SingleUseGuestCallContext) -> Self {
181-
Self { call_context }
182-
}
183-
184-
/// Call the guest function called `func_name` with the given arguments
185-
pub fn call(
186-
&mut self,
187-
func_name: &str,
188-
func_ret_type: ReturnType,
189-
args: Option<Vec<ParameterValue>>,
190-
) -> Result<ReturnValue> {
191-
self.call_context
192-
.call_internal(func_name, func_ret_type, args)
193-
}
194-
}
195-
196102
#[cfg(test)]
197103
mod tests {
198104
use std::sync::mpsc::sync_channel;
@@ -203,13 +109,9 @@ mod tests {
203109
};
204110
use hyperlight_testing::simple_guest_as_string;
205111

206-
use crate::func::call_ctx::SingleUseMultiGuestCallContext;
207112
use crate::sandbox_state::sandbox::EvolvableSandbox;
208113
use crate::sandbox_state::transition::Noop;
209-
use crate::{
210-
GuestBinary, HyperlightError, MultiUseSandbox, Result, SingleUseSandbox,
211-
UninitializedSandbox,
212-
};
114+
use crate::{GuestBinary, HyperlightError, MultiUseSandbox, Result, UninitializedSandbox};
213115

214116
fn new_uninit() -> Result<UninitializedSandbox> {
215117
let path = simple_guest_as_string().map_err(|e| {
@@ -218,68 +120,6 @@ mod tests {
218120
UninitializedSandbox::new(GuestBinary::FilePath(path), None, None, None)
219121
}
220122

221-
/// Test to create a `SingleUseSandbox`, then call several guest
222-
/// functions sequentially.
223-
#[test]
224-
fn singleusesandbox_single_call() {
225-
let calls = [
226-
(
227-
"StackAllocate",
228-
ReturnType::Int,
229-
Some(vec![ParameterValue::Int(1)]),
230-
ReturnValue::Int(1),
231-
),
232-
(
233-
"CallMalloc",
234-
ReturnType::Int,
235-
Some(vec![ParameterValue::Int(200)]),
236-
ReturnValue::Int(200),
237-
),
238-
];
239-
240-
for call in calls.iter() {
241-
let sbox: SingleUseSandbox = new_uninit().unwrap().evolve(Noop::default()).unwrap();
242-
let ctx = sbox.new_call_context();
243-
let res = ctx.call(call.0, call.1, call.2.clone()).unwrap();
244-
assert_eq!(call.3, res);
245-
}
246-
}
247-
248-
#[test]
249-
fn singleusesandbox_multi_call() {
250-
let calls = [
251-
(
252-
"StackAllocate",
253-
ReturnType::Int,
254-
Some(vec![ParameterValue::Int(1)]),
255-
ReturnValue::Int(1),
256-
),
257-
(
258-
"CallMalloc",
259-
ReturnType::Int,
260-
Some(vec![ParameterValue::Int(200)]),
261-
ReturnValue::Int(200),
262-
),
263-
];
264-
265-
let sbox: SingleUseSandbox = new_uninit().unwrap().evolve(Noop::default()).unwrap();
266-
let ctx = sbox.new_call_context();
267-
268-
let callback_closure = |ctx: &mut SingleUseMultiGuestCallContext| {
269-
let mut res: ReturnValue = ReturnValue::Int(0);
270-
for call in calls.iter() {
271-
res = ctx
272-
.call(call.0, call.1, call.2.clone())
273-
.expect("failed to call guest function");
274-
assert_eq!(call.3, res);
275-
}
276-
Ok(res)
277-
};
278-
279-
let res = ctx.call_from_func(callback_closure).unwrap();
280-
assert_eq!(calls.last().unwrap().3, res);
281-
}
282-
283123
/// Test to create a `MultiUseSandbox`, then call several guest functions
284124
/// on it across different threads.
285125
///

src/hyperlight_host/src/func/guest_dispatch.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,13 @@ mod tests {
111111
use hyperlight_testing::{callback_guest_as_string, simple_guest_as_string};
112112

113113
use super::*;
114-
use crate::func::call_ctx::{MultiUseGuestCallContext, SingleUseGuestCallContext};
114+
use crate::func::call_ctx::MultiUseGuestCallContext;
115115
use crate::func::host_functions::HostFunction0;
116116
use crate::sandbox::is_hypervisor_present;
117117
use crate::sandbox::uninitialized::GuestBinary;
118118
use crate::sandbox_state::sandbox::EvolvableSandbox;
119119
use crate::sandbox_state::transition::Noop;
120-
use crate::{
121-
new_error, HyperlightError, MultiUseSandbox, Result, SingleUseSandbox, UninitializedSandbox,
122-
};
120+
use crate::{new_error, HyperlightError, MultiUseSandbox, Result, UninitializedSandbox};
123121

124122
// simple function
125123
fn test_function0(_: MultiUseGuestCallContext) -> Result<i32> {
@@ -129,7 +127,7 @@ mod tests {
129127
struct GuestStruct;
130128

131129
// function that return type unsupported by the host
132-
fn test_function1(_: SingleUseGuestCallContext) -> Result<GuestStruct> {
130+
fn test_function1(_: MultiUseGuestCallContext) -> Result<GuestStruct> {
133131
Ok(GuestStruct)
134132
}
135133

@@ -246,7 +244,7 @@ mod tests {
246244
// test_function1
247245
{
248246
let usbox = uninitialized_sandbox();
249-
let sandbox: SingleUseSandbox = usbox
247+
let sandbox: MultiUseSandbox = usbox
250248
.evolve(Noop::default())
251249
.expect("Failed to initialize sandbox");
252250
let result = test_function1(sandbox.new_call_context());

src/hyperlight_host/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,6 @@ pub use sandbox::uninitialized::GuestBinary;
101101
pub use sandbox::MultiUseSandbox;
102102
/// The re-export for the `SandboxRunOptions` type
103103
pub use sandbox::SandboxRunOptions;
104-
/// A sandbox that can be used at most once to call a guest function, and
105-
/// then must be discarded.
106-
pub use sandbox::SingleUseSandbox;
107104
/// The re-export for the `UninitializedSandbox` type
108105
pub use sandbox::UninitializedSandbox;
109106

0 commit comments

Comments
 (0)