fn running(&mut self) -> StateMachine<Self> {
        // This loop is here just for optimizing the emulation path.
        // No point in ticking the state machine if there are no external events.
        loop {
            match self.run_emulation() {
                // Emulation ran successfully, continue.
                Ok(VcpuEmulation::Handled) => (),
                // Emulation was interrupted, check external events.
                Ok(VcpuEmulation::Interrupted) => break,
                // If the guest was rebooted or halted:
                // - vCPU0 will always exit out of `KVM_RUN` with KVM_EXIT_SHUTDOWN or
                //   KVM_EXIT_HLT.
                // - the other vCPUs won't ever exit out of `KVM_RUN`, but they won't consume CPU.
                // Moreover if we allow the vCPU0 thread to finish execution, this might generate a
                // seccomp failure because musl calls `sigprocmask` as part of `pthread_exit`.
                // So we pause vCPU0 and send a signal to the emulation thread to stop the VMM.
                Ok(VcpuEmulation::Stopped) => return self.exit(FC_EXIT_CODE_OK),
                // Emulation errors lead to vCPU exit.
                Err(_) => return self.exit(FC_EXIT_CODE_GENERIC_ERROR),
            }
        }

        // By default don't change state.
        let mut state = StateMachine::next(Self::running);

        // Break this emulation loop on any transition request/external event.
        match self.event_receiver.try_recv() {
            // Running ---- Pause ----> Paused
            Ok(VcpuEvent::Pause) => {
                // Nothing special to do.
                self.response_sender
                    .send(VcpuResponse::Paused)
                    .expect("failed to send pause status");

                // TODO: we should call `KVM_KVMCLOCK_CTRL` here to make sure
                // TODO continued: the guest soft lockup watchdog does not panic on Resume.

                // Move to 'paused' state.
                state = StateMachine::next(Self::paused);
            }
            Ok(VcpuEvent::Resume) => {
                self.response_sender
                    .send(VcpuResponse::Resumed)
                    .expect("failed to send resume status");
            }
            // Unhandled exit of the other end.
            Err(TryRecvError::Disconnected) => {
                // Move to 'exited' state.
                state = self.exit(FC_EXIT_CODE_GENERIC_ERROR);
            }
            // All other events or lack thereof have no effect on current 'running' state.
            Err(TryRecvError::Empty) => (),
        }

        state
    }
// This is the main loop of the `Running` state.
This is the main loop of the `Running` state.
This is the main loop of the ` Running ` state .
fn running(&mut self) -> StateMachine<Self> {
        // This loop is here just for optimizing the emulation path.
        // No point in ticking the state machine if there are no external events.
        loop {
            match self.run_emulation() {
                // Emulation ran successfully, continue.
                Ok(VcpuEmulation::Handled) => (),
                // Emulation was interrupted, check external events.
                Ok(VcpuEmulation::Interrupted) => break,
                // If the guest was rebooted or halted:
                // - vCPU0 will always exit out of `KVM_RUN` with KVM_EXIT_SHUTDOWN or
                //   KVM_EXIT_HLT.
                // - the other vCPUs won't ever exit out of `KVM_RUN`, but they won't consume CPU.
                // Moreover if we allow the vCPU0 thread to finish execution, this might generate a
                // seccomp failure because musl calls `sigprocmask` as part of `pthread_exit`.
                // So we pause vCPU0 and send a signal to the emulation thread to stop the VMM.
                Ok(VcpuEmulation::Stopped) => return self.exit(FC_EXIT_CODE_OK),
                // Emulation errors lead to vCPU exit.
                Err(_) => return self.exit(FC_EXIT_CODE_GENERIC_ERROR),
            }
        }
        // By default don't change state.
        let mut state = StateMachine::next(Self::running);
        // Break this emulation loop on any transition request/external event.
        match self.event_receiver.try_recv() {
            // Running ---- Pause ----> Paused
            Ok(VcpuEvent::Pause) => {
                // Nothing special to do.
                self.response_sender
                    .send(VcpuResponse::Paused)
                    .expect("failed to send pause status");
                // TODO: we should call `KVM_KVMCLOCK_CTRL` here to make sure
                // TODO continued: the guest soft lockup watchdog does not panic on Resume.
                // Move to 'paused' state.
                state = StateMachine::next(Self::paused);
            }
            Ok(VcpuEvent::Resume) => {
                self.response_sender
                    .send(VcpuResponse::Resumed)
                    .expect("failed to send resume status");
            }
            // Unhandled exit of the other end.
            Err(TryRecvError::Disconnected) => {
                // Move to 'exited' state.
                state = self.exit(FC_EXIT_CODE_GENERIC_ERROR);
            }
            // All other events or lack thereof have no effect on current 'running' state.
            Err(TryRecvError::Empty) => (),
        }
        state
    }
fn running ( & mut self ) -> StateMachine < Self > { // This loop is here just for optimizing the emulation path. // No point in ticking the state machine if there are no external events. loop { match self . run_emulation ( ) { // Emulation ran successfully, continue. Ok ( VcpuEmulation :: Handled ) => ( ) , // Emulation was interrupted, check external events. Ok ( VcpuEmulation :: Interrupted ) => break , // If the guest was rebooted or halted: // - vCPU0 will always exit out of `KVM_RUN` with KVM_EXIT_SHUTDOWN or //   KVM_EXIT_HLT. // - the other vCPUs won't ever exit out of `KVM_RUN`, but they won't consume CPU. // Moreover if we allow the vCPU0 thread to finish execution, this might generate a // seccomp failure because musl calls `sigprocmask` as part of `pthread_exit`. // So we pause vCPU0 and send a signal to the emulation thread to stop the VMM. Ok ( VcpuEmulation :: Stopped ) => return self . exit ( FC_EXIT_CODE_OK ) , // Emulation errors lead to vCPU exit. Err ( _ ) => return self . exit ( FC_EXIT_CODE_GENERIC_ERROR ) , } } // By default don't change state. let mut state = StateMachine :: next ( Self :: running ) ; // Break this emulation loop on any transition request/external event. match self . event_receiver . try_recv ( ) { // Running ---- Pause ----> Paused Ok ( VcpuEvent :: Pause ) => { // Nothing special to do. self . response_sender . send ( VcpuResponse :: Paused ) . expect ( " " ) ; // TODO: we should call `KVM_KVMCLOCK_CTRL` here to make sure // TODO continued: the guest soft lockup watchdog does not panic on Resume. // Move to 'paused' state. state = StateMachine :: next ( Self :: paused ) ; } Ok ( VcpuEvent :: Resume ) => { self . response_sender . send ( VcpuResponse :: Resumed ) . expect ( " " ) ; } // Unhandled exit of the other end. Err ( TryRecvError :: Disconnected ) => { // Move to 'exited' state. state = self . exit ( FC_EXIT_CODE_GENERIC_ERROR ) ; } // All other events or lack thereof have no effect on current 'running' state. Err ( TryRecvError :: Empty ) => ( ) , } state }
This is the main loop of the `Running` state.
This is the main loop of the ` Running ` state .
&mut self