Skip to content

Commit 6c4ca58

Browse files
committed
Ctrl+c in gdb works on kvm and whp
Signed-off-by: Ludvig Liljenberg <[email protected]>
1 parent 76fa02b commit 6c4ca58

File tree

6 files changed

+55
-25
lines changed

6 files changed

+55
-25
lines changed

src/hyperlight_host/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ cfg_aliases = "0.2.1"
116116
built = { version = "0.8.0", optional = true, features = ["chrono", "git2"] }
117117

118118
[features]
119-
default = ["kvm", "mshv2", "seccomp", "build-metadata"]
119+
default = ["kvm", "mshv2", "seccomp", "build-metadata", "gdb"]
120120
seccomp = ["dep:seccompiler"]
121121
function_call_metrics = []
122122
executable_heap = []

src/hyperlight_host/src/hypervisor/gdb/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
mod arch;
17+
pub(crate) mod arch;
1818
mod event_loop;
1919
mod x86_64_target;
2020

@@ -79,7 +79,6 @@ pub enum VcpuStopReason {
7979
EntryPointBp,
8080
HwBp,
8181
SwBp,
82-
#[allow(dead_code)] // TODO confirm with doru if this really is needed
8382
Interrupt,
8483
Unknown,
8584
}

src/hyperlight_host/src/hypervisor/hyperlight_vm.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use super::mshv::MshvVm;
3434
use super::regs::{
3535
CommonFpu, CommonRegisters, FP_CONTROL_WORD_DEFAULT, FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT,
3636
};
37-
use super::vm::{HyperlightExit, Vm};
37+
use super::vm::{DebugExit, HyperlightExit, Vm};
3838
use super::{
3939
HyperlightVm, CR0_AM, CR0_ET, CR0_MP, CR0_NE, CR0_PE, CR0_PG, CR0_WP, CR4_OSFXSR,
4040
CR4_OSXMMEXCPT, CR4_PAE, EFER_LMA, EFER_LME, EFER_NX, EFER_SCE,
@@ -502,11 +502,29 @@ impl HyperlightVm for HyperlightSandbox {
502502
loop {
503503
match self.vm.run_vcpu() {
504504
#[cfg(gdb)]
505-
Ok(HyperlightExit::Debug { dr6, exception }) => {
506-
let stop_reason =
507-
arch::vcpu_stop_reason(self.vm.as_mut(), self.entrypoint, dr6, exception)?;
508-
if let Err(e) = self.handle_debug(dbg_mem_access_fn.clone(), stop_reason) {
509-
log_then_return!(e);
505+
Ok(HyperlightExit::Debug(debug_exit)) => {
506+
match debug_exit {
507+
DebugExit::Debug { dr6, exception } => {
508+
// Handle debug event (breakpoints)
509+
let stop_reason = arch::vcpu_stop_reason(
510+
self.vm.as_mut(),
511+
self.entrypoint,
512+
dr6,
513+
exception,
514+
)?;
515+
if let Err(e) =
516+
self.handle_debug(dbg_mem_access_fn.clone(), stop_reason)
517+
{
518+
log_then_return!(e);
519+
}
520+
}
521+
DebugExit::Interrupt => {
522+
if let Err(e) = self
523+
.handle_debug(dbg_mem_access_fn.clone(), VcpuStopReason::Interrupt)
524+
{
525+
log_then_return!(e);
526+
}
527+
}
510528
}
511529
}
512530

@@ -580,7 +598,6 @@ impl HyperlightVm for HyperlightSandbox {
580598
}
581599
}
582600
}
583-
584601
Ok(HyperlightExit::Cancelled()) => {
585602
// Shutdown is returned when the host has cancelled execution
586603
// After termination, the main thread will re-initialize the VM

src/hyperlight_host/src/hypervisor/kvm.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ use kvm_ioctls::{Kvm, VcpuExit, VcpuFd, VmFd};
2626
use tracing::{instrument, Span};
2727

2828
use super::regs::{CommonFpu, CommonRegisters, CommonSpecialRegisters};
29-
use super::vm::Vm;
30-
use super::HyperlightExit;
29+
use super::vm::{DebugExit, HyperlightExit, Vm};
3130
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
3231
use crate::{log_then_return, new_error, Result};
3332

@@ -145,18 +144,18 @@ impl Vm for KvmVm {
145144
Ok(VcpuExit::MmioWrite(addr, _)) => Ok(HyperlightExit::MmioWrite(addr)),
146145
#[cfg(gdb)]
147146
// KVM provides architecture specific information about the vCPU state when exiting
148-
Ok(VcpuExit::Debug(debug_exit)) => Ok(HyperlightExit::Debug {
147+
Ok(VcpuExit::Debug(debug_exit)) => Ok(HyperlightExit::Debug(DebugExit::Debug {
149148
dr6: debug_exit.dr6,
150149
exception: debug_exit.exception,
151-
}),
150+
})),
152151
Err(e) => match e.errno() {
153152
// In case of the gdb feature, the timeout is not enabled, this
154153
// exit is because of a signal sent from the gdb thread to the
155-
// hypervisor thread to cancel execution
156-
// #[cfg(gdb)]
157-
// libc::EINTR => Ok(HyperlightExit::Debug(VcpuStopReason::Interrupt)),
158-
// we send a signal to the thread to cancel execution this results in EINTR being returned by KVM so we return Cancelled
159-
// #[cfg(not(gdb))]
154+
// hypervisor thread to cancel execution (e.g. Ctrl+C from GDB)
155+
#[cfg(gdb)]
156+
libc::EINTR => Ok(HyperlightExit::Debug(DebugExit::Interrupt)),
157+
// we send a signal to the thread to cancel execution. This results in EINTR being returned
158+
#[cfg(not(gdb))]
160159
libc::EINTR => Ok(HyperlightExit::Cancelled()),
161160
libc::EAGAIN => Ok(HyperlightExit::Retry()),
162161
_ => {

src/hyperlight_host/src/hypervisor/mshv.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ use tracing::{instrument, Span};
5252
#[cfg(gdb)]
5353
use super::handlers::DbgMemAccessHandlerCaller;
5454
use super::regs::{CommonFpu, CommonRegisters, CommonSpecialRegisters};
55-
use super::vm::Vm;
56-
use super::HyperlightExit;
55+
use super::vm::{HyperlightExit, Vm};
56+
use crate::hypervisor::vm::DebugExit;
5757
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
5858
use crate::{log_then_return, new_error, Result};
5959

@@ -236,18 +236,24 @@ impl Vm for MshvVm {
236236
EXCEPTION_INTERCEPT => {
237237
let exception_message = m.to_exception_info()?;
238238
let DebugRegisters { dr6, .. } = self.vcpu_fd.get_debug_regs()?;
239-
HyperlightExit::Debug {
239+
HyperlightExit::Debug(DebugExit::Debug {
240240
dr6,
241241
exception: exception_message.exception_vector as u32,
242-
}
242+
})
243243
}
244244
other => {
245245
crate::debug!("mshv Other Exit: Exit: {:#?} \n {:#?}", other, &self);
246246
log_then_return!("unknown Hyper-V run message type {:?}", other);
247247
}
248248
},
249249
Err(e) => match e.errno() {
250-
// we send a signal to the thread to cancel execution this results in EINTR being returned by KVM so we return Cancelled
250+
// In case of the gdb feature, the timeout is not enabled, this
251+
// exit is because of a signal sent from the gdb thread to the
252+
// hypervisor thread to cancel execution (e.g. Ctrl+C from GDB)
253+
#[cfg(gdb)]
254+
libc::EINTR => HyperlightExit::Debug(DebugExit::Interrupt),
255+
// we send a signal to the thread to cancel execution. This results in EINTR being returned
256+
#[cfg(not(gdb))]
251257
libc::EINTR => HyperlightExit::Cancelled(),
252258
libc::EAGAIN => HyperlightExit::Retry(),
253259
_ => {

src/hyperlight_host/src/hypervisor/vm.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,19 @@ pub(crate) trait Vm: Send + Sync + Debug {
7878
) -> Result<()>;
7979
}
8080

81+
#[derive(Debug)]
82+
pub(super) enum DebugExit {
83+
/// The vCPU has exited due to a debug event (usually breakpoint)
84+
Debug { dr6: u64, exception: u32 },
85+
/// The user has requested to stop the VM during execution (e.g. via Ctrl+C inside GDB)
86+
Interrupt,
87+
}
88+
8189
/// Possible exit reasons of a VM's vCPU
8290
pub(super) enum HyperlightExit {
8391
#[cfg(gdb)]
8492
/// The vCPU has exited due to a debug event
85-
Debug { dr6: u64, exception: u32 },
93+
Debug(DebugExit),
8694
/// The vCPU has halted
8795
Halt(),
8896
/// The vCPU has issued a write to the given port with the given value
@@ -92,6 +100,7 @@ pub(super) enum HyperlightExit {
92100
/// The vCPU tried to write to the given (unmapped) addr
93101
MmioWrite(u64),
94102
/// The vCPU execution has been cancelled
103+
#[allow(dead_code)]
95104
Cancelled(),
96105
/// The vCPU has exited for a reason that is not handled by Hyperlight
97106
Unknown(String),

0 commit comments

Comments
 (0)