Skip to content

Commit 63a051a

Browse files
authored
Merge branch 'main' into devigned-patch-1
2 parents da6c4b7 + 617b158 commit 63a051a

File tree

19 files changed

+163
-332
lines changed

19 files changed

+163
-332
lines changed

.github/workflows/CreateRelease.yml

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ jobs:
8383
[
8484
build-rust-ubuntu,
8585
build-rust-windows,
86-
build-guest-binaries,
8786
benchmarks,
8887
]
8988

@@ -117,20 +116,6 @@ jobs:
117116
echo "HYPERLIGHT_VERSION=$version" >> $GITHUB_ENV
118117
echo "HYPERLIGHT_VERSION=$version"
119118
120-
- name: Download Guest Binaries
121-
uses: actions/download-artifact@v4
122-
with:
123-
name: guest-binaries-${{ env.CONFIG }}
124-
path: ./downloaded-guest-binaries-${{ env.CONFIG }}
125-
126-
- name: Copy Guest Binaries
127-
run: |
128-
cp ./downloaded-guest-binaries-${{ env.CONFIG }}/callbackguest ./src/tests/rust_guests/bin/${{ env.CONFIG }}/callbackguest
129-
cp ./downloaded-guest-binaries-${{ env.CONFIG }}/callbackguest.exe ./src/tests/rust_guests/bin/${{ env.CONFIG }}/callbackguest.exe
130-
cp ./downloaded-guest-binaries-${{ env.CONFIG }}/simpleguest ./src/tests/rust_guests/bin/${{ env.CONFIG }}/simpleguest
131-
cp ./downloaded-guest-binaries-${{ env.CONFIG }}/simpleguest.exe ./src/tests/rust_guests/bin/${{ env.CONFIG }}/simpleguest.exe
132-
cp ./downloaded-guest-binaries-${{ env.CONFIG }}/dummyguest ./src/tests/rust_guests/bin/${{ env.CONFIG }}/dummyguest
133-
134119
- name: Build and archive guest library + header files
135120
run: |
136121
just tar-headers
@@ -159,20 +144,19 @@ jobs:
159144
- name: Extract release notes from changelog
160145
if: ${{ contains(github.ref, 'refs/heads/release/') }}
161146
run: just create-release-notes v${{ env.HYPERLIGHT_VERSION }} > RELEASE_NOTES.md
147+
env:
148+
GH_TOKEN: ${{ github.token }}
162149

163150
- name: Extract prerelease notes from changelog
164151
if: ${{ github.ref=='refs/heads/main' }}
165152
run: just create-release-notes dev-latest > RELEASE_NOTES.md
153+
env:
154+
GH_TOKEN: ${{ github.token }}
166155

167156
- name: Create release
168157
if: ${{ contains(github.ref, 'refs/heads/release/') }}
169158
run: |
170159
gh release create v${{ env.HYPERLIGHT_VERSION }} -t "Release v${{ env.HYPERLIGHT_VERSION }}" --notes-file RELEASE_NOTES.md \
171-
src/tests/rust_guests/bin/${{ env.CONFIG }}/callbackguest \
172-
src/tests/rust_guests/bin/${{ env.CONFIG }}/callbackguest.exe \
173-
src/tests/rust_guests/bin/${{ env.CONFIG }}/simpleguest \
174-
src/tests/rust_guests/bin/${{ env.CONFIG }}/simpleguest.exe \
175-
src/tests/rust_guests/bin/${{ env.CONFIG }}/dummyguest \
176160
benchmarks_Windows_hyperv_amd.tar.gz \
177161
benchmarks_Windows_hyperv_intel.tar.gz \
178162
benchmarks_Linux_kvm_amd.tar.gz \
@@ -192,11 +176,6 @@ jobs:
192176
run: |
193177
gh release delete dev-latest -y --cleanup-tag || true
194178
gh release create dev-latest -t "Latest prerelease from main branch" --notes-file RELEASE_NOTES.md --latest=false -p \
195-
src/tests/rust_guests/bin/${{ env.CONFIG }}/callbackguest \
196-
src/tests/rust_guests/bin/${{ env.CONFIG }}/callbackguest.exe \
197-
src/tests/rust_guests/bin/${{ env.CONFIG }}/simpleguest \
198-
src/tests/rust_guests/bin/${{ env.CONFIG }}/simpleguest.exe \
199-
src/tests/rust_guests/bin/${{ env.CONFIG }}/dummyguest \
200179
benchmarks_Windows_hyperv_amd.tar.gz \
201180
benchmarks_Windows_hyperv_intel.tar.gz \
202181
benchmarks_Linux_kvm_amd.tar.gz \

