@@ -16,16 +16,17 @@ limitations under the License.
1616
1717//! This file contains architecture specific code for the x86_64
1818
19- use std:: collections:: HashMap ;
20-
2119use super :: VcpuStopReason ;
20+ use crate :: hypervisor:: regs:: CommonRegisters ;
21+ use crate :: hypervisor:: vm:: Vm ;
22+ use crate :: Result ;
2223
2324// Described in Table 6-1. Exceptions and Interrupts at Page 6-13 Vol. 1
2425// of Intel 64 and IA-32 Architectures Software Developer's Manual
2526/// Exception id for #DB
26- const DB_EX_ID : u32 = 1 ;
27+ pub ( crate ) const DB_EX_ID : u32 = 1 ;
2728/// Exception id for #BP - triggered by the INT3 instruction
28- const BP_EX_ID : u32 = 3 ;
29+ pub ( crate ) const BP_EX_ID : u32 = 3 ;
2930
3031/// Software Breakpoint size in memory
3132pub ( crate ) const SW_BP_SIZE : usize = 1 ;
@@ -54,58 +55,51 @@ pub(crate) const DR6_HW_BP_FLAGS_MASK: u64 = 0x0F << DR6_HW_BP_FLAGS_POS;
5455/// NOTE: Additional checks are done for the entrypoint, stored hw_breakpoints
5556/// and sw_breakpoints to ensure the stop reason is valid with internal state
5657pub ( crate ) fn vcpu_stop_reason (
57- single_step : bool ,
58- rip : u64 ,
59- dr6 : u64 ,
58+ vm : & mut dyn Vm ,
6059 entrypoint : u64 ,
60+ dr6 : u64 ,
6161 exception : u32 ,
62- hw_breakpoints : & [ u64 ] ,
63- sw_breakpoints : & HashMap < u64 , [ u8 ; SW_BP_SIZE ] > ,
64- ) -> VcpuStopReason {
62+ ) -> Result < VcpuStopReason > {
63+ let CommonRegisters { rip, .. } = vm. get_regs ( ) ?;
6564 if DB_EX_ID == exception {
6665 // If the BS flag in DR6 register is set, it means a single step
6766 // instruction triggered the exit
6867 // Check page 19-4 Vol. 3B of Intel 64 and IA-32
6968 // Architectures Software Developer's Manual
70- if dr6 & DR6_BS_FLAG_MASK != 0 && single_step {
71- return VcpuStopReason :: DoneStep ;
69+ if dr6 & DR6_BS_FLAG_MASK != 0 {
70+ return Ok ( VcpuStopReason :: DoneStep ) ;
7271 }
7372
7473 // If any of the B0-B3 flags in DR6 register is set, it means a
7574 // hardware breakpoint triggered the exit
7675 // Check page 19-4 Vol. 3B of Intel 64 and IA-32
7776 // Architectures Software Developer's Manual
78- if DR6_HW_BP_FLAGS_MASK & dr6 != 0 && hw_breakpoints . contains ( & rip ) {
77+ if DR6_HW_BP_FLAGS_MASK & dr6 != 0 {
7978 if rip == entrypoint {
80- return VcpuStopReason :: EntryPointBp ;
79+ vm. remove_hw_breakpoint ( entrypoint) ?;
80+ return Ok ( VcpuStopReason :: EntryPointBp ) ;
8181 }
82- return VcpuStopReason :: HwBp ;
82+ return Ok ( VcpuStopReason :: HwBp ) ;
8383 }
8484 }
8585
86- if BP_EX_ID == exception && sw_breakpoints . contains_key ( & rip ) {
87- return VcpuStopReason :: SwBp ;
86+ if BP_EX_ID == exception {
87+ return Ok ( VcpuStopReason :: SwBp ) ;
8888 }
8989
9090 // Log an error and provide internal debugging info
9191 log:: error!(
9292 r"The vCPU exited because of an unknown reason:
93- single_step: {:?}
9493 rip: {:?}
9594 dr6: {:?}
9695 entrypoint: {:?}
9796 exception: {:?}
98- hw_breakpoints: {:?}
99- sw_breakpoints: {:?}
10097 " ,
101- single_step,
10298 rip,
10399 dr6,
104100 entrypoint,
105101 exception,
106- hw_breakpoints,
107- sw_breakpoints,
108102 ) ;
109103
110- VcpuStopReason :: Unknown
104+ Ok ( VcpuStopReason :: Unknown )
111105}
0 commit comments