@@ -32,7 +32,7 @@ use mshv_bindings::{
3232} ;
3333use mshv_ioctls:: VcpuFd ;
3434
35- use super :: arch:: { DR6_BS_FLAG_MASK , DR6_HW_BP_FLAGS_MASK , MAX_NO_OF_HW_BP , SW_BP_SIZE } ;
35+ use super :: arch:: { vcpu_stop_reason , MAX_NO_OF_HW_BP , SW_BP_SIZE } ;
3636use super :: { GuestDebug , VcpuStopReason , X86_64Regs } ;
3737use crate :: { new_error, HyperlightError , Result } ;
3838
@@ -131,52 +131,38 @@ impl MshvDebug {
131131 pub ( crate ) fn get_stop_reason (
132132 & mut self ,
133133 vcpu_fd : & VcpuFd ,
134+ exception : u16 ,
134135 entrypoint : u64 ,
135136 ) -> Result < VcpuStopReason > {
136- // MSHV does not provide info on the vCPU exits but the debug
137- // information can be retrieved from the DEBUG REGISTERS
138137 let regs = vcpu_fd
139138 . get_debug_regs ( )
140139 . map_err ( |e| new_error ! ( "Cannot retrieve debug registers from vCPU: {}" , e) ) ?;
141140
142141 // DR6 register contains debug state related information
143142 let debug_status = regs. dr6 ;
144143
145- // If the BS flag in DR6 register is set, it means a single step
146- // instruction triggered the exit
147- // Check page 19-4 Vol. 3B of Intel 64 and IA-32
148- // Architectures Software Developer's Manual
149- if debug_status & DR6_BS_FLAG_MASK != 0 && self . single_step {
150- return Ok ( VcpuStopReason :: DoneStep ) ;
151- }
144+ let rip = self . get_instruction_pointer ( vcpu_fd) ?;
145+ let rip = self . translate_gva ( vcpu_fd, rip) ?;
152146
153- let ip = self . get_instruction_pointer ( vcpu_fd) ?;
154- let gpa = self . translate_gva ( vcpu_fd, ip) ?;
147+ let reason = vcpu_stop_reason (
148+ self . single_step ,
149+ rip,
150+ debug_status,
151+ entrypoint,
152+ exception as u32 ,
153+ & self . hw_breakpoints ,
154+ & self . sw_breakpoints ,
155+ ) ;
155156
156- // If any of the B0-B3 flags in DR6 register is set, it means a
157- // hardware breakpoint triggered the exit
158- // Check page 19-4 Vol. 3B of Intel 64 and IA-32
159- // Architectures Software Developer's Manual
160- if debug_status & DR6_HW_BP_FLAGS_MASK != 0 && self . hw_breakpoints . contains ( & gpa) {
157+ if let VcpuStopReason :: EntryPointBp = reason {
161158 // In case the hw breakpoint is the entry point, remove it to
162159 // avoid hanging here as gdb does not remove breakpoints it
163160 // has not set.
164161 // Gdb expects the target to be stopped when connected.
165- if gpa == entrypoint {
166- self . remove_hw_breakpoint ( vcpu_fd, entrypoint) ?;
167- }
168- return Ok ( VcpuStopReason :: HwBp ) ;
169- }
170-
171- // mshv does not provide a way to specify which exception triggered the
172- // vCPU exit as the mshv intercepts both #DB and #BP
173- // We check against the SW breakpoints Hashmap to detect whether the
174- // vCPU exited due to a SW breakpoint
175- if self . sw_breakpoints . contains_key ( & gpa) {
176- return Ok ( VcpuStopReason :: SwBp ) ;
162+ self . remove_hw_breakpoint ( vcpu_fd, entrypoint) ?;
177163 }
178164
179- Ok ( VcpuStopReason :: Unknown )
165+ Ok ( reason )
180166 }
181167}
182168
0 commit comments