Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[target.'cfg(target_os = "macos")']
runner = "dev/macos-sign-and-run.sh"
6 changes: 4 additions & 2 deletions .github/workflows/DailyArm64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ jobs:
fail-fast: false
matrix:
config: [debug, release]
hypervisor: [hvf, kvm]
uses: ./.github/workflows/dep_build_test.yml
secrets: inherit
with:
hypervisor: kvm
hypervisor: ${{ matrix.hypervisor }}
cpu_vendor: apple
arch: arm64
config: ${{ matrix.config }}
Expand All @@ -65,10 +66,11 @@ jobs:
fail-fast: false
matrix:
config: [debug, release]
hypervisor: [hvf, kvm]
uses: ./.github/workflows/dep_run_examples.yml
secrets: inherit
with:
hypervisor: kvm
hypervisor: ${{ matrix.hypervisor }}
cpu_vendor: apple
arch: arm64
config: ${{ matrix.config }}
Expand Down
29 changes: 15 additions & 14 deletions .github/workflows/RegenSnapshotGoldens.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ jobs:
strategy:
fail-fast: false
matrix:
hypervisor: [kvm, mshv3, hyperv-ws2025]
hypervisor: [kvm, mshv3, hyperv-ws2025, hvf]
cpu: [amd, intel, apple]
arch: [X64, arm64]
config: [debug, release]
Expand All @@ -148,25 +148,26 @@ jobs:
hypervisor: mshv3
- cpu: apple
hypervisor: hyperv-ws2025
- arch: X64
hypervisor: hvf
- cpu: apple
arch: X64
- cpu: amd
arch: arm64
- cpu: intel
arch: arm64
runs-on: ${{ fromJson(
format('["self-hosted", "{0}", "{1}"{2}]',
matrix.hypervisor == 'hyperv-ws2025' && 'Windows' || 'Linux',
matrix.arch,
matrix.arch == 'X64'
&& format(', "1ES.Pool=hld-{0}-{1}", "JobId=regen-goldens-{2}-{3}-{4}-{5}"',
matrix.hypervisor == 'hyperv-ws2025' && 'win2025' || matrix.hypervisor == 'mshv3' && 'azlinux3-mshv' || matrix.hypervisor,
matrix.cpu,
matrix.config,
github.run_id,
github.run_number,
github.run_attempt)
|| ', "kvm", "ubuntu-24.04"')) }}
runs-on: ${{ fromJson(matrix.arch == 'X64'
&& format('["self-hosted", "{0}", "X64", "1ES.Pool=hld-{1}-{2}", "JobId=regen-goldens-{3}-{4}-{5}-{6}"]',
matrix.hypervisor == 'hyperv-ws2025' && 'Windows' || 'Linux',
matrix.hypervisor == 'hyperv-ws2025' && 'win2025' || matrix.hypervisor == 'mshv3' && 'azlinux3-mshv' || matrix.hypervisor,
matrix.cpu,
matrix.config,
github.run_id,
github.run_number,
github.run_attempt)
|| format('["self-hosted", "{0}", "arm64", "{1}"]',
matrix.hypervisor == 'hvf' && 'macos' || 'Linux',
matrix.hypervisor)) }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/ValidatePullRequest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ jobs:
strategy:
fail-fast: true
matrix:
hypervisor: ['hyperv-ws2025', mshv3, kvm]
hypervisor: ['hyperv-ws2025', mshv3, kvm, hvf]
cpu_vendor: [amd, intel, apple]
arch: [X64, arm64]
config: [debug, release]
Expand All @@ -158,6 +158,8 @@ jobs:
hypervisor: hyperv-ws2025
- cpu_vendor: apple
hypervisor: mshv3
- arch: X64
hypervisor: hvf
- cpu_vendor: amd
arch: arm64
- cpu_vendor: intel
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/dep_build_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ jobs:
github.run_id,
github.run_number,
github.run_attempt)
|| '["self-hosted", "Linux", "arm64", "kvm", "ubuntu-24.04"]') }}
|| format('["self-hosted", "{0}", "arm64", "{1}"]',
inputs.hypervisor == 'hvf' && 'macos' || 'Linux',
inputs.hypervisor)) }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
MSRs, on MSHV and WHP this is not enforced. by @ludfjig in https://github.com/hyperlight-dev/hyperlight/pull/991
* **Breaking:** Filesystem paths are now represented using `PathBuf`. `GuestBinary::FilePath` now stores a `PathBuf` instead of a `String`, and `MultiUseSandbox::generate_crashdump_to_dir` accepts `Into<PathBuf>` instead of `Into<String>`. Callers passing a `String` to `GuestBinary::FilePath` must convert it using `.into()`.

Certain fixed guest addresses were changed on AArch64 to more easily
accommodate 16k pages without wasting memory. Snapshots taken from
sandboxes using the old addresses will not be loadable by new
hyperlight versions.

Comment thread
jsturtevant marked this conversation as resolved.
### Removed

