Skip to content

feat(aarch64): add GDB debugging for Windows ARM64 WHP - #1907

Open
cshung wants to merge 3 commits into
hyperlight-dev:mainfrom
cshung:cshung/whp-aarch64-gdb
Open

cshung wants to merge 3 commits into
hyperlight-dev:mainfrom
cshung:cshung/whp-aarch64-gdb

Conversation

@cshung

@cshung cshung commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds GDB stub support for guests running on the ARM64 WHP backend.

Changes

Debug core

  • Split the x86_64 debug code out of hyperlight_vm/x86_64.rs into a shared hyperlight_vm/debug.rs.
  • Rename gdb/x86_64_target.rs to gdb/target.rs and add per-architecture register handling in gdb/arch/.
  • Give DebuggableVm default methods so backends without hardware breakpoints or single step report Unsupported.

ARM64 WHP

  • Implement DebuggableVm for the aarch64 WHP VM, using the batched register helpers.
  • Flush the host instruction cache after guest memory writes so software breakpoints take effect.

Docs

  • Document ARM64 debugging in docs/how-to-debug-a-hyperlight-guest.md and CHANGELOG.md.

Verification

On Windows ARM64 (WHP):

  • just build, just clippy, just guests, just test and just fmt-check pass.

@cshung cshung added the kind/enhancement For PRs adding features, improving functionality, docs, tests, etc. label Oct 8, 2026
@hyperlight-gh-bot

This comment has been minimized.

@cshung
cshung marked this pull request as ready for review October 8, 2026 19:33
Copilot AI balanced review requested due to automatic review settings October 8, 2026 19:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Breakpoint state can survive crash or cancellation recovery, and the hidden cache-sync mapping conflicts with the public mapping contract.

4 open findings
What changed in this PR

Adds Windows ARM64 WHP guest debugging and generalizes the GDB implementation across architectures.

Changes:

  • Adds ARM64 registers, software breakpoints, stepping, and cache synchronization.
  • Extracts shared debugger logic from x86_64 code.
  • Updates tests, documentation, and platform configuration.
File Description
CHANGELOG.md Records ARM64 GDB support.
docs/​how-to-debug-a-hyperlight-guest.md Documents architecture-specific capabilities.
src/​hyperlight_host/​build.rs Enables GDB on Windows ARM64.
src/​hyperlight_host/​examples/​guest-debugging/​main.rs Adds ARM64 debugging tests.
src/​hyperlight_host/​src/​hypervisor/​gdb/​arch.rs Dispatches architecture-specific logic.
src/​hyperlight_host/​src/​hypervisor/​gdb/​arch/​aarch64.rs Implements ARM64 breakpoint and step decoding.
src/​hyperlight_host/​src/​hypervisor/​gdb/​arch/​x86_64.rs Houses extracted x86_64 logic.
src/​hyperlight_host/​src/​hypervisor/​gdb/​event_loop.rs Maps ARM64 stop reasons.
src/​hyperlight_host/​src/​hypervisor/​gdb/​mod.rs Extends shared debugging interfaces.
src/​hyperlight_host/​src/​hypervisor/​gdb/​target.rs Adds architecture-specific GDB registers.
src/​hyperlight_host/​src/​hypervisor/​hyperlight_vm/​aarch64.rs Connects GDB to ARM64 VMs.
src/​hyperlight_host/​src/​hypervisor/​hyperlight_vm/​debug.rs Centralizes breakpoint and stepping state.
src/​hyperlight_host/​src/​hypervisor/​hyperlight_vm/​mod.rs Handles ARM64 debug exits.
src/​hyperlight_host/​src/​hypervisor/​hyperlight_vm/​x86_64.rs Removes extracted debugger logic.
src/​hyperlight_host/​src/​hypervisor/​virtual_machine/​mod.rs Extends VM exits and errors.
src/​hyperlight_host/​src/​hypervisor/​virtual_machine/​whp/​aarch64.rs Implements WHP debugging and cache synchronization.
src/​hyperlight_host/​src/​sandbox/​initialized.rs Guards snapshots with active breakpoints.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/hyperlight_host/src/hypervisor/hyperlight_vm/debug.rs
Comment thread src/hyperlight_host/src/hypervisor/hyperlight_vm/mod.rs Outdated
Comment thread src/hyperlight_host/src/hypervisor/virtual_machine/whp/aarch64.rs
Comment thread src/hyperlight_host/src/hypervisor/hyperlight_vm/x86_64.rs Outdated
@cshung
cshung force-pushed the cshung/whp-aarch64-gdb branch from 8c0c245 to 39ea4cb Compare October 9, 2026 16:54
@hyperlight-gh-bot

This comment has been minimized.

@syntactically

Copy link
Copy Markdown
Member

@cshung I guess you are using software breakpoints here because WHPX aarch64 does not yet support setting MDCR_EL2.TDE. I think this is very divergent from the other implementations and especially the emulation of software step looks very fragile in its current state.

