fn try_inject_interrupt(&mut self, vmcs: &mut AutoVmcs) -> RvmResult {
        use super::consts::*;
        // Since hardware generated exceptions are delivered to the guest directly, the only exceptions
        // we see here are those we generate in the VMM, e.g. GP faults in vmexit handlers. Therefore
        // we simplify interrupt priority to 1) NMIs, 2) interrupts, and 3) generated exceptions. See
        // Volume 3, Section 6.9, Table 6-2.
        let vector = if self.controller.try_pop(NonMaskableInterrupt as usize) {
            NonMaskableInterrupt
        } else if let Some(vec) = self.controller.pop() {
            // Pop scans vectors from highest to lowest, which will correctly pop interrupts before
            // exceptions. All vectors <= VirtualizationException except the NMI vector are exceptions.
            vec as u8
        } else {
            return Ok(());
        };

        if vector > VirtualizationException && vector < IRQ0 {
            return Err(RvmError::NotSupported);
        } else {
            use InterruptibilityState as IntrState;
            let intr_state =
                IntrState::from_bits_truncate(vmcs.read32(GUEST_INTERRUPTIBILITY_STATE));
            let can_inject_nmi = !intr_state.contains(IntrState::BLOCKING_BY_NMI)
                && !intr_state.contains(IntrState::BLOCKING_BY_MOV_SS);
            let can_inject_external_int = vmcs.readXX(GUEST_RFLAGS).get_bit(9)
                && !intr_state.contains(IntrState::BLOCKING_BY_STI)
                && !intr_state.contains(IntrState::BLOCKING_BY_MOV_SS);
            if (vector >= IRQ0 && !can_inject_external_int)
                || (vector == NonMaskableInterrupt && !can_inject_nmi)
            {
                self.controller.virtual_interrupt(vector as usize);
                // If interrupts are disabled, we set VM exit on interrupt enable.
                vmcs.interrupt_window_exiting(true);
                return Ok(());
            }
        }

        // If the vector is non-maskable or interrupts are enabled, we inject an interrupt.
        vmcs.issue_interrupt(vector);

        // Volume 3, Section 6.9: Lower priority exceptions are discarded; lower priority interrupts are
        // held pending. Discarded exceptions are re-generated when the interrupt handler returns
        // execution to the point in the program or task where the exceptions and/or interrupts
        // occurred.
        self.controller
            .clear_and_keep(NonMaskableInterrupt as usize);

        Ok(())
    }
/// Injects an interrupt into the guest, if there is one pending.
Injects an interrupt into the guest, if there is one pending.
Injects an interrupt into the guest if there is one pending .
fn try_inject_interrupt(&mut self, vmcs: &mut AutoVmcs) -> RvmResult {
        use super::consts::*;
        // Since hardware generated exceptions are delivered to the guest directly, the only exceptions
        // we see here are those we generate in the VMM, e.g. GP faults in vmexit handlers. Therefore
        // we simplify interrupt priority to 1) NMIs, 2) interrupts, and 3) generated exceptions. See
        // Volume 3, Section 6.9, Table 6-2.
        let vector = if self.controller.try_pop(NonMaskableInterrupt as usize) {
            NonMaskableInterrupt
        } else if let Some(vec) = self.controller.pop() {
            // Pop scans vectors from highest to lowest, which will correctly pop interrupts before
            // exceptions. All vectors <= VirtualizationException except the NMI vector are exceptions.
            vec as u8
        } else {
            return Ok(());
        };
        if vector > VirtualizationException && vector < IRQ0 {
            return Err(RvmError::NotSupported);
        } else {
            use InterruptibilityState as IntrState;
            let intr_state =
                IntrState::from_bits_truncate(vmcs.read32(GUEST_INTERRUPTIBILITY_STATE));
            let can_inject_nmi = !intr_state.contains(IntrState::BLOCKING_BY_NMI)
                && !intr_state.contains(IntrState::BLOCKING_BY_MOV_SS);
            let can_inject_external_int = vmcs.readXX(GUEST_RFLAGS).get_bit(9)
                && !intr_state.contains(IntrState::BLOCKING_BY_STI)
                && !intr_state.contains(IntrState::BLOCKING_BY_MOV_SS);
            if (vector >= IRQ0 && !can_inject_external_int)
                || (vector == NonMaskableInterrupt && !can_inject_nmi)
            {
                self.controller.virtual_interrupt(vector as usize);
                // If interrupts are disabled, we set VM exit on interrupt enable.
                vmcs.interrupt_window_exiting(true);
                return Ok(());
            }
        }
        // If the vector is non-maskable or interrupts are enabled, we inject an interrupt.
        vmcs.issue_interrupt(vector);
        // Volume 3, Section 6.9: Lower priority exceptions are discarded; lower priority interrupts are
        // held pending. Discarded exceptions are re-generated when the interrupt handler returns
        // execution to the point in the program or task where the exceptions and/or interrupts
        // occurred.
        self.controller
            .clear_and_keep(NonMaskableInterrupt as usize);
        Ok(())
    }
fn try_inject_interrupt ( & mut self , vmcs : & mut AutoVmcs ) -> RvmResult { use super :: consts :: * ; // Since hardware generated exceptions are delivered to the guest directly, the only exceptions // we see here are those we generate in the VMM, e.g. GP faults in vmexit handlers. Therefore // we simplify interrupt priority to 1) NMIs, 2) interrupts, and 3) generated exceptions. See // Volume 3, Section 6.9, Table 6-2. let vector = if self . controller . try_pop ( NonMaskableInterrupt as usize ) { NonMaskableInterrupt } else if let Some ( vec ) = self . controller . pop ( ) { // Pop scans vectors from highest to lowest, which will correctly pop interrupts before // exceptions. All vectors <= VirtualizationException except the NMI vector are exceptions. vec as u8 } else { return Ok ( ( ) ) ; } ; if vector > VirtualizationException && vector < IRQ0 { return Err ( RvmError :: NotSupported ) ; } else { use InterruptibilityState as IntrState ; let intr_state = IntrState :: from_bits_truncate ( vmcs . read32 ( GUEST_INTERRUPTIBILITY_STATE ) ) ; let can_inject_nmi = ! intr_state . contains ( IntrState :: BLOCKING_BY_NMI ) && ! intr_state . contains ( IntrState :: BLOCKING_BY_MOV_SS ) ; let can_inject_external_int = vmcs . readXX ( GUEST_RFLAGS ) . get_bit ( 9 ) && ! intr_state . contains ( IntrState :: BLOCKING_BY_STI ) && ! intr_state . contains ( IntrState :: BLOCKING_BY_MOV_SS ) ; if ( vector >= IRQ0 && ! can_inject_external_int ) || ( vector == NonMaskableInterrupt && ! can_inject_nmi ) { self . controller . virtual_interrupt ( vector as usize ) ; // If interrupts are disabled, we set VM exit on interrupt enable. vmcs . interrupt_window_exiting ( true ) ; return Ok ( ( ) ) ; } } // If the vector is non-maskable or interrupts are enabled, we inject an interrupt. vmcs . issue_interrupt ( vector ) ; // Volume 3, Section 6.9: Lower priority exceptions are discarded; lower priority interrupts are // held pending. Discarded exceptions are re-generated when the interrupt handler returns // execution to the point in the program or task where the exceptions and/or interrupts // occurred. self . controller . clear_and_keep ( NonMaskableInterrupt as usize ) ; Ok ( ( ) ) }
Injects an interrupt into the guest, if there is one pending.
Injects an interrupt into the guest if there is one pending .
&mut self
vmcs
&mut AutoVmcs