Repository navigation
Conversation
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
requested review from
andreiltd,
danbugs,
dblnz,
devigned,
jprendes,
jsturtevant,
ludfjig,
simongdavies,
squillace and
syntactically
as code owners
November 3, 2026 00:34
cshung
marked this pull request as draft
November 3, 2026 00:36
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical flaws allow guest modification of executable trampoline code and debugger memory corruption, while breakpoint cleanup and snapshot-ordering issues can leave sandboxes unrecoverable.
5 open issues
Split memory operations at guest page boundaries · New Make the cache-sync trampoline guest read/execute only · New Recheck for breakpoints after snapshot checkpoint interaction · New Clear breakpoint bookkeeping when crash detach cannot restore instructions · New Reconcile breakpoints when restoring a cancelled sandbox · New
What changed in this PR
Adds ARM64 guest debugging on Linux/KVM, alongside the shared debugger infrastructure and Windows/WHP support from #1907.
Changes:
- Supports ARM64 register and memory access, software and hardware breakpoints, and hardware single-step.
- Adds instruction-cache synchronization, debug-state preservation across reset, and snapshot safeguards.
- Adds debugger tests and documents platform capabilities.
| File | Description |
|---|---|
src/hyperlight_host/src/sandbox/uninitialized_evolve.rs |
Initializes ARM64 debug vectors during VM setup. |
src/hyperlight_host/src/sandbox/snapshot/memory/backing.rs |
Exposes backing ranges for cache synchronization. |
src/hyperlight_host/src/sandbox/initialized.rs |
Guards snapshots and restores against active software breakpoints. |
src/hyperlight_host/src/mem/mgr.rs |
Exposes checked host memory ranges to the debugger. |
src/hyperlight_host/src/mem/exe.rs |
Carries debug-vector addresses in load metadata. |
src/hyperlight_host/src/mem/elf.rs |
Finds and relocates the debug-vector symbol. |
src/hyperlight_host/src/hypervisor/virtual_machine/whp/x86_64.rs |
Adapts address translation to the shared interface. |
src/hyperlight_host/src/hypervisor/virtual_machine/whp/aarch64.rs |
Implements WHP debugging, cache synchronization, and tests. |
src/hyperlight_host/src/hypervisor/virtual_machine/mshv/x86_64.rs |
Adapts address translation to the shared interface. |
src/hyperlight_host/src/hypervisor/virtual_machine/mod.rs |
Adds ARM64 debug exits and initialization errors. |
src/hyperlight_host/src/hypervisor/virtual_machine/kvm/x86_64.rs |
Adapts address translation to the shared interface. |
src/hyperlight_host/src/hypervisor/virtual_machine/kvm/aarch64.rs |
Implements KVM debugging and active-stack-pointer handling. |
src/hyperlight_host/src/hypervisor/regs/aarch64/whp_reg.rs |
Defines WHP debug register identifiers. |
src/hyperlight_host/src/hypervisor/hyperlight_vm/x86_64.rs |
Uses shared debugger handling and breakpoint storage. |
src/hyperlight_host/src/hypervisor/hyperlight_vm/mod.rs |
Integrates ARM64 stops, stepping, and mapping safeguards. |
src/hyperlight_host/src/hypervisor/hyperlight_vm/debug.rs |
Provides shared requests and software-breakpoint lifecycle handling. |
src/hyperlight_host/src/hypervisor/hyperlight_vm/aarch64.rs |
Connects ARM64 VM setup and execution to GDB. |
src/hyperlight_host/src/hypervisor/gdb/target.rs |
Adds ARM64 register conversion to the shared target. |
src/hyperlight_host/src/hypervisor/gdb/mod.rs |
Adds page-table translation and cache-flush support. |
src/hyperlight_host/src/hypervisor/gdb/event_loop.rs |
Reports ARM64 initial stops to GDB. |
src/hyperlight_host/src/hypervisor/gdb/arch/x86_64.rs |
Houses x86 breakpoint constants and stop classification. |
src/hyperlight_host/src/hypervisor/gdb/arch/aarch64.rs |
Defines ARM64 software breakpoints and alignment checks. |
src/hyperlight_host/src/hypervisor/gdb/arch.rs |
Selects architecture-specific debugger helpers. |
src/hyperlight_host/examples/guest-debugging/main.rs |
Adds ARM64 breakpoint, stepping, and code-write integration tests. |
src/hyperlight_host/build.rs |
Enables GDB for supported ARM64 platforms. |
src/hyperlight_guest_bin/src/arch/aarch64/exception/entry.rs |
Exports debug vectors and forwards synchronous exceptions. |
src/hyperlight_common/src/arch/aarch64/exn.rs |
Defines the shared debug-exception HVC immediate. |
docs/how-to-debug-a-hyperlight-guest.md |
Documents ARM64 capabilities and guest-symbol requirements. |
CHANGELOG.md |
Records Linux/KVM and Windows/WHP ARM64 debugging support. |
Review effort: Balanced
Comment on lines
+339
to
+361
| page_size::get() - (gpa as usize & (page_size::get() - 1)), | ||
| ); | ||
| mem_access.read(&mut data[..read_len], gpa)?; | ||
| data = &mut data[read_len..]; | ||
| gva += read_len as u64; | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| fn write_addrs( | ||
| &mut self, | ||
| mut gva: u64, | ||
| mut data: &[u8], | ||
| mem_access: &DebugMemoryView<'_>, | ||
| ) -> std::result::Result<(), ProcessDebugRequestError> { | ||
| tracing::debug!("Write addr: {:X} len: {:X}", gva, data.len()); | ||
|
|
||
| while !data.is_empty() { | ||
| let gpa = self.vm.translate_gva(gva, mem_access)?; | ||
| let write_len = std::cmp::min( | ||
| data.len(), | ||
| page_size::get() - (gpa as usize & (page_size::get() - 1)), |
| .copy_from_slice(&DEBUG_CACHE_SYNC_CODE, 0) | ||
| .map_err(|e| CreateVmError::InitializeDebug(e.to_string()))?; | ||
| let (host_memory, guest_memory) = memory.build(); | ||
| let region = guest_memory.mapping_at(DEBUG_CACHE_SYNC_GPA, MemoryRegionType::Scratch); |
Comment on lines
+469
to
+470
| #[cfg(all(gdb, target_arch = "aarch64"))] | ||
| if self.vm.has_sw_breakpoints() { |
Comment on lines
+99
to
+102
| Err(error) => { | ||
| tracing::error!("Failed to clean up after detach: {error}"); | ||
| DebugResponse::ErrorOccurred | ||
| } |
Comment on lines
+719
to
+723
| #[cfg(all(gdb, target_arch = "aarch64"))] | ||
| if self.vm.has_sw_breakpoints() { | ||
| return Err(crate::new_error!( | ||
| "Cannot restore an ARM64 sandbox while software breakpoints are installed" | ||
| )); |
ARM64 KVM debugging uses KVM_SET_GUEST_DEBUG for hardware single-step and two hardware breakpoints. Software breakpoints use BRK. Guest virtual addresses use the existing page-table reader. Debugger code writes synchronize the host instruction cache. Register access respects the active stack pointer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: cshung <3410332+cshung@users.noreply.github.com>
ARM64 KVM debug jobs run the GDB suite before the general Rust tests. Install GDB when the runner lacks it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: cshung <3410332+cshung@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
cshung
force-pushed
the
cshung/kvm-aarch64-gdb
branch
from
November 3, 2026 01:58
a60be9b to
55da94f
Compare
Benchmark ResultsMeasured commit: kvm / amd (Linux) (➖ stable)No benchmark improved or regressed. Benchmark Resultsfunction_call_codec
payload_allocation
sandboxes
slot_pool
snapshot_files
virtq_readonly
virtq_readwrite
kvm / intel (Linux) (➖ stable)No benchmark improved or regressed. Benchmark Resultsfunction_call_codec
payload_allocation
sandboxes
slot_pool
snapshot_files
virtq_readonly
virtq_readwrite
mshv3 / amd (Linux) (➖ stable)No benchmark improved or regressed. Benchmark Resultsfunction_call_codec
payload_allocation
sandboxes
slot_pool
snapshot_files
virtq_readonly
virtq_readwrite
mshv3 / intel (Linux) (➖ stable)No benchmark improved or regressed. Benchmark Resultsfunction_call_codec
payload_allocation
sandboxes
slot_pool
snapshot_files
virtq_readonly
virtq_readwrite
hyperv-ws2025 / amd (Windows) (➖ stable)No benchmark improved or regressed. Benchmark Resultsfunction_call_codec
payload_allocation
sandboxes
slot_pool
snapshot_files
virtq_readonly
virtq_readwrite
Reported by |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
ARM64 Linux/KVM guests support GDB register and memory access, two hardware breakpoints, BRK software breakpoints, and hardware single-step.
KVM reports debug stops through
KVM_EXIT_DEBUG. Guest address translation uses the existing page-table reader. Debugger code writes synchronize the instruction cache. Debug state survives vCPU reset, and register access respects the active stack pointer.Depends on #1907. This branch includes its shared ARM64 debugger support.
KVM-only comparison.
Validation
just testandjust test-rust-gdb-debuggingpass.just fmt-apply,just guests,just clippy, and native ARM64 KVM Clippy with GDB enabled pass.Pi validation uses a separate, uncommitted ARMv8.0 allocator fix and guests built with
RUSTFLAGS="-C target-feature=-lse". Pi compatibility changes are outside this commit.