@@ -18,10 +18,6 @@ use gdbstub::target::ext::breakpoints::{
1818} ; 
1919use  gdbstub:: target:: ext:: thread_extra_info:: { ThreadExtraInfo ,  ThreadExtraInfoOps } ; 
2020use  gdbstub:: target:: { Target ,  TargetError ,  TargetResult } ; 
21- #[ cfg( target_arch = "aarch64" ) ]  
22- use  gdbstub_arch:: aarch64:: reg:: AArch64CoreRegs  as  CoreRegs ; 
23- #[ cfg( target_arch = "aarch64" ) ]  
24- use  gdbstub_arch:: aarch64:: AArch64  as  GdbArch ; 
2521#[ cfg( target_arch = "x86_64" ) ]  
2622use  gdbstub_arch:: x86:: reg:: X86_64CoreRegs  as  CoreRegs ; 
2723#[ cfg( target_arch = "x86_64" ) ]  
@@ -30,7 +26,8 @@ use kvm_bindings::kvm_regs;
3026use  vm_memory:: { Bytes ,  GuestAddress } ; 
3127
3228use  crate :: logger:: { error,  info} ; 
33- use  crate :: { FcExitCode ,  VcpuEvent ,  VcpuHandle ,  VcpuResponse ,  Vmm } ; 
29+ use  crate :: vstate:: vcpu:: VcpuError ; 
30+ use  crate :: { arch,  FcExitCode ,  VcpuEvent ,  VcpuHandle ,  VcpuResponse ,  Vmm } ; 
3431
3532const  X86_SW_BP_OP :  u8  = 0xCC ; 
3633
@@ -51,6 +48,12 @@ pub enum Error {
5148VCPURequestError , 
5249    /// No currently paused Vcpu error 
5350NoPausedVCpu , 
51+     /// Error when setting vcpu debug flags 
52+ VcpuKvmError , 
53+     /// Server socket Error 
54+ ServerSocketError , 
55+     /// Error with creating GDB thread 
56+ GdbThreadError , 
5457} 
5558
5659impl < E >  From < Error >  for  TargetError < E >  { 
@@ -72,7 +75,7 @@ pub struct FirecrackerTarget {
7275    hw_breakpoints :  Vec < GuestAddress > , 
7376    sw_breakpoints :  HashMap < <GdbArch  as  Arch >:: Usize ,  [ u8 ;  1 ] > , 
7477
75-     vcpu_state :  HashMap < Tid ,   VCpuState > , 
78+     vcpu_state :  Vec < VCpuState > , 
7679
7780    paused_vcpu :  Option < Tid > , 
7881} 
@@ -98,22 +101,19 @@ impl FirecrackerTarget {
98101/// will handle requests from GDB and perform the appropriate actions, while also updating GDB 
99102/// with the state of the VMM / VCPU's as we hit debug events 
100103pub  fn  new ( vmm :  Arc < Mutex < Vmm > > ,  gdb_event :  Receiver < usize > ,  entry_addr :  GuestAddress )  -> Self  { 
101-         let  mut  vcpu_state = HashMap :: new ( ) ; 
102104        let  cpu_count = { 
103105            vmm. lock ( ) 
104106                . expect ( "Exception unlocking vmm" ) 
105107                . vcpus_handles 
106108                . len ( ) 
107109        } ; 
108110
109-         for  cpu_id  in   0 ..cpu_count  { 
110-             let  new_state =  VCpuState  { 
111+         let  vcpu_state =  ( 0 ..cpu_count) 
112+             . map ( |_|  VCpuState  { 
111113                paused :  false , 
112114                single_step :  false , 
113-             } ; 
114- 
115-             vcpu_state. insert ( cpuid_to_tid ( cpu_id) ,  new_state) ; 
116-         } 
115+             } ) 
116+             . collect ( ) ; 
117117
118118        Self  { 
119119            vmm, 
@@ -138,24 +138,19 @@ impl FirecrackerTarget {
138138    /// This is used to notify the target that the provided Tid 
139139/// is in a paused state 
140140pub  fn  notify_paused_vcpu ( & mut  self ,  tid :  Tid )  { 
141-         let  found = match  self . vcpu_state . get_mut ( & tid)  { 
142-             Some ( res)  => res, 
143-             None  => { 
144-                 info ! ( "TID {tid} was not known." ) ; 
145-                 return ; 
146-             } 
147-         } ; 
148- 
141+         let  found = & mut  self . vcpu_state [ tid_to_cpuid ( tid) ] ; 
149142        found. paused  = true ; 
143+ 
150144        self . paused_vcpu  = Some ( tid) ; 
151145    } 
152146
153147    fn  resume_execution ( & mut  self )  -> Result < ( ) ,  Error >  { 
154148        let  to_resume:  Vec < Tid >  = self 
155149            . vcpu_state 
156150            . iter ( ) 
157-             . filter_map ( |( tid,  state) | match  state. paused  { 
158-                 true  => Some ( * tid) , 
151+             . enumerate ( ) 
152+             . filter_map ( |( cpu_id,  state) | match  state. paused  { 
153+                 true  => Some ( cpuid_to_tid ( cpu_id) ) , 
159154                false  => None , 
160155            } ) 
161156            . collect ( ) ; 
@@ -165,7 +160,7 @@ impl FirecrackerTarget {
165160            self . request_resume ( tid) ?; 
166161        } 
167162
168-         self . vcpu_state . iter_mut ( ) . for_each ( |( _ ,   state) | { 
163+         self . vcpu_state . iter_mut ( ) . for_each ( |state| { 
169164            state. paused  = false ; 
170165        } ) ; 
171166
@@ -179,7 +174,7 @@ impl FirecrackerTarget {
179174    } 
180175
181176    fn  reset_all_states ( & mut  self )  { 
182-         for  ( _ ,   value)  in  self . vcpu_state . iter_mut ( )  { 
177+         for  value in  self . vcpu_state . iter_mut ( )  { 
183178            Self :: reset_vcpu_state ( value) ; 
184179        } 
185180    } 
@@ -194,13 +189,7 @@ impl FirecrackerTarget {
194189
195190    /// This method can be used to manually pause the requested vcpu 
196191pub  fn  request_pause ( & mut  self ,  tid :  Tid )  -> Result < ( ) ,  Error >  { 
197-         let  vcpu_state = match  self . vcpu_state . get_mut ( & tid)  { 
198-             Some ( res)  => res, 
199-             None  => { 
200-                 info ! ( "Attempted to pause a vcpu we have no state for." ) ; 
201-                 return  Err ( Error :: VCPURequestError ) ; 
202-             } 
203-         } ; 
192+         let  vcpu_state = & mut  self . vcpu_state [ tid_to_cpuid ( tid) ] ; 
204193
205194        if  vcpu_state. paused  { 
206195            info ! ( "Attempted to pause a vcpu already paused." ) ; 
@@ -268,13 +257,7 @@ impl FirecrackerTarget {
268257    /// Used to request the specified core to resume execution. The function 
269258/// will return early if the vcpu is already paused and not currently running 
270259pub  fn  request_resume ( & mut  self ,  tid :  Tid )  -> Result < ( ) ,  Error >  { 
271-         let  vcpu_state = match  self . vcpu_state . get_mut ( & tid)  { 
272-             Some ( res)  => res, 
273-             None  => { 
274-                 error ! ( "Attempted to resume a vcpu we have no state for." ) ; 
275-                 return  Err ( Error :: VCPURequestError ) ; 
276-             } 
277-         } ; 
260+         let  vcpu_state = & mut  self . vcpu_state [ tid_to_cpuid ( tid) ] ; 
278261
279262        if  !vcpu_state. paused  { 
280263            info ! ( "Attempted to resume a vcpu already running." ) ; 
@@ -288,6 +271,7 @@ impl FirecrackerTarget {
288271        cpu_handle
289272            . send_event ( VcpuEvent :: Resume ) 
290273            . expect ( "Error sending message to vcpu" ) ; 
274+ 
291275        let  response = cpu_handle
292276            . response_receiver ( ) 
293277            . recv ( ) 
@@ -305,13 +289,7 @@ impl FirecrackerTarget {
305289        let  cpu_handle =
306290            & self . vmm . lock ( ) . expect ( "error unlocking vmm" ) . vcpus_handles [ tid_to_cpuid ( tid) ] ; 
307291
308-         let  vcpu_state = match  self . vcpu_state . get ( & tid)  { 
309-             Some ( res)  => res, 
310-             None  => { 
311-                 error ! ( "Attempted to write kvm debug to a vcpu we have no state for." ) ; 
312-                 return  Err ( Error :: VCPURequestError ) ; 
313-             } 
314-         } ; 
292+         let  vcpu_state = & self . vcpu_state [ tid_to_cpuid ( tid) ] ; 
315293
316294        cpu_handle
317295            . send_event ( VcpuEvent :: SetKvmDebug ( 
@@ -325,6 +303,7 @@ impl FirecrackerTarget {
325303                error ! ( "Response resume : {message}" ) ; 
326304                Err ( Error :: VCPURequestError ) 
327305            } 
306+             Ok ( VcpuResponse :: Error ( VcpuError :: GdbRequest ( e) ) )  => Err ( e) , 
328307            Err ( _)  => Err ( Error :: VCPURequestError ) , 
329308            _ => Ok ( ( ) ) , 
330309        } 
@@ -340,7 +319,10 @@ impl FirecrackerTarget {
340319            . expect ( "Error recieving message from vcpu" ) ; 
341320
342321        if  let  VcpuResponse :: GvaTranslation ( response)  = response { 
343-             return  Ok ( response) ; 
322+             return  match  response { 
323+                 Some ( res)  => Ok ( res. into ( ) ) , 
324+                 None  => Err ( Error :: VCPURequestError ) , 
325+             } ; 
344326        } 
345327
346328        if  let  VcpuResponse :: NotAllowed ( message)  = response { 
@@ -364,6 +346,7 @@ impl FirecrackerTarget {
364346                error ! ( "Response resume : {message}" ) ; 
365347                Err ( Error :: VCPURequestError ) 
366348            } 
349+             Ok ( VcpuResponse :: Error ( VcpuError :: GdbRequest ( e) ) )  => Err ( e) , 
367350            Err ( _)  => Err ( Error :: VCPURequestError ) , 
368351            _ => Ok ( ( ) ) , 
369352        } 
@@ -387,13 +370,7 @@ impl FirecrackerTarget {
387370        } 
388371
389372        let  cpu_regs = self . get_regs ( tid) ; 
390- 
391-         let  vcpu_state = match  self . vcpu_state . get ( & tid)  { 
392-             Some ( res)  => res, 
393-             None  => { 
394-                 return  None ; 
395-             } 
396-         } ; 
373+         let  vcpu_state = & mut  self . vcpu_state [ tid_to_cpuid ( tid) ] ; 
397374
398375        if  vcpu_state. single_step  { 
399376            return  Some ( MultiThreadStopReason :: SignalWithThread  { 
@@ -539,7 +516,7 @@ impl MultiThreadBase for FirecrackerTarget {
539516                    } 
540517                } ; 
541518
542-             let  psize = 4096 ; 
519+             let  psize = arch :: PAGE_SIZE ; 
543520            let  read_len = std:: cmp:: min ( len - total_read,  psize - ( paddr &  ( psize - 1 ) ) ) ; 
544521
545522            if  memory
@@ -629,13 +606,7 @@ impl MultiThreadResume for FirecrackerTarget {
629606        tid :  Tid , 
630607        _signal :  Option < Signal > , 
631608    )  -> Result < ( ) ,  Self :: Error >  { 
632-         let  vcpu_state = match  self . vcpu_state . get_mut ( & tid)  { 
633-             Some ( res)  => res, 
634-             None  => { 
635-                 error ! ( "Attempted to set action on a vcpu we have no state for." ) ; 
636-                 return  Err ( Error :: VCPURequestError ) ; 
637-             } 
638-         } ; 
609+         let  vcpu_state = & mut  self . vcpu_state [ tid_to_cpuid ( tid) ] ; 
639610        vcpu_state. single_step  = false ; 
640611
641612        Ok ( ( ) ) 
@@ -663,13 +634,7 @@ impl MultiThreadSingleStep for FirecrackerTarget {
663634        tid :  Tid , 
664635        _signal :  Option < Signal > , 
665636    )  -> Result < ( ) ,  Self :: Error >  { 
666-         let  vcpu_state = match  self . vcpu_state . get_mut ( & tid)  { 
667-             Some ( res)  => res, 
668-             None  => { 
669-                 info ! ( "Attempted to set action on a vcpu we have no state for." ) ; 
670-                 return  Ok ( ( ) ) ; 
671-             } 
672-         } ; 
637+         let  vcpu_state = & mut  self . vcpu_state [ tid_to_cpuid ( tid) ] ; 
673638        vcpu_state. single_step  = true ; 
674639
675640        Ok ( ( ) ) 
0 commit comments