static int nvmx_intr_intercept(struct vcpu *v, struct hvm_intack intack) { u32 ctrl; /* If blocked by L1's tpr, then nothing to do. */ if ( nestedhvm_vcpu_in_guestmode(v) && hvm_interrupt_blocked(v, intack) == hvm_intblk_tpr ) return 1; if ( nvmx_intr_blocked(v) != hvm_intblk_none ) { vmx_enable_intr_window(v, intack); return 1; } if ( nestedhvm_vcpu_in_guestmode(v) ) { ctrl = get_vvmcs(v, PIN_BASED_VM_EXEC_CONTROL); if ( !(ctrl & PIN_BASED_EXT_INTR_MASK) ) return 0; if ( intack.source == hvm_intsrc_pic || intack.source == hvm_intsrc_lapic ) { vmx_inject_extint(intack.vector, intack.source); ctrl = get_vvmcs(v, VM_EXIT_CONTROLS); if ( ctrl & VM_EXIT_ACK_INTR_ON_EXIT ) { /* for now, duplicate the ack path in vmx_intr_assist */ hvm_vcpu_ack_pending_irq(v, intack); pt_intr_post(v, intack); intack = hvm_vcpu_has_pending_irq(v); if ( unlikely(intack.source != hvm_intsrc_none) ) vmx_enable_intr_window(v, intack); } else vmx_enable_intr_window(v, intack); return 1; } else if ( intack.source == hvm_intsrc_vector ) { vmx_inject_extint(intack.vector, intack.source); return 1; } } return 0; }
static int nvmx_intr_intercept(struct vcpu *v, struct hvm_intack intack) { u32 ctrl; if ( nvmx_intr_blocked(v) != hvm_intblk_none ) { enable_intr_window(v, intack); return 1; } if ( nestedhvm_vcpu_in_guestmode(v) ) { if ( intack.source == hvm_intsrc_pic || intack.source == hvm_intsrc_lapic ) { ctrl = __get_vvmcs(vcpu_nestedhvm(v).nv_vvmcx, PIN_BASED_VM_EXEC_CONTROL); if ( !(ctrl & PIN_BASED_EXT_INTR_MASK) ) return 0; vmx_inject_extint(intack.vector); ctrl = __get_vvmcs(vcpu_nestedhvm(v).nv_vvmcx, VM_EXIT_CONTROLS); if ( ctrl & VM_EXIT_ACK_INTR_ON_EXIT ) { /* for now, duplicate the ack path in vmx_intr_assist */ hvm_vcpu_ack_pending_irq(v, intack); pt_intr_post(v, intack); intack = hvm_vcpu_has_pending_irq(v); if ( unlikely(intack.source != hvm_intsrc_none) ) enable_intr_window(v, intack); } else enable_intr_window(v, intack); return 1; } } return 0; }