### Fixed
Expand Down
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ snapshot-goldens-pull target=default-target which="all" image=default-snapshot-g
if [[ -e /dev/mshv ]]; then hv=mshv
elif [[ -e /dev/kvm ]]; then hv=kvm
elif [[ "${OS:-}" == "Windows_NT" ]]; then hv=whp
elif [[ "$(sysctl -n kern.hv_support)" == "1" ]]; then hv=hvf
else echo "snapshot-goldens-pull: no hypervisor found" >&2; exit 1
fi
# Mirror of `CpuVendor::golden_tag` in file/config.rs. x86_64 reads
Expand Down
8 changes: 8 additions & 0 deletions dev/macos-entitlements.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.hypervisor</key>
<true/>
</dict>
</plist>
6 changes: 6 additions & 0 deletions dev/macos-sign-and-run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -Eeuo pipefail


codesign -f -s - --entitlements "$(dirname "$0")/macos-entitlements.plist" "$1"
exec "$@"
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 18 additions & 16 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
orig = super.rustChannelOf args;
patchRustPkg = pkg: (pkg.overrideAttrs (oA: {
buildCommand = (builtins.replaceStrings
[ "rustc,rustdoc" ]
[ "rustc,rustdoc,clippy-driver,cargo-clippy,miri,cargo-miri" ]
[ "rustc,rustdoc" "librustc_driver-*.so" ]
[ "rustc,rustdoc,clippy-driver,cargo-clippy,miri,cargo-miri" "librustc_driver-*.{so,dylib}" ]
oA.buildCommand) + (let
wrapperPath = self.path + "/pkgs/build-support/bintools-wrapper/ld-wrapper.sh";
baseOut = self.clangStdenv.cc.bintools.out;
Expand Down Expand Up @@ -51,7 +51,7 @@
toolchainVersionAttrs = args;
};
})) // {
targetPlatforms = [ "aarch64-linux" "x86_64-linux" ];
targetPlatforms = [ "aarch64-linux" "x86_64-linux" "aarch64-darwin" ];
badTargetPlatforms = [ ];
};
overrideRustPkg = pkg: self.lib.makeOverridable (origArgs:
Expand Down Expand Up @@ -82,7 +82,7 @@
"x86_64-unknown-linux-gnu"
"x86_64-pc-windows-msvc" "x86_64-unknown-none"
"wasm32-wasip1" "wasm32-wasip2" "wasm32-unknown-unknown"
"aarch64-unknown-none"
"aarch64-unknown-none" "aarch64-apple-darwin"
];
extensions = [ "rust-src" ] ++ (if args.channel == "nightly" then [ "miri-preview" ] else []);
});
Expand Down Expand Up @@ -166,13 +166,14 @@
esac
if [ -f ''${root}/flake.nix ]; then

mkdir -p $root/$.cargo
cat >$root/.cargo/config.toml <<EOF
[source.crates-io]
replace-with = "vendored-sources"
sed -i '/# vendor dependency configuration generated by nix/{N;N;N;N;N;d;}' $root/.cargo/config.toml
cat >>$root/.cargo/config.toml <<EOF
# vendor dependency configuration generated by nix
[source.crates-io]
replace-with = "vendored-sources"

[source.vendored-sources]
directory = "${deps}"
[source.vendored-sources]
directory = "${deps}"
EOF

sed -i '/# vendor dependency configuration generated by nix/{N;d;}' $root/.git/info/exclude
Expand Down Expand Up @@ -228,14 +229,14 @@

