diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index d4191b5b2..6006d0ce5 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,6 +1,6 @@ ## Dockerfile for devcontainer -FROM mcr.microsoft.com/devcontainers/base:debian AS base +FROM mcr.microsoft.com/devcontainers/base:bookworm AS base ARG USER=vscode ARG GROUP=vscode @@ -22,7 +22,8 @@ RUN apt-get update \ make \ software-properties-common \ sudo \ - wget + wget \ + musl-tools ARG LLVM_VERSION=18 @@ -54,7 +55,8 @@ ARG RUST_TOOLCHAIN=1.89 RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \ && rustup default ${RUST_TOOLCHAIN} \ && rustup target add x86_64-unknown-linux-gnu \ + && rustup target add x86_64-unknown-linux-musl \ && rustup target add x86_64-unknown-none \ && rustup toolchain add nightly-x86_64-unknown-linux-gnu \ - && cargo install just - + && cargo install just \ + && cargo install cross --locked --version 0.2.5 diff --git a/.github/workflows/Fuzzing.yml b/.github/workflows/Fuzzing.yml index a3c19778a..006afe0b7 100644 --- a/.github/workflows/Fuzzing.yml +++ b/.github/workflows/Fuzzing.yml @@ -28,6 +28,6 @@ jobs: uses: actions/checkout@v5 - name: Notify Fuzzing Failure - run: ./dev/notify-fuzzing-failure.sh "fuzz_host_print,fuzz_guest_call,fuzz_host_call" + run: ./dev/notify-ci-failure.sh --labels="area/fuzzing,kind/bug,area/testing,lifecycle/needs-review,release-blocker" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/RustNightly.yml b/.github/workflows/RustNightly.yml new file mode 100644 index 000000000..71aad6dba --- /dev/null +++ b/.github/workflows/RustNightly.yml @@ -0,0 +1,44 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: Nightly + +on: + workflow_dispatch: + schedule: + # 12:00 AM, every 2 days + - cron: '0 0 */2 * *' + +permissions: + id-token: write + contents: read + +jobs: + musl: + strategy: + fail-fast: true + matrix: + hypervisor: [kvm, mshv3] + cpu: [amd, intel] + config: [debug, release] + uses: ./.github/workflows/dep_rust.yml + secrets: inherit + with: + hypervisor: ${{ matrix.hypervisor }} + cpu: ${{ matrix.cpu }} + config: ${{ matrix.config }} + target_triple: x86_64-unknown-linux-musl + + notify-failure: + runs-on: ubuntu-latest + needs: musl + if: always() && needs.musl.result == 'failure' + permissions: + issues: write + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Notify Nightly Failure + run: ./dev/notify-ci-failure.sh --title="Nightly musl Failure - ${{ github.run_number }}" --labels="area/ci-periodics,area/testing,kind/bug,lifecycle/needs-review,release-blocker" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ValidatePullRequest.yml b/.github/workflows/ValidatePullRequest.yml index e6b07ddac..ccd7a276b 100644 --- a/.github/workflows/ValidatePullRequest.yml +++ b/.github/workflows/ValidatePullRequest.yml @@ -44,10 +44,19 @@ jobs: rust: needs: - docs-pr + strategy: + fail-fast: true + matrix: + hypervisor: [hyperv, 'hyperv-ws2025', mshv, mshv3, kvm] + cpu: [amd, intel] + config: [debug, release] uses: ./.github/workflows/dep_rust.yml secrets: inherit with: docs_only: ${{needs.docs-pr.outputs.docs-only}} + hypervisor: ${{ matrix.hypervisor }} + cpu: ${{ matrix.cpu }} + config: ${{ matrix.config }} fuzzing: needs: @@ -65,7 +74,7 @@ jobs: steps: - uses: actions/checkout@v5 - name: Spell Check Repo - uses: crate-ci/typos@v1.36.2 + uses: crate-ci/typos@v1.37.1 license-headers: name: check license headers diff --git a/.github/workflows/dep_rust.yml b/.github/workflows/dep_rust.yml index ffa79aa8c..a6acefd1c 100644 --- a/.github/workflows/dep_rust.yml +++ b/.github/workflows/dep_rust.yml @@ -11,6 +11,26 @@ on: required: false type: string default: "false" + target_triple: + description: Target triple for cross-compilation + required: false + type: string + default: "" + hypervisor: + description: Hypervisor for this run (passed from caller matrix) + required: false + type: string + default: "kvm" + config: + description: Build configuration for this run (passed from caller matrix) + required: false + type: string + default: "debug" + cpu: + description: CPU architecture for the build (passed from caller matrix) + required: false + type: string + default: "amd" env: CARGO_TERM_COLOR: always @@ -32,17 +52,12 @@ defaults: jobs: code-checks: - if: ${{ inputs.docs_only == 'false' }} + if: ${{ inputs.docs_only == 'false' && (inputs.hypervisor == 'hyperv-ws2025' || inputs.hypervisor == 'kvm') }} timeout-minutes: 60 - strategy: - fail-fast: true - matrix: - hypervisor: ['hyperv-ws2025', kvm] - config: [debug, release] runs-on: ${{ fromJson( format('["self-hosted", "{0}", "X64", "1ES.Pool=hld-{1}-amd"]', - (matrix.hypervisor == 'hyperv-ws2025') && 'Windows' || 'Linux', - matrix.hypervisor == 'hyperv-ws2025' && 'win2025' || 'kvm')) }} + (inputs.hypervisor == 'hyperv-ws2025') && 'Windows' || 'Linux', + inputs.hypervisor == 'hyperv-ws2025' && 'win2025' || 'kvm')) }} steps: - uses: actions/checkout@v5 @@ -63,13 +78,17 @@ jobs: - name: clippy if: ${{ (runner.os == 'Windows' )}} run: | - just clippy ${{ matrix.config }} - just clippy-guests ${{ matrix.config }} + just clippy ${{ inputs.config }} + just clippy-guests ${{ inputs.config }} + env: + TARGET_TRIPLE: ${{ inputs.target_triple }} - name: clippy exhaustive check if: ${{ (runner.os == 'Linux' )}} run: | - just clippy-exhaustive ${{ matrix.config }} + just clippy-exhaustive ${{ inputs.config }} + env: + TARGET_TRIPLE: ${{ inputs.target_triple }} - name: Verify MSRV run: ./dev/verify-msrv.sh hyperlight-host hyperlight-guest hyperlight-guest-bin hyperlight-common @@ -77,18 +96,11 @@ jobs: build: if: ${{ inputs.docs_only == 'false' }} timeout-minutes: 60 - strategy: - fail-fast: true - matrix: - hypervisor: [hyperv, 'hyperv-ws2025', mshv, mshv3, kvm] # hyperv is windows, mshv and kvm are linux - cpu: [amd, intel] - config: [debug, release] - runs-on: ${{ fromJson( format('["self-hosted", "{0}", "X64", "1ES.Pool=hld-{1}-{2}"]', - (matrix.hypervisor == 'hyperv' || matrix.hypervisor == 'hyperv-ws2025') && 'Windows' || 'Linux', - matrix.hypervisor == 'hyperv' && 'win2022' || matrix.hypervisor == 'hyperv-ws2025' && 'win2025' || matrix.hypervisor == 'mshv3' && 'azlinux3-mshv' || matrix.hypervisor, - matrix.cpu)) }} + (inputs.hypervisor == 'hyperv' || inputs.hypervisor == 'hyperv-ws2025') && 'Windows' || 'Linux', + inputs.hypervisor == 'hyperv' && 'win2022' || inputs.hypervisor == 'hyperv-ws2025' && 'win2025' || inputs.hypervisor == 'mshv3' && 'azlinux3-mshv' || inputs.hypervisor, + inputs.cpu)) }} steps: - uses: actions/checkout@v5 @@ -112,35 +124,36 @@ jobs: - name: Build and move Rust guests run: | # use these commands in favor of build-and-move-rust-guests to avoid building both configs - just build-rust-guests ${{ matrix.config }} - just move-rust-guests ${{ matrix.config }} + just build-rust-guests ${{ inputs.config }} + just move-rust-guests ${{ inputs.config }} - name: Build c guests run: | # use these commands in favor of build-and-move-c-guests to avoid building both configs - just build-c-guests ${{ matrix.config }} - just move-c-guests ${{ matrix.config }} + just build-c-guests ${{ inputs.config }} + just move-c-guests ${{ inputs.config }} + - name: Build - run: just build ${{ matrix.config }} + run: just build ${{ inputs.config }} + env: + TARGET_TRIPLE: ${{ inputs.target_triple }} - name: Run Rust tests env: CARGO_TERM_COLOR: always + TARGET_TRIPLE: ${{ inputs.target_triple }} run: | # with default features - just test ${{ matrix.config }} ${{ matrix.hypervisor == 'mshv' && 'mshv2' || ''}} + just test ${{ inputs.config }} ${{ inputs.hypervisor == 'mshv' && 'mshv2' || '""'}} # with only one driver enabled (driver mshv/kvm feature is ignored on windows) + seccomp - just test ${{ matrix.config }} seccomp,${{ matrix.hypervisor == 'mshv' && 'mshv2' || matrix.hypervisor == 'mshv3' && 'mshv3' || 'kvm' }} + just test ${{ inputs.config }} seccomp,${{ inputs.hypervisor == 'mshv' && 'mshv2' || inputs.hypervisor == 'mshv3' && 'mshv3' || 'kvm' }} # make sure certain cargo features compile - cargo check -p hyperlight-host --features crashdump - cargo check -p hyperlight-host --features print_debug - cargo check -p hyperlight-host --features gdb - cargo check -p hyperlight-host --features trace_guest,unwind_guest,mem_profile + just check # without any features - just test-compilation-no-default-features ${{ matrix.config }} + just test-compilation-no-default-features ${{ inputs.config }} # One of the examples is flaky on Windows GH runners, so this allows us to disable it for now - name: Run Rust examples - windows @@ -148,43 +161,48 @@ jobs: env: CARGO_TERM_COLOR: always RUST_LOG: debug - run: just run-rust-examples ${{ matrix.config }} + TARGET_TRIPLE: ${{ inputs.target_triple }} + run: just run-rust-examples ${{ inputs.config }} + - name: Run Rust examples - linux if: ${{ (runner.os != 'Windows') }} env: CARGO_TERM_COLOR: always RUST_LOG: debug - run: just run-rust-examples-linux ${{ matrix.config }} ${{ matrix.hypervisor == 'mshv' && 'mshv2' || ''}} + TARGET_TRIPLE: ${{ inputs.target_triple }} + run: just run-rust-examples-linux ${{ inputs.config }} ${{ inputs.hypervisor == 'mshv' && 'mshv2' || '""'}} - - name: Run Rust Gdb tests - linux - if: runner.os == 'Linux' + - name: Run Rust Gdb tests env: CARGO_TERM_COLOR: always RUST_LOG: debug - run: just test-rust-gdb-debugging ${{ matrix.config }} ${{ matrix.hypervisor == 'mshv' && 'mshv2' || ''}} + TARGET_TRIPLE: ${{ inputs.target_triple }} + run: just test-rust-gdb-debugging ${{ inputs.config }} ${{ inputs.hypervisor == 'mshv' && 'mshv2' || '""'}} - name: Run Rust Crashdump tests env: CARGO_TERM_COLOR: always RUST_LOG: debug - run: just test-rust-crashdump ${{ matrix.config }} ${{ matrix.hypervisor == 'mshv' && 'mshv2' || ''}} + TARGET_TRIPLE: ${{ inputs.target_triple }} + run: just test-rust-crashdump ${{ inputs.config }} ${{ inputs.hypervisor == 'mshv' && 'mshv2' || '""'}} - name: Run Rust Tracing tests - linux if: runner.os == 'Linux' env: CARGO_TERM_COLOR: always RUST_LOG: debug - run: just test-rust-tracing ${{ matrix.config }} ${{ matrix.hypervisor == 'mshv' && 'mshv2' || ''}} + TARGET_TRIPLE: ${{ inputs.target_triple }} + run: just test-rust-tracing ${{ inputs.config }} ${{ inputs.hypervisor == 'mshv' && 'mshv2' || '""'}} - name: Download benchmarks from "latest" - run: just bench-download ${{ runner.os }} ${{ matrix.hypervisor }} ${{ matrix.cpu}} dev-latest # compare to prerelease + run: just bench-download ${{ runner.os }} ${{ inputs.hypervisor }} ${{ inputs.cpu}} dev-latest # compare to prerelease env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} continue-on-error: true - if: ${{ matrix.config == 'release' }} + if: ${{ inputs.config == 'release' && inputs.target_triple == '' }} - name: Run benchmarks run: | - just bench-ci main ${{ matrix.hypervisor == 'mshv' && 'mshv2' || ''}} - if: ${{ matrix.config == 'release' }} + just bench-ci main ${{ inputs.hypervisor == 'mshv' && 'mshv2' || ''}} + if: ${{ inputs.config == 'release' && inputs.target_triple == '' }} diff --git a/.gitignore b/.gitignore index 2abe2940f..dbd55529f 100644 --- a/.gitignore +++ b/.gitignore @@ -472,3 +472,4 @@ hyperlight_guest.h # gdb .gdbinit trace/* +.gdbguest diff --git a/.vscode/settings.json b/.vscode/settings.json index 3d6d12789..f8cea4474 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,10 @@ "Cargo.toml", // guest crates for testing, not part of the workspace "src/tests/rust_guests/simpleguest/Cargo.toml", - ] + ], + // Enable features in rust analyzer here + "rust-analyzer.cargo.features": [ + // "gdb", + // "kvm" + ], } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a774369a4..084090a51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Prerelease] - Unreleased +## [v0.10.0] - 2025-10-02 + +### Fixed + +- Fix error code conversion for Exception enum TryFrom implementation by @vshailesh in https://github.com/hyperlight-dev/hyperlight/pull/869 +- Remove Allocations from Panic Handler by @adamperlin in https://github.com/hyperlight-dev/hyperlight/pull/818 + +### Changed + +- Update rust to 1.89 by @simongdavies in https://github.com/hyperlight-dev/hyperlight/pull/883 +- Update mshv crates for Azure Linux to v0.6.1 (from v0.3.2) by @simongdavies in https://github.com/hyperlight-dev/hyperlight/pull/891 +- Only clear io buffer after unsuccessful guest call by @ludfjig in https://github.com/hyperlight-dev/hyperlight/pull/811 + ## [v0.9.0] - 2025-08-28 ### Fixed @@ -188,7 +201,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). The Initial Hyperlight Release 🎉 -[Prerelease]: +[Prerelease]: +[v0.10.0]: [v0.9.0]: [v0.8.0]: [v0.7.0]: diff --git a/Cargo.lock b/Cargo.lock index 2aad7fd30..2adb00180 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -362,9 +362,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.38" +version = "1.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9" +checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" dependencies = [ "find-msvc-tools", "jobserver", @@ -703,7 +703,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.0", + "windows-sys 0.61.1", ] [[package]] @@ -841,9 +841,9 @@ checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" [[package]] name = "flatbuffers" -version = "25.2.10" +version = "25.9.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1045398c1bfd89168b5fd3f1fc11f6e70b34f6f66300c87d44d3de849463abf1" +checksum = "09b6620799e7340ebd9968d2e0708eb82cf1971e9a16821e2091b6d6e475eed5" dependencies = [ "bitflags 2.9.4", "rustc_version", @@ -921,6 +921,21 @@ dependencies = [ "pe-unwind-info", ] +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -983,6 +998,7 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", "futures-io", "futures-macro", @@ -1328,7 +1344,7 @@ dependencies = [ [[package]] name = "hyperlight-common" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "arbitrary", @@ -1341,7 +1357,7 @@ dependencies = [ [[package]] name = "hyperlight-component-macro" -version = "0.9.0" +version = "0.10.0" dependencies = [ "env_logger", "hyperlight-component-util", @@ -1355,7 +1371,7 @@ dependencies = [ [[package]] name = "hyperlight-component-util" -version = "0.9.0" +version = "0.10.0" dependencies = [ "itertools 0.14.0", "log", @@ -1377,7 +1393,7 @@ dependencies = [ [[package]] name = "hyperlight-guest" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "flatbuffers", @@ -1388,7 +1404,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-bin" -version = "0.9.0" +version = "0.10.0" dependencies = [ "buddy_system_allocator", "cc", @@ -1403,7 +1419,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-tracing" -version = "0.9.0" +version = "0.10.0" dependencies = [ "hyperlight-common", "hyperlight-guest-tracing-macro", @@ -1412,7 +1428,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-tracing-macro" -version = "0.9.0" +version = "0.10.0" dependencies = [ "proc-macro2", "quote", @@ -1421,7 +1437,7 @@ dependencies = [ [[package]] name = "hyperlight-host" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "bitflags 2.9.4", @@ -1470,11 +1486,12 @@ dependencies = [ "seccompiler", "serde", "serde_json", + "serial_test", "sha256", "signal-hook-registry", "tempfile", "termcolor", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", "tracing-chrome", @@ -1487,9 +1504,9 @@ dependencies = [ "tracing-tracy", "uuid", "vmm-sys-util", - "windows 0.62.0", + "windows 0.62.1", "windows-result 0.4.0", - "windows-sys 0.61.0", + "windows-sys 0.61.1", "windows-version", ] @@ -1510,7 +1527,7 @@ dependencies = [ [[package]] name = "hyperlight_guest_capi" -version = "0.9.0" +version = "0.10.0" dependencies = [ "cbindgen", "hyperlight-common", @@ -1802,9 +1819,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.175" +version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" [[package]] name = "libfuzzer-sys" @@ -1927,7 +1944,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb4bdc8b0ce69932332cf76d24af69c3a155242af95c226b2ab6c2e371ed1149" dependencies = [ - "thiserror 2.0.16", + "thiserror 2.0.17", "zerocopy 0.8.26", "zerocopy-derive 0.8.26", ] @@ -1989,7 +2006,7 @@ dependencies = [ "metrics", "metrics-util", "quanta", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -2083,7 +2100,7 @@ checksum = "fdbb879d6a9ca5359ae020c17ebf8587e0be309bf32beae636030e4408c2e481" dependencies = [ "libc", "mshv-bindings 0.6.1", - "thiserror 2.0.16", + "thiserror 2.0.17", "vmm-sys-util", ] @@ -2204,7 +2221,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", ] @@ -2234,7 +2251,7 @@ dependencies = [ "opentelemetry_sdk", "prost", "reqwest", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -2251,9 +2268,9 @@ dependencies = [ [[package]] name = "opentelemetry-semantic-conventions" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d059a296a47436748557a353c5e6c5705b9470ef6c95cfc52c21a8814ddac2" +checksum = "e62e29dfe041afb8ed2a6c9737ab57db4907285d999ef8ad3a59092a36bdc846" [[package]] name = "opentelemetry_sdk" @@ -2268,7 +2285,7 @@ dependencies = [ "percent-encoding", "rand", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", ] @@ -2385,7 +2402,7 @@ checksum = "97f6fccfd2d9d2df765ca23ff85fe5cc437fb0e6d3e164e4d3cbe09d14780c93" dependencies = [ "arrayvec", "bitflags 2.9.4", - "thiserror 2.0.16", + "thiserror 2.0.17", "zerocopy 0.8.26", "zerocopy-derive 0.8.26", ] @@ -2709,9 +2726,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -2825,7 +2842,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -3003,6 +3020,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scc" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc" +dependencies = [ + "sdd", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -3035,6 +3061,12 @@ dependencies = [ "syn", ] +[[package]] +name = "sdd" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" + [[package]] name = "seccompiler" version = "0.5.0" @@ -3052,9 +3084,9 @@ checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] name = "serde" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", "serde_derive", @@ -3062,18 +3094,18 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -3114,6 +3146,31 @@ dependencies = [ "serde", ] +[[package]] +name = "serial_test" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" +dependencies = [ + "futures", + "log", + "once_cell", + "parking_lot", + "scc", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "sha2" version = "0.10.9" @@ -3287,15 +3344,15 @@ checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" [[package]] name = "tempfile" -version = "3.22.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.61.0", + "windows-sys 0.61.1", ] [[package]] @@ -3318,11 +3375,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.17", ] [[package]] @@ -3338,9 +3395,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -3527,7 +3584,7 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "trace_dump" -version = "0.9.0" +version = "0.10.0" dependencies = [ "addr2line 0.25.1", "blake3", @@ -3587,7 +3644,7 @@ dependencies = [ "chrono", "serde", "smallvec", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", "tracing-subscriber", "uuid", @@ -4044,14 +4101,13 @@ dependencies = [ [[package]] name = "windows" -version = "0.62.0" +version = "0.62.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9579d0e6970fd5250aa29aba5994052385ff55cf7b28a059e484bb79ea842e42" +checksum = "49e6c4a1f363c8210c6f77ba24f645c61c6fb941eccf013da691f7e09515b8ac" dependencies = [ - "windows-collections 0.3.0", - "windows-core 0.62.0", - "windows-future 0.3.0", - "windows-link 0.2.0", + "windows-collections 0.3.1", + "windows-core 0.62.1", + "windows-future 0.3.1", "windows-numerics 0.3.0", ] @@ -4066,11 +4122,11 @@ dependencies = [ [[package]] name = "windows-collections" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a90dd7a7b86859ec4cdf864658b311545ef19dbcf17a672b52ab7cefe80c336f" +checksum = "123e712f464a8a60ce1a13f4c446d2d43ab06464cb5842ff68f5c71b6fb7852e" dependencies = [ - "windows-core 0.62.0", + "windows-core 0.62.1", ] [[package]] @@ -4088,9 +4144,9 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.62.0" +version = "0.62.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c" +checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" dependencies = [ "windows-implement", "windows-interface", @@ -4112,20 +4168,20 @@ dependencies = [ [[package]] name = "windows-future" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2194dee901458cb79e1148a4e9aac2b164cc95fa431891e7b296ff0b2f1d8a6" +checksum = "68f3db6b24b120200d649cd4811b4947188ed3a8d2626f7075146c5d178a9a4a" dependencies = [ - "windows-core 0.62.0", + "windows-core 0.62.1", "windows-link 0.2.0", "windows-threading 0.2.0", ] [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" dependencies = [ "proc-macro2", "quote", @@ -4134,9 +4190,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" dependencies = [ "proc-macro2", "quote", @@ -4171,7 +4227,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ce3498fe0aba81e62e477408383196b4b0363db5e0c27646f932676283b43d8" dependencies = [ - "windows-core 0.62.0", + "windows-core 0.62.1", "windows-link 0.2.0", ] @@ -4240,9 +4296,9 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.61.0" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" dependencies = [ "windows-link 0.2.0", ] @@ -4300,9 +4356,9 @@ dependencies = [ [[package]] name = "windows-version" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e061eb0a22b4a1d778ad70f7575ec7845490abb35b08fa320df7895882cacb" +checksum = "700dad7c058606087f6fdc1f88da5841e06da40334413c6cd4367b25ef26d24e" dependencies = [ "windows-link 0.2.0", ] diff --git a/Cargo.toml b/Cargo.toml index dcf5f8f7b..7e8133bcf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ exclude = [ ] [workspace.package] -version = "0.9.0" +version = "0.10.0" edition = "2024" rust-version = "1.88" license = "Apache-2.0" @@ -36,15 +36,15 @@ repository = "https://github.com/hyperlight-dev/hyperlight" readme = "README.md" [workspace.dependencies] -hyperlight-common = { path = "src/hyperlight_common", version = "0.9.0", default-features = false } -hyperlight-host = { path = "src/hyperlight_host", version = "0.9.0", default-features = false } -hyperlight-guest = { path = "src/hyperlight_guest", version = "0.9.0", default-features = false } -hyperlight-guest-bin = { path = "src/hyperlight_guest_bin", version = "0.9.0", default-features = false } +hyperlight-common = { path = "src/hyperlight_common", version = "0.10.0", default-features = false } +hyperlight-host = { path = "src/hyperlight_host", version = "0.10.0", default-features = false } +hyperlight-guest = { path = "src/hyperlight_guest", version = "0.10.0", default-features = false } +hyperlight-guest-bin = { path = "src/hyperlight_guest_bin", version = "0.10.0", default-features = false } hyperlight-testing = { path = "src/hyperlight_testing", default-features = false } -hyperlight-guest-tracing = { path = "src/hyperlight_guest_tracing", version = "0.9.0", default-features = false } -hyperlight-guest-tracing-macro = { path = "src/hyperlight_guest_tracing_macro", version = "0.9.0", default-features = false } -hyperlight-component-util = { path = "src/hyperlight_component_util", version = "0.9.0", default-features = false } -hyperlight-component-macro = { path = "src/hyperlight_component_macro", version = "0.9.0", default-features = false } +hyperlight-guest-tracing = { path = "src/hyperlight_guest_tracing", version = "0.10.0", default-features = false } +hyperlight-guest-tracing-macro = { path = "src/hyperlight_guest_tracing_macro", version = "0.10.0", default-features = false } +hyperlight-component-util = { path = "src/hyperlight_component_util", version = "0.10.0", default-features = false } +hyperlight-component-macro = { path = "src/hyperlight_component_macro", version = "0.10.0", default-features = false } [workspace.lints.rust] unsafe_op_in_unsafe_fn = "deny" diff --git a/Cross.toml b/Cross.toml new file mode 100644 index 000000000..da3c48089 --- /dev/null +++ b/Cross.toml @@ -0,0 +1,14 @@ +[build] +pre-build = [ + "apt-get update && apt-get -y install wget build-essential libgmp-dev libmpfr-dev", + "cd /tmp && curl https://sourceware.org/pub/gdb/releases/gdb-16.3.tar.gz -o /tmp/gdb-16.3.tar.gz", + "cd /tmp && tar -xf gdb-16.3.tar.gz", + "cd /tmp/gdb-16.3 && ./configure --prefix=/usr/local", + "cd /tmp/gdb-16.3 && make -j$(nproc)", + "cd /tmp/gdb-16.3 && make install", +] + +[build.env] +passthrough = [ + "TARGET_TRIPLE", # Some tests invoke Cargo directly and need this to run correctly +] diff --git a/Justfile b/Justfile index 9d7b62dfe..f0cb57a5c 100644 --- a/Justfile +++ b/Justfile @@ -6,6 +6,20 @@ set dotenv-load := true set-env-command := if os() == "windows" { "$env:" } else { "export " } bin-suffix := if os() == "windows" { ".bat" } else { ".sh" } +################ +### cross-rs ### +################ +target-triple := env('TARGET_TRIPLE', "") +docker := if target-triple != "" { require("docker") } else { "" } +# this command is only used host side not for guests +# include the --target-dir for the cross builds. This ensures that the builds are separated and avoid any conflicts with the guest builds +cargo-cmd := if target-triple != "" { require("cross") } else { "cargo" } +target-triple-flag := if target-triple != "" { "--target " + target-triple + " --target-dir ./target/host"} else { "" } +# set up cross to use the devices +kvm-gid := if path_exists("/dev/kvm") == "true" { `getent group kvm | cut -d: -f3` } else { "" } +export CROSS_CONTAINER_OPTS := if path_exists("/dev/kvm") == "true" { "--device=/dev/kvm" } else if path_exists("/dev/mshv") == "true" { "--device=/dev/mshv" } else { "" } +export CROSS_CONTAINER_GID := if path_exists("/dev/kvm") == "true" { kvm-gid } else {"1000"} # required to have ownership of the mapped in device on kvm + root := justfile_directory() default-target := "debug" @@ -23,12 +37,7 @@ alias cg := build-and-move-c-guests # build host library build target=default-target: - cargo build --profile={{ if target == "debug" { "dev" } else { target } }} - -# build host library -build-with-musl-libc target=default-target: - cargo build --profile={{ if target == "debug" { "dev" } else { target } }} --target x86_64-unknown-linux-musl - + {{ cargo-cmd }} build --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} # build testing guest binaries guests: build-and-move-rust-guests build-and-move-c-guests @@ -75,10 +84,7 @@ test-like-ci config=default-target hypervisor="kvm": just test {{config}} seccomp,build-metadata,init-paging,{{ if hypervisor == "mshv" {"mshv2"} else if hypervisor == "mshv3" {"mshv3"} else {"kvm"} }} @# make sure certain cargo features compile - cargo check -p hyperlight-host --features crashdump - cargo check -p hyperlight-host --features print_debug - cargo check -p hyperlight-host --features gdb - cargo check -p hyperlight-host --features trace_guest,unwind_guest,mem_profile + just check @# without any driver (should fail to compile) just test-compilation-no-default-features {{config}} @@ -126,8 +132,8 @@ like-ci config=default-target hypervisor="kvm": @# Run Rust examples - linux {{ if os() == "linux" { "just run-rust-examples-linux " + config + " " + if hypervisor == "mshv" { "mshv2" } else if hypervisor == "mshv3" { "mshv3" } else { "kvm" } } else { "" } }} - @# Run Rust Gdb tests - linux - {{ if os() == "linux" { "just test-rust-gdb-debugging " + config + " " + if hypervisor == "mshv" { "mshv2" } else if hypervisor == "mshv3" { "mshv3" } else { "kvm" } } else { "" } }} + @# Run Rust Gdb tests + just test-rust-gdb-debugging {{ config }} {{ if hypervisor == "mshv" { "mshv2" } else if hypervisor == "mshv3" { "mshv3" } else { "kvm" } }} @# Run Rust Crashdump tests just test-rust-crashdump {{config}} {{ if hypervisor == "mshv" { "mshv2" } else if hypervisor == "mshv3" { "mshv3" } else { "kvm" } }} @@ -143,65 +149,67 @@ test target=default-target features="": (test-unit target features) (test-isolat # runs unit tests test-unit target=default-target features="": - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} --lib + {{ cargo-cmd }} test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --lib # runs tests that requires being run separately, for example due to global state -test-isolated target=default-target features="": - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::uninitialized::tests::test_trace_trace --exact --ignored - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::uninitialized::tests::test_log_trace --exact --ignored - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::initialized_multi_use::tests::create_1000_sandboxes --exact --ignored - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- sandbox::outb::tests::test_log_outb_log --exact --ignored - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- mem::shared_mem::tests::test_drop --exact --ignored - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --test integration_test -- log_message --exact --ignored +test-isolated target=default-target features="" : + {{ cargo-cmd }} test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} -p hyperlight-host --lib -- sandbox::uninitialized::tests::test_trace_trace --exact --ignored + {{ cargo-cmd }} test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} -p hyperlight-host --lib -- sandbox::uninitialized::tests::test_log_trace --exact --ignored + {{ cargo-cmd }} test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} -p hyperlight-host --lib -- sandbox::initialized_multi_use::tests::create_1000_sandboxes --exact --ignored + {{ cargo-cmd }} test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} -p hyperlight-host --lib -- sandbox::outb::tests::test_log_outb_log --exact --ignored + {{ cargo-cmd }} test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} -p hyperlight-host --lib -- mem::shared_mem::tests::test_drop --exact --ignored + {{ cargo-cmd }} test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} -p hyperlight-host --test integration_test -- log_message --exact --ignored @# metrics tests - cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F function_call_metrics,init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host --lib -- metrics::tests::test_metrics_are_emitted --exact + {{ cargo-cmd }} test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F function_call_metrics,init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} -p hyperlight-host --lib -- metrics::tests::test_metrics_are_emitted --exact # runs integration tests. Guest can either be "rust" or "c" test-integration guest target=default-target features="": @# run execute_on_heap test with feature "executable_heap" on and off - {{if os() == "windows" { "$env:" } else { "" } }}GUEST="{{guest}}"{{if os() == "windows" { ";" } else { "" } }} cargo test --profile={{ if target == "debug" { "dev" } else { target } }} --test integration_test execute_on_heap {{ if features =="" {" --features executable_heap"} else {"--features executable_heap," + features} }} -- --ignored - {{if os() == "windows" { "$env:" } else { "" } }}GUEST="{{guest}}"{{if os() == "windows" { ";" } else { "" } }} cargo test --profile={{ if target == "debug" { "dev" } else { target } }} --test integration_test execute_on_heap {{ if features =="" {""} else {"--features " + features} }} -- --ignored + {{if os() == "windows" { "$env:" } else { "" } }}GUEST="{{guest}}"{{if os() == "windows" { ";" } else { "" } }} {{ cargo-cmd }} test --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --test integration_test execute_on_heap {{ if features =="" {" --features executable_heap"} else {"--features executable_heap," + features} }} -- --ignored + {{if os() == "windows" { "$env:" } else { "" } }}GUEST="{{guest}}"{{if os() == "windows" { ";" } else { "" } }} {{ cargo-cmd }} test --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --test integration_test execute_on_heap {{ if features =="" {""} else {"--features " + features} }} -- --ignored @# run the rest of the integration tests - {{if os() == "windows" { "$env:" } else { "" } }}GUEST="{{guest}}"{{if os() == "windows" { ";" } else { "" } }} cargo test -p hyperlight-host {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} --test '*' + {{if os() == "windows" { "$env:" } else { "" } }}GUEST="{{guest}}"{{if os() == "windows" { ";" } else { "" } }} {{ cargo-cmd }} test -p hyperlight-host {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F init-paging," + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --test '*' # runs seccomp tests test-seccomp target=default-target features="": @# run seccomp test with feature "seccomp" on and off - cargo test --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host test_violate_seccomp_filters --lib {{ if features =="" {''} else { "--features " + features } }} -- --ignored - cargo test --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host test_violate_seccomp_filters --no-default-features {{ if features =~"mshv2" {"--features init-paging,mshv2"} else {"--features mshv3,init-paging,kvm" } }} --lib -- --ignored + {{ cargo-cmd }} test --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} -p hyperlight-host test_violate_seccomp_filters --lib {{ if features =="" {''} else { "--features " + features } }} -- --ignored + {{ cargo-cmd }} test --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} -p hyperlight-host test_violate_seccomp_filters --no-default-features {{ if features =~"mshv2" {"--features init-paging,mshv2"} else {"--features mshv3,init-paging,kvm" } }} --lib -- --ignored # tests compilation with no default features on different platforms test-compilation-no-default-features target=default-target: @# Linux should fail without a hypervisor feature (kvm, mshv, or mshv3) - {{ if os() == "linux" { "! cargo check -p hyperlight-host --no-default-features 2> /dev/null" } else { "" } }} + {{ if os() == "linux" { "! " + cargo-cmd + " check -p hyperlight-host --no-default-features "+target-triple-flag+" 2> /dev/null" } else { "" } }} @# Windows should succeed even without default features - {{ if os() == "windows" { "cargo check -p hyperlight-host --no-default-features" } else { "" } }} + {{ if os() == "windows" { cargo-cmd + " check -p hyperlight-host --no-default-features" } else { "" } }} @# Linux should succeed with a hypervisor driver but without init-paging - {{ if os() == "linux" { "cargo check -p hyperlight-host --no-default-features --features kvm" } else { "" } }} - {{ if os() == "linux" { "cargo check -p hyperlight-host --no-default-features --features mshv2" } else { "" } }} - {{ if os() == "linux" { "cargo check -p hyperlight-host --no-default-features --features mshv3" } else { "" } }} + {{ if os() == "linux" { cargo-cmd + " check -p hyperlight-host --no-default-features --features kvm" } else { "" } }} {{ target-triple-flag }} + {{ if os() == "linux" { cargo-cmd + " check -p hyperlight-host --no-default-features --features mshv2" } else { "" } }} {{ target-triple-flag }} + {{ if os() == "linux" { cargo-cmd + " check -p hyperlight-host --no-default-features --features mshv3" } else { "" } }} {{ target-triple-flag }} # runs tests that exercise gdb debugging test-rust-gdb-debugging target=default-target features="": - cargo test --profile={{ if target == "debug" { "dev" } else { target } }} --example guest-debugging {{ if features =="" {'--features gdb'} else { "--features gdb," + features } }} - cargo test --profile={{ if target == "debug" { "dev" } else { target } }} {{ if features =="" {'--features gdb'} else { "--features gdb," + features } }} -- test_gdb + {{ cargo-cmd }} test --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --example guest-debugging {{ if features =="" {'--features gdb'} else { "--features gdb," + features } }} + {{ cargo-cmd }} test --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} {{ if features =="" {'--features gdb'} else { "--features gdb," + features } }} -- test_gdb # rust test for crashdump test-rust-crashdump target=default-target features="": - cargo test --profile={{ if target == "debug" { "dev" } else { target } }} {{ if features =="" {'--features crashdump'} else { "--features crashdump," + features } }} -- test_crashdump + {{ cargo-cmd }} test --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} {{ if features =="" {'--features crashdump'} else { "--features crashdump," + features } }} -- test_crashdump # rust test for tracing test-rust-tracing target=default-target features="": # Run tests for the tracing guest and macro - cargo test -p hyperlight-guest-tracing --profile={{ if target == "debug" { "dev" } else { target } }} - cargo test -p hyperlight-guest-tracing-macro --profile={{ if target == "debug" { "dev" } else { target } }} + {{ cargo-cmd }} test -p hyperlight-guest-tracing --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} + {{ cargo-cmd }} test -p hyperlight-guest-tracing-macro --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} # Prepare the tracing guest for testing just build-rust-guests {{ target }} trace_guest just move-rust-guests {{ target }} # Run hello-world example with tracing enabled to get the trace output - TRACE_OUTPUT="$(cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example hello-world --features {{ if features =="" {"trace_guest"} else { "trace_guest," + features } }})" && \ + # note that trace-dump doesn't run on MUSL target as of now + TRACE_OUTPUT="$({{ cargo-cmd }} run --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --example hello-world --features {{ if features =="" {"trace_guest"} else { "trace_guest," + features } }})" && \ TRACE_FILE="$(echo "$TRACE_OUTPUT" | grep -oE 'Creating trace file at: [^ ]+' | awk -F': ' '{print $2}')" && \ + TRACE_FILE="$(echo "$TRACE_OUTPUT" | grep -oE 'Creating trace file at: [^ ]+' | awk -F': ' '{print $2}' | sed -E 's|^(trace/[^ ]+\.trace)$|./\1|; s|.*/(trace/[^ ]+\.trace)$|./\1|')" && \ echo "$TRACE_OUTPUT" && \ if [ -z "$TRACE_FILE" ]; then \ echo "Error: Could not extract trace file path from output." >&2 ; \ @@ -215,13 +223,18 @@ test-rust-tracing target=default-target features="": just move-rust-guests {{ target }} test-doc target=default-target features="": - cargo test --profile={{ if target == "debug" { "dev" } else { target } }} {{ if features =="" {''} else { "--features " + features } }} --doc + {{ cargo-cmd }} test --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} {{ if features =="" {''} else { "--features " + features } }} --doc + ################ ### LINTING #### ################ check: - cargo check + {{ cargo-cmd }} check {{ target-triple-flag }} + {{ cargo-cmd }} check -p hyperlight-host --features crashdump {{ target-triple-flag }} + {{ cargo-cmd }} check -p hyperlight-host --features print_debug {{ target-triple-flag }} + {{ cargo-cmd }} check -p hyperlight-host --features gdb {{ target-triple-flag }} + {{ cargo-cmd }} check -p hyperlight-host --features trace_guest,unwind_guest,mem_profile {{ target-triple-flag }} fmt-check: cargo +nightly fmt --all -- --check @@ -241,7 +254,7 @@ fmt-apply: cargo +nightly fmt --manifest-path src/hyperlight_guest_capi/Cargo.toml clippy target=default-target: (witguest-wit) - cargo clippy --all-targets --all-features --profile={{ if target == "debug" { "dev" } else { target } }} -- -D warnings + {{ cargo-cmd }} clippy --all-targets --all-features --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} -- -D warnings clippy-guests target=default-target: (witguest-wit) cd src/tests/rust_guests/simpleguest && cargo clippy --profile={{ if target == "debug" { "dev" } else { target } }} -- -D warnings @@ -255,13 +268,13 @@ clippy-apply-fix-windows: # Run clippy with feature combinations for all packages clippy-exhaustive target=default-target: (witguest-wit) - ./hack/clippy-package-features.sh hyperlight-host {{ target }} - ./hack/clippy-package-features.sh hyperlight-guest {{ target }} + ./hack/clippy-package-features.sh hyperlight-host {{ target }} {{ target-triple }} + ./hack/clippy-package-features.sh hyperlight-guest {{ target }} ./hack/clippy-package-features.sh hyperlight-guest-bin {{ target }} - ./hack/clippy-package-features.sh hyperlight-common {{ target }} - ./hack/clippy-package-features.sh hyperlight-testing {{ target }} - ./hack/clippy-package-features.sh hyperlight-component-macro {{ target }} - ./hack/clippy-package-features.sh hyperlight-component-util {{ target }} + ./hack/clippy-package-features.sh hyperlight-common {{ target }} {{ target-triple }} + ./hack/clippy-package-features.sh hyperlight-testing {{ target }} {{ target-triple }} + ./hack/clippy-package-features.sh hyperlight-component-macro {{ target }} {{ target-triple }} + ./hack/clippy-package-features.sh hyperlight-component-util {{ target }} {{ target-triple }} ./hack/clippy-package-features.sh hyperlight-guest-tracing-macro {{ target }} ./hack/clippy-package-features.sh hyperlight-guest-tracing {{ target }} just clippy-guests {{ target }} @@ -279,14 +292,14 @@ verify-msrv: ##################### run-rust-examples target=default-target features="": - cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example metrics {{ if features =="" {''} else { "--features " + features } }} - cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example metrics {{ if features =="" {"--features function_call_metrics"} else {"--features function_call_metrics," + features} }} - cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example logging {{ if features =="" {''} else { "--features " + features } }} + {{ cargo-cmd }} run --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --example metrics {{ if features =="" {''} else { "--features " + features } }} + {{ cargo-cmd }} run --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --example metrics {{ if features =="" {"--features function_call_metrics"} else {"--features function_call_metrics," + features} }} + {{ cargo-cmd }} run --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --example logging {{ if features =="" {''} else { "--features " + features } }} # The two tracing examples are flaky on windows so we run them on linux only for now, need to figure out why as they run fine locally on windows run-rust-examples-linux target=default-target features="": (run-rust-examples target features) - cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example tracing {{ if features =="" {''} else { "--features " + features } }} - cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example tracing {{ if features =="" {"--features function_call_metrics" } else {"--features function_call_metrics," + features} }} + {{ cargo-cmd }} run --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --example tracing {{ if features =="" {''} else { "--features " + features } }} + {{ cargo-cmd }} run --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --example tracing {{ if features =="" {"--features function_call_metrics" } else {"--features function_call_metrics," + features} }} ######################### diff --git a/dev/notify-ci-failure.sh b/dev/notify-ci-failure.sh new file mode 100755 index 000000000..69be564c1 --- /dev/null +++ b/dev/notify-ci-failure.sh @@ -0,0 +1,169 @@ +#!/bin/bash +set -e +set -u +set -o pipefail + +## DESCRIPTION: +## +# Generic notifier for CI job failures that can create or update GitHub issues. +## This script creates or updates GitHub issues when a jobs fail. +## It checks for existing open failure issues and either creates +## a new one or adds a comment to an existing one. +## +## PRE-REQS: +## +## This script assumes that the gh cli is installed and in the PATH +## and that there is a GitHub PAT in the GITHUB_TOKEN env var +## with the following permissions: +## - issues (read/write) +## or that the user is logged into the gh cli with an account with those permissions +## +## Usage examples: +## ./dev/notify-fuzzing-failure.sh +## ./dev/notify-fuzzing-failure.sh --title="Nightly Failure" --labels="area/testing,kind/bug" +## ./dev/notify-fuzzing-failure.sh --test +## Run this script locally like: +## GITHUB_REPOSITORY="fork/hyperlight" GITHUB_RUN_ID=1 ./dev/notify-fuzzing-failure.sh --title="Nightly Failure" --labels="area/testing,kind/bug" + +REPO="${GITHUB_REPOSITORY:-hyperlight-dev/hyperlight}" +WORKFLOW_RUN_URL="${GITHUB_SERVER_URL:-https://github.com}/${REPO}/actions/runs/${GITHUB_RUN_ID:-unknown}" +TEST_MODE=false +ISSUE_TITLE="" +LABELS="area/testing,kind/bug,area/fuzzing,lifecycle/needs-review" + +for arg in "$@"; do + case $arg in + --test) + TEST_MODE=true + shift + ;; + --title=*) + ISSUE_TITLE="${arg#*=}" + shift + ;; + --labels=*) + LABELS="${arg#*=}" + shift + ;; + *) + esac +done + +# Normalize labels into an array +IFS=',' read -r -a LABEL_ARRAY <<< "$LABELS" + +# Choose a label to search existing issues for; prefer the first label if present +SEARCH_LABEL="${LABEL_ARRAY[0]:-area/fuzzing}" + +# Build issue title if not provided +if [ -z "$ISSUE_TITLE" ]; then + ISSUE_TITLE="Job Failure - $(date '+%Y-%m-%d')" +fi + + +if [ "$TEST_MODE" = true ]; then + echo "✅ Running in test mode - script structure is valid" + echo "Would check for issues in $REPO" + echo "Workflow URL would be: $WORKFLOW_RUN_URL" + echo "Issue Title would be: $ISSUE_TITLE" + echo "Labels would be: $LABELS" + echo "Search Label would be: $SEARCH_LABEL" + exit 0 +fi + +# Extract owner and repo name from the repository +OWNER=$(echo "$REPO" | cut -d'/' -f1) +REPO_NAME=$(echo "$REPO" | cut -d'/' -f2) + +echo "Checking for existing issues in $REPO with label '$SEARCH_LABEL'..." +EXISTING_ISSUES=$(gh api graphql -f query=' + query($owner: String!, $repo: String!, $label: String!) { + repository(owner: $owner, name: $repo) { + issues(first: 10, states: OPEN, labels: [$label]) { + totalCount + nodes { + number + title + url + labels(first: 20) { + nodes { + name + } + } + } + } + } + }' -f owner="$OWNER" -f repo="$REPO_NAME" -f label="$SEARCH_LABEL" --jq '.data.repository.issues') || EXISTING_ISSUES="" + +FUZZING_ISSUES=$(echo "$EXISTING_ISSUES" | jq '.nodes[]' 2>/dev/null || echo "") +FUZZING_ISSUE_COUNT=0 +if [ -n "$FUZZING_ISSUES" ]; then + FUZZING_ISSUE_COUNT=$(echo "$FUZZING_ISSUES" | jq -s 'length' 2>/dev/null || echo "0") +fi + +echo "Found $FUZZING_ISSUE_COUNT existing issue(s) matching label '$SEARCH_LABEL'" + +if [ "$FUZZING_ISSUE_COUNT" -gt 0 ]; then + ISSUE_NUMBER=$(echo "$FUZZING_ISSUES" | jq -r '.number' | head -1) + ISSUE_URL=$(echo "$FUZZING_ISSUES" | jq -r '.url' | head -1) + if [ "$ISSUE_NUMBER" = "null" ] || [ -z "$ISSUE_NUMBER" ]; then + echo "⚠️ Could not parse issue number from search results; will create a new issue" + FUZZING_ISSUE_COUNT=0 + else + echo "Adding comment to existing issue #$ISSUE_NUMBER" + COMMENT_BODY="## Job Failed Again + +**Date:** $(date '+%Y-%m-%d %H:%M:%S UTC') +**Workflow Run:** [$WORKFLOW_RUN_URL]($WORKFLOW_RUN_URL) + +The scheduled job has failed again. Please check the workflow logs and artifacts for details." + + if gh issue comment "$ISSUE_NUMBER" --body "$COMMENT_BODY" --repo "$REPO"; then + echo "✅ Added comment to existing issue #$ISSUE_NUMBER: $ISSUE_URL" + exit 0 + else + echo "❌ Failed to add comment to existing issue. Will attempt to create a new issue instead." + FUZZING_ISSUE_COUNT=0 + fi + fi +fi + +if [ "$FUZZING_ISSUE_COUNT" -eq 0 ]; then + echo "No existing matching issues found. Creating a new issue..." + + ISSUE_BODY="## Job Failure Report + +**Date:** $(date '+%Y-%m-%d %H:%M:%S UTC') +**Workflow Run:** [$WORKFLOW_RUN_URL]($WORKFLOW_RUN_URL) + +### Details +The scheduled job failed during execution. This issue was automatically created to track the failure. Please check the workflow logs and any uploaded artifacts for more details. + +### Next Steps +- [ ] Review the workflow logs for error details +- [ ] Download and analyze any crash artifacts if available +- [ ] Determine the root cause of the failure +- [ ] Fix the underlying issue + +--- +*This issue was automatically created by the CI failure notification system.*" + + # Build label args for gh issue create + LABEL_ARGS=() + for lbl in "${LABEL_ARRAY[@]}"; do + LABEL_ARGS+=("--label" "$lbl") + done + + if ISSUE_URL=$(gh issue create \ + --title "$ISSUE_TITLE" \ + --body "$ISSUE_BODY" \ + "${LABEL_ARGS[@]}" \ + --repo "$REPO"); then + echo "✅ Created new issue: $ISSUE_URL" + else + echo "❌ Failed to create new issue" + exit 1 + fi +fi + +echo "Notification script completed successfully" \ No newline at end of file diff --git a/dev/notify-fuzzing-failure.sh b/dev/notify-fuzzing-failure.sh deleted file mode 100755 index f4a6ac04f..000000000 --- a/dev/notify-fuzzing-failure.sh +++ /dev/null @@ -1,153 +0,0 @@ -#!/bin/bash -set -e -set -u -set -o pipefail - -## DESCRIPTION: -## -## This script creates or updates GitHub issues when fuzzing jobs fail. -## It checks for existing open fuzzing failure issues and either creates -## a new one or adds a comment to an existing one. -## -## PRE-REQS: -## -## This script assumes that the gh cli is installed and in the PATH -## and that there is a GitHub PAT in the GITHUB_TOKEN env var -## with the following permissions: -## - issues (read/write) -## or that the user is logged into the gh cli with an account with those permissions -## -## Run this script locally like: -## GITHUB_REPOSITORY="fork/hyperlight" GITHUB_RUN_ID=1 ./dev/notify-fuzzing-failure.sh "fuzz_host_print,fuzz_guest_call,fuzz_host_call" - -REPO="${GITHUB_REPOSITORY:-hyperlight-dev/hyperlight}" -WORKFLOW_RUN_URL="${GITHUB_SERVER_URL:-https://github.com}/${REPO}/actions/runs/${GITHUB_RUN_ID:-unknown}" -FUZZING_TARGETS="${1:-unknown}" - -# Check if running in test mode (handle both first and second arguments) -if [ "${1:-}" = "--test" ] || [ "${2:-}" = "--test" ]; then - echo "✅ Running in test mode - script structure is valid" - echo "Would check for fuzzing failure issues in $REPO" - echo "Would create issue or comment for fuzzing targets: ${1:-unknown}" - echo "Workflow URL would be: $WORKFLOW_RUN_URL" - exit 0 -fi - -echo "Checking for existing fuzzing failure issues in $REPO..." - -# Extract owner and repo name from the repository -OWNER=$(echo "$REPO" | cut -d'/' -f1) -REPO_NAME=$(echo "$REPO" | cut -d'/' -f2) - -# Define the issue title and labels -ISSUE_TITLE="Fuzzing Job Failure - $(date '+%Y-%m-%d')" -TESTING_LABEL="area/testing" -FAILURE_LABEL="kind/bug" -FUZZING_LABEL="area/fuzzing" -LIFECYCLE_LABEL="lifecycle/needs-review" - -# Search for existing open fuzzing failure issues -echo "Searching for existing open fuzzing failure issues..." -EXISTING_ISSUES=$(gh api graphql -f query=' - query($owner: String!, $repo: String!) { - repository(owner: $owner, name: $repo) { - issues(first: 10, states: OPEN, labels: ["area/fuzzing"]) { - totalCount - nodes { - number - title - url - labels(first: 20) { - nodes { - name - } - } - } - } - } - }' -f owner="$OWNER" -f repo="$REPO_NAME" --jq '.data.repository.issues') - -# Filter for fuzzing-related issues (now all results should be fuzzing issues due to label filter) -FUZZING_ISSUES=$(echo "$EXISTING_ISSUES" | jq '.nodes[]' 2>/dev/null || echo "") -FUZZING_ISSUE_COUNT=0 -if [ -n "$FUZZING_ISSUES" ]; then - FUZZING_ISSUE_COUNT=$(echo "$FUZZING_ISSUES" | jq -s 'length' 2>/dev/null || echo "0") -fi - -echo "Found $FUZZING_ISSUE_COUNT existing fuzzing failure issue(s)" - -if [ "$FUZZING_ISSUE_COUNT" -gt 0 ]; then - # Get the most recent fuzzing failure issue - ISSUE_NUMBER=$(echo "$FUZZING_ISSUES" | jq -r '.number' | head -1) - ISSUE_URL=$(echo "$FUZZING_ISSUES" | jq -r '.url' | head -1) - - if [ "$ISSUE_NUMBER" = "null" ] || [ -z "$ISSUE_NUMBER" ]; then - echo "⚠️ Could not parse issue number from fuzzing issues, creating new issue instead" - FUZZING_ISSUE_COUNT=0 - else - echo "Adding comment to existing issue #$ISSUE_NUMBER" - - # Create comment body - COMMENT_BODY="## Fuzzing Job Failed Again - -**Date:** $(date '+%Y-%m-%d %H:%M:%S UTC') -**Workflow Run:** [$WORKFLOW_RUN_URL]($WORKFLOW_RUN_URL) -**Fuzzing Targets:** $FUZZING_TARGETS - -The scheduled fuzzing job has failed again. Please check the workflow logs and artifacts for details." - - # Add comment to the existing issue - if gh issue comment "$ISSUE_NUMBER" --body "$COMMENT_BODY" --repo "$REPO"; then - echo "✅ Added comment to existing issue #$ISSUE_NUMBER: $ISSUE_URL" - else - echo "❌ Failed to add comment to existing issue. Creating new issue instead." - FUZZING_ISSUE_COUNT=0 - fi - fi -fi - -if [ "$FUZZING_ISSUE_COUNT" -eq 0 ]; then - echo "No existing fuzzing failure issues found. Creating new issue..." - - # Create issue body - ISSUE_BODY="## Fuzzing Job Failure Report - -**Date:** $(date '+%Y-%m-%d %H:%M:%S UTC') -**Workflow Run:** [$WORKFLOW_RUN_URL]($WORKFLOW_RUN_URL) -**Fuzzing Targets:** $FUZZING_TARGETS - -The scheduled fuzzing job has failed. This issue was automatically created to track the failure. - -### Details -The fuzzing workflow failed during execution. Please check the workflow logs and any uploaded artifacts for more details. - -### Next Steps -- [ ] Review the workflow logs for error details -- [ ] Download and analyze any crash artifacts if available -- [ ] Determine the root cause of the failure -- [ ] Fix the underlying issue - -### Related Documentation -- [Fuzzing README](https://github.com/$REPO/blob/main/fuzz/README.md) -- [Security Guidance](https://github.com/$REPO/blob/main/docs/security-guidance-for-developers.md) - ---- -*This issue was automatically created by the fuzzing failure notification system.*" - - # Create the new issue - if ISSUE_URL=$(gh issue create \ - --title "$ISSUE_TITLE" \ - --body "$ISSUE_BODY" \ - --label "$TESTING_LABEL" \ - --label "$FAILURE_LABEL" \ - --label "$FUZZING_LABEL" \ - --label "$LIFECYCLE_LABEL" \ - --repo "$REPO"); then - echo "✅ Created new fuzzing failure issue: $ISSUE_URL" - else - echo "❌ Failed to create new fuzzing failure issue" - exit 1 - fi -fi - -echo "Fuzzing failure notification completed successfully" \ No newline at end of file diff --git a/fuzz/fuzz_targets/host_call.rs b/fuzz/fuzz_targets/host_call.rs index 8011c7314..2bf241673 100644 --- a/fuzz/fuzz_targets/host_call.rs +++ b/fuzz/fuzz_targets/host_call.rs @@ -57,21 +57,18 @@ fuzz_target!( sandbox.restore(&snapshot).unwrap(); host_func_params.insert(0, ParameterValue::String(host_func_name)); - match sandbox.call_type_erased_guest_function_by_name("FuzzHostFunc", host_func_return, host_func_params) { - Err(e) => { - match e { - // the following are expected errors and occur frequently since - // we are randomly generating the function name and parameters - // to call with. - HyperlightError::HostFunctionNotFound(_) => {} - HyperlightError::UnexpectedNoOfArguments(_, _) => {}, - HyperlightError::ParameterValueConversionFailure(_, _) => {}, + if let Err(e) = sandbox.call_type_erased_guest_function_by_name("FuzzHostFunc", host_func_return, host_func_params) { + match e { + // the following are expected errors and occur frequently since + // we are randomly generating the function name and parameters + // to call with. + HyperlightError::HostFunctionNotFound(_) => {} + HyperlightError::UnexpectedNoOfArguments(_, _) => {}, + HyperlightError::ParameterValueConversionFailure(_, _) => {}, - // any other error should be reported - _ => panic!("Guest Aborted with Unexpected Error: {:?}", e), - } + // any other error should be reported + _ => panic!("Guest Aborted with Unexpected Error: {:?}", e), } - _ => {} } } ); diff --git a/hack/clippy-package-features.sh b/hack/clippy-package-features.sh index dddf582d8..e769700ff 100755 --- a/hack/clippy-package-features.sh +++ b/hack/clippy-package-features.sh @@ -4,13 +4,23 @@ set -euo pipefail # Check for required arguments if [[ $# -lt 2 ]]; then - echo "Usage: $0 " >&2 - echo "Example: $0 hyperlight-host debug" >&2 + echo "Usage: $0 [target_triple]" >&2 + echo "Example: $0 hyperlight-host debug x86_64-unknown-linux-musl" >&2 exit 1 fi PACKAGE="$1" TARGET="$2" +TARGET_TRIPLE="${3:-}" + +CARGO="cargo" + +# Cargo target argument to append to cargo calls (empty if not provided) +TRIPLE_ARG="" +if [[ -n "${TARGET_TRIPLE}" ]]; then + TRIPLE_ARG="--target ${TARGET_TRIPLE} --target-dir ./target/host" + CARGO="cross" +fi # Convert target for cargo profile PROFILE=$([ "$TARGET" = "debug" ] && echo "dev" || echo "$TARGET") @@ -38,23 +48,23 @@ fi # Test with minimal features if [[ ${#REQUIRED_FEATURES[@]} -gt 0 ]]; then echo "Testing $PACKAGE with required features only ($required_features_str)..." - (set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --features "$required_features_str" --profile="$PROFILE" -- -D warnings) + (set -x; "$CARGO" clippy -p "$PACKAGE" --all-targets --no-default-features --features "$required_features_str" --profile="$PROFILE" ${TRIPLE_ARG} -- -D warnings) else echo "Testing $PACKAGE with no features..." - (set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --profile="$PROFILE" -- -D warnings) + (set -x; "$CARGO" clippy -p "$PACKAGE" --all-targets --no-default-features --profile="$PROFILE" ${TRIPLE_ARG} -- -D warnings) fi echo "Testing $PACKAGE with default features..." -(set -x; cargo clippy -p "$PACKAGE" --all-targets --profile="$PROFILE" -- -D warnings) +(set -x; "$CARGO" clippy -p "$PACKAGE" --all-targets --profile="$PROFILE" ${TRIPLE_ARG} -- -D warnings) # Test each additional feature individually for feature in $features; do if [[ ${#REQUIRED_FEATURES[@]} -gt 0 ]]; then echo "Testing $PACKAGE with feature: $required_features_str,$feature" - (set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --features "$required_features_str,$feature" --profile="$PROFILE" -- -D warnings) + (set -x; "$CARGO" clippy -p "$PACKAGE" --all-targets --no-default-features --features "$required_features_str,$feature" --profile="$PROFILE" ${TRIPLE_ARG} -- -D warnings) else echo "Testing $PACKAGE with feature: $feature" - (set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --features "$feature" --profile="$PROFILE" -- -D warnings) + (set -x; "$CARGO" clippy -p "$PACKAGE" --all-targets --no-default-features --features "$feature" --profile="$PROFILE" ${TRIPLE_ARG} -- -D warnings) fi done @@ -63,9 +73,9 @@ if [[ -n "$features" ]]; then all_features=$(echo $features | tr '\n' ',' | sed 's/,$//') if [[ ${#REQUIRED_FEATURES[@]} -gt 0 ]]; then echo "Testing $PACKAGE with all features: $required_features_str,$all_features" - (set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --features "$required_features_str,$all_features" --profile="$PROFILE" -- -D warnings) + (set -x; "$CARGO" clippy -p "$PACKAGE" --all-targets --no-default-features --features "$required_features_str,$all_features" --profile="$PROFILE" ${TRIPLE_ARG} -- -D warnings) else echo "Testing $PACKAGE with all features: $all_features" - (set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --features "$all_features" --profile="$PROFILE" -- -D warnings) + (set -x; "$CARGO" clippy -p "$PACKAGE" --all-targets --no-default-features --features "$all_features" --profile="$PROFILE" ${TRIPLE_ARG} -- -D warnings) fi fi \ No newline at end of file diff --git a/src/hyperlight_common/Cargo.toml b/src/hyperlight_common/Cargo.toml index da6e90aaa..93854f5d9 100644 --- a/src/hyperlight_common/Cargo.toml +++ b/src/hyperlight_common/Cargo.toml @@ -15,7 +15,7 @@ Hyperlight's components common to host and guest. workspace = true [dependencies] -flatbuffers = { version = "25.2.10", default-features = false } +flatbuffers = { version = "25.9.23", default-features = false } anyhow = { version = "1.0.100", default-features = false } log = "0.4.28" tracing = { version = "0.1.41", optional = true } diff --git a/src/hyperlight_component_macro/Cargo.toml b/src/hyperlight_component_macro/Cargo.toml index 69eb27006..f82b9bb56 100644 --- a/src/hyperlight_component_macro/Cargo.toml +++ b/src/hyperlight_component_macro/Cargo.toml @@ -17,7 +17,7 @@ proc-macro = true [dependencies] wasmparser = { version = "0.239.0" } -quote = { version = "1.0.38" } +quote = { version = "1.0.41" } proc-macro2 = { version = "1.0.101" } syn = { version = "2.0.106" } itertools = { version = "0.14.0" } diff --git a/src/hyperlight_component_util/Cargo.toml b/src/hyperlight_component_util/Cargo.toml index 9abbdd845..1a03e25d0 100644 --- a/src/hyperlight_component_util/Cargo.toml +++ b/src/hyperlight_component_util/Cargo.toml @@ -16,7 +16,7 @@ name = "hyperlight_component_util" [dependencies] wasmparser = { version = "0.239.0" } -quote = { version = "1.0.38" } +quote = { version = "1.0.41" } proc-macro2 = { version = "1.0.101" } syn = { version = "2.0.106" } itertools = { version = "0.14.0" } diff --git a/src/hyperlight_guest/Cargo.toml b/src/hyperlight_guest/Cargo.toml index 31d872092..e15b1e996 100644 --- a/src/hyperlight_guest/Cargo.toml +++ b/src/hyperlight_guest/Cargo.toml @@ -16,7 +16,7 @@ anyhow = { version = "1.0.100", default-features = false } serde_json = { version = "1.0", default-features = false, features = ["alloc"] } hyperlight-common = { workspace = true } hyperlight-guest-tracing = { workspace = true, default-features = false } -flatbuffers = { version= "25.2.10", default-features = false } +flatbuffers = { version= "25.9.23", default-features = false } [features] default = [] diff --git a/src/hyperlight_guest_capi/src/flatbuffer.rs b/src/hyperlight_guest_capi/src/flatbuffer.rs index b710d4245..d5c41fe4d 100644 --- a/src/hyperlight_guest_capi/src/flatbuffer.rs +++ b/src/hyperlight_guest_capi/src/flatbuffer.rs @@ -15,6 +15,9 @@ limitations under the License. */ use alloc::boxed::Box; +use alloc::ffi::CString; +use alloc::string::String; +use alloc::vec::Vec; use core::ffi::{CStr, c_char}; use hyperlight_common::flatbuffer_wrappers::util::get_flatbuffer_result; @@ -115,4 +118,34 @@ pub extern "C" fn hl_get_host_return_value_as_ULong() -> u64 { get_host_return_value().expect("Unable to get host return value as ulong") } -// TODO add bool, float, double, string, vecbytes +#[unsafe(no_mangle)] +pub extern "C" fn hl_get_host_return_value_as_Bool() -> bool { + get_host_return_value().expect("Unable to get host return value as bool") +} + +#[unsafe(no_mangle)] +pub extern "C" fn hl_get_host_return_value_as_float() -> f32 { + get_host_return_value().expect("Unable to get host return value as f32") +} + +#[unsafe(no_mangle)] +pub extern "C" fn hl_get_host_return_value_as_double() -> f64 { + get_host_return_value().expect("Unable to get host return value as f32") +} + +#[unsafe(no_mangle)] +pub extern "C" fn hl_flatbuffer_result_from_String() -> *const c_char { + let string_value: String = get_host_return_value() + .expect("Unable to get host return value as string"); + + let c_string = CString::new(string_value).expect("Failes to create CString"); + c_string.into_raw() +} + +#[unsafe(no_mangle)] +pub extern "C" fn hl_flatbuffer_result_from_VecBytes() -> Box { + let vec_value: Vec = get_host_return_value() + .expect("Unable to get host return value as vec bytes"); + + Box::new(unsafe { FfiVec::from_vec(vec_value) }) +} \ No newline at end of file diff --git a/src/hyperlight_guest_tracing_macro/Cargo.toml b/src/hyperlight_guest_tracing_macro/Cargo.toml index 2070e868f..7688232a4 100644 --- a/src/hyperlight_guest_tracing_macro/Cargo.toml +++ b/src/hyperlight_guest_tracing_macro/Cargo.toml @@ -11,7 +11,7 @@ description = """Provides the tracing macros for the hyperlight guest, enabling [dependencies] proc-macro2 = "1.0" -quote = "1.0.40" +quote = "1.0.41" syn = { version = "2.0.106", features = ["full"] } [features] diff --git a/src/hyperlight_host/Cargo.toml b/src/hyperlight_host/Cargo.toml index ab5c91388..bce81f2e1 100644 --- a/src/hyperlight_host/Cargo.toml +++ b/src/hyperlight_host/Cargo.toml @@ -26,8 +26,8 @@ gdbstub_arch = { version = "0.3.2", optional = true } goblin = { version = "0.10", default-features = false, features = ["std", "elf32", "elf64", "endian_fd"] } rand = { version = "0.9" } cfg-if = { version = "1.0.3" } -libc = { version = "0.2.175" } -flatbuffers = "25.2.10" +libc = { version = "0.2.176" } +flatbuffers = "25.9.23" framehop = { version = "0.15.0", optional = true } fallible-iterator = { version = "0.3.0", optional = true } blake3 = "1.8.2" @@ -42,7 +42,7 @@ hyperlight-common = { workspace = true, default-features = true, features = [ "s hyperlight-guest-tracing = { workspace = true, default-features = true, optional = true } vmm-sys-util = "0.15.0" crossbeam-channel = "0.5.15" -thiserror = "2.0.16" +thiserror = "2.0.17" chrono = { version = "0.4", optional = true } anyhow = "1.0" metrics = "0.24.2" @@ -87,9 +87,10 @@ signal-hook-registry = "1.4.6" envy = { version = "0.4.2" } serde = "1.0" proptest = "1.8.0" -tempfile = "3.22.0" +tempfile = "3.23.0" crossbeam-queue = "0.3.12" tracing-serde = "0.2.0" +serial_test = "3.1.1" hyperlight-testing = { workspace = true } env_logger = "0.11.8" tracing-forest = { version = "0.2.0", features = ["uuid", "chrono", "smallvec", "serde", "env-filter"] } @@ -98,7 +99,7 @@ tracing-subscriber = {version = "0.3.20", features = ["std", "env-filter"]} tracing-opentelemetry = "0.31.0" opentelemetry = "0.30.0" opentelemetry-otlp = { version = "0.30.0", default-features = false, features = ["http-proto", "reqwest-blocking-client"] } -opentelemetry-semantic-conventions = "0.30" +opentelemetry-semantic-conventions = "0.31" opentelemetry_sdk = { version = "0.30.0", features = ["rt-tokio"] } tokio = { version = "1.47.1", features = ["full"] } criterion = "0.7.0" diff --git a/src/hyperlight_host/build.rs b/src/hyperlight_host/build.rs index 6c90a485f..bef001b22 100644 --- a/src/hyperlight_host/build.rs +++ b/src/hyperlight_host/build.rs @@ -101,6 +101,7 @@ fn main() -> Result<()> { // the other features they want. mshv2: { all(feature = "mshv2", target_os = "linux") }, mshv3: { all(feature = "mshv3", not(feature="mshv2"), target_os = "linux") }, + seccomp: { all(feature = "seccomp", target_os = "linux", not(target_env = "musl")) }, } #[cfg(feature = "build-metadata")] diff --git a/src/hyperlight_host/examples/guest-debugging/main.rs b/src/hyperlight_host/examples/guest-debugging/main.rs index e414b72d8..9d9ac230e 100644 --- a/src/hyperlight_host/examples/guest-debugging/main.rs +++ b/src/hyperlight_host/examples/guest-debugging/main.rs @@ -72,6 +72,10 @@ fn main() -> hyperlight_host::Result<()> { let mut multi_use_sandbox: MultiUseSandbox = uninitialized_sandbox.evolve()?; // Call guest function + multi_use_sandbox_dbg + .call::<()>("UseSSE2Registers", ()) + .unwrap(); + let message = "Hello, World! I am executing inside of a VM with debugger attached :)\n".to_string(); multi_use_sandbox_dbg @@ -103,54 +107,52 @@ mod tests { use hyperlight_host::{Result, new_error}; use io::{BufReader, BufWriter, Read, Write}; + use serial_test::serial; use super::*; - fn write_cmds_file(cmd_file_path: &str, out_file_path: &str) -> io::Result<()> { - let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("Failed to get manifest dir"); + #[cfg(not(windows))] + const GDB_COMMAND: &str = "rust-gdb"; + #[cfg(windows)] + const GDB_COMMAND: &str = "gdb"; + + fn write_cmds_file(cmd_file_path: &str, cmd: &str) -> io::Result<()> { let file = File::create(cmd_file_path)?; let mut writer = BufWriter::new(file); // write from string to file - writer.write_all( - format!( - "file {manifest_dir}/../tests/rust_guests/bin/debug/simpleguest - target remote :8080 - - set pagination off - set logging file {out_file_path} - set logging on - - break hyperlight_main - commands - echo \"Stopped at hyperlight_main breakpoint\\n\" - backtrace - continue - end - - continue - - set logging off - quit - " - ) - .as_bytes(), - )?; + writer.write_all(cmd.as_bytes())?; writer.flush() } - fn run_guest_and_gdb(cmd_file_path: &str, out_file_path: &str) -> Result<()> { + fn run_guest_and_gdb( + cmd_file_path: &str, + out_file_path: &str, + cmd: &str, + checker: fn(String) -> bool, + ) -> Result<()> { // write gdb commands to file - write_cmds_file(&cmd_file_path, &out_file_path) - .expect("Failed to write gdb commands to file"); + write_cmds_file(&cmd_file_path, cmd).expect("Failed to write gdb commands to file"); #[cfg(mshv2)] // mshv3 is a default feature is mutually exclusive with the mshv2 feature let features = "gdb,mshv2"; #[cfg(not(mshv2))] let features = "gdb"; + // build it before running to avoid a race condition below + let mut guest_child = Command::new("cargo") + .arg("build") + .arg("--example") + .arg("guest-debugging") + .arg("--features") + .arg(features) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .status() + .map_err(|e| new_error!("Failed to build guest process: {}", e))?; + let mut guest_child = Command::new("cargo") .arg("run") .arg("--example") @@ -165,7 +167,7 @@ mod tests { // wait 3 seconds for the gdb to connect thread::sleep(Duration::from_secs(3)); - let mut gdb = Command::new("rust-gdb") + let mut gdb = Command::new(GDB_COMMAND) .arg("--nw") .arg("--batch") .arg("-x") @@ -215,17 +217,17 @@ mod tests { } } - check_output(&out_file_path) + check_output(&out_file_path, checker) } - fn check_output(out_file_path: &str) -> Result<()> { + fn check_output(out_file_path: &str, checker: fn(contents: String) -> bool) -> Result<()> { let results = File::open(out_file_path) .map_err(|e| new_error!("Failed to open gdb.output file: {}", e))?; let mut reader = BufReader::new(results); let mut contents = String::new(); reader.read_to_string(&mut contents).unwrap(); - if contents.contains("Stopped at hyperlight_main breakpoint") { + if checker(contents) { Ok(()) } else { Err(new_error!( @@ -247,12 +249,95 @@ mod tests { } #[test] + #[serial] fn test_gdb_end_to_end() { let out_dir = std::env::var("OUT_DIR").expect("Failed to get out dir"); + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR") + .expect("Failed to get manifest dir") + .replace('\\', "/"); let out_file_path = format!("{out_dir}/gdb.output"); let cmd_file_path = format!("{out_dir}/gdb-commands.txt"); - let result = run_guest_and_gdb(&cmd_file_path, &out_file_path); + let cmd = format!( + "file {manifest_dir}/../tests/rust_guests/bin/debug/simpleguest + target remote :8080 + + set pagination off + set logging file {out_file_path} + set logging on + + break hyperlight_main + commands + echo \"Stopped at hyperlight_main breakpoint\\n\" + backtrace + + continue + end + + continue + + set logging off + quit + " + ); + + #[cfg(windows)] + let cmd = format!("set osabi none\n{}", cmd); + + let checker = |contents: String| contents.contains("Stopped at hyperlight_main breakpoint"); + + let result = run_guest_and_gdb(&cmd_file_path, &out_file_path, &cmd, checker); + + // cleanup + let cleanup_result = cleanup(&out_file_path, &cmd_file_path); + assert!(cleanup_result.is_ok(), "{}", cleanup_result.unwrap_err()); + // check if the test passed - done at the end to ensure cleanup is done + assert!(result.is_ok(), "{}", result.unwrap_err()); + } + + #[test] + #[serial] + fn test_gdb_sse_check() { + let out_dir = std::env::var("OUT_DIR").expect("Failed to get out dir"); + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR") + .expect("Failed to get manifest dir") + .replace('\\', "/"); + println!("manifest dir {manifest_dir}"); + let out_file_path = format!("{out_dir}/gdb-sse.output"); + let cmd_file_path = format!("{out_dir}/gdb-sse--commands.txt"); + + let cmd = format!( + "file {manifest_dir}/../tests/rust_guests/bin/debug/simpleguest + target remote :8080 + + set pagination off + set logging file {out_file_path} + set logging on + + break main.rs:simpleguest::use_sse2_registers + commands 1 + print $xmm1.v4_float + break +2 + commands 2 + print $xmm1.v4_float + continue + end + continue + end + + + continue + + set logging off + quit + " + ); + + #[cfg(windows)] + let cmd = format!("set osabi none\n{}", cmd); + + let checker = |contents: String| contents.contains("$2 = [1.20000005, 0, 0, 0]"); + let result = run_guest_and_gdb(&cmd_file_path, &out_file_path, &cmd, checker); // cleanup let cleanup_result = cleanup(&out_file_path, &cmd_file_path); diff --git a/src/hyperlight_host/src/error.rs b/src/hyperlight_host/src/error.rs index d2fb382a0..9ecce9968 100644 --- a/src/hyperlight_host/src/error.rs +++ b/src/hyperlight_host/src/error.rs @@ -71,7 +71,7 @@ pub enum HyperlightError { /// A disallowed syscall was caught #[error("Seccomp filter trapped on disallowed syscall (check STDERR for offending syscall)")] - #[cfg(all(feature = "seccomp", target_os = "linux"))] + #[cfg(seccomp)] DisallowedSyscall, /// A generic error with a message @@ -218,12 +218,12 @@ pub enum HyperlightError { /// a backend error occurred with seccomp filters #[error("Backend Error with Seccomp Filter {0:?}")] - #[cfg(all(feature = "seccomp", target_os = "linux"))] + #[cfg(seccomp)] SeccompFilterBackendError(#[from] seccompiler::BackendError), /// an error occurred with seccomp filters #[error("Error with Seccomp Filter {0:?}")] - #[cfg(all(feature = "seccomp", target_os = "linux"))] + #[cfg(seccomp)] SeccompFilterError(#[from] seccompiler::Error), /// Tried to restore snapshot to a sandbox that is not the same as the one the snapshot was taken from diff --git a/src/hyperlight_host/src/func/host_functions.rs b/src/hyperlight_host/src/func/host_functions.rs index 871d04c97..a0fcbb52f 100644 --- a/src/hyperlight_host/src/func/host_functions.rs +++ b/src/hyperlight_host/src/func/host_functions.rs @@ -35,7 +35,7 @@ pub trait Registerable { ) -> Result<()>; /// Register a primitive host function whose worker thread has /// extra permissive seccomp filters installed - #[cfg(all(feature = "seccomp", target_os = "linux"))] + #[cfg(seccomp)] fn register_host_function_with_syscalls( &mut self, name: &str, @@ -63,7 +63,7 @@ impl Registerable for UninitializedSandbox { (*hfs).register_host_function(name.to_string(), entry, &mut self.mgr) } - #[cfg(all(feature = "seccomp", target_os = "linux"))] + #[cfg(seccomp)] fn register_host_function_with_syscalls( &mut self, name: &str, diff --git a/src/hyperlight_host/src/hypervisor/gdb/hyperv_debug.rs b/src/hyperlight_host/src/hypervisor/gdb/hyperv_debug.rs index 7a902d6de..c6528f8ab 100644 --- a/src/hyperlight_host/src/hypervisor/gdb/hyperv_debug.rs +++ b/src/hyperlight_host/src/hypervisor/gdb/hyperv_debug.rs @@ -211,6 +211,18 @@ impl GuestDebug for HypervDebug { regs.rip = vcpu_regs.rip; regs.rflags = vcpu_regs.rflags; + // Fetch XMM from WHVP + if let Ok(fpu) = vcpu_fd.get_fpu() { + regs.xmm = [ + fpu.xmm0, fpu.xmm1, fpu.xmm2, fpu.xmm3, fpu.xmm4, fpu.xmm5, fpu.xmm6, fpu.xmm7, + fpu.xmm8, fpu.xmm9, fpu.xmm10, fpu.xmm11, fpu.xmm12, fpu.xmm13, fpu.xmm14, + fpu.xmm15, + ]; + regs.mxcsr = fpu.mxcsr; + } else { + log::warn!("Failed to read FPU/XMM via WHVP for debug registers"); + } + Ok(()) } @@ -226,7 +238,7 @@ impl GuestDebug for HypervDebug { fn write_regs(&self, vcpu_fd: &Self::Vcpu, regs: &X86_64Regs) -> Result<()> { log::debug!("Write registers"); - let regs = WHvGeneralRegisters { + let gprs = WHvGeneralRegisters { rax: regs.rax, rbx: regs.rbx, rcx: regs.rcx, @@ -249,7 +261,37 @@ impl GuestDebug for HypervDebug { }; vcpu_fd - .set_general_purpose_registers(®s) + .set_general_purpose_registers(&gprs) + .map_err(|e| new_error!("Could not write guest registers: {:?}", e))?; + + // Load existing FPU state, replace XMM and MXCSR, and write it back. + let mut fpu = match vcpu_fd.get_fpu() { + Ok(f) => f, + Err(e) => { + return Err(new_error!("Could not write guest registers: {:?}", e)); + } + }; + + fpu.xmm0 = regs.xmm[0]; + fpu.xmm1 = regs.xmm[1]; + fpu.xmm2 = regs.xmm[2]; + fpu.xmm3 = regs.xmm[3]; + fpu.xmm4 = regs.xmm[4]; + fpu.xmm5 = regs.xmm[5]; + fpu.xmm6 = regs.xmm[6]; + fpu.xmm7 = regs.xmm[7]; + fpu.xmm8 = regs.xmm[8]; + fpu.xmm9 = regs.xmm[9]; + fpu.xmm10 = regs.xmm[10]; + fpu.xmm11 = regs.xmm[11]; + fpu.xmm12 = regs.xmm[12]; + fpu.xmm13 = regs.xmm[13]; + fpu.xmm14 = regs.xmm[14]; + fpu.xmm15 = regs.xmm[15]; + fpu.mxcsr = regs.mxcsr; + + vcpu_fd + .set_fpu(&fpu) .map_err(|e| new_error!("Could not write guest registers: {:?}", e)) } } diff --git a/src/hyperlight_host/src/hypervisor/gdb/kvm_debug.rs b/src/hyperlight_host/src/hypervisor/gdb/kvm_debug.rs index c20b3b279..fdd6943fa 100644 --- a/src/hyperlight_host/src/hypervisor/gdb/kvm_debug.rs +++ b/src/hyperlight_host/src/hypervisor/gdb/kvm_debug.rs @@ -193,6 +193,30 @@ impl GuestDebug for KvmDebug { regs.rip = vcpu_regs.rip; regs.rflags = vcpu_regs.rflags; + // Read XMM registers from FPU state + // note kvm get_fpu doesn't actually set or read the mxcsr value + // https://elixir.bootlin.com/linux/v6.16/source/arch/x86/kvm/x86.c#L12229 + match vcpu_fd.get_fpu() { + Ok(fpu) => { + // Convert KVM XMM registers ([u8; 16] x 16) to [u128; 16] + regs.xmm = fpu.xmm.map(u128::from_le_bytes); + } + Err(e) => { + log::warn!("Failed to read FPU state for XMM registers: {:?}", e); + } + } + + // Read MXCSR from XSAVE (MXCSR is at byte offset 24 -> u32 index 6) + // 11.5.10 Mode-Specific XSAVE/XRSTOR State Management + match vcpu_fd.get_xsave() { + Ok(xsave) => { + regs.mxcsr = xsave.region[6]; + } + Err(e) => { + log::warn!("Failed to read XSAVE for MXCSR: {:?}", e); + } + } + Ok(()) } @@ -238,6 +262,38 @@ impl GuestDebug for KvmDebug { vcpu_fd .set_regs(&new_regs) - .map_err(|e| new_error!("Could not write guest registers: {:?}", e)) + .map_err(|e| new_error!("Could not write guest registers: {:?}", e))?; + + // load existing values and replace the xmm registers + let mut fpu = match vcpu_fd.get_fpu() { + Ok(fpu) => fpu, + Err(e) => { + return Err(new_error!("Could not write guest registers: {:?}", e)); + } + }; + + // Convert XMM registers from [u128; 16] (our internal representation) + // to [[u8; 16]; 16] (KVM FPU representation) using little-endian byte order. + fpu.xmm = regs.xmm.map(u128::to_le_bytes); + vcpu_fd + .set_fpu(&fpu) + .map_err(|e| new_error!("Could not write guest registers: {:?}", e))?; + + // Update MXCSR using XSAVE region entry 6 (MXCSR) if available. + let mut xsave = match vcpu_fd.get_xsave() { + Ok(xsave) => xsave, + Err(e) => { + return Err(new_error!("Could not write guest registers: {:?}", e)); + } + }; + + xsave.region[6] = regs.mxcsr; + unsafe { + vcpu_fd + .set_xsave(&xsave) + .map_err(|e| new_error!("Could not write guest registers: {:?}", e))? + }; + + Ok(()) } } diff --git a/src/hyperlight_host/src/hypervisor/gdb/mod.rs b/src/hyperlight_host/src/hypervisor/gdb/mod.rs index eac14f323..e8daf5aa9 100644 --- a/src/hyperlight_host/src/hypervisor/gdb/mod.rs +++ b/src/hyperlight_host/src/hypervisor/gdb/mod.rs @@ -109,6 +109,8 @@ pub(crate) struct X86_64Regs { pub(crate) r15: u64, pub(crate) rip: u64, pub(crate) rflags: u64, + pub(crate) xmm: [u128; 16], + pub(crate) mxcsr: u32, } /// Defines the possible reasons for which a vCPU can be stopped when debugging @@ -140,7 +142,7 @@ pub(crate) enum DebugMsg { RemoveSwBreakpoint(u64), Step, WriteAddr(u64, Vec), - WriteRegisters(X86_64Regs), + WriteRegisters(Box), } /// Enumerates the possible responses that a hypervisor can provide to a debugger @@ -155,7 +157,7 @@ pub(crate) enum DebugResponse { NotAllowed, InterruptHandle(Arc), ReadAddr(Vec), - ReadRegisters(X86_64Regs), + ReadRegisters(Box), RemoveHwBreakpoint(bool), RemoveSwBreakpoint(bool), Step, @@ -449,7 +451,7 @@ mod tests { let res = gdb_conn.try_recv(); assert!(res.is_err()); - let res = hyp_conn.send(DebugResponse::ReadRegisters(X86_64Regs::default())); + let res = hyp_conn.send(DebugResponse::ReadRegisters(Box::default())); assert!(res.is_ok()); let res = gdb_conn.recv(); diff --git a/src/hyperlight_host/src/hypervisor/gdb/mshv_debug.rs b/src/hyperlight_host/src/hypervisor/gdb/mshv_debug.rs index 9688d9ed1..540581426 100644 --- a/src/hyperlight_host/src/hypervisor/gdb/mshv_debug.rs +++ b/src/hyperlight_host/src/hypervisor/gdb/mshv_debug.rs @@ -220,6 +220,18 @@ impl GuestDebug for MshvDebug { regs.rip = vcpu_regs.rip; regs.rflags = vcpu_regs.rflags; + // Try to read XMM from the FPU state + match vcpu_fd.get_fpu() { + Ok(fpu) => { + // MSHV exposes XMM as [[u8; 16]; 16]. Convert to [u128; 16] + regs.xmm = fpu.xmm.map(u128::from_le_bytes); + regs.mxcsr = fpu.mxcsr; + } + Err(e) => { + log::warn!("Failed to read FPU state for XMM registers (MSHV): {:?}", e); + } + } + Ok(()) } @@ -262,6 +274,21 @@ impl GuestDebug for MshvDebug { vcpu_fd .set_regs(&new_regs) + .map_err(|e| new_error!("Could not write guest registers: {:?}", e))?; + + // Load existing FPU state, replace XMM and MXCSR, and write it back. + let mut fpu = match vcpu_fd.get_fpu() { + Ok(f) => f, + Err(e) => { + return Err(new_error!("Could not write guest registers: {:?}", e)); + } + }; + + fpu.xmm = regs.xmm.map(u128::to_le_bytes); + fpu.mxcsr = regs.mxcsr; + + vcpu_fd + .set_fpu(&fpu) .map_err(|e| new_error!("Could not write guest registers: {:?}", e)) } } diff --git a/src/hyperlight_host/src/hypervisor/gdb/x86_64_target.rs b/src/hyperlight_host/src/hypervisor/gdb/x86_64_target.rs index a3e36ebb7..3a67d3017 100644 --- a/src/hyperlight_host/src/hypervisor/gdb/x86_64_target.rs +++ b/src/hyperlight_host/src/hypervisor/gdb/x86_64_target.rs @@ -227,6 +227,8 @@ impl SingleThreadBase for HyperlightSandboxTarget { regs.regs[15] = read_regs.r15; regs.rip = read_regs.rip; regs.eflags = read_regs.rflags as u32; + regs.xmm = read_regs.xmm; + regs.mxcsr = read_regs.mxcsr; Ok(()) } @@ -267,9 +269,11 @@ impl SingleThreadBase for HyperlightSandboxTarget { r15: regs.regs[15], rip: regs.rip, rflags: u64::from(regs.eflags), + xmm: regs.xmm, + mxcsr: regs.mxcsr, }; - match self.send_command(DebugMsg::WriteRegisters(regs))? { + match self.send_command(DebugMsg::WriteRegisters(Box::new(regs)))? { DebugResponse::WriteRegisters => Ok(()), DebugResponse::NotAllowed => { log::error!("Action not allowed at this time, crash might have occurred"); @@ -482,7 +486,7 @@ mod tests { // Check response to read registers - send the response first to not be blocked // by the recv call in the target - let msg = DebugResponse::ReadRegisters(X86_64Regs::default()); + let msg = DebugResponse::ReadRegisters(Box::default()); let res = gdb_conn.send(msg); assert!(res.is_ok()); diff --git a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs index aaef9316d..5a009823e 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs @@ -202,7 +202,7 @@ mod debug { e }) - .map(|_| DebugResponse::ReadRegisters(regs)) + .map(|_| DebugResponse::ReadRegisters(Box::new(regs))) } DebugMsg::RemoveHwBreakpoint(addr) => Ok(DebugResponse::RemoveHwBreakpoint( debug diff --git a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs index 620910004..e9aa45703 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs @@ -185,7 +185,7 @@ mod debug { e }) - .map(|_| DebugResponse::ReadRegisters(regs)) + .map(|_| DebugResponse::ReadRegisters(Box::new(regs))) } DebugMsg::RemoveHwBreakpoint(addr) => Ok(DebugResponse::RemoveHwBreakpoint( debug diff --git a/src/hyperlight_host/src/hypervisor/kvm.rs b/src/hyperlight_host/src/hypervisor/kvm.rs index a69b51f55..36a7066b6 100644 --- a/src/hyperlight_host/src/hypervisor/kvm.rs +++ b/src/hyperlight_host/src/hypervisor/kvm.rs @@ -194,7 +194,7 @@ mod debug { e }) - .map(|_| DebugResponse::ReadRegisters(regs)) + .map(|_| DebugResponse::ReadRegisters(Box::new(regs))) } DebugMsg::RemoveHwBreakpoint(addr) => Ok(DebugResponse::RemoveHwBreakpoint( debug @@ -586,6 +586,9 @@ impl Hypervisor for KVMDriver { mxcsr: MXCSR_DEFAULT, ..Default::default() // zero out the rest }; + + // note kvm set_fpu doesn't actually set or read the mxcsr value + // https://elixir.bootlin.com/linux/v6.16/source/arch/x86/kvm/x86.c#L12229 self.vcpu_fd.set_fpu(&fpu)?; // run diff --git a/src/hyperlight_host/src/hypervisor/windows_hypervisor_platform.rs b/src/hyperlight_host/src/hypervisor/windows_hypervisor_platform.rs index 3d97de9ea..2212fd433 100644 --- a/src/hyperlight_host/src/hypervisor/windows_hypervisor_platform.rs +++ b/src/hyperlight_host/src/hypervisor/windows_hypervisor_platform.rs @@ -696,6 +696,125 @@ impl VMProcessor { Ok(()) } + #[cfg(gdb)] + pub(super) fn get_fpu(&self) -> Result { + use windows::Win32::System::Hypervisor::*; + + const LEN: usize = 26; + let names: [WHV_REGISTER_NAME; LEN] = [ + WHvX64RegisterXmm0, + WHvX64RegisterXmm1, + WHvX64RegisterXmm2, + WHvX64RegisterXmm3, + WHvX64RegisterXmm4, + WHvX64RegisterXmm5, + WHvX64RegisterXmm6, + WHvX64RegisterXmm7, + WHvX64RegisterXmm8, + WHvX64RegisterXmm9, + WHvX64RegisterXmm10, + WHvX64RegisterXmm11, + WHvX64RegisterXmm12, + WHvX64RegisterXmm13, + WHvX64RegisterXmm14, + WHvX64RegisterXmm15, + WHvX64RegisterFpMmx0, + WHvX64RegisterFpMmx1, + WHvX64RegisterFpMmx2, + WHvX64RegisterFpMmx3, + WHvX64RegisterFpMmx4, + WHvX64RegisterFpMmx5, + WHvX64RegisterFpMmx6, + WHvX64RegisterFpMmx7, + WHvX64RegisterFpControlStatus, + WHvX64RegisterXmmControlStatus, + ]; + + let mut out: [WHV_REGISTER_VALUE; LEN] = unsafe { std::mem::zeroed() }; + unsafe { + WHvGetVirtualProcessorRegisters( + self.get_partition_hdl(), + 0, + names.as_ptr(), + LEN as u32, + out.as_mut_ptr(), + )?; + + // Helper to read a WHV_UINT128 -> u128 + fn u128_from_whv(fp: WHV_REGISTER_VALUE) -> u128 { + unsafe { + let low = fp.Fp.AsUINT128.Anonymous.Low64 as u128; + let high = fp.Fp.AsUINT128.Anonymous.High64 as u128; + (high << 64) | low + } + } + + let xmm = [ + u128_from_whv(out[0]), + u128_from_whv(out[1]), + u128_from_whv(out[2]), + u128_from_whv(out[3]), + u128_from_whv(out[4]), + u128_from_whv(out[5]), + u128_from_whv(out[6]), + u128_from_whv(out[7]), + u128_from_whv(out[8]), + u128_from_whv(out[9]), + u128_from_whv(out[10]), + u128_from_whv(out[11]), + u128_from_whv(out[12]), + u128_from_whv(out[13]), + u128_from_whv(out[14]), + u128_from_whv(out[15]), + ]; + + let mmx = [ + out[16].Reg64, + out[17].Reg64, + out[18].Reg64, + out[19].Reg64, + out[20].Reg64, + out[21].Reg64, + out[22].Reg64, + out[23].Reg64, + ]; + + let fp_control_word = out[24].FpControlStatus.Anonymous.FpControl; + let fp_tag_word = out[24].FpControlStatus.Anonymous.FpTag; + let mxcsr = out[25].XmmControlStatus.Anonymous.XmmStatusControl; + + Ok(WHvFPURegisters { + xmm0: xmm[0], + xmm1: xmm[1], + xmm2: xmm[2], + xmm3: xmm[3], + xmm4: xmm[4], + xmm5: xmm[5], + xmm6: xmm[6], + xmm7: xmm[7], + xmm8: xmm[8], + xmm9: xmm[9], + xmm10: xmm[10], + xmm11: xmm[11], + xmm12: xmm[12], + xmm13: xmm[13], + xmm14: xmm[14], + xmm15: xmm[15], + mmx0: mmx[0], + mmx1: mmx[1], + mmx2: mmx[2], + mmx3: mmx[3], + mmx4: mmx[4], + mmx5: mmx[5], + mmx6: mmx[6], + mmx7: mmx[7], + fp_control_word, + fp_tag_word, + mxcsr, + }) + } + } + #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] pub(super) fn run(&mut self) -> Result { let partition_handle = self.get_partition_hdl(); diff --git a/src/hyperlight_host/src/lib.rs b/src/hyperlight_host/src/lib.rs index 34c7ddd2a..10e8a898a 100644 --- a/src/hyperlight_host/src/lib.rs +++ b/src/hyperlight_host/src/lib.rs @@ -76,7 +76,7 @@ pub mod metrics; /// outside this file. Types from this module needed for public consumption are /// re-exported below. pub mod sandbox; -#[cfg(all(feature = "seccomp", target_os = "linux"))] +#[cfg(seccomp)] pub(crate) mod seccomp; /// Signal handling for Linux #[cfg(target_os = "linux")] diff --git a/src/hyperlight_host/src/mem/shared_mem.rs b/src/hyperlight_host/src/mem/shared_mem.rs index 84cbb4c8e..030c2c958 100644 --- a/src/hyperlight_host/src/mem/shared_mem.rs +++ b/src/hyperlight_host/src/mem/shared_mem.rs @@ -1230,10 +1230,17 @@ mod tests { #[test] fn guard_page_testing_shim() { let tests = vec!["read", "write", "exec"]; - for test in tests { + let triple = std::env::var("TARGET_TRIPLE").ok(); + let target_args = if let Some(triple) = triple.filter(|t| !t.is_empty()) { + vec!["--target".to_string(), triple.to_string()] + } else { + vec![] + }; let status = std::process::Command::new("cargo") - .args(["test", "-p", "hyperlight-host", "--", "--ignored", test]) + .args(["test", "-p", "hyperlight-host"]) + .args(target_args) + .args(["--", "--ignored", test]) .stdin(std::process::Stdio::null()) .stdout(std::process::Stdio::null()) .stderr(std::process::Stdio::null()) diff --git a/src/hyperlight_host/src/metrics/mod.rs b/src/hyperlight_host/src/metrics/mod.rs index 76e9b93a3..67a7b0eca 100644 --- a/src/hyperlight_host/src/metrics/mod.rs +++ b/src/hyperlight_host/src/metrics/mod.rs @@ -133,7 +133,7 @@ mod tests { if #[cfg(feature = "function_call_metrics")] { use metrics::Label; - let expected_num_metrics = if cfg!(all(feature = "seccomp", target_os = "linux")) { + let expected_num_metrics = if cfg!(all(seccomp)) { 3 // if seccomp enabled, the host call duration metric is emitted on a separate thread which this local recorder doesn't capture } else { 4 @@ -186,7 +186,7 @@ mod tests { "Histogram metric does not match expected value" ); - if !cfg!(all(feature = "seccomp", target_os = "linux")) { + if !cfg!(all(seccomp)) { // 4. Host call duration let histogram_key = CompositeKey::new( metrics_util::MetricKind::Histogram, diff --git a/src/hyperlight_host/src/sandbox/host_funcs.rs b/src/hyperlight_host/src/sandbox/host_funcs.rs index 6d3c8d98a..b61a2cd77 100644 --- a/src/hyperlight_host/src/sandbox/host_funcs.rs +++ b/src/hyperlight_host/src/sandbox/host_funcs.rs @@ -154,7 +154,7 @@ pub(super) fn default_writer_func(s: String) -> Result { } } -#[cfg(all(feature = "seccomp", target_os = "linux"))] +#[cfg(seccomp)] fn maybe_with_seccomp( name: &str, syscalls: Option<&[ExtraAllowedSyscall]>, @@ -199,7 +199,7 @@ fn maybe_with_seccomp( }) } -#[cfg(not(all(feature = "seccomp", target_os = "linux")))] +#[cfg(not(seccomp))] fn maybe_with_seccomp( _name: &str, _syscalls: Option<&[ExtraAllowedSyscall]>, diff --git a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs index fc860caf6..b80a7c960 100644 --- a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs +++ b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs @@ -625,7 +625,7 @@ mod tests { let res: Result = sbox.call("ViolateSeccompFilters", ()); - #[cfg(feature = "seccomp")] + #[cfg(seccomp)] match res { Ok(_) => panic!("Expected to fail due to seccomp violation"), Err(e) => match e { @@ -634,7 +634,7 @@ mod tests { }, } - #[cfg(not(feature = "seccomp"))] + #[cfg(not(seccomp))] match res { Ok(_) => (), Err(e) => panic!("Expected to succeed without seccomp: {}", e), @@ -642,7 +642,7 @@ mod tests { } // Second, run with allowing `SYS_getpid` - #[cfg(feature = "seccomp")] + #[cfg(seccomp)] { let mut usbox = UninitializedSandbox::new( GuestBinary::FilePath(simple_guest_as_string().expect("Guest Binary Missing")), @@ -719,7 +719,7 @@ mod tests { ) .expect("Expected to call host function that returns i64"); - if cfg!(feature = "seccomp") { + if cfg!(seccomp) { // If seccomp is enabled, we expect the syscall to return EACCES, as setup by our seccomp filter assert_eq!(host_func_result, -libc::EACCES as i64); } else { @@ -728,7 +728,7 @@ mod tests { } } - #[cfg(feature = "seccomp")] + #[cfg(seccomp)] { // Now let's make sure if we register the `openat` syscall as an extra allowed syscall, it will succeed let mut ubox = UninitializedSandbox::new( diff --git a/src/hyperlight_host/src/sandbox/mod.rs b/src/hyperlight_host/src/sandbox/mod.rs index 2f8bee004..b63357d40 100644 --- a/src/hyperlight_host/src/sandbox/mod.rs +++ b/src/hyperlight_host/src/sandbox/mod.rs @@ -58,7 +58,6 @@ pub use uninitialized::UninitializedSandbox; #[cfg(target_os = "windows")] use crate::hypervisor::windows_hypervisor_platform; -use crate::mem::shared_mem::HostSharedMemory; // In case its not obvious why there are separate is_supported_platform and is_hypervisor_present functions its because // Hyperlight is designed to be able to run on a host that doesn't have a hypervisor. diff --git a/src/hyperlight_host/src/sandbox/uninitialized.rs b/src/hyperlight_host/src/sandbox/uninitialized.rs index f952c6bd7..c4b08da2f 100644 --- a/src/hyperlight_host/src/sandbox/uninitialized.rs +++ b/src/hyperlight_host/src/sandbox/uninitialized.rs @@ -35,7 +35,7 @@ use crate::mem::shared_mem::ExclusiveSharedMemory; use crate::sandbox::SandboxConfiguration; use crate::{MultiUseSandbox, Result, new_error}; -#[cfg(all(target_os = "linux", feature = "seccomp"))] +#[cfg(seccomp)] const EXTRA_ALLOWED_SYSCALLS_FOR_WRITER_FUNC: &[super::ExtraAllowedSyscall] = &[ // Fuzzing fails without `mmap` being an allowed syscall on our seccomp filter. // All fuzzing does is call `PrintOutput` (which calls `HostPrint` ). Thing is, `println!` @@ -92,18 +92,6 @@ impl Debug for UninitializedSandbox { } } -impl UninitializedSandbox { - /// Creates and initializes the virtual machine, transforming this into a ready-to-use sandbox. - /// - /// This method consumes the `UninitializedSandbox` and performs the final initialization - /// steps to create the underlying virtual machine. Once evolved, the resulting - /// [`MultiUseSandbox`] can execute guest code and handle function calls. - #[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")] - pub fn evolve(self) -> Result { - evolve_impl_multi_use(self) - } -} - /// A `GuestBinary` is either a buffer or the file path to some data (e.g., a guest binary). #[derive(Debug)] pub enum GuestBinary<'a> { @@ -265,6 +253,16 @@ impl UninitializedSandbox { Ok(sandbox) } + /// Creates and initializes the virtual machine, transforming this into a ready-to-use sandbox. + /// + /// This method consumes the `UninitializedSandbox` and performs the final initialization + /// steps to create the underlying virtual machine. Once evolved, the resulting + /// [`MultiUseSandbox`] can execute guest code and handle function calls. + #[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")] + pub fn evolve(self) -> Result { + evolve_impl_multi_use(self) + } + /// Load the file at `bin_path_str` into a PE file, then attempt to /// load the PE file into a `SandboxMemoryManager` and return it. /// @@ -313,7 +311,7 @@ impl UninitializedSandbox { /// /// Unlike [`register`](Self::register), this variant allows specifying extra syscalls /// that will be permitted when the function handler runs. - #[cfg(all(feature = "seccomp", target_os = "linux"))] + #[cfg(seccomp)] pub fn register_with_extra_allowed_syscalls< Args: ParameterTuple, Output: SupportedReturnType, @@ -336,10 +334,10 @@ impl UninitializedSandbox { &mut self, print_func: impl Into>, ) -> Result<()> { - #[cfg(not(all(target_os = "linux", feature = "seccomp")))] + #[cfg(not(seccomp))] self.register("HostPrint", print_func)?; - #[cfg(all(target_os = "linux", feature = "seccomp"))] + #[cfg(seccomp)] self.register_with_extra_allowed_syscalls( "HostPrint", print_func, @@ -353,13 +351,13 @@ impl UninitializedSandbox { /// /// Like [`register_print`](Self::register_print), but allows specifying extra syscalls /// that will be permitted during function execution. - #[cfg(all(feature = "seccomp", target_os = "linux"))] + #[cfg(seccomp)] pub fn register_print_with_extra_allowed_syscalls( &mut self, print_func: impl Into>, extra_allowed_syscalls: impl IntoIterator, ) -> Result<()> { - #[cfg(all(target_os = "linux", feature = "seccomp"))] + #[cfg(seccomp)] self.register_with_extra_allowed_syscalls( "HostPrint", print_func, diff --git a/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs b/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs index f73e334e8..637d71998 100644 --- a/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs +++ b/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +#[cfg(gdb)] use std::sync::{Arc, Mutex}; use rand::Rng; @@ -33,40 +34,16 @@ use crate::mem::ptr_offset::Offset; use crate::mem::shared_mem::GuestSharedMemory; #[cfg(any(feature = "init-paging", target_os = "windows"))] use crate::mem::shared_mem::SharedMemory; -use crate::sandbox::HostSharedMemory; #[cfg(feature = "trace_guest")] use crate::sandbox::TraceInfo; #[cfg(gdb)] use crate::sandbox::config::DebugInfo; -use crate::sandbox::host_funcs::FunctionRegistry; #[cfg(target_os = "linux")] use crate::signal_handlers::setup_signal_handlers; use crate::{MultiUseSandbox, Result, UninitializedSandbox, log_then_return, new_error}; -/// The implementation for evolving `UninitializedSandbox`es to -/// `Sandbox`es. -/// -/// Note that `cb_opt`'s type has been carefully considered. -/// Particularly, it's not using a constrained generic to define -/// the type of the callback because if it did, you'd have to provide -/// type hints to the compiler if you want to pass `None` to the function. -/// With this type signature, you can pass `None` without having to do that. -/// -/// If this doesn't make sense, and you want to change this type, -/// please reach out to a Hyperlight developer before making the change. -#[instrument(err(Debug), skip_all, , parent = Span::current(), level = "Trace")] -fn evolve_impl( - u_sbox: UninitializedSandbox, - transform: TransformFunc, -) -> Result -where - TransformFunc: Fn( - Arc>, - SandboxMemoryManager, - Box, - RawPtr, - ) -> Result, -{ +#[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")] +pub(super) fn evolve_impl_multi_use(u_sbox: UninitializedSandbox) -> Result { let (hshm, mut gshm) = u_sbox.mgr.build(); let mut vm = set_up_hypervisor_partition( &mut gshm, @@ -109,28 +86,19 @@ where return Err(new_error!("Dispatch function address is null")); } - transform( + let dispatch_ptr = RawPtr::from(dispatch_function_addr); + + #[cfg(gdb)] + let dbg_mem_wrapper = Arc::new(Mutex::new(hshm.clone())); + + Ok(MultiUseSandbox::from_uninit( u_sbox.host_funcs, hshm, vm, - RawPtr::from(dispatch_function_addr), - ) -} - -#[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")] -pub(super) fn evolve_impl_multi_use(u_sbox: UninitializedSandbox) -> Result { - evolve_impl(u_sbox, |hf, hshm, vm, dispatch_ptr| { + dispatch_ptr, #[cfg(gdb)] - let dbg_mem_wrapper = Arc::new(Mutex::new(hshm.clone())); - Ok(MultiUseSandbox::from_uninit( - hf, - hshm, - vm, - dispatch_ptr, - #[cfg(gdb)] - dbg_mem_wrapper, - )) - }) + dbg_mem_wrapper, + )) } pub(crate) fn set_up_hypervisor_partition( diff --git a/src/hyperlight_host/src/signal_handlers/mod.rs b/src/hyperlight_host/src/signal_handlers/mod.rs index 1644a7206..43a58977b 100644 --- a/src/hyperlight_host/src/signal_handlers/mod.rs +++ b/src/hyperlight_host/src/signal_handlers/mod.rs @@ -18,7 +18,7 @@ use libc::c_int; use crate::sandbox::SandboxConfiguration; -#[cfg(feature = "seccomp")] +#[cfg(seccomp)] pub mod sigsys_signal_handler; pub(crate) fn setup_signal_handlers(config: &SandboxConfiguration) -> crate::Result<()> { @@ -27,7 +27,7 @@ pub(crate) fn setup_signal_handlers(config: &SandboxConfiguration) -> crate::Res // Anything that performs memory allocations, locks, and others are non-async-signal-safe. // Hyperlight signal handlers are all designed to be async-signal-safe, so this function // should be safe to call. - #[cfg(feature = "seccomp")] + #[cfg(seccomp)] { use std::sync::Once; diff --git a/src/hyperlight_host/src/signal_handlers/sigsys_signal_handler.rs b/src/hyperlight_host/src/signal_handlers/sigsys_signal_handler.rs index 1bab82e1e..0202873f5 100644 --- a/src/hyperlight_host/src/signal_handlers/sigsys_signal_handler.rs +++ b/src/hyperlight_host/src/signal_handlers/sigsys_signal_handler.rs @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -#[cfg(feature = "seccomp")] +#[cfg(seccomp)] pub(super) extern "C" fn handle_sigsys( signal: i32, info: *mut libc::siginfo_t, diff --git a/src/hyperlight_host/tests/integration_test.rs b/src/hyperlight_host/tests/integration_test.rs index 8b2077a19..68d5ebbaf 100644 --- a/src/hyperlight_host/tests/integration_test.rs +++ b/src/hyperlight_host/tests/integration_test.rs @@ -49,10 +49,10 @@ fn interrupt_host_call() { Ok(()) }; - #[cfg(any(target_os = "windows", not(feature = "seccomp")))] + #[cfg(any(target_os = "windows", not(seccomp)))] usbox.register("Spin", spin).unwrap(); - #[cfg(all(target_os = "linux", feature = "seccomp"))] + #[cfg(seccomp)] usbox .register_with_extra_allowed_syscalls("Spin", spin, vec![libc::SYS_clock_nanosleep]) .unwrap(); @@ -765,3 +765,24 @@ fn log_test_messages(levelfilter: Option) { .unwrap(); } } + +/// Tests whether host is able to return Bool as return type +/// or not +#[test] +fn test_if_guest_is_able_to_get_return_values_from_host() { + let mut sbox1 = new_uninit().unwrap(); + + sbox1.register("HostBool", |a: i32, b: i32| a + b > 10); + + for i in 1..10 { + if i < 6 { + let res = sbox1.call::<()>("HostReturnsBoolValue", (i, i)).unwrap_err(); + println!("{:?}", res); + assert!(matches!(res, false)); + } else { + let res = sbox1.call::<()>("HostReturnsBoolValue", (i, i)).unwrap_err(); + println!("{:?}", res); + assert!(matches!(res, true)); + } + } +} \ No newline at end of file diff --git a/src/tests/c_guests/c_simpleguest/main.c b/src/tests/c_guests/c_simpleguest/main.c index 2822b108d..e9cc1f803 100644 --- a/src/tests/c_guests/c_simpleguest/main.c +++ b/src/tests/c_guests/c_simpleguest/main.c @@ -256,6 +256,29 @@ int guest_function(const char *from_host) { return 0; } + +bool guest_fn_checks_if_host_returns_bool_value(int32_t a, int32_t b) { + char guest_message[256] = "Hello from host_returns_bool_value, "; + int len = strlen(guest_message); + + hl_Parameter params[2]; + + params[0].tag = hl_ParameterType_Int; + params[0].value.Int = a; + + params[1].tag = hl_ParameterType_Int; + params[1].value.Int = b; + + const hl_FunctionCall host_call = {.function_name = "HostBool", + .parameters = ¶ms, + .parameters_len = 2, + .return_type = hl_ReturnType_Bool + }; + hl_call_host_function(&host_call); + return hl_get_host_return_value_as_Bool(); +} + +HYPERLIGHT_WRAP_FUNCTION(guest_fn_checks_if_host_returns_bool_value, Bool, 2, Int, Int) HYPERLIGHT_WRAP_FUNCTION(echo, String, 1, String) // HYPERLIGHT_WRAP_FUNCTION(set_byte_array_to_zero, 1, VecBytes) is not valid for functions that return VecBytes HYPERLIGHT_WRAP_FUNCTION(guest_function, Int, 1, String) @@ -289,6 +312,7 @@ HYPERLIGHT_WRAP_FUNCTION(log_message, Int, 2, String, Long) void hyperlight_main(void) { + HYPERLIGHT_REGISTER_FUNCTION("HostReturnsBoolValue", guest_fn_checks_if_host_returns_bool_value); HYPERLIGHT_REGISTER_FUNCTION("Echo", echo); // HYPERLIGHT_REGISTER_FUNCTION macro does not work for functions that return VecBytes, // so we use hl_register_function_definition directly diff --git a/src/tests/rust_guests/callbackguest/Cargo.lock b/src/tests/rust_guests/callbackguest/Cargo.lock new file mode 100644 index 000000000..21ba7c47d --- /dev/null +++ b/src/tests/rust_guests/callbackguest/Cargo.lock @@ -0,0 +1,270 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "buddy_system_allocator" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0108968a3a2dab95b089c0fc3f1afa7759aa5ebe6f1d86d206d6f7ba726eb" +dependencies = [ + "spin 0.9.8", +] + +[[package]] +name = "callbackguest" +version = "0.1.0" +dependencies = [ + "hyperlight-common", + "hyperlight-guest", + "hyperlight-guest-bin", + "hyperlight-guest-tracing", +] + +[[package]] +name = "cc" +version = "1.2.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "flatbuffers" +version = "25.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1045398c1bfd89168b5fd3f1fc11f6e70b34f6f66300c87d44d3de849463abf1" +dependencies = [ + "bitflags", + "rustc_version", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "hyperlight-common" +version = "0.8.0" +dependencies = [ + "anyhow", + "flatbuffers", + "log", + "spin 0.10.0", +] + +[[package]] +name = "hyperlight-guest" +version = "0.8.0" +dependencies = [ + "anyhow", + "hyperlight-common", + "hyperlight-guest-tracing", + "serde_json", +] + +[[package]] +name = "hyperlight-guest-bin" +version = "0.8.0" +dependencies = [ + "buddy_system_allocator", + "cc", + "cfg-if", + "glob", + "hyperlight-common", + "hyperlight-guest", + "hyperlight-guest-tracing", + "log", + "spin 0.10.0", +] + +[[package]] +name = "hyperlight-guest-tracing" +version = "0.8.0" +dependencies = [ + "hyperlight-common", + "hyperlight-guest-tracing-macro", + "spin 0.10.0", +] + +[[package]] +name = "hyperlight-guest-tracing-macro" +version = "0.8.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.141" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +dependencies = [ + "lock_api", +] + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" diff --git a/src/tests/rust_guests/dummyguest/Cargo.lock b/src/tests/rust_guests/dummyguest/Cargo.lock index fa3de189b..12437e491 100644 --- a/src/tests/rust_guests/dummyguest/Cargo.lock +++ b/src/tests/rust_guests/dummyguest/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "autocfg" @@ -46,7 +46,7 @@ checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "dummyguest" -version = "0.9.0" +version = "0.10.0" dependencies = [ "hyperlight-common", "hyperlight-guest-bin", @@ -54,9 +54,9 @@ dependencies = [ [[package]] name = "flatbuffers" -version = "25.2.10" +version = "25.9.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1045398c1bfd89168b5fd3f1fc11f6e70b34f6f66300c87d44d3de849463abf1" +checksum = "09b6620799e7340ebd9968d2e0708eb82cf1971e9a16821e2091b6d6e475eed5" dependencies = [ "bitflags", "rustc_version", @@ -70,7 +70,7 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "hyperlight-common" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "flatbuffers", @@ -80,7 +80,7 @@ dependencies = [ [[package]] name = "hyperlight-guest" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "flatbuffers", @@ -91,7 +91,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-bin" -version = "0.9.0" +version = "0.10.0" dependencies = [ "buddy_system_allocator", "cc", @@ -106,7 +106,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-tracing" -version = "0.9.0" +version = "0.10.0" dependencies = [ "hyperlight-common", "hyperlight-guest-tracing-macro", @@ -115,7 +115,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-tracing-macro" -version = "0.9.0" +version = "0.10.0" dependencies = [ "proc-macro2", "quote", @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] diff --git a/src/tests/rust_guests/dummyguest/Cargo.toml b/src/tests/rust_guests/dummyguest/Cargo.toml index 9a35944ec..6c39889b1 100644 --- a/src/tests/rust_guests/dummyguest/Cargo.toml +++ b/src/tests/rust_guests/dummyguest/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dummyguest" -version = "0.9.0" +version = "0.10.0" edition = "2021" diff --git a/src/tests/rust_guests/simpleguest/Cargo.lock b/src/tests/rust_guests/simpleguest/Cargo.lock index 9081da46b..5f9e34407 100644 --- a/src/tests/rust_guests/simpleguest/Cargo.lock +++ b/src/tests/rust_guests/simpleguest/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "autocfg" @@ -46,9 +46,9 @@ checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "flatbuffers" -version = "25.2.10" +version = "25.9.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1045398c1bfd89168b5fd3f1fc11f6e70b34f6f66300c87d44d3de849463abf1" +checksum = "09b6620799e7340ebd9968d2e0708eb82cf1971e9a16821e2091b6d6e475eed5" dependencies = [ "bitflags", "rustc_version", @@ -62,7 +62,7 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "hyperlight-common" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "flatbuffers", @@ -72,7 +72,7 @@ dependencies = [ [[package]] name = "hyperlight-guest" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "flatbuffers", @@ -83,7 +83,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-bin" -version = "0.9.0" +version = "0.10.0" dependencies = [ "buddy_system_allocator", "cc", @@ -98,7 +98,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-tracing" -version = "0.9.0" +version = "0.10.0" dependencies = [ "hyperlight-common", "hyperlight-guest-tracing-macro", @@ -107,7 +107,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-tracing-macro" -version = "0.9.0" +version = "0.10.0" dependencies = [ "proc-macro2", "quote", @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -227,7 +227,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "simpleguest" -version = "0.9.0" +version = "0.10.0" dependencies = [ "hyperlight-common", "hyperlight-guest", diff --git a/src/tests/rust_guests/simpleguest/Cargo.toml b/src/tests/rust_guests/simpleguest/Cargo.toml index 34925b9fc..7700a0758 100644 --- a/src/tests/rust_guests/simpleguest/Cargo.toml +++ b/src/tests/rust_guests/simpleguest/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "simpleguest" -version = "0.9.0" +version = "0.10.0" edition = "2021" [dependencies] diff --git a/src/tests/rust_guests/simpleguest/src/main.rs b/src/tests/rust_guests/simpleguest/src/main.rs index aabe74dc5..681165a60 100644 --- a/src/tests/rust_guests/simpleguest/src/main.rs +++ b/src/tests/rust_guests/simpleguest/src/main.rs @@ -787,6 +787,15 @@ fn call_given_paramless_hostfunc_that_returns_i64(function_call: &FunctionCall) } } +#[hyperlight_guest_tracing::trace_function] +fn use_sse2_registers(_: &FunctionCall) -> Result> { + unsafe { + let val: f32 = 1.2f32; + core::arch::asm!("movss xmm1, DWORD PTR [{0}]", in(reg) &val); + } + Ok(get_flatbuffer_result(())) +} + #[hyperlight_guest_tracing::trace_function] fn add(function_call: &FunctionCall) -> Result> { if let (ParameterValue::Int(a), ParameterValue::Int(b)) = ( @@ -947,7 +956,6 @@ pub extern "C" fn hyperlight_main() { ReturnType::VecBytes, read_from_user_memory as usize, ); - register_function(read_from_user_memory_def); let read_mapped_buffer_def = GuestFunctionDefinition::new( @@ -956,7 +964,6 @@ pub extern "C" fn hyperlight_main() { ReturnType::VecBytes, read_mapped_buffer as usize, ); - register_function(read_mapped_buffer_def); let write_mapped_buffer_def = GuestFunctionDefinition::new( @@ -965,7 +972,6 @@ pub extern "C" fn hyperlight_main() { ReturnType::Bool, write_mapped_buffer as usize, ); - register_function(write_mapped_buffer_def); let exec_mapped_buffer_def = GuestFunctionDefinition::new( @@ -974,7 +980,6 @@ pub extern "C" fn hyperlight_main() { ReturnType::Bool, exec_mapped_buffer as usize, ); - register_function(exec_mapped_buffer_def); let set_static_def = GuestFunctionDefinition::new( @@ -983,7 +988,6 @@ pub extern "C" fn hyperlight_main() { ReturnType::Int, set_static as usize, ); - register_function(set_static_def); let simple_print_output_def = GuestFunctionDefinition::new( @@ -1477,6 +1481,14 @@ pub extern "C" fn hyperlight_main() { call_given_paramless_hostfunc_that_returns_i64 as usize, ); register_function(call_given_hostfunc_def); + + let use_sse2_registers = GuestFunctionDefinition::new( + "UseSSE2Registers".to_string(), + Vec::new(), + ReturnType::Void, + use_sse2_registers as usize, + ); + register_function(use_sse2_registers); } #[hyperlight_guest_tracing::trace_function] diff --git a/src/tests/rust_guests/witguest/Cargo.lock b/src/tests/rust_guests/witguest/Cargo.lock index 6a33cb503..8ab31004c 100644 --- a/src/tests/rust_guests/witguest/Cargo.lock +++ b/src/tests/rust_guests/witguest/Cargo.lock @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "autocfg" @@ -146,9 +146,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "flatbuffers" -version = "25.2.10" +version = "25.9.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1045398c1bfd89168b5fd3f1fc11f6e70b34f6f66300c87d44d3de849463abf1" +checksum = "09b6620799e7340ebd9968d2e0708eb82cf1971e9a16821e2091b6d6e475eed5" dependencies = [ "bitflags", "rustc_version", @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "hyperlight-common" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "flatbuffers", @@ -188,7 +188,7 @@ dependencies = [ [[package]] name = "hyperlight-component-macro" -version = "0.9.0" +version = "0.10.0" dependencies = [ "env_logger", "hyperlight-component-util", @@ -202,7 +202,7 @@ dependencies = [ [[package]] name = "hyperlight-component-util" -version = "0.9.0" +version = "0.10.0" dependencies = [ "itertools", "log", @@ -215,7 +215,7 @@ dependencies = [ [[package]] name = "hyperlight-guest" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "flatbuffers", @@ -226,7 +226,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-bin" -version = "0.9.0" +version = "0.10.0" dependencies = [ "buddy_system_allocator", "cc", @@ -241,7 +241,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-tracing" -version = "0.9.0" +version = "0.10.0" dependencies = [ "hyperlight-common", "hyperlight-guest-tracing-macro", @@ -250,7 +250,7 @@ dependencies = [ [[package]] name = "hyperlight-guest-tracing-macro" -version = "0.9.0" +version = "0.10.0" dependencies = [ "proc-macro2", "quote", @@ -377,9 +377,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -614,7 +614,7 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "witguest" -version = "0.9.0" +version = "0.10.0" dependencies = [ "hyperlight-common", "hyperlight-component-macro", diff --git a/src/tests/rust_guests/witguest/Cargo.toml b/src/tests/rust_guests/witguest/Cargo.toml index 82f87b9f5..fbdb6b15e 100644 --- a/src/tests/rust_guests/witguest/Cargo.toml +++ b/src/tests/rust_guests/witguest/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "witguest" -version = "0.9.0" +version = "0.10.0" edition = "2021" [dependencies] diff --git a/src/trace_dump/Cargo.toml b/src/trace_dump/Cargo.toml index f98c2c251..d72631198 100644 --- a/src/trace_dump/Cargo.toml +++ b/src/trace_dump/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "trace_dump" -version = "0.9.0" +version = "0.10.0" publish = false edition = "2021" diff --git a/src/trace_dump/main.rs b/src/trace_dump/main.rs index 4f8416769..e6d205eb9 100644 --- a/src/trace_dump/main.rs +++ b/src/trace_dump/main.rs @@ -120,10 +120,8 @@ fn dump_trace_record( // With the exception of `> halt`, which decreases the indent (because `> entrypoint` does not // have a corresponding `< entrypoint`) let msg = if msg.starts_with('>') { - if msg == "> halt" { - if *indent > 0 { - *indent -= 1; - } + if msg == "> halt" && *indent > 0 { + *indent -= 1; } let indent_str = " ".repeat(*indent as usize); let msg = format!("{}{}", indent_str, &msg); @@ -174,7 +172,7 @@ impl TraceTrie { let mut node = self; for frame in trace { f(&mut node.value); - node = (*node).children.entry(*frame).or_insert(Self::new()) + node = node.children.entry(*frame).or_insert(Self::new()) } f(&mut node.value); } @@ -185,7 +183,7 @@ struct SymbolCache { symbol_cache: HashMap)>>, } impl SymbolCache { - fn resolve_symbol<'c>(&'c mut self, addr: u64) -> &'c Option<(String, Option)> { + fn resolve_symbol(&mut self, addr: u64) -> &Option<(String, Option)> { self.symbol_cache.entry(addr).or_insert_with(|| { let frame = &self.loader.find_frames(addr).ok()?.next().ok()??; let function = frame.function.as_ref()?; @@ -382,7 +380,7 @@ impl ViewParams { bar_start: width / 4.0, bar_height: 12.0, bar_leading: 4.0, - bar_brush: bar_brush, + bar_brush, } } } @@ -391,7 +389,7 @@ struct BarRenderer<'r> { state: &'r mut State, now: Duration, } -impl<'r, 'a, 's> RenderWrapper for BarRenderer<'r> { +impl<'a, 's> RenderWrapper for BarRenderer<'_> { fn render(&mut self, ctx: &mut R, wd: u64, ht: u64) -> Option<()> { let v = ViewParams::new(ctx, ht, wd); draw_bg(ctx, &v); @@ -422,7 +420,7 @@ impl<'r, 'a, 's> RenderWrapper for BarRenderer<'r> { &v, false, (3 + i) as u64, - (&mut self.state.symbol_cache).format_symbol(**site), + self.state.symbol_cache.format_symbol(**site), **size, self.state.total, )?; @@ -488,7 +486,7 @@ fn draw_flame( } Some(()) } -impl<'r, 'a, 's> RenderWrapper for FlameRenderer<'r> { +impl<'a, 's> RenderWrapper for FlameRenderer<'_> { fn render(&mut self, ctx: &mut R, wd: u64, ht: u64) -> Option<()> { let mut v = ViewParams::new(ctx, ht, wd); v.bar_start = v.width / 8.0; @@ -745,7 +743,7 @@ fn spawn_render_thread( let mut bar_ffmpeg = ffmpeg_for(&out_dir, Visualisation::Bar, interval.0)?; let mut flame_ffmpeg = ffmpeg_for(&out_dir, Visualisation::Flame, interval.0)?; let mut job_state = State { - inf: inf, + inf, symbol_cache: SymbolCache { loader, symbol_cache: HashMap::new(), @@ -801,9 +799,9 @@ fn main() { }; let inf = File::open(args[2].clone()).expect("could not open trace file"); let state = State { - inf: inf, + inf, symbol_cache: SymbolCache { - loader: loader, + loader, symbol_cache: HashMap::new(), }, start_time: None, @@ -854,7 +852,6 @@ fn plot_mem(args: Vec, mut state: State) { Some(()) => (), None => { eprintln!("i/o error encountered"); - () } } eprintln!("max total memory used is {}", state.max_total);