@@ -53,6 +53,7 @@ use tracing::{instrument, Span};
5353use super :: handlers:: DbgMemAccessHandlerCaller ;
5454use super :: regs:: { CommonFpu , CommonRegisters , CommonSpecialRegisters } ;
5555use super :: vm:: { HyperlightExit , Vm } ;
56+ #[ cfg( gdb) ]
5657use crate :: hypervisor:: vm:: DebugExit ;
5758use crate :: mem:: memory_region:: { MemoryRegion , MemoryRegionFlags } ;
5859use crate :: { log_then_return, new_error, Result } ;
@@ -334,57 +335,50 @@ impl Vm for MshvVm {
334335
335336 #[ cfg( gdb) ]
336337 fn add_hw_breakpoint ( & mut self , addr : u64 ) -> Result < ( ) > {
338+ use crate :: hypervisor:: gdb:: arch:: MAX_NO_OF_HW_BP ;
337339 use crate :: new_error;
338340
339- let dr7 = self . debug . regs . dr7 ;
340- // count only LOCAL (L0, L1, L2, L3) enable bits
341- let num_hw_breakpoints = [ 0 , 2 , 4 , 6 ]
342- . iter ( )
343- . filter ( |& & bit| ( dr7 & ( 1 << bit) ) != 0 )
344- . count ( ) ;
341+ // Find the first available LOCAL (L0–L3) slot
342+ let i = ( 0 ..MAX_NO_OF_HW_BP )
343+ . position ( |i| self . debug . regs . dr7 & ( 1 << ( i * 2 ) ) == 0 )
344+ . ok_or_else ( || new_error ! ( "Tried to add more than 4 hardware breakpoints" ) ) ?;
345345
346- if num_hw_breakpoints >= 4 {
347- return Err ( new_error ! ( "Tried to add more than 4 hardware breakpoints" ) ) ;
348- }
346+ // Assign to corresponding debug register
347+ * [
348+ & mut self . debug . regs . dr0 ,
349+ & mut self . debug . regs . dr1 ,
350+ & mut self . debug . regs . dr2 ,
351+ & mut self . debug . regs . dr3 ,
352+ ] [ i] = addr;
349353
350- // find the first available LOCAL, and then enable it
351- let available_debug_register_idx = ( 0 ..4 ) . find ( |& i| ( dr7 & ( 1 << ( i * 2 ) ) ) == 0 ) . unwrap ( ) ; // safe because of the check above
352- match available_debug_register_idx {
353- 0 => self . debug . regs . dr0 = addr,
354- 1 => self . debug . regs . dr1 = addr,
355- 2 => self . debug . regs . dr2 = addr,
356- 3 => self . debug . regs . dr3 = addr,
357- _ => unreachable ! ( ) ,
358- }
359- self . debug . regs . dr7 |= 1 << ( available_debug_register_idx * 2 ) ;
354+ // Enable LOCAL bit
355+ self . debug . regs . dr7 |= 1 << ( i * 2 ) ;
360356
361357 self . vcpu_fd . set_debug_regs ( & self . debug . regs ) ?;
362-
363358 Ok ( ( ) )
364359 }
365360
366361 #[ cfg( gdb) ]
367362 fn remove_hw_breakpoint ( & mut self , addr : u64 ) -> Result < ( ) > {
368363 use crate :: new_error;
369364
370- if self . debug . regs . dr0 == addr {
371- self . debug . regs . dr0 = 0 ;
372- self . debug . regs . dr7 &= !( 1 << 0 ) ;
373- } else if self . debug . regs . dr1 == addr {
374- self . debug . regs . dr1 = 0 ;
375- self . debug . regs . dr7 &= !( 1 << 2 ) ;
376- } else if self . debug . regs . dr2 == addr {
377- self . debug . regs . dr2 = 0 ;
378- self . debug . regs . dr7 &= !( 1 << 4 ) ;
379- } else if self . debug . regs . dr3 == addr {
380- self . debug . regs . dr3 = 0 ;
381- self . debug . regs . dr7 &= !( 1 << 6 ) ;
365+ let regs = [
366+ & mut self . debug . regs . dr0 ,
367+ & mut self . debug . regs . dr1 ,
368+ & mut self . debug . regs . dr2 ,
369+ & mut self . debug . regs . dr3 ,
370+ ] ;
371+
372+ if let Some ( i) = regs. iter ( ) . position ( |& & mut reg| reg == addr) {
373+ // Clear the address
374+ * regs[ i] = 0 ;
375+ // Disable LOCAL bit
376+ self . debug . regs . dr7 &= !( 1 << ( i * 2 ) ) ;
377+ self . vcpu_fd . set_debug_regs ( & self . debug . regs ) ?;
378+ Ok ( ( ) )
382379 } else {
383- return Err ( new_error ! ( "Tried to remove non-existing hw-breakpoint" ) ) ;
380+ Err ( new_error ! ( "Tried to remove non-existing hw-breakpoint" ) )
384381 }
385-
386- self . vcpu_fd . set_debug_regs ( & self . debug . regs ) ?;
387- Ok ( ( ) )
388382 }
389383
390384 #[ cfg( gdb) ]
0 commit comments