Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

openvmm: add basic gdbstub support for aarch64 #307

Merged
merged 6 commits into from
Nov 17, 2024

Conversation

jstarks
Copy link
Member

@jstarks jstarks commented Nov 13, 2024

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.

@jstarks jstarks requested review from a team as code owners November 13, 2024 00:18
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.
#[derive(Debug, Protobuf)]
pub enum DebuggerVpState {
X86_64(X86VpState),
Aarch64(Aarch64VpState),
Copy link
Contributor

Choose a reason for hiding this comment

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

unfortunate that x86 has to "pay" due to ARM support being added here...

are you completely opposed to having this arch gated?

Copy link
Member Author

Choose a reason for hiding this comment

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

I am not completely opposed. But aren't we trying to minimize cfg(guest_arch = ...)?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think my worry is that we're making different design choices based on how "impactful" the changes are.

Correct me if I'm wrong, but we use compile-time gates in things like, say, core virt_ infrastructure, precisely because we don't want to carry x86 specific stuff on ARM (and vice-versa). We could've done something similar to this approach, where things like CPU topology would be arch-based enums, but we didn't do that.

I think whichever way we go in this code is gonna be reasonable, but nailing down some specific guidelines / philosophy around multi-arch code would be good moving forwards.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fair. Collecting some thoughts here... I think general there are three different approaches we can take:

  1. Define types/traits/functions that are the union of the arch-specific details.
  2. Define types/traits/functions that use generics to describe arch-specific details.
  3. Use cfg(guest_arch = ...) to just gate stuff at compile time.

I think each of these have their uses, and I think we can probably be a bit more prescriptive about when you should reach for which tool.

For example, I think we generally should avoid the use of cfg in cross-worker communication types (like the ones defined here), because that makes it hard for us to ever support a cross-arch VMM via emulation--even if the VM worker binary needs to be built multiple times to support multiple arches, we should not require multiple builds of client binaries (such as petri).

It's also just a good principle that the build configuration should not affect the cross-process protocol--we ran into problems with petri being built with different features from openvmm and having protocol incompatibilities. It's easier to have a rule forbidding all cfg in protocol types than to explain that it's just feature that's prohibited.

I also think we should generally avoid arch generics in protocol types, since generics are viral. In this case, we'd have to propagate the arch up through... DebugRequest, VmProxy, State, DebuggerWorker...

So that leaves us with unions, which I think make sense here.

But for traits and functions, different constraints are at play. There, we have experimented with guest_arch and generics to a greater degree. I think we'll want to revisit some of our decisions there over time, and maybe use the union technique in a few more places.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's a very insightful comment John, thank you. Thinking about it in terms of worker code vs. "client" code is not something I had considered, but makes a lot of sense.

Could you send a PR up which adds these thoughts to https://openvmm.dev/guide/dev_guide/contrib/code.html, so we can codify some of this thinking? Or, if you'd like to drive-by include it as part of this PR (which looks like it'll need at least one more revision anyways), that'd be great.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll do this separately. Tracking via #320 so I don't forget.

romank-msft
romank-msft previously approved these changes Nov 13, 2024
@jstarks jstarks enabled auto-merge (squash) November 14, 2024 06:38
@@ -641,7 +641,7 @@ impl<'p> virt::Processor for HvfProcessor<'p> {
_vtl: Vtl,
_state: Option<&virt::x86::DebugState>,
) -> Result<(), Self::Error> {
todo!()
Ok(())
Copy link
Contributor

Choose a reason for hiding this comment

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

meta: this seems life a x86 specific function that should prob get tweaked / yoinked from the virt::Processor API (or put behind an IDET or something)

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this just gets generalized once we support hw breakpoints on ARM.

let DebuggerVpState::Aarch64(_state) = state else {
anyhow::bail!("wrong architecture")
};
anyhow::bail!("todo");
Copy link
Contributor

Choose a reason for hiding this comment

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

is this hard to do, or just annoying to do? would be nice to just get it out of the way now if its just the latter

Copy link
Contributor

Choose a reason for hiding this comment

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

I kept reading, and see that there's a solid amount of wiring here. Seems reasonable to punt for now.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll wire it up here because it's straightforward. But I won't bother with the end-to-end for now.

@@ -0,0 +1,95 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

Copy link
Contributor

Choose a reason for hiding this comment

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

missing mod comment

},
pc: state.pc,
cpsr: state.cpsr as u32,
v: [0; 32],
Copy link
Contributor

Choose a reason for hiding this comment

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

are these just TODO, or...?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah. I'll add a comment.

@daprilik
Copy link
Contributor

A few misc comments, but broadly LGTM

@jstarks jstarks merged commit f9ebf91 into microsoft:main Nov 17, 2024
24 checks passed
@jstarks jstarks deleted the aarch64_gdb branch November 17, 2024 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants