From a8f10d7931c1ea96cef9fa7cc36f156e6ddf7036 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Mon, 20 Jan 2025 12:51:05 +0000 Subject: [PATCH 1/8] Update dependencies Signed-off-by: Simon Davies --- Cargo.lock | 58 ++++++++++++++++++++++++++++++---- Cargo.toml | 2 -- src/hyperlight_host/Cargo.toml | 11 ++++--- 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97e1700cf..b44d8801e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1102,8 +1102,10 @@ dependencies = [ "lazy_static", "libc", "log", - "mshv-bindings", - "mshv-ioctls", + "mshv-bindings 0.2.1", + "mshv-bindings 0.3.2", + "mshv-ioctls 0.2.1", + "mshv-ioctls 0.3.2", "once_cell", "opentelemetry", "opentelemetry-otlp", @@ -1617,7 +1619,19 @@ dependencies = [ "libc", "num_enum", "vmm-sys-util", - "zerocopy", + "zerocopy 0.7.35", +] + +[[package]] +name = "mshv-bindings" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0cb5031f3243a7459b7c13d960d25420980874eebda816db24ce6077e21d43" +dependencies = [ + "libc", + "num_enum", + "vmm-sys-util", + "zerocopy 0.8.14", ] [[package]] @@ -1627,11 +1641,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d57586da719aacc905042eea71ff2efb52d16c7228a94af155c9ea45fe09c1c7" dependencies = [ "libc", - "mshv-bindings", + "mshv-bindings 0.2.1", "thiserror 1.0.69", "vmm-sys-util", ] +[[package]] +name = "mshv-ioctls" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89abe853221fa6f14ad4066affb9abda241a03d65622887d5794e1422d0bd75a" +dependencies = [ + "libc", + "mshv-bindings 0.3.2", + "thiserror 2.0.10", + "vmm-sys-util", +] + [[package]] name = "nom" version = "7.1.3" @@ -1910,7 +1936,7 @@ version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -3499,7 +3525,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468" +dependencies = [ + "zerocopy-derive 0.8.14", ] [[package]] @@ -3513,6 +3548,17 @@ dependencies = [ "syn", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zerofrom" version = "0.1.4" diff --git a/Cargo.toml b/Cargo.toml index 9e3d0b3ca..52359d14b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,8 +33,6 @@ repository = "https://github.com/hyperlight-dev/hyperlight" readme = "README.md" [workspace.dependencies] -mshv-bindings = { version = "=0.2.1" } -mshv-ioctls = { version = "=0.2.1" } hyperlight-common = { path = "src/hyperlight_common", version = "0.1.0", default-features = false } hyperlight-host = { path = "src/hyperlight_host", version = "0.1.0", default-features = false } diff --git a/src/hyperlight_host/Cargo.toml b/src/hyperlight_host/Cargo.toml index fc18566ad..b1f02b03b 100644 --- a/src/hyperlight_host/Cargo.toml +++ b/src/hyperlight_host/Cargo.toml @@ -71,10 +71,12 @@ windows-version = "0.1" [target.'cfg(unix)'.dependencies] seccompiler = { version = "0.4.0", optional = true } -mshv-bindings = { workspace = true, optional = true } -mshv-ioctls = { workspace = true, optional = true } kvm-bindings = { version = "0.10.0", features = ["fam-wrappers"], optional = true } kvm-ioctls = { version = "0.19.1", optional = true } +mshv-bindings2 = { package="mshv-bindings", version = "=0.2.1", optional = true } +mshv-ioctls2 = { package="mshv-ioctls", version = "=0.2.1", optional = true} +mshv-bindings3 = { package="mshv-bindings", version = "0.3.2", optional = true } +mshv-ioctls3 = { package="mshv-ioctls", version = "0.3.2", optional = true} [dev-dependencies] uuid = { version = "1.12.1", features = ["v4"] } @@ -114,7 +116,7 @@ cfg_aliases = "0.2.1" built = { version = "0.7.0", features = ["chrono", "git2"] } [features] -default = ["kvm", "mshv", "seccomp"] +default = ["kvm", "mshv2", "seccomp"] seccomp = ["dep:seccompiler"] function_call_metrics = [] executable_heap = [] @@ -122,7 +124,8 @@ executable_heap = [] print_debug = [] crashdump = ["dep:tempfile"] # Dumps the VM state to a file on unexpected errors or crashes. The path of the file will be printed on stdout and logged. This feature can only be used in debug builds. kvm = ["dep:kvm-bindings", "dep:kvm-ioctls"] -mshv = ["dep:mshv-bindings", "dep:mshv-ioctls"] +mshv2 = ["dep:mshv-bindings2", "dep:mshv-ioctls2"] +mshv3 = ["dep:mshv-bindings3", "dep:mshv-ioctls3"] inprocess = [] [[bench]] From 851cd847323ab651f37b29e7a1e18512ca37eb84 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Mon, 20 Jan 2025 12:58:17 +0000 Subject: [PATCH 2/8] Update the justfile Enable features to be passed when running rust all tests,examples and benchmarks so AZ Linux3 can enabled when any of these are run on an AZ Linux3 host Signed-off-by: Simon Davies --- Justfile | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Justfile b/Justfile index 604113610..56045d0b8 100644 --- a/Justfile +++ b/Justfile @@ -76,7 +76,7 @@ clean-rust: # Some tests cannot run with other tests, they are marked as ignored so that cargo test works # there may be tests that we really want to ignore so we can't just use --ignored and we have to # Specify the test name of the ignored tests that we want to run -test-rust target=default-target features="": (test-rust-int "rust" target features) (test-rust-int "c" target features) (test-seccomp target) +test-rust target=default-target features="": (test-rust-int "rust" target features) (test-rust-int "c" target features) (test-seccomp target features) # unit tests cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} --lib @@ -91,23 +91,23 @@ test-rust target=default-target features="": (test-rust-int "rust" target featur cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} hypervisor::hypervisor_handler::tests::create_1000_sandboxes -p hyperlight-host --lib -- --ignored {{ set-trace-env-vars }} cargo test {{ if features =="" {''} else if features=="no-default-features" {"--no-default-features" } else {"--no-default-features -F " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} --lib sandbox::outb::tests::test_log_outb_log -- --ignored -test-seccomp target=default-target: +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 -- --ignored - cargo test --profile={{ if target == "debug" { "dev" } else { target } }} -p hyperlight-host test_violate_seccomp_filters --no-default-features --features mshv,kvm --lib -- --ignored + 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 =~"mshv3" {"--features mshv3"} else {"--features mshv2,kvm" } }} --lib -- --ignored # rust integration tests. guest can either be "rust" or "c" test-rust-int guest target=default-target features="": # integration tests # 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 --features executable_heap -- --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 -- --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 =="" {" --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 # 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 " + features } }} --profile={{ if target == "debug" { "dev" } else { target } }} --test '*' test-rust-feature-compilation-fail target=default-target: - @# the following should fail on linux because either kvm or msh feature must be specified, which is why the exit code is inverted with an !. + @# the following should fail on linux because one of kvm, mshv, or mshv3 feature must be specified, which is why the exit code is inverted with an !. {{ if os() == "linux" { "! cargo check -p hyperlight-host --no-default-features 2> /dev/null"} else { "" } }} test target=default-target: (test-rust target) @@ -149,15 +149,15 @@ gen-all-fbs-rust-code: just fmt-apply # RUST EXAMPLES -run-rust-examples target=default-target: (build-rust target) - cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example metrics - cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example metrics --features "function_call_metrics" - {{ set-trace-env-vars }} cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example logging +run-rust-examples target=default-target features="": (build-rust target) + 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} }} + {{ set-trace-env-vars }} cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --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: (build-rust target) (run-rust-examples target) - {{ set-trace-env-vars }} cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example tracing - {{ set-trace-env-vars }} cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example tracing --features "function_call_metrics" +run-rust-examples-linux target=default-target features="": (build-rust target) (run-rust-examples target features) + {{ set-trace-env-vars }} cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example tracing {{ if features =="" {''} else { "--features " + features } }} + {{ set-trace-env-vars }} cargo run --profile={{ if target == "debug" { "dev" } else { target } }} --example tracing {{ if features =="" {"--features function_call_metrics" } else {"--features function_call_metrics," + features} }} # BENCHMARKING @@ -174,15 +174,15 @@ bench-download os hypervisor cpu tag="": tar -zxvf target/benchmarks_{{ os }}_{{ hypervisor }}_{{ cpu }}.tar.gz -C target/criterion/ --strip-components=1 # Warning: compares to and then OVERWRITES the given baseline -bench-ci baseline target=default-target: - cargo bench --profile={{ if target == "debug" { "dev" } else { target } }} -- --verbose --save-baseline {{ baseline }} +bench-ci baseline target=default-target features="": + cargo bench --profile={{ if target == "debug" { "dev" } else { target } }} {{ if features =="" {''} else { "--features " + features } }} -- --verbose --save-baseline {{ baseline }} -bench target=default-target: - cargo bench --profile={{ if target == "debug" { "dev" } else { target } }} -- --verbose +bench target=default-target features="": + cargo bench --profile={{ if target == "debug" { "dev" } else { target } }} {{ if features =="" {''} else { "--features " + features } }} -- --verbose # FUZZING fuzz: cd src/hyperlight_host && cargo +nightly fuzz run fuzz_target_1 fuzz-timed: - cd src/hyperlight_host && cargo +nightly fuzz run fuzz_target_1 -- -max_total_time=300 \ No newline at end of file + cd src/hyperlight_host && cargo +nightly fuzz run fuzz_target_1 -- -max_total_time=300 From e9ef6faf22a584656430cc1cd40a2049045167c7 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Mon, 20 Jan 2025 12:59:14 +0000 Subject: [PATCH 3/8] Add running benchmarks on mshv3 Signed-off-by: Simon Davies --- .github/workflows/Benchmarks.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Benchmarks.yml b/.github/workflows/Benchmarks.yml index 022064066..245fbf625 100644 --- a/.github/workflows/Benchmarks.yml +++ b/.github/workflows/Benchmarks.yml @@ -17,11 +17,11 @@ jobs: strategy: fail-fast: true matrix: - hypervisor: [hyperv, mshv, kvm] # hyperv is windows, mshv and kvm are linux + hypervisor: [hyperv, mshv, mshv3, kvm] # hyperv is windows, mshv and kvm are linux cpu: [amd, intel] config: [release] # don't want to benchmark debug-builds - runs-on: ${{ fromJson(format('["self-hosted", "{0}", "X64", "1ES.Pool=hld-{1}-{2}"]', matrix.hypervisor == 'hyperv' && 'Windows' || 'Linux', matrix.hypervisor == 'hyperv' && 'win2022' || matrix.hypervisor, matrix.cpu)) }} + runs-on: ${{ fromJson(format('["self-hosted", "{0}", "X64", "1ES.Pool=hld-{1}-{2}"]', matrix.hypervisor == 'hyperv' && 'Windows' || 'Linux', matrix.hypervisor == 'hyperv' && 'win2022' || matrix.hypervisor == 'mshv3' && 'azlinux3-mshv' || matrix.hypervisor, matrix.cpu)) }} steps: ### Setup ### @@ -67,7 +67,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run Benchmarks - run: just bench-ci main release + run: just bench-ci main release ${{ matrix.hypervisor == 'mshv3' && 'mshv3' || ''}} - uses: actions/upload-artifact@v4 with: From b1255e9dc0d58517be4fe83deb17692fe5baa7e4 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Mon, 20 Jan 2025 16:36:44 +0000 Subject: [PATCH 4/8] Support Azure Linux3 in Rust workflow Signed-off-by: Simon Davies --- .github/workflows/dep_rust.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dep_rust.yml b/.github/workflows/dep_rust.yml index d55d70033..b725210d4 100644 --- a/.github/workflows/dep_rust.yml +++ b/.github/workflows/dep_rust.yml @@ -26,11 +26,15 @@ jobs: strategy: fail-fast: true matrix: - hypervisor: [hyperv, mshv, kvm] # hyperv is windows, mshv and kvm are linux + hypervisor: [hyperv, 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' && 'Windows' || 'Linux', matrix.hypervisor == 'hyperv' && 'win2022' || matrix.hypervisor, matrix.cpu)) }} + runs-on: ${{ fromJson( + format('["self-hosted", "{0}", "X64", "1ES.Pool=hld-{1}-{2}"]', + matrix.hypervisor == 'hyperv' && 'Windows' || 'Linux', + matrix.hypervisor == 'hyperv' && 'win2022' || matrix.hypervisor == 'mshv3' && 'azlinux3-mshv' || matrix.hypervisor, + matrix.cpu)) }} steps: - uses: actions/checkout@v4 @@ -75,10 +79,10 @@ jobs: CARGO_TERM_COLOR: always run: | # with default features - just test-rust ${{ matrix.config }} + just test-rust ${{ matrix.config }} ${{ matrix.hypervisor == 'mshv3' && 'mshv3' || ''}} # with only one driver enabled (driver mshv/kvm feature is ignored on windows) + seccomp + inprocess - just test-rust ${{ matrix.config }} inprocess,seccomp,${{ matrix.hypervisor == 'mshv' && 'mshv' || 'kvm' }} + just test-rust ${{ matrix.config }} inprocess,seccomp,${{ matrix.hypervisor == 'mshv' && 'mshv2' || matrix.hypervisor == 'mshv3' && 'mshv3' || 'kvm' }} # make sure certain cargo features compile cargo check -p hyperlight-host --features crashdump @@ -100,7 +104,7 @@ jobs: env: CARGO_TERM_COLOR: always RUST_LOG: debug - run: just run-rust-examples-linux ${{ matrix.config }} + run: just run-rust-examples-linux ${{ matrix.config }} ${{ matrix.hypervisor == 'mshv3' && 'mshv3' || ''}} ### Benchmarks ### - name: Install github-cli (Linux mariner) @@ -120,5 +124,5 @@ jobs: - name: Run benchmarks run: | - just bench-ci main ${{ matrix.config }} + just bench-ci main ${{ matrix.config }} ${{ matrix.hypervisor == 'mshv3' && 'mshv3' || ''}} if: ${{ matrix.config == 'release' }} From 76e3c2152941204c2f072ed0c606dcf95c5148bc Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Mon, 20 Jan 2025 16:42:22 +0000 Subject: [PATCH 5/8] update build to support mshv3 feature Signed-off-by: Simon Davies --- src/hyperlight_host/build.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/hyperlight_host/build.rs b/src/hyperlight_host/build.rs index 2aa321e79..7600f6470 100644 --- a/src/hyperlight_host/build.rs +++ b/src/hyperlight_host/build.rs @@ -85,12 +85,12 @@ fn main() -> Result<()> { } // Makes #[cfg(kvm)] == #[cfg(all(feature = "kvm", target_os = "linux"))] - // and #[cfg(mshv)] == #[cfg(all(feature = "mshv", target_os = "linux"))]. + // and #[cfg(mshv)] == #[cfg(all(any(feature = "mshv2", feature = "mshv3"), target_os = "linux"))]. // Essentially the kvm and mshv features are ignored on windows as long as you use #[cfg(kvm)] and not #[cfg(feature = "kvm")]. // You should never use #[cfg(feature = "kvm")] or #[cfg(feature = "mshv")] in the codebase. cfg_aliases::cfg_aliases! { kvm: { all(feature = "kvm", target_os = "linux") }, - mshv: { all(feature = "mshv", target_os = "linux") }, + mshv: { all(any(feature = "mshv2", feature = "mshv3"), target_os = "linux") }, // inprocess feature is aliased with debug_assertions to make it only available in debug-builds. // You should never use #[cfg(feature = "inprocess")] in the codebase. Use #[cfg(inprocess)] instead. inprocess: { all(feature = "inprocess", debug_assertions) }, @@ -98,6 +98,11 @@ fn main() -> Result<()> { crashdump: { all(feature = "crashdump", debug_assertions) }, // print_debug feature is aliased with debug_assertions to make it only available in debug-builds. print_debug: { all(feature = "print_debug", debug_assertions) }, + // the following features are mutually exclusive but rather than enforcing that here we are enabling mshv3 to override mshv2 when both are enabled + // because mshv2 is in the default feature set we want to allow users to enable mshv3 without having to set --no-default-features and the re-enable + // the other features they want. + mshv2: { all(feature = "mshv2", not(feature="mshv3"), target_os = "linux") }, + mshv3: { all(feature = "mshv3", target_os = "linux") }, } write_built_file()?; From a8a24b0708dc6df3e669ab2541fe0158cd9e3833 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Mon, 20 Jan 2025 16:43:36 +0000 Subject: [PATCH 6/8] Update HyperlightError to support mshv3 Signed-off-by: Simon Davies --- src/hyperlight_host/src/error.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hyperlight_host/src/error.rs b/src/hyperlight_host/src/error.rs index f6bed4f90..e846ee12e 100644 --- a/src/hyperlight_host/src/error.rs +++ b/src/hyperlight_host/src/error.rs @@ -14,6 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ +#[cfg(mshv2)] +extern crate mshv_ioctls2 as mshv_ioctls; + +#[cfg(mshv3)] +extern crate mshv_ioctls3 as mshv_ioctls; + use std::array::TryFromSliceError; use std::cell::{BorrowError, BorrowMutError}; use std::convert::Infallible; From 3da95b9f3da883bf4b271efb52989810d63d5460 Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Mon, 20 Jan 2025 16:44:51 +0000 Subject: [PATCH 7/8] Update the mshv driver to support mshv3 Signed-off-by: Simon Davies --- .../src/hypervisor/hyperv_linux.rs | 50 +++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs index db00a2c8c..33798d881 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs @@ -14,16 +14,32 @@ See the License for the specific language governing permissions and limitations under the License. */ +#[cfg(mshv2)] +extern crate mshv_bindings2 as mshv_bindings; +#[cfg(mshv2)] +extern crate mshv_ioctls2 as mshv_ioctls; + +#[cfg(mshv3)] +extern crate mshv_bindings3 as mshv_bindings; +#[cfg(mshv3)] +extern crate mshv_ioctls3 as mshv_ioctls; + use std::fmt::{Debug, Formatter}; use log::error; +#[cfg(mshv2)] +use mshv_bindings::hv_message; use mshv_bindings::{ - hv_message, hv_message_type, hv_message_type_HVMSG_GPA_INTERCEPT, - hv_message_type_HVMSG_UNMAPPED_GPA, hv_message_type_HVMSG_X64_HALT, - hv_message_type_HVMSG_X64_IO_PORT_INTERCEPT, hv_register_assoc, + hv_message_type, hv_message_type_HVMSG_GPA_INTERCEPT, hv_message_type_HVMSG_UNMAPPED_GPA, + hv_message_type_HVMSG_X64_HALT, hv_message_type_HVMSG_X64_IO_PORT_INTERCEPT, hv_register_assoc, hv_register_name_HV_X64_REGISTER_RIP, hv_register_value, mshv_user_mem_region, FloatingPointUnit, SegmentRegister, SpecialRegisters, StandardRegisters, }; +#[cfg(mshv3)] +use mshv_bindings::{ + hv_partition_property_code_HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES, + hv_partition_synthetic_processor_features, +}; use mshv_ioctls::{Mshv, VcpuFd, VmFd}; use tracing::{instrument, Span}; @@ -86,7 +102,24 @@ impl HypervLinuxDriver { ) -> Result { let mshv = Mshv::new()?; let pr = Default::default(); + #[cfg(mshv2)] let vm_fd = mshv.create_vm_with_config(&pr)?; + #[cfg(mshv3)] + let vm_fd = { + // It's important to avoid create_vm() and explicitly use + // create_vm_with_args() with an empty arguments structure + // here, because otherwise the partition is set up with a SynIC. + + let vm_fd = mshv.create_vm_with_args(&pr)?; + let features: hv_partition_synthetic_processor_features = Default::default(); + vm_fd.hvcall_set_partition_property( + hv_partition_property_code_HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES, + unsafe { features.as_uint64[0] }, + )?; + vm_fd.initialize()?; + vm_fd + }; + let mut vcpu_fd = vm_fd.create_vcpu(0)?; mem_regions.iter().try_for_each(|region| { @@ -280,8 +313,15 @@ impl Hypervisor for HypervLinuxDriver { const UNMAPPED_GPA_MESSAGE: hv_message_type = hv_message_type_HVMSG_UNMAPPED_GPA; const INVALID_GPA_ACCESS_MESSAGE: hv_message_type = hv_message_type_HVMSG_GPA_INTERCEPT; - let hv_message: hv_message = Default::default(); - let result = match &self.vcpu_fd.run(hv_message) { + #[cfg(mshv2)] + let run_result = { + let hv_message: hv_message = Default::default(); + &self.vcpu_fd.run(hv_message) + }; + #[cfg(mshv3)] + let run_result = &self.vcpu_fd.run(); + + let result = match run_result { Ok(m) => match m.header.message_type { HALT_MESSAGE => { crate::debug!("mshv - Halt Details : {:#?}", &self); From 6b8de9c45c3dd8c2edd4b78b1f5bb1b8252b4c8e Mon Sep 17 00:00:00 2001 From: Simon Davies Date: Mon, 20 Jan 2025 16:46:22 +0000 Subject: [PATCH 8/8] Update memoy region mapping to support mshv3 Signed-off-by: Simon Davies --- src/hyperlight_host/src/mem/memory_region.rs | 74 +++++++++++++++----- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/src/hyperlight_host/src/mem/memory_region.rs b/src/hyperlight_host/src/mem/memory_region.rs index f8911ff69..6956d9635 100644 --- a/src/hyperlight_host/src/mem/memory_region.rs +++ b/src/hyperlight_host/src/mem/memory_region.rs @@ -14,6 +14,16 @@ See the License for the specific language governing permissions and limitations under the License. */ +#[cfg(mshv2)] +extern crate mshv_bindings2 as mshv_bindings; +#[cfg(mshv2)] +extern crate mshv_ioctls2 as mshv_ioctls; + +#[cfg(mshv3)] +extern crate mshv_bindings3 as mshv_bindings; +#[cfg(mshv3)] +extern crate mshv_ioctls3 as mshv_ioctls; + use std::ops::Range; use bitflags::bitflags; @@ -21,9 +31,14 @@ use bitflags::bitflags; use hyperlight_common::mem::PAGE_SHIFT; use hyperlight_common::mem::PAGE_SIZE_USIZE; #[cfg(mshv)] +use mshv_bindings::{hv_x64_memory_intercept_message, mshv_user_mem_region}; +#[cfg(mshv2)] +use mshv_bindings::{ + HV_MAP_GPA_EXECUTABLE, HV_MAP_GPA_PERMISSIONS_NONE, HV_MAP_GPA_READABLE, HV_MAP_GPA_WRITABLE, +}; +#[cfg(mshv3)] use mshv_bindings::{ - hv_x64_memory_intercept_message, mshv_user_mem_region, HV_MAP_GPA_EXECUTABLE, - HV_MAP_GPA_PERMISSIONS_NONE, HV_MAP_GPA_READABLE, HV_MAP_GPA_WRITABLE, + MSHV_SET_MEM_BIT_EXECUTABLE, MSHV_SET_MEM_BIT_UNMAP, MSHV_SET_MEM_BIT_WRITABLE, }; #[cfg(target_os = "windows")] use windows::Win32::System::Hypervisor::{self, WHV_MEMORY_ACCESS_TYPE}; @@ -227,22 +242,45 @@ impl From for mshv_user_mem_region { let guest_pfn = region.guest_region.start as u64 >> PAGE_SHIFT; let userspace_addr = region.host_region.start as u64; - let flags = region.flags.iter().fold(0, |acc, flag| { - let flag_value = match flag { - MemoryRegionFlags::NONE => HV_MAP_GPA_PERMISSIONS_NONE, - MemoryRegionFlags::READ => HV_MAP_GPA_READABLE, - MemoryRegionFlags::WRITE => HV_MAP_GPA_WRITABLE, - MemoryRegionFlags::EXECUTE => HV_MAP_GPA_EXECUTABLE, - _ => 0, // ignore any unknown flags - }; - acc | flag_value - }); - - mshv_user_mem_region { - guest_pfn, - size, - userspace_addr, - flags, + #[cfg(mshv2)] + { + let flags = region.flags.iter().fold(0, |acc, flag| { + let flag_value = match flag { + MemoryRegionFlags::NONE => HV_MAP_GPA_PERMISSIONS_NONE, + MemoryRegionFlags::READ => HV_MAP_GPA_READABLE, + MemoryRegionFlags::WRITE => HV_MAP_GPA_WRITABLE, + MemoryRegionFlags::EXECUTE => HV_MAP_GPA_EXECUTABLE, + _ => 0, // ignore any unknown flags + }; + acc | flag_value + }); + mshv_user_mem_region { + guest_pfn, + size, + userspace_addr, + flags, + } + } + #[cfg(mshv3)] + { + let flags: u8 = region.flags.iter().fold(0, |acc, flag| { + let flag_value = match flag { + MemoryRegionFlags::NONE => 1 << MSHV_SET_MEM_BIT_UNMAP, + MemoryRegionFlags::READ => 0, + MemoryRegionFlags::WRITE => 1 << MSHV_SET_MEM_BIT_WRITABLE, + MemoryRegionFlags::EXECUTE => 1 << MSHV_SET_MEM_BIT_EXECUTABLE, + _ => 0, // ignore any unknown flags + }; + acc | flag_value + }); + + mshv_user_mem_region { + guest_pfn, + size, + userspace_addr, + flags, + ..Default::default() + } } } }