feat(aarch64): add WHP backend for ARM64 Windows - #1638
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a Windows Hypervisor Platform (WHP) backend for Windows/aarch64 so Hyperlight can run micro-VMs on ARM64 Windows systems, aligning WHP’s structure with existing per-arch hypervisor layouts.
Changes:
- Introduces
whp/aarch64.rsimplementing theVirtualMachinetrait for ARM64 WHP, including MMIO-based exit handling and register get/set viaWHvGet/SetVirtualProcessorRegisters. - Restructures the WHP backend into
whp/with per-architecture modules and fixes x86_64 interrupt helper module paths. - Wires WHP into the aarch64 Hyperlight VM path on Windows and moves
vmm-sys-utilinto unix-only dependencies to fix Windows builds.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/hyperlight_host/src/sandbox/snapshot/file/config.rs | Adds Windows/aarch64 CPU vendor token for snapshot config. |
| src/hyperlight_host/src/hypervisor/virtual_machine/whp/x86_64.rs | Updates hw_interrupts module paths after WHP directory restructure. |
| src/hyperlight_host/src/hypervisor/virtual_machine/whp/mod.rs | New per-arch WHP module dispatcher (x86_64 vs aarch64). |
| src/hyperlight_host/src/hypervisor/virtual_machine/whp/aarch64.rs | New ARM64 WHP backend implementation and manual ARM64 WHP FFI bindings. |
| src/hyperlight_host/src/hypervisor/hyperlight_vm/aarch64.rs | Selects WHP on Windows/aarch64 and adds Windows interrupt handle wiring. |
| src/hyperlight_host/Cargo.toml | Makes vmm-sys-util unix-only to avoid Windows compilation failures. |
Implement the WHP hypervisor backend for aarch64 Windows, enabling
hyperlight to run micro-VMs on Windows ARM64 systems.
Changes:
- Restructure whp.rs into whp/ directory (whp/mod.rs + whp/x86_64.rs)
to support per-architecture implementations (matching kvm/mshv pattern)
- Add whp/aarch64.rs with full VirtualMachine trait implementation:
- Manual FFI bindings for ARM64 WHP register names, exit reasons, and
exit context layout (from Windows SDK WinHvPlatformDefs.h)
- Run loop handling MMIO-based I/O (ARM64 has no IO ports)
- Register get/set via WHvGet/SetVirtualProcessorRegisters
- Surrogate process support (same pattern as x86_64)
- Wire WhpVm into hyperlight_vm/aarch64.rs for Windows platform
- Fix super::x86_64::hw_interrupts path after directory restructure
Resolves: hyperlight-dev#1544
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6f20a05d-6bee-4e2e-b320-12f8d9759bbc
Signed-off-by: cshung <3410332+cshung@users.noreply.github.com>
- Move vmm-sys-util to unix-only dependencies (it doesn't compile on Windows) - Fix WHV_UINT128 field access (requires Anonymous wrapper on windows crate) - Add CpuVendor::current() for aarch64 Windows target - Remove redundant partition_handle inherent method and unused cancelled field - Fix unused import warnings - Add #[allow(dead_code)] on exit reason constants module Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6f20a05d-6bee-4e2e-b320-12f8d9759bbc Signed-off-by: cshung <3410332+cshung@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: cshung <3410332+cshung@users.noreply.github.com>
5f992dc to
1d3a299
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: cshung <3410332+cshung@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: cshung <3410332+cshung@users.noreply.github.com>
Preserve FPU register errors, use safe DLL lookup, and document the Windows snapshot token accurately. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: cshung <3410332+cshung@users.noreply.github.com>
|
End-to-end Using this PR's 0.16 crates, a freshly scaffolded sample successfully built The backend works. The published scaffold is the remaining user-experience gap: |
syntactically
left a comment
There was a problem hiding this comment.
This looks great! I have a bunch of little nits, and also I (more majorly) think that the addition of reset_vcpu to InteruptHandle seems wrong.
| // TODO: mshv support | ||
| #[cfg(mshv3)] | ||
| Some(HypervisorType::Mshv) => return Err(CreateHyperlightVmError::NoHypervisorFound), | ||
| Some(HypervisorType::Mshv) => { |
There was a problem hiding this comment.
This line looks like it's the same before/after?
| }); | ||
|
|
||
| #[cfg(target_os = "windows")] | ||
| let interrupt_handle: Arc<dyn InterruptHandleImpl> = Arc::new(WindowsInterruptHandle { |
There was a problem hiding this comment.
Just a heads up that there is a big refactor/simplification to the interrupt handle machinery in #1674 that you may want to take a look at.
| "No fallback path for vcpu reset on aarch64" | ||
| ); | ||
| self.vm.reset_vcpu()?; | ||
| self.interrupt_handle.reset_vcpu(self.vm.as_mut())?; |
There was a problem hiding this comment.
What's this change about? It seems like the wrong place for this.
If it's related to the locking that happens in the interrupt handle: that's required because the interrupt handle can outlive the WhpVm object that it is created from (and the partition is destroyed when the latter is dropped). Here, you have a reference to the WhpVm on hand, so you can be sure that it hasn't been dropped (and then destroyed).
| //! This module provides the [`VirtualMachine`] trait implementation using the | ||
| //! WHP APIs on Windows ARM64 systems. Because the `windows` crate does not yet | ||
| //! expose ARM64 WHP structures, we define our own FFI bindings derived from | ||
| //! the Windows SDK header `WinHvPlatformDefs.h` (10.0.26100.0). |
There was a problem hiding this comment.
Is there an issue on the upstream windows crate about getting these exposed?
Also, I remember that Windows APIs in general often have a bunch of random aligned(16) or similar things---are those accounted for here? I remember that the bindgen that the windows crate uses used to get that wrong.
| WHV_PARTITION_PROPERTY_CODE(0x00001012); | ||
| const WHV_ARM64_REGISTER_GICR_BASE_GPA: WHV_REGISTER_NAME = WHV_REGISTER_NAME(0x00063000); | ||
|
|
||
| #[repr(C)] |
There was a problem hiding this comment.
Ouch, is it really a hard requirement from WHP to have the interrupt controller configured? I think I have done some experiments with mshv on Linux in the past and had success without an ic.
| } | ||
| } | ||
|
|
||
| // ============================================================================ |
There was a problem hiding this comment.
This can also perhaps be shared with the x86_64 variant?
| } | ||
| } else if let Some(val) = super::x86_64::hw_interrupts::handle_io_in(port) { | ||
| } else if let Some(val) = | ||
| crate::hypervisor::virtual_machine::x86_64::hw_interrupts::handle_io_in( |
There was a problem hiding this comment.
Perhaps use crate::hypervisor::virtual_machine::x86_64 or something to reduce the formatting churn?
| fn clear_cancel(&self); | ||
|
|
||
| /// Reset the vCPU while honoring platform lifecycle synchronization. | ||
| #[cfg(target_arch = "aarch64")] |
There was a problem hiding this comment.
As mentioned above, this seems like the wrong place for this.
| use std::thread; | ||
|
|
||
| // We have a high thread count to stress test and to have interesting interleavings | ||
| // ARM64 WHP partitions include GICv3 state, limiting practical partition |
There was a problem hiding this comment.
Can you elaborate on this a little bit?
| use tracing::{error, trace}; | ||
|
|
||
| #[cfg(target_arch = "aarch64")] | ||
| const POOL_SIZE: usize = 64; |
There was a problem hiding this comment.
Summary
Implements the WHP (Windows Hypervisor Platform) hypervisor backend for aarch64, enabling hyperlight to run micro-VMs on Windows ARM64 systems.
Resolves #1544
Changes
Structural
whp.rsintowhp/directory (mod.rs+x86_64.rs) to support per-architecture implementations, matching the existingkvm/andmshv/patternsuper::x86_64::hw_interruptsmodule path after directory restructureNew:
whp/aarch64.rsWinHvPlatformDefs.h)VirtualMachinetrait implementation with:WHvGet/SetVirtualProcessorRegistersIntegration
WhpVmintohyperlight_vm/aarch64.rsfor Windows platformWindowsInterruptHandlefor aarch64 WindowsCpuVendor::current()for aarch64 Windows targetCross-compilation fix
vmm-sys-utilto unix-only dependencies (it doesn't compile on Windows)Verification
Verified compilation on three targets:
just clippy debug/releasepasscargo checkpassescargo check --features kvmpassesWhy manual FFI bindings?
The
windowscrate (v0.62) does not expose ARM64 WHP types (register names, exit reasons, exit context structs). All definitions were extracted from the Windows SDK headerWinHvPlatformDefs.h(SDK 10.0.26100.0) which has full ARM64 support behind#ifdef _ARM64_.