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 and others added 3 commits October 20, 2026 10:58
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 <3410332+cshung@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## 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 <3410332+cshung@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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 <223556219+Copilot@users.noreply.github.com>
Signed-off-by: cshung <3410332+cshung@users.noreply.github.com>
@cshung
cshung force-pushed the cshung/whp-aarch64-gdb branch from dd86b49 to 698b851 Compare October 20, 2026 17:59
@hyperlight-gh-bot

Copy link
Copy Markdown

Benchmark Results

Measured commit: 698b85108794
Baseline commit: f0934723ebf0

kvm / amd (Linux) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 749.69 ns (➖ 1.00x faster)
vec_bytes 581.49 ns (➖ 1.02x faster)
374.57 µs (➖ 1.00x slower)

payload_allocation

slot_pool_segmented
65536 142.86 ns (➖ 1.00x faster)
262144 524.20 ns (➖ 1.00x faster)

sandboxes

create_initialized_and_drop
medium 83.75 ms (➖ 1.04x slower)

slot_pool

alloc_dealloc_4096 alloc_dealloc_128 alloc_dealloc_1500
7.72 ns (➖ 1.00x faster) 8.66 ns (➖ 1.12x slower) 7.88 ns (➖ 1.02x slower)

snapshot_files

load_snapshot_unverified
small 94.58 µs (➖ 1.02x slower)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
65536 2.05 µs (➖ 1.04x slower) 1.92 µs (➖ 1.09x faster)
262144 7.04 µs (➖ 1.13x faster) 7.54 µs (➖ 1.07x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 6.29 µs (➖ 1.01x faster) 6.22 µs (➖ 1.10x faster)
8192 1.06 µs (➖ 1.07x faster) 1.05 µs (➖ 1.01x faster)
262144 27.31 µs (➖ 1.01x faster)
kvm / intel (Linux) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 788.95 ns (➖ 1.01x faster)
vec_bytes 587.19 ns (➖ 1.02x slower)
708.92 µs (➖ 1.01x faster)

payload_allocation

slot_pool_segmented
65536 149.32 ns (➖ 1.01x faster)
262144 576.67 ns (➖ 1.01x faster)

sandboxes

create_initialized_and_drop
medium 79.11 ms (➖ 1.02x faster)

slot_pool

alloc_dealloc_4096 alloc_dealloc_128 alloc_dealloc_1500
7.84 ns (➖ 1.01x faster) 7.71 ns (➖ 1.01x faster) 7.68 ns (➖ 1.01x faster)

snapshot_files

load_snapshot_unverified
small 46.56 µs (➖ 1.05x faster)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
65536 2.33 µs (➖ 1.06x slower) 2.31 µs (➖ 1.06x slower)
262144 8.29 µs (➖ 1.04x slower) 8.34 µs (➖ 1.07x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 8.02 µs (➖ 1.00x faster) 8.10 µs (➖ 1.02x slower)
8192 949.69 ns (➖ 1.12x slower) 843.54 ns (➖ 1.01x slower)
262144 33.20 µs (➖ 1.01x faster)
mshv3 / amd (Linux) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 919.09 ns (➖ 1.01x slower)
vec_bytes 700.80 ns (➖ 1.01x faster)
318.51 µs (➖ 1.00x slower)

payload_allocation

slot_pool_segmented
65536 187.48 ns (➖ 1.01x slower)
262144 684.49 ns (➖ 1.02x slower)

sandboxes

create_initialized_and_drop
medium 65.08 ms (➖ 1.07x slower)

slot_pool

alloc_dealloc_4096 alloc_dealloc_128 alloc_dealloc_1500
9.91 ns (➖ 1.00x faster) 9.93 ns (➖ 1.00x faster) 9.95 ns (➖ 1.00x slower)

snapshot_files

load_snapshot_unverified
small 86.07 µs (➖ 1.00x slower)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
65536 2.68 µs (➖ 1.00x faster) 2.47 µs (➖ 1.00x slower)
262144 9.15 µs (➖ 1.02x faster) 9.00 µs (➖ 1.01x faster)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 8.04 µs (➖ 1.03x faster) 8.04 µs (➖ 1.03x faster)
8192 1.38 µs (➖ 1.00x slower) 1.36 µs (➖ 1.02x slower)
262144 34.80 µs (➖ 1.03x faster)
mshv3 / intel (Linux) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 946.40 ns (➖ 1.04x slower)
vec_bytes 654.72 ns (➖ 1.01x slower)
717.81 µs (➖ 1.08x faster)

payload_allocation

slot_pool_segmented
65536 173.27 ns (➖ 1.06x faster)
262144 664.66 ns (➖ 1.02x slower)

sandboxes

create_initialized_and_drop
medium 66.28 ms (➖ 1.01x faster)

slot_pool

alloc_dealloc_4096 alloc_dealloc_128 alloc_dealloc_1500
9.40 ns (➖ 1.01x faster) 9.33 ns (➖ 1.00x faster) 9.65 ns (➖ 1.01x faster)

snapshot_files

load_snapshot_unverified
small 46.14 µs (➖ 1.02x slower)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
65536 2.28 µs (➖ 1.01x slower) 2.28 µs (➖ 1.01x slower)
262144 8.21 µs (➖ 1.03x slower) 7.93 µs (➖ 1.00x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 7.56 µs (➖ 1.00x faster) 7.51 µs (➖ 1.03x faster)
8192 921.88 ns (➖ 1.02x faster) 942.39 ns (➖ 1.04x slower)
262144 41.45 µs (➖ 1.06x 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.01x faster)
vec_bytes 801.45 ns (➖ 1.01x slower)
1.99 ms (➖ 1.00x slower)

payload_allocation

slot_pool_segmented
65536 240.03 ns (➖ 1.03x slower)
262144 788.28 ns (➖ 1.00x slower)

sandboxes

create_initialized_and_drop
medium 83.22 ms (➖ 1.04x faster)

slot_pool

alloc_dealloc_4096 alloc_dealloc_128 alloc_dealloc_1500
10.54 ns (➖ 1.01x slower) 10.16 ns (➖ 1.01x slower) 11.09 ns (➖ 1.08x slower)

snapshot_files

load_snapshot_unverified
small 1.12 ms (➖ 1.44x slower)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
65536 2.35 µs (➖ 1.03x faster) 2.34 µs (➖ 1.00x faster)
262144 9.00 µs (➖ 1.05x faster) 9.16 µs (➖ 1.00x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 9.21 µs (➖ 1.03x slower) 8.91 µs (➖ 1.05x faster)
8192 1.31 µs (➖ 1.07x faster) 1.29 µs (➖ 1.03x faster)
262144 40.64 µs (➖ 1.03x 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.24 µs (➖ 1.04x slower)
vec_bytes 784.27 ns (➖ 1.01x slower)
2.98 ms (➖ 1.05x faster)

payload_allocation

slot_pool_segmented
65536 208.55 ns (➖ 1.02x faster)
262144 740.62 ns (➖ 1.08x faster)

sandboxes

create_initialized_and_drop
medium 103.25 ms (➖ 1.13x faster)

slot_pool

alloc_dealloc_4096 alloc_dealloc_128 alloc_dealloc_1500
9.99 ns (➖ 1.00x slower) 9.97 ns (➖ 1.00x slower) 9.97 ns (➖ 1.00x slower)

snapshot_files

load_snapshot_unverified
small 539.28 µs (➖ 1.09x faster)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
65536 2.34 µs (➖ 1.01x slower) 2.34 µs (➖ 1.01x faster)
262144 7.79 µs (➖ 1.02x slower) 7.79 µs (➖ 1.00x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 8.54 µs (➖ 1.02x faster) 8.54 µs (➖ 1.04x faster)
8192 1.12 µs (➖ 1.12x faster) 1.09 µs (➖ 1.01x faster)
262144 42.84 µs (➖ 1.01x faster)

Reported by cargo ci bench-report --candidate run:39470905052 --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