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. |
5f992dc to
1d3a299
Compare
|
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.
7e93813 to
4c2f4e4
Compare
b64225b to
404a655
Compare
Implements the WHP hypervisor backend for aarch64, enabling Hyperlight to run micro-VMs on Windows ARM64 systems with Hyper-V. 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>
404a655 to
189317a
Compare
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_.