@@ -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 {
5148 VCPURequestError ,
5249 /// No currently paused Vcpu error
5350 NoPausedVCpu ,
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
100103 pub 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
140140 pub 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
196191 pub 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
270259 pub 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