Skip to content

Commit

Permalink
openvmm: add basic gdbstub support for aarch64
Browse files Browse the repository at this point in the history
Plumb aarch64 support, using the `gdbstub_arch` crate to provide the register
definitions.

Only register reads and memory access are supported. Register updates and
breakpoints are not.
  • Loading branch information
jstarks committed Nov 13, 2024
1 parent c113573 commit a4658b5
Show file tree
Hide file tree
Showing 17 changed files with 393 additions and 103 deletions.
13 changes: 13 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -876,10 +876,12 @@ version = "0.0.0"
name = "debug_worker"
version = "0.0.0"
dependencies = [
"aarch64defs",
"anyhow",
"debug_worker_defs",
"futures",
"gdbstub",
"gdbstub_arch",
"inspect",
"mesh",
"mesh_worker",
Expand Down Expand Up @@ -2032,6 +2034,16 @@ dependencies = [
"paste",
]

[[package]]
name = "gdbstub_arch"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eecb536c55c43593a00dde9074dbbdb0e81ce5f20dbca921400f8779c21dea9c"
dependencies = [
"gdbstub",
"num-traits",
]

[[package]]
name = "gdma"
version = "0.0.0"
Expand Down Expand Up @@ -7992,6 +8004,7 @@ dependencies = [
"thiserror 2.0.0",
"tracing",
"virt",
"virt_support_aarch64emu",
"virt_support_x86emu",
"vm_resource",
"vm_topology",
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ futures-core = "0.3"
futures-channel = "0.3"
futures-io = "0.3"
gdbstub = "0.6"
gdbstub_arch = "0.2"
getrandom = "0.2"
glob = "0.3"
gptman = "1.0"
Expand Down
5 changes: 5 additions & 0 deletions openvmm/hvlite_entry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1744,6 +1744,11 @@ async fn run_control(driver: &DefaultDriver, mesh: &VmmMesh, opt: Options) -> an
listener,
req_chan: req_tx,
vp_count: vm_config.processor_topology.proc_count,
target_arch: if cfg!(guest_arch = "x86_64") {
debug_worker_defs::TargetArch::X86_64
} else {
debug_worker_defs::TargetArch::Aarch64
},
},
)
.await
Expand Down
3 changes: 2 additions & 1 deletion vmm_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ edition = "2021"
rust-version.workspace = true

[features]
gdb = ["iced-x86", "virt_support_x86emu"]
gdb = ["iced-x86", "virt_support_aarch64emu", "virt_support_x86emu"]

[dependencies]
virt.workspace = true
virt_support_aarch64emu = { workspace = true, optional = true }
virt_support_x86emu = { workspace = true, optional = true }
state_unit.workspace = true
vmm_core_defs.workspace = true
Expand Down
20 changes: 10 additions & 10 deletions vmm_core/src/partition_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ struct PartitionUnitRunner {
topology: ProcessorTopology,
initial_regs: Option<Arc<InitialRegs>>,

#[cfg(all(feature = "gdb", guest_arch = "x86_64"))]
#[cfg(feature = "gdb")]
debugger_state: debug::DebuggerState,
}

Expand Down Expand Up @@ -204,7 +204,7 @@ impl PartitionUnit {
req_recv,
topology: params.processor_topology.clone(),
initial_regs: None,
#[cfg(all(feature = "gdb", guest_arch = "x86_64"))]
#[cfg(feature = "gdb")]
debugger_state: debug::DebuggerState::new(
params.vtl_guest_memory[0]
.ok_or(Error::MissingGuestMemory)?
Expand Down Expand Up @@ -280,25 +280,25 @@ impl PartitionUnitRunner {
State(Option<StateRequest>),
Halt(InternalHaltReason),
Request(PartitionRequest),
#[cfg(all(feature = "gdb", guest_arch = "x86_64"))]
#[cfg(feature = "gdb")]
Debug(vmm_core_defs::debug_rpc::DebugRequest),
}

#[cfg(all(feature = "gdb", guest_arch = "x86_64"))]
#[cfg(feature = "gdb")]
let debug = self.debugger_state.wait_rpc();
#[cfg(not(all(feature = "gdb", guest_arch = "x86_64")))]
#[cfg(not(feature = "gdb"))]
let debug = std::future::pending();

let event = futures::select! { // merge semantics
request = recv.next() => Event::State(request),
request = self.halt_request_recv.select_next_some() => Event::Halt(request),
request = self.req_recv.select_next_some() => Event::Request(request),
request = debug.fuse() => {
#[cfg(all(feature = "gdb", guest_arch = "x86_64"))]
#[cfg(feature = "gdb")]
{
Event::Debug(request)
}
#[cfg(not(all(feature = "gdb", guest_arch = "x86_64")))]
#[cfg(not(feature = "gdb"))]
{
let _: std::convert::Infallible = request;
unreachable!()
Expand Down Expand Up @@ -334,7 +334,7 @@ impl PartitionUnitRunner {
.await
}
},
#[cfg(all(feature = "gdb", guest_arch = "x86_64"))]
#[cfg(feature = "gdb")]
Event::Debug(request) => {
self.handle_gdb(request).await;
}
Expand All @@ -356,9 +356,9 @@ impl PartitionUnitRunner {
self.halt_reason = Some(reason.clone());

// Report the halt to the debugger.
#[cfg(all(feature = "gdb", guest_arch = "x86_64"))]
#[cfg(feature = "gdb")]
let reported = self.debugger_state.report_halt_to_debugger(&reason);
#[cfg(not(all(feature = "gdb", guest_arch = "x86_64")))]
#[cfg(not(feature = "gdb"))]
let reported = false;

// If the debugger is not attached, then report the halt
Expand Down
2 changes: 1 addition & 1 deletion vmm_core/src/partition_unit/debug.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#![cfg(all(feature = "gdb", guest_arch = "x86_64"))]
#![cfg(feature = "gdb")]

//! Implements debugging support for [`PartitionUnitRunner`]. This is a separate
//! module because it is cfg gated on the `gdb` feature.
Expand Down
Loading

0 comments on commit a4658b5

Please sign in to comment.