pub fn run_emulation(&self) -> Result<VcpuEmulation> {
        match self.emulate() {
            Ok(run) => match run {
                VcpuExit::MmioRead(addr, data) => {
                    if let Some(mmio_bus) = &self.kvm_vcpu.mmio_bus {
                        mmio_bus.read(addr, data);
                        METRICS.vcpu.exit_mmio_read.inc();
                    }
                    Ok(VcpuEmulation::Handled)
                }
                VcpuExit::MmioWrite(addr, data) => {
                    if let Some(mmio_bus) = &self.kvm_vcpu.mmio_bus {
                        mmio_bus.write(addr, data);
                        METRICS.vcpu.exit_mmio_write.inc();
                    }
                    Ok(VcpuEmulation::Handled)
                }
                VcpuExit::Hlt => {
                    info!("Received KVM_EXIT_HLT signal");
                    Ok(VcpuEmulation::Stopped)
                }
                VcpuExit::Shutdown => {
                    info!("Received KVM_EXIT_SHUTDOWN signal");
                    Ok(VcpuEmulation::Stopped)
                }
                // Documentation specifies that below kvm exits are considered
                // errors.
                VcpuExit::FailEntry => {
                    // Hardware entry failure.
                    METRICS.vcpu.failures.inc();
                    error!("Received KVM_EXIT_FAIL_ENTRY signal");
                    Err(Error::FaultyKvmExit(format!("{:?}", VcpuExit::FailEntry)))
                }
                VcpuExit::InternalError => {
                    // Failure from the Linux KVM subsystem rather than from the hardware.
                    METRICS.vcpu.failures.inc();
                    error!("Received KVM_EXIT_INTERNAL_ERROR signal");
                    Err(Error::FaultyKvmExit(format!(
                        "{:?}",
                        VcpuExit::InternalError
                    )))
                }
                VcpuExit::SystemEvent(event_type, event_flags) => match event_type {
                    KVM_SYSTEM_EVENT_RESET | KVM_SYSTEM_EVENT_SHUTDOWN => {
                        info!(
                            "Received KVM_SYSTEM_EVENT: type: {}, event: {}",
                            event_type, event_flags
                        );
                        Ok(VcpuEmulation::Stopped)
                    }
                    _ => {
                        METRICS.vcpu.failures.inc();
                        error!(
                            "Received KVM_SYSTEM_EVENT signal type: {}, flag: {}",
                            event_type, event_flags
                        );
                        Err(Error::FaultyKvmExit(format!(
                            "{:?}",
                            VcpuExit::SystemEvent(event_type, event_flags)
                        )))
                    }
                },
                arch_specific_reason => {
                    // run specific architecture emulation.
                    self.kvm_vcpu.run_arch_emulation(arch_specific_reason)
                }
            },
            // The unwrap on raw_os_error can only fail if we have a logic
            // error in our code in which case it is better to panic.
            Err(ref e) => {
                match e.errno() {
                    libc::EAGAIN => Ok(VcpuEmulation::Handled),
                    libc::EINTR => {
                        self.kvm_vcpu.fd.set_kvm_immediate_exit(0);
                        // Notify that this KVM_RUN was interrupted.
                        Ok(VcpuEmulation::Interrupted)
                    }
                    libc::ENOSYS => {
                        METRICS.vcpu.failures.inc();
                        error!(
                            "Received ENOSYS error because KVM failed to emulate an instruction."
                        );
                        Err(Error::FaultyKvmExit(
                            "Received ENOSYS error because KVM failed to emulate an instruction."
                                .to_string(),
                        ))
                    }
                    _ => {
                        METRICS.vcpu.failures.inc();
                        error!("Failure during vcpu run: {}", e);
                        Err(Error::FaultyKvmExit(format!("{}", e)))
                    }
                }
            }
        }
    }
