-
Notifications
You must be signed in to change notification settings - Fork 152
Introduce new Vm trait #924
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
base: main
Are you sure you want to change the base?
Conversation
81f0d54 to
62fad87
Compare
1562f26 to
edc7f00
Compare
f6337f9 to
350b8e0
Compare
d2e6bf8 to
afa720d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spent some time looking at these changes. There seem to be alot of really good things in here. My main concern is that it is a very big change that encompases new features, changes, and simplifications across multiple implementations.
My initial thought would be break this down in to small chunks: Add a VM trait, and implement for a single platform. Then move each platform over, this would keep the set of changes smaller. I would also think that we could keep things simplier to review by not doing updates to implementations like the changes for "Simplifies and refactors some cancellation stuff" and have those as seperate change sets
| let cancel_was_requested_manually = | ||
| interrupt_handle_internal.is_cancel_requested_for_generation(generation); | ||
| fn unmap_memory(&mut self, (_slot, _region): (u32, &MemoryRegion)) -> Result<()> { | ||
| log_then_return!("Mapping host memory into the guest not yet supported on this platform"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks implemented above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's just the initial mapping. Subsequent mappings after creating the initial sandbox is not yet supported on windows
|
|
||
| let mut regs = self.regs()?; | ||
| regs.rip = rip + instruction_length; | ||
| self.set_regs(®s) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this rip set in the new implementation in hyperlight_vm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since not all drivers require incrementing RIP, it's an implementation detail of each driver to handle it as part of their run_vcpu. If you check hyperv_linux/windows.rs, you'll see that it's still done
|
|
||
| // -------------------------- | ||
| // --- DEBUGGING BELOW ------ | ||
| // -------------------------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I preferd this being another trait that was implemented as it was before. Whats the motivation for bringing this in here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally I thought it made sense for them to belong on the "Vm" and to be able to get rid of the vcpu abstraction, and a lot of these are not needed anymore. But I agree I think maybe it makes sense.... I can implement all the debugging functionality separately on a supertrait of Vm trait, that should be a bit cleaner. In additon, some code such as getting/setting debug registers, etc, will be needed in the future for purposes of resetting vcpu, even when debugging is not enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since these are all hidden behind the flag, you could keep GuestDebug (modified to what you have here) in the gdb folder and impl GuestDebug for Hyperlight_vm when the flag is enabled I believe
| WriteAddr, | ||
| WriteRegisters, | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couldn't we keep some of this trait here instead of moving it up into the new vm trait?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could, I could make it a supertrait of vm
| exception, | ||
| hw_breakpoints, | ||
| sw_breakpoints, | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unclear why these have been removed from the error log
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are not necessary to determine stop reason so I removed them in order not having to keep unnecessary state around and simplify the code
Signed-off-by: Ludvig Liljenberg <[email protected]>
Signed-off-by: Ludvig Liljenberg <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work!
I like that we get rid of duplicated code, and we now have a clear separation of common Vm code and specific Vm logic.
It is definitely the right direction we want to go.
I left some small comments.
I need to emphasize the fact that being a big change, it is difficult to follow where code was moved.
| ) | ||
| )] | ||
| Retry(), | ||
| #[cfg(gdb)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Invert the comment and #[cfg..
| #[cfg(gdb)] | |
| /// The vCPU has exited due to a debug event (usually breakpoint) | |
| #[cfg(gdb)] |
| use crate::sandbox::uninitialized::SandboxRuntimeConfig; | ||
| use crate::{HyperlightError, Result, log_then_return, new_error}; | ||
|
|
||
| pub(crate) struct HyperlightVm { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments here explaining what this struct wants to achieve and why we need it would be helpful.
I assume this replaces the old Hypervisor
| // Architectures Software Developer's Manual | ||
| if dr6 & DR6_BS_FLAG_MASK != 0 && single_step { | ||
| return VcpuStopReason::DoneStep; | ||
| if dr6 & DR6_BS_FLAG_MASK != 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is fine to remove the single_step variable here. It was only an additional state for verifying the correct flag was in sync with internal state of debugging
|
|
||
| if BP_EX_ID == exception && sw_breakpoints.contains_key(&rip) { | ||
| return VcpuStopReason::SwBp; | ||
| if BP_EX_ID == exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might remove an option here.
If the vCPU stops because of an issue, not a SW/HW breakpoint set by the debugger, it will not be transmitted as an unknown breakpoint.
I am not sure though if this means that the debugger won't show it as an exception.
This is PR 2/3 in a bigger effort to remove duplicate code across drivers.
depends on #907 which must be merged first, will mark this PR as ready then
This PR introduces
Vmtrait. It's a minimal trait for common functionality of a minimal Vm. It abstracts over differences in kvm, mshv, whp. This traits only knows things like set/get registers, run, but nothing about guest functions or hyperlight specifics.HyperlightVmstruct. This is a struct that contains thedyn Vmabove, as well as things like guest_ptr, rsp, memory-regions, gdb connections, etc. You can think of this as replacing the previous Hypervisor trait (but now it's just 1 struct to avoid duplicate code). HyperlightVm knows about initialization, dispatching guest calls, gdb-debugging etc, guest-tracing, whichVmtrait doesn't.kill()without changing behaviorCloses #465, #904