I wonder if we can make things a little bit more congruent with the other implementations by using the same hardware debug approach as other targets, but on WHP set MDSCR_EL1.KDE and have little assembly stubs catch this case and make hvcs (or, even make an hvc on every exception entry, when in gdb mode)? Admittedly this will not work very well if VBAR_EL1 or virtual memory configuration for the exception handlers are messed up, but in that case I think given the current guest architecture it is extremely unlikely that guest code would continue to execute and produce any useful results.

@cshung
cshung force-pushed the cshung/whp-aarch64-gdb branch from 7238539 to 6c35092 Compare October 19, 2026 14:56
@hyperlight-gh-bot

This comment has been minimized.

@hyperlight-gh-bot

This comment has been minimized.

@hyperlight-gh-bot

This comment has been minimized.

@cshung
cshung force-pushed the cshung/whp-aarch64-gdb branch from dd86b49 to 698b851 Compare October 20, 2026 17:59
@hyperlight-gh-bot

This comment has been minimized.

cshung and others added 3 commits October 26, 2026 09:23
Adds GDB stub support for guests running on the ARM64 WHP backend.

* Split the x86_64 debug code out of `hyperlight_vm/x86_64.rs` into a shared `hyperlight_vm/debug.rs`.
* Rename `gdb/x86_64_target.rs` to `gdb/target.rs` and add per-architecture register handling in `gdb/arch/`.
* Give `DebuggableVm` default methods so backends without hardware breakpoints or single step report `Unsupported`.

* Implement `DebuggableVm` for the aarch64 WHP VM, using the batched register helpers.
* Flush the host instruction cache after guest memory writes so software breakpoints take effect.

* Document ARM64 debugging in `docs/how-to-debug-a-hyperlight-guest.md` and `CHANGELOG.md`.

On Windows ARM64 (WHP):
* `just build`, `just clippy`, `just guests`, `just test` and `just fmt-check` pass.

---------

Signed-off-by: cshung <[email protected]>
Co-authored-by: Copilot <[email protected]>
## Changes

* Run the full disable path when the debugger detaches after a crash, so software breakpoints and pending steps are cleaned up.
* Cancel pending software steps for any cancellation source, not only debugger interrupts.
* Reject `map_region` requests that overlap the hidden cache sync page at GPA 0x1000, and add a test.
* Restore the `≡` and `×` characters in `hyperlight_vm/x86_64.rs` comments.

## Verification

On Windows ARM64 (WHP):
* `just clippy`, `just fmt-check` and the `hypervisor::` and `map_region` lib tests with the `gdb` feature pass.

---------

Signed-off-by: cshung <[email protected]>
Co-authored-by: Copilot <[email protected]>
Guest synchronous exception vectors forward debug stops through HVC. Hardware single-step supports branches, returns, and self-loops. Two hardware breakpoint slots and BRK software breakpoints are available.

Interrupted register context and breakpoint configuration survive cache synchronization and vCPU reset. Asynchronous vectors retain their normal exception paths.

Co-authored-by: Copilot <[email protected]>
Signed-off-by: cshung <[email protected]>
@cshung
cshung force-pushed the cshung/whp-aarch64-gdb branch from 698b851 to 3e3983f Compare October 26, 2026 16:30
@hyperlight-gh-bot

Copy link
Copy Markdown

Benchmark Results

Measured commit: 3e3983fbf848
Baseline commit: 559b19185766

kvm / amd (Linux) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 759.19 ns (➖ 1.03x faster)
vec_bytes 577.90 ns (➖ 1.01x faster)
372.28 µs (➖ 1.00x faster)

payload_allocation

slot_pool_segmented
262144 524.82 ns (➖ 1.09x faster)
65536 144.04 ns (➖ 1.02x slower)

sandboxes

create_initialized_and_drop
medium 81.03 ms (➖ 1.01x slower)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
7.69 ns (➖ 1.00x faster) 7.68 ns (➖ 1.00x faster) 7.70 ns (➖ 1.00x faster)

snapshot_files

load_snapshot_unverified
small 93.12 µs (➖ 1.01x slower)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 7.46 µs (➖ 1.05x slower) 6.96 µs (➖ 1.02x faster)
65536 2.04 µs (➖ 1.05x slower) 1.91 µs (➖ 1.10x faster)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 6.72 µs (➖ 1.04x slower) 6.29 µs (➖ 1.03x faster)
8192 1.03 µs (➖ 1.04x faster) 1.02 µs (➖ 1.02x slower)
262144 28.34 µs (➖ 1.04x slower)
kvm / intel (Linux) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 797.31 ns (➖ 1.03x faster)
vec_bytes 572.58 ns (➖ 1.10x faster)
756.41 µs (➖ 1.01x faster)

payload_allocation

slot_pool_segmented
262144 597.11 ns (➖ 1.00x faster)
65536 183.41 ns (➖ 1.01x faster)

sandboxes

create_initialized_and_drop
medium 85.77 ms (➖ 1.01x slower)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
8.11 ns (➖ 1.00x faster) 8.13 ns (➖ 1.01x faster) 8.12 ns (➖ 1.00x slower)

snapshot_files

load_snapshot_unverified
small 50.01 µs (➖ 1.04x faster)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 8.99 µs (➖ 1.01x faster) 9.03 µs (➖ 1.00x faster)
65536 2.55 µs (➖ 1.01x faster) 2.61 µs (➖ 1.02x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 8.33 µs (➖ 1.02x faster) 8.33 µs (➖ 1.02x faster)
8192 961.82 ns (➖ 1.11x slower) 844.75 ns (➖ 1.00x slower)
262144 34.92 µs (➖ 1.00x slower)
mshv3 / amd (Linux) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 919.56 ns (➖ 1.01x faster)
vec_bytes 716.23 ns (➖ 1.00x faster)
305.43 µs (➖ 1.03x slower)

payload_allocation

slot_pool_segmented
262144 732.53 ns (➖ 1.06x faster)
65536 194.50 ns (➖ 1.31x faster)

sandboxes

create_initialized_and_drop
medium 58.88 ms (➖ 1.04x slower)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
10.38 ns (➖ 1.40x faster) 9.54 ns (➖ 1.00x slower) 9.53 ns (➖ 1.01x faster)

snapshot_files

load_snapshot_unverified
small 84.61 µs (➖ 1.03x faster)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 10.07 µs (➖ 1.03x faster) 9.98 µs (➖ 1.01x slower)
65536 2.49 µs (➖ 1.00x slower) 2.25 µs (➖ 1.01x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 8.16 µs (➖ 1.18x faster) 8.24 µs (➖ 1.22x faster)
8192 1.24 µs (➖ 1.02x faster) 1.22 µs (➖ 1.02x slower)
262144 35.87 µs (➖ 1.07x faster)
mshv3 / intel (Linux) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 892.73 ns (➖ 1.03x faster)
vec_bytes 652.82 ns (➖ 1.00x slower)
697.49 µs (➖ 1.02x faster)

payload_allocation

slot_pool_segmented
262144 655.91 ns (➖ 1.01x faster)
65536 255.39 ns (➖ 1.01x slower)

sandboxes

create_initialized_and_drop
medium 64.44 ms (➖ 1.03x faster)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
8.74 ns (➖ 1.01x slower) 8.73 ns (➖ 1.01x slower) 8.68 ns (➖ 1.00x faster)

snapshot_files

load_snapshot_unverified
small 44.92 µs (➖ 1.01x slower)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 7.98 µs (➖ 1.01x slower) 8.00 µs (➖ 1.00x faster)
65536 2.43 µs (➖ 1.07x slower) 2.29 µs (➖ 1.01x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 7.50 µs (➖ 1.01x faster) 7.50 µs (➖ 1.01x slower)
8192 889.93 ns (➖ 1.02x faster) 883.99 ns (➖ 1.03x faster)
262144 38.91 µs (➖ 1.00x faster)
hyperv-ws2025 / amd (Windows) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 1.15 µs (➖ 1.05x faster)
vec_bytes 779.77 ns (➖ 1.01x slower)
1.87 ms (➖ 1.02x faster)

payload_allocation

slot_pool_segmented
262144 794.27 ns (➖ 1.01x slower)
65536 233.88 ns (➖ 1.02x slower)

sandboxes

create_initialized_and_drop
medium 76.68 ms (➖ 1.09x faster)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
10.03 ns (➖ 1.17x faster) 10.01 ns (➖ 1.02x faster) 10.02 ns (➖ 1.03x faster)

snapshot_files

load_snapshot_unverified
small 679.51 µs (➖ 1.18x faster)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 9.46 µs (➖ 1.01x slower) 10.00 µs (➖ 1.05x slower)
65536 2.48 µs (➖ 1.07x slower) 2.54 µs (➖ 1.02x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 9.51 µs (➖ 1.07x slower) 9.10 µs (➖ 1.02x slower)
8192 1.43 µs (➖ 1.12x slower) 1.38 µs (➖ 1.05x slower)
262144 39.33 µs (➖ 1.09x faster)
hyperv-ws2025 / intel (Windows) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 1.22 µs (➖ 1.00x slower)
vec_bytes 760.23 ns (➖ 1.02x faster)
2.96 ms (➖ 1.01x slower)

payload_allocation

slot_pool_segmented
262144 737.86 ns (➖ 1.02x faster)
65536 227.91 ns (➖ 1.10x slower)

sandboxes

create_initialized_and_drop
medium 119.83 ms (➖ 1.09x slower)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
9.65 ns (➖ 1.01x slower) 10.05 ns (➖ 1.01x slower) 9.61 ns (➖ 1.02x faster)

snapshot_files

load_snapshot_unverified
small 559.56 µs (➖ 1.00x slower)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 7.60 µs (➖ 1.02x slower) 7.43 µs (➖ 1.02x faster)
65536 2.27 µs (➖ 1.00x slower) 2.41 µs (➖ 1.05x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 8.24 µs (➖ 1.00x faster) 8.30 µs (➖ 1.01x faster)
8192 1.18 µs (➖ 1.13x slower) 1.07 µs (➖ 1.03x slower)
262144 40.23 µs (➖ 1.23x faster)

Reported by cargo ci bench-report --candidate run:40359831927 --config-file bench_report.toml.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/enhancement For PRs adding features, improving functionality, docs, tests, etc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants