}
 
 static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu,
-                                     struct vmcs12 *vmcs12)
+                                     struct vmcs12 *vmcs12,
+                                     u32 vm_exit_reason, u32 exit_intr_info)
 {
        u32 idt_vectoring;
        unsigned int nr;
 
-       if (vcpu->arch.exception.injected) {
+       /*
+        * Per the SDM, VM-Exits due to double and triple faults are never
+        * considered to occur during event delivery, even if the double/triple
+        * fault is the result of an escalating vectoring issue.
+        *
+        * Note, the SDM qualifies the double fault behavior with "The original
+        * event results in a double-fault exception".  It's unclear why the
+        * qualification exists since exits due to double fault can occur only
+        * while vectoring a different exception (injected events are never
+        * subject to interception), i.e. there's _always_ an original event.
+        *
+        * The SDM also uses NMI as a confusing example for the "original event
+        * causes the VM exit directly" clause.  NMI isn't special in any way,
+        * the same rule applies to all events that cause an exit directly.
+        * NMI is an odd choice for the example because NMIs can only occur on
+        * instruction boundaries, i.e. they _can't_ occur during vectoring.
+        */
+       if ((u16)vm_exit_reason == EXIT_REASON_TRIPLE_FAULT ||
+           ((u16)vm_exit_reason == EXIT_REASON_EXCEPTION_NMI &&
+            is_double_fault(exit_intr_info))) {
+               vmcs12->idt_vectoring_info_field = 0;
+       } else if (vcpu->arch.exception.injected) {
                nr = vcpu->arch.exception.nr;
                idt_vectoring = nr | VECTORING_INFO_VALID_MASK;
 
                        idt_vectoring |= INTR_TYPE_EXT_INTR;
 
                vmcs12->idt_vectoring_info_field = idt_vectoring;
+       } else {
+               vmcs12->idt_vectoring_info_field = 0;
        }
 }
 
                 * Transfer the event that L0 or L1 may wanted to inject into
                 * L2 to IDT_VECTORING_INFO_FIELD.
                 */
-               vmcs12->idt_vectoring_info_field = 0;
-               vmcs12_save_pending_event(vcpu, vmcs12);
+               vmcs12_save_pending_event(vcpu, vmcs12,
+                                         vm_exit_reason, exit_intr_info);
 
                vmcs12->vm_exit_intr_info = exit_intr_info;
                vmcs12->vm_exit_instruction_len = vmcs_read32(VM_EXIT_INSTRUCTION_LEN);