cargo-hyperlight = buildRustPackageClang rec {
pname = "cargo-hyperlight";
version = "0.1.5";
version = "0.1.14-pre";
src = fetchFromGitHub {
owner = "hyperlight-dev";
repo = "cargo-hyperlight";
rev = "28ac7b57e8e7b83f80bd601f1fab334aa3ae6d4a";
hash = "sha256-a/mvPEDJycrCbmd826SmFdasE8BFtMkCsefCNR5JnkM=";
rev = "33384c0c4ed9dea4f0525943809fc444c41a27df";
hash = "sha256-A2/SNHCdPPzW86bd00IucZEyZHZWDqXVKPccZULcEu0=";
};
cargoHash = "sha256-wLapaao8qcB/toltV/xjQ7SXXcfh2J19nw6jWljmb2s=";
cargoHash = "sha256-ImWnNzXvDKokML0BDyyjifrZ1bnG6ymXt5vAMRIpwUY==";
doCheck = false;
};
in (buildRustPackageClang (mkDerivationAttrs: {
Expand All @@ -251,7 +252,6 @@
llvmPackages_18.llvm
gh
lld
valgrind
pkg-config
ffmpeg
mkvtoolnix
Expand All @@ -264,7 +264,9 @@
typos
flatbuffers
cargo-fuzz
];
] ++ (if system == "x86_64-linux" || system == "aarch64-linux"
then [ valgrind ]
else []);
buildInputs = [
pango
cairo
Expand Down
100 changes: 100 additions & 0 deletions src/hyperlight_common/src/arch/aarch64/exn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
Copyright 2026 The Hyperlight Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

use crate::vmem::bits;

const ESR_EC_DATA_ABORT_LOWER_EL: u64 = 0b100100;
const ESR_EC_DATA_ABORT_SAME_EL: u64 = 0b100101;

// some of the data in these is not used presently, but is logically
// part of the code being decoded & should be accounted for
#[allow(dead_code)]
#[derive(Debug, Copy, Clone)]
pub enum DataFaultKind {
TranslationFault(i64),
PermissionFault(i64),
Other(u64),
}
fn decode_data_fault_status_code(dfsc: u64) -> DataFaultKind {
if bits::<5, 2>(dfsc) == 0b0011 {
DataFaultKind::PermissionFault(bits::<1, 0>(dfsc) as i64)
} else if bits::<5, 2>(dfsc) == 0b0001 {
DataFaultKind::TranslationFault(bits::<1, 0>(dfsc) as i64)
} else if bits::<5, 2>(dfsc) == 0b1010 {
if bits::<1, 0>(dfsc) >= 2 {
DataFaultKind::TranslationFault(bits::<1, 0>(dfsc) as i64 - 4)
} else {
DataFaultKind::Other(dfsc)
}
} else {
DataFaultKind::Other(dfsc)
}
}

#[derive(Debug, Copy, Clone)]
pub struct DataFaultInstructionSyndrome {
pub srt: u8,
// ...
}
fn decode_data_fault_instruction_syndrome(iss: u64) -> Option<DataFaultInstructionSyndrome> {
let isv = bits::<24, 24>(iss);
if isv != 0b1 {
return None;
}
Some(DataFaultInstructionSyndrome {
srt: bits::<20, 16>(iss) as u8,
})
}

#[derive(Debug, Copy, Clone)]
pub struct DataFault {
pub from_lower_el: bool,
pub is_s1ptw: bool,
pub is_write: bool,
pub kind: DataFaultKind,
pub insn: Option<DataFaultInstructionSyndrome>,
}

fn decode_data_fault(from_lower_el: bool, iss: u64) -> DataFault {
DataFault {
from_lower_el,
is_s1ptw: bits::<7, 7>(iss) == 0b1,
is_write: bits::<6, 6>(iss) == 0b1,
kind: decode_data_fault_status_code(bits::<5, 0>(iss)),
insn: decode_data_fault_instruction_syndrome(iss),
}
}

// some of the data in these is not used presently, but is logically
// part of the code being decoded & should be accounted for
#[allow(dead_code)]
#[derive(Debug, Copy, Clone)]
pub enum Exception {
/// lower el?, faulting address, status code
DataFault(DataFault),
Other(u64),
}
/// Decode the value of ESR_ELx into a nice enum. Also takes FAR_ELx,
/// which will be embedded in the structure if relevant.
pub fn decode_syndrome(esr: u64) -> Exception {
let ec = bits::<31, 26>(esr);
match ec {
ESR_EC_DATA_ABORT_LOWER_EL | ESR_EC_DATA_ABORT_SAME_EL => Exception::DataFault(
decode_data_fault(ec == ESR_EC_DATA_ABORT_LOWER_EL, bits::<24, 0>(esr)),
),
_ => Exception::Other(esr),
}
}
2 changes: 1 addition & 1 deletion src/hyperlight_common/src/arch/aarch64/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ limitations under the License.
pub const SCRATCH_TOP_GVA: usize = 0x0000_ffff_ffff_dfff;
pub const SNAPSHOT_PT_GVA_MIN: usize = 0x0000_8000_0000_0000;
pub const SNAPSHOT_PT_GVA_MAX: usize = 0x0000_80ff_ffff_ffff;
pub const SCRATCH_TOP_GPA: usize = 0x0000_000f_ffff_efff;
pub const SCRATCH_TOP_GPA: usize = 0x0000_000f_ffff_bfff;

pub const IO_PAGE_GVA: u64 = 0x0000_ffff_ffff_e000;
pub const IO_PAGE_GPA: u64 = 0x0000_000f_ffff_f000;
Expand Down
7 changes: 7 additions & 0 deletions src/hyperlight_common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,10 @@ pub mod version_note;

/// cbindgen:ignore
pub mod virtq;

/// cbindgen:ignore
pub mod arch {
#[cfg(target_arch = "aarch64")]
#[path = "aarch64/exn.rs"]
pub mod exn;
}
4 changes: 0 additions & 4 deletions src/hyperlight_common/src/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

pub const PAGE_SHIFT: u64 = 12;
pub const PAGE_SIZE: u64 = 1 << 12;
pub const PAGE_SIZE_USIZE: usize = 1 << 12;

/// A memory region in the guest address space
#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
#[repr(C)]
Expand Down
Loading
Loading