/// Runs the vCPU in KVM context and handles the kvm exit reason.
///
/// Returns error or enum specifying whether emulation was handled or interrupted.
Runs the vCPU in KVM context and handles the kvm exit reason.
Returns error or enum specifying whether emulation was handled or interrupted.
Runs the vCPU in KVM context and handles the kvm exit reason . Returns error or enum specifying whether emulation was handled or interrupted .
pub fn run_emulation(&self) -> Result<VcpuEmulation> {
        match self.emulate() {
            Ok(run) => match run {
                VcpuExit::MmioRead(addr, data) => {
                    if let Some(mmio_bus) = &self.kvm_vcpu.mmio_bus {
                        mmio_bus.read(addr, data);
                        METRICS.vcpu.exit_mmio_read.inc();
                    }
                    Ok(VcpuEmulation::Handled)
                }
                VcpuExit::MmioWrite(addr, data) => {
                    if let Some(mmio_bus) = &self.kvm_vcpu.mmio_bus {
                        mmio_bus.write(addr, data);
                        METRICS.vcpu.exit_mmio_write.inc();
                    }
                    Ok(VcpuEmulation::Handled)
                }
                VcpuExit::Hlt => {
                    info!("Received KVM_EXIT_HLT signal");
                    Ok(VcpuEmulation::Stopped)
                }
                VcpuExit::Shutdown => {
                    info!("Received KVM_EXIT_SHUTDOWN signal");
                    Ok(VcpuEmulation::Stopped)
                }
                // Documentation specifies that below kvm exits are considered
                // errors.
                VcpuExit::FailEntry => {
                    // Hardware entry failure.
                    METRICS.vcpu.failures.inc();
                    error!("Received KVM_EXIT_FAIL_ENTRY signal");
                    Err(Error::FaultyKvmExit(format!("{:?}", VcpuExit::FailEntry)))
                }
                VcpuExit::InternalError => {
                    // Failure from the Linux KVM subsystem rather than from the hardware.
                    METRICS.vcpu.failures.inc();
                    error!("Received KVM_EXIT_INTERNAL_ERROR signal");
                    Err(Error::FaultyKvmExit(format!(
                        "{:?}",
                        VcpuExit::InternalError
                    )))
                }
                VcpuExit::SystemEvent(event_type, event_flags) => match event_type {
                    KVM_SYSTEM_EVENT_RESET | KVM_SYSTEM_EVENT_SHUTDOWN => {
                        info!(
                            "Received KVM_SYSTEM_EVENT: type: {}, event: {}",
                            event_type, event_flags
                        );
                        Ok(VcpuEmulation::Stopped)
                    }
                    _ => {
                        METRICS.vcpu.failures.inc();
                        error!(
                            "Received KVM_SYSTEM_EVENT signal type: {}, flag: {}",
                            event_type, event_flags
                        );
                        Err(Error::FaultyKvmExit(format!(
                            "{:?}",
                            VcpuExit::SystemEvent(event_type, event_flags)
                        )))
                    }
                },
                arch_specific_reason => {
                    // run specific architecture emulation.
                    self.kvm_vcpu.run_arch_emulation(arch_specific_reason)
                }
            },
            // The unwrap on raw_os_error can only fail if we have a logic
            // error in our code in which case it is better to panic.
            Err(ref e) => {
                match e.errno() {
                    libc::EAGAIN => Ok(VcpuEmulation::Handled),
                    libc::EINTR => {
                        self.kvm_vcpu.fd.set_kvm_immediate_exit(0);
                        // Notify that this KVM_RUN was interrupted.
                        Ok(VcpuEmulation::Interrupted)
                    }
                    libc::ENOSYS => {
                        METRICS.vcpu.failures.inc();
                        error!(
                            "Received ENOSYS error because KVM failed to emulate an instruction."
                        );
                        Err(Error::FaultyKvmExit(
                            "Received ENOSYS error because KVM failed to emulate an instruction."
                                .to_string(),
                        ))
                    }
                    _ => {
                        METRICS.vcpu.failures.inc();
                        error!("Failure during vcpu run: {}", e);
                        Err(Error::FaultyKvmExit(format!("{}", e)))
                    }
                }
            }
        }
    }
pub fn run_emulation ( & self ) -> Result < VcpuEmulation > { match self . emulate ( ) { Ok ( run ) => match run { VcpuExit :: MmioRead ( addr , data ) => { if let Some ( mmio_bus ) = & self . kvm_vcpu . mmio_bus { mmio_bus . read ( addr , data ) ; METRICS . vcpu . exit_mmio_read . inc ( ) ; } Ok ( VcpuEmulation :: Handled ) } VcpuExit :: MmioWrite ( addr , data ) => { if let Some ( mmio_bus ) = & self . kvm_vcpu . mmio_bus { mmio_bus . write ( addr , data ) ; METRICS . vcpu . exit_mmio_write . inc ( ) ; } Ok ( VcpuEmulation :: Handled ) } VcpuExit :: Hlt => { info ! ( " " ) ; Ok ( VcpuEmulation :: Stopped ) } VcpuExit :: Shutdown => { info ! ( " " ) ; Ok ( VcpuEmulation :: Stopped ) } // Documentation specifies that below kvm exits are considered // errors. VcpuExit :: FailEntry => { // Hardware entry failure. METRICS . vcpu . failures . inc ( ) ; error ! ( " " ) ; Err ( Error :: FaultyKvmExit ( format ! ( " " VcpuExit FailEntry ) ) ) } VcpuExit :: InternalError => { // Failure from the Linux KVM subsystem rather than from the hardware. METRICS . vcpu . failures . inc ( ) ; error ! ( " " ) ; Err ( Error :: FaultyKvmExit ( format ! ( " " VcpuExit InternalError ) ) ) } VcpuExit :: SystemEvent ( event_type , event_flags ) => match event_type { KVM_SYSTEM_EVENT_RESET | KVM_SYSTEM_EVENT_SHUTDOWN => { info ! ( " " event_type event_flags ) ; Ok ( VcpuEmulation :: Stopped ) } _ => { METRICS . vcpu . failures . inc ( ) ; error ! ( " " event_type event_flags ) ; Err ( Error :: FaultyKvmExit ( format ! ( " " VcpuExit SystemEvent ( event_type event_flags ) ) ) ) } } , arch_specific_reason => { // run specific architecture emulation. self . kvm_vcpu . run_arch_emulation ( arch_specific_reason ) } } , // The unwrap on raw_os_error can only fail if we have a logic // error in our code in which case it is better to panic. Err ( ref e ) => { match e . errno ( ) { libc :: EAGAIN => Ok ( VcpuEmulation :: Handled ) , libc :: EINTR => { self . kvm_vcpu . fd . set_kvm_immediate_exit ( 0 ) ; // Notify that this KVM_RUN was interrupted. Ok ( VcpuEmulation :: Interrupted ) } libc :: ENOSYS => { METRICS . vcpu . failures . inc ( ) ; error ! ( " " ) ; Err ( Error :: FaultyKvmExit ( " " . to_string ( ) , ) ) } _ => { METRICS . vcpu . failures . inc ( ) ; error ! ( " " e ) ; Err ( Error :: FaultyKvmExit ( format ! ( " " e ) ) ) } } } } }
Runs the vCPU in KVM context and handles the kvm exit reason.
Runs the vCPU in KVM context and handles the kvm exit reason .
&self
&self