return vlapic_apicv_write(current, exit_qualification & 0xfff);
}
+static void undo_nmis_unblocked_by_iret(void)
+{
+ unsigned long guest_info;
+
+ __vmread(GUEST_INTERRUPTIBILITY_INFO, &guest_info);
+ __vmwrite(GUEST_INTERRUPTIBILITY_INFO,
+ guest_info | VMX_INTR_SHADOW_NMI);
+}
+
void vmx_vmexit_handler(struct cpu_user_regs *regs)
{
unsigned long exit_qualification, exit_reason, idtv_info, intr_info = 0;
if ( unlikely(intr_info & INTR_INFO_NMI_UNBLOCKED_BY_IRET) &&
!(idtv_info & INTR_INFO_VALID_MASK) &&
(vector != TRAP_double_fault) )
- {
- unsigned long guest_info;
-
- __vmread(GUEST_INTERRUPTIBILITY_INFO, &guest_info);
- __vmwrite(GUEST_INTERRUPTIBILITY_INFO,
- guest_info | VMX_INTR_SHADOW_NMI);
- }
+ undo_nmis_unblocked_by_iret();
perfc_incra(cause_vector, vector);
__vmread(GUEST_PHYSICAL_ADDRESS, &gpa);
__vmread(EXIT_QUALIFICATION, &exit_qualification);
+
+ if ( unlikely(exit_qualification & INTR_INFO_NMI_UNBLOCKED_BY_IRET) &&
+ !(idtv_info & INTR_INFO_VALID_MASK) )
+ undo_nmis_unblocked_by_iret();
+
ept_handle_violation(exit_qualification, gpa);
break;
}
break;
case EXIT_REASON_PML_FULL:
+ __vmread(EXIT_QUALIFICATION, &exit_qualification);
+
+ if ( unlikely(exit_qualification & INTR_INFO_NMI_UNBLOCKED_BY_IRET) &&
+ !(idtv_info & INTR_INFO_VALID_MASK) )
+ undo_nmis_unblocked_by_iret();
+
vmx_vcpu_flush_pml_buffer(v);
break;