@@ -16,16 +16,16 @@ limitations under the License.
1616
1717//! This file contains architecture specific code for the x86_64
1818
19- use std :: collections :: HashMap ;
20-
21- use super :: VcpuStopReason ;
19+ use super :: { DebuggableVm , VcpuStopReason } ;
20+ use crate :: Result ;
21+ use crate :: hypervisor :: regs :: CommonRegisters ;
2222
2323// Described in Table 6-1. Exceptions and Interrupts at Page 6-13 Vol. 1
2424// of Intel 64 and IA-32 Architectures Software Developer's Manual
2525/// Exception id for #DB
26- const DB_EX_ID : u32 = 1 ;
26+ pub ( crate ) const DB_EX_ID : u32 = 1 ;
2727/// Exception id for #BP - triggered by the INT3 instruction
28- const BP_EX_ID : u32 = 3 ;
28+ pub ( crate ) const BP_EX_ID : u32 = 3 ;
2929
3030/// Software Breakpoint size in memory
3131pub ( crate ) const SW_BP_SIZE : usize = 1 ;
@@ -51,61 +51,52 @@ pub(crate) const DR6_HW_BP_FLAGS_MASK: u64 = 0x0F << DR6_HW_BP_FLAGS_POS;
5151
5252/// Determine the reason the vCPU stopped
5353/// This is done by checking the DR6 register and the exception id
54- /// NOTE: Additional checks are done for the entrypoint, stored hw_breakpoints
55- /// and sw_breakpoints to ensure the stop reason is valid with internal state
5654pub ( crate ) fn vcpu_stop_reason (
57- single_step : bool ,
58- rip : u64 ,
59- dr6 : u64 ,
55+ vm : & mut dyn DebuggableVm ,
6056 entrypoint : u64 ,
57+ dr6 : u64 ,
6158 exception : u32 ,
62- hw_breakpoints : & [ u64 ] ,
63- sw_breakpoints : & HashMap < u64 , [ u8 ; SW_BP_SIZE ] > ,
64- ) -> VcpuStopReason {
59+ ) -> Result < VcpuStopReason > {
60+ let CommonRegisters { rip, .. } = vm. regs ( ) ?;
6561 if DB_EX_ID == exception {
6662 // If the BS flag in DR6 register is set, it means a single step
6763 // instruction triggered the exit
6864 // Check page 19-4 Vol. 3B of Intel 64 and IA-32
6965 // Architectures Software Developer's Manual
70- if dr6 & DR6_BS_FLAG_MASK != 0 && single_step {
71- return VcpuStopReason :: DoneStep ;
66+ if dr6 & DR6_BS_FLAG_MASK != 0 {
67+ return Ok ( VcpuStopReason :: DoneStep ) ;
7268 }
7369
7470 // If any of the B0-B3 flags in DR6 register is set, it means a
7571 // hardware breakpoint triggered the exit
7672 // Check page 19-4 Vol. 3B of Intel 64 and IA-32
7773 // Architectures Software Developer's Manual
78- if DR6_HW_BP_FLAGS_MASK & dr6 != 0 && hw_breakpoints . contains ( & rip ) {
74+ if DR6_HW_BP_FLAGS_MASK & dr6 != 0 {
7975 if rip == entrypoint {
80- return VcpuStopReason :: EntryPointBp ;
76+ vm. remove_hw_breakpoint ( entrypoint) ?;
77+ return Ok ( VcpuStopReason :: EntryPointBp ) ;
8178 }
82- return VcpuStopReason :: HwBp ;
79+ return Ok ( VcpuStopReason :: HwBp ) ;
8380 }
8481 }
8582
86- if BP_EX_ID == exception && sw_breakpoints . contains_key ( & rip ) {
87- return VcpuStopReason :: SwBp ;
83+ if BP_EX_ID == exception {
84+ return Ok ( VcpuStopReason :: SwBp ) ;
8885 }
8986
9087 // Log an error and provide internal debugging info
9188 log:: error!(
9289 r"The vCPU exited because of an unknown reason:
93- single_step: {:?}
9490 rip: {:?}
9591 dr6: {:?}
9692 entrypoint: {:?}
9793 exception: {:?}
98- hw_breakpoints: {:?}
99- sw_breakpoints: {:?}
10094 " ,
101- single_step,
10295 rip,
10396 dr6,
10497 entrypoint,
10598 exception,
106- hw_breakpoints,
107- sw_breakpoints,
10899 ) ;
109100
110- VcpuStopReason :: Unknown
101+ Ok ( VcpuStopReason :: Unknown )
111102}
0 commit comments