.github/workflows/ValidatePullRequest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
steps:
6666
- uses: actions/checkout@v4
6767
- name: Spell Check Repo
68-
uses: crate-ci/[email protected].1
68+
uses: crate-ci/[email protected].2
6969

7070
# Gate PR merges on this specific "join-job" which requires all other
7171
# jobs to run first. We need this job since we cannot gate on particular jobs

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,3 +468,6 @@ hyperlight_guest.h
468468
.mono
469469

470470
!.gitkeep
471+
472+
# gdb
473+
.gdbinit

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
55
## [Prerelease] - Unreleased
66

77

8-
## [v0.4.0] - Unreleased
8+
## [v0.4.0] - 2025-04-30
99

1010
### Changed
1111
- Metrics are now emitted using the [metrics](https://crates.io/crates/metrics) crate by @ludfjig in [#361](https://github.com/hyperlight-dev/hyperlight/pull/361)

Cargo.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ exclude = [
2121
]
2222

2323
[workspace.package]
24-
version = "0.3.0"
24+
version = "0.4.0"
2525
edition = "2021"
2626
rust-version = "1.81.0"
2727
license = "Apache-2.0"
@@ -30,9 +30,9 @@ repository = "https://github.com/hyperlight-dev/hyperlight"
3030
readme = "README.md"
3131

3232
[workspace.dependencies]
33-
hyperlight-common = { path = "src/hyperlight_common", version = "0.3.0", default-features = false }
34-
hyperlight-host = { path = "src/hyperlight_host", version = "0.3.0", default-features = false }
35-
hyperlight-guest = { path = "src/hyperlight_guest", version = "0.3.0", default-features = false }
33+
hyperlight-common = { path = "src/hyperlight_common", version = "0.4.0", default-features = false }
34+
hyperlight-host = { path = "src/hyperlight_host", version = "0.4.0", default-features = false }
35+
hyperlight-guest = { path = "src/hyperlight_guest", version = "0.4.0", default-features = false }
3636
hyperlight-testing = { path = "src/hyperlight_testing", default-features = false }
3737

3838
[workspace.lints.rust]

Justfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,22 @@ clean-rust:
6262

6363
# Note: most testing recipes take an optional "features" comma separated list argument. If provided, these will be passed to cargo as **THE ONLY FEATURES**, i.e. default features will be disabled.
6464

65+
# convenience recipe to run all tests with the given target and features (similar to CI)
66+
test-like-ci config=default-target hypervisor="kvm":
67+
@# with default features
68+
just test {{config}} {{ if hypervisor == "mshv3" {"mshv3"} else {""} }}
69+
70+
@# with only one driver enabled + seccomp + inprocess
71+
just test {{config}} inprocess,seccomp,{{ if hypervisor == "mshv" {"mshv2"} else if hypervisor == "mshv3" {"mshv3"} else {"kvm"} }}
72+
73+
@# make sure certain cargo features compile
74+
cargo check -p hyperlight-host --features crashdump
75+
cargo check -p hyperlight-host --features print_debug
76+
cargo check -p hyperlight-host --features gdb
77+
78+
@# without any driver (should fail to compile)
79+
just test-compilation-fail {{config}}
80+
6581
# runs all tests
6682
test target=default-target features="": (test-unit target features) (test-isolated target features) (test-integration "rust" target features) (test-integration "c" target features) (test-seccomp target features)
6783

docs/paging-development-notes.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,35 @@ Hyperlight uses paging, which means the all addresses inside a Hyperlight VM are
99

1010
## Host-to-Guest memory mapping
1111

12-
Into each Hyperlight VM, memory from the host is mapped into the VM as physical memory. The physical memory inside the VM starts at address `0x200_000` and extends linearly to however much memory was mapped into the VM (depends on various parameters).
12+
Into each Hyperlight VM, memory from the host is mapped into the VM as physical memory. The physical memory inside the VM starts at address `0x0` and extends linearly to however much memory was mapped into the VM (depends on various parameters).
1313

1414
## Page table setup
1515

1616
The following page table structs are set up in memory before running a Hyperlight VM (See [Access Flags](#access-flags) for details on access flags that are also set on each entry)
1717

1818
### PML4 (Page Map Level 4) Table
1919

20-
The PML4 table is located at physical address specified in CR3. In Hyperlight we set `CR3=0x200_000`, which means the PML4 table is located at physical address `0x200_000`. The PML4 table comprises 512 64-bit entries.
20+
The PML4 table is located at physical address specified in CR3. In Hyperlight we set `CR3=0x0`, which means the PML4 table is located at physical address `0x0`. The PML4 table comprises 512 64-bit entries.
2121

22-
In Hyperlight, we only initialize the first entry (at address `0x200_000`), with value `0x201_000`, implying that we only have a single PDPT.
22+
In Hyperlight, we only initialize the first entry (at address `0x0`), with value `0x1_000`, implying that we only have a single PDPT.
2323

2424
### PDPT (Page-directory-pointer Table)
2525

26-
The first and only PDPT is located at physical address `0x201_000`. The PDPT comprises 512 64-bit entries. In Hyperlight, we only initialize the first entry of the PDPT (at address `0x201_000`), with the value `0x202_000`, implying that we only have a single PD.
26+
The first and only PDPT is located at physical address `0x1_000`. The PDPT comprises 512 64-bit entries. In Hyperlight, we only initialize the first entry of the PDPT (at address `0x1_000`), with the value `0x2_000`, implying that we only have a single PD.
2727

2828
### PD (Page Directory)
2929

30-
The first and only PD is located at physical address `0x202_000`. The PD comprises 512 64-bit entries, each entry `i` is set to the value `(i * 0x1000) + 0x203_000`. Thus, the first entry is `0x203_000`, the second entry is `0x204_000` and so on.
30+
The first and only PD is located at physical address `0x2_000`. The PD comprises 512 64-bit entries, each entry `i` is set to the value `(i * 0x1000) + 0x3_000`. Thus, the first entry is `0x3_000`, the second entry is `0x4_000` and so on.
3131

3232
### PT (Page Table)
3333

34-
The page tables start at physical address `0x203_000`. Each page table has 512 64-bit entries. Each entry is set to the value `p << 21|i << 12` where `p` is the page table number and `i` is the index of the entry in the page table. Thus, the first entry of the first page table is `0x000_000`, the second entry is `0x000_000 + 0x1000`, and so on. The first entry of the second page table is `0x200_000 + 0x1000`, the second entry is `0x200_000 + 0x2000`, and so on. Enough page tables are created to cover the size of memory mapped into the VM.
34+
The page tables start at physical address `0x3_000`. Each page table has 512 64-bit entries. Each entry is set to the value `p << 21|i << 12` where `p` is the page table number and `i` is the index of the entry in the page table. Thus, the first entry of the first page table is `0x000_000`, the second entry is `0x000_000 + 0x1000`, and so on. The first entry of the second page table is `0x200_000 + 0x1000`, the second entry is `0x200_000 + 0x2000`, and so on. Enough page tables are created to cover the size of memory mapped into the VM.
3535

3636
## Address Translation
3737

3838
Given a 64-bit virtual address X, the corresponding physical address is obtained as follows:
3939

40-
1. PML4 table's physical address is located using CR3 (CR3 is `0x200_000`).
40+
1. PML4 table's physical address is located using CR3 (CR3 is `0x0`).
4141
2. Bits 47:39 of X are used to index into PML4, giving us the address of the PDPT.
4242
3. Bits 38:30 of X are used to index into PDPT, giving us the address of the PD.
4343
4. Bits 29:21 of X are used to index into PD, giving us the address of the PT.
@@ -63,7 +63,7 @@ In addition to providing addresses, page table entries also contain access flags
6363

6464
PML4E, PDPTE, and PD Entries have the present flag set to 1, and the rest of the flags are not set.
6565

66-
PTE Entries all have the present flag set to 1, apart from those for the address range `0x000_000` to `0x1FF_000` which have the present flag set to 0 as we do not map memory below physical address `0x200_000`.
66+
PTE Entries all have the present flag set to 1.
6767

6868
In addition, the following flags are set according to the type of memory being mapped:
6969

src/hyperlight_host/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ proc-maps = "0.4.0"
116116
[build-dependencies]
117117
anyhow = { version = "1.0.98" }
118118
cfg_aliases = "0.2.1"
119-
built = { version = "0.7.7", features = ["chrono", "git2"] }
119+
built = { version = "0.8.0", features = ["chrono", "git2"] }
120120

121121
[features]
122122
default = ["kvm", "mshv2", "seccomp"]

src/hyperlight_host/benches/benchmarks.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ limitations under the License.
1515
*/
1616

1717
use std::sync::{Arc, Mutex};
18+
use std::time::Duration;
1819

1920
use criterion::{criterion_group, criterion_main, Criterion};
2021
use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterValue, ReturnType};
2122
use hyperlight_host::func::HostFunction2;
22-
use hyperlight_host::sandbox::{MultiUseSandbox, UninitializedSandbox};
23+
use hyperlight_host::sandbox::{MultiUseSandbox, SandboxConfiguration, UninitializedSandbox};
2324
use hyperlight_host::sandbox_state::sandbox::EvolvableSandbox;
2425
use hyperlight_host::sandbox_state::transition::Noop;
2526
use hyperlight_host::GuestBinary;
@@ -69,6 +70,40 @@ fn guest_call_benchmark(c: &mut Criterion) {
6970
});
7071
});
7172

73+
// This benchmark includes time to first clone a vector and string, so it is not a "pure' benchmark of the guest call, but it's still useful
74+
group.bench_function("guest_call_with_large_parameters", |b| {
75+
const SIZE: usize = 50 * 1024 * 1024; // 50 MB
76+
let large_vec = vec![0u8; SIZE];
77+
let large_string = unsafe { String::from_utf8_unchecked(large_vec.clone()) }; // Safety: indeed above vec is valid utf8
78+
79+
let mut config = SandboxConfiguration::default();
80+
config.set_input_data_size(2 * SIZE + (1024 * 1024)); // 2 * SIZE + 1 MB, to allow 1MB for the rest of the serialized function call
81+
config.set_heap_size(SIZE as u64 * 15);
82+
config.set_max_execution_time(Duration::from_secs(10));
83+
84+
let sandbox = UninitializedSandbox::new(
85+
GuestBinary::FilePath(simple_guest_as_string().unwrap()),
86+
Some(config),
87+
None,
88+
None,
89+
)
90+
.unwrap();
91+
let mut sandbox = sandbox.evolve(Noop::default()).unwrap();
92+
93+
b.iter(|| {
94+
sandbox
95+
.call_guest_function_by_name(
96+
"LargeParameters",
97+
ReturnType::Void,
98+
Some(vec![
99+
ParameterValue::VecBytes(large_vec.clone()),
100+
ParameterValue::String(large_string.clone()),
101+
]),
102+
)
103+
.unwrap()
104+
});
105+
});
106+
72107
// Benchmarks a guest function call calling into the host.
73108
// The benchmark does **not** include the time to reset the sandbox memory after the call.
74109
group.bench_function("guest_call_with_call_to_host_function", |b| {

0 commit comments

Comments
 (0)