static void __inject_pit_timer_intr(struct kvm *kvm)
 {
+       struct kvm_vcpu *vcpu;
+       int i;
+
        mutex_lock(&kvm->lock);
        kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1);
        kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0);
        mutex_unlock(&kvm->lock);
+
+       /*
+        * Provides NMI watchdog support in IOAPIC mode.
+        * The route is: PIT -> PIC -> LVT0 in NMI mode,
+        * timer IRQs will continue to flow through the IOAPIC.
+        */
+       for (i = 0; i < KVM_MAX_VCPUS; ++i) {
+               vcpu = kvm->vcpus[i];
+               if (!vcpu)
+                       continue;
+               kvm_apic_local_deliver(vcpu, APIC_LVT0);
+       }
 }
 
 void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
 
 void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec);
 void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu);
 void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu);
+int kvm_apic_local_deliver(struct kvm_vcpu *vcpu, int lvt_type);
 void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu);
 void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu);
 void __kvm_migrate_timers(struct kvm_vcpu *vcpu);
 
                }
                break;
 
+       case APIC_DM_EXTINT:
+               /*
+                * Should only be called by kvm_apic_local_deliver() with LVT0,
+                * before NMI watchdog was enabled. Already handled by
+                * kvm_apic_accept_pic_intr().
+                */
+               break;
+
        default:
                printk(KERN_ERR "TODO: unsupported delivery mode %x\n",
                       delivery_mode);
                apic_set_reg(apic, APIC_ICR2, val & 0xff000000);
                break;
 
+       case APIC_LVT0:
+               if (val == APIC_DM_NMI)
+                       apic_debug("Receive NMI setting on APIC_LVT0 "
+                               "for cpu %d\n", apic->vcpu->vcpu_id);
        case APIC_LVTT:
        case APIC_LVTTHMR:
        case APIC_LVTPC:
-       case APIC_LVT0:
        case APIC_LVT1:
        case APIC_LVTERR:
                /* TODO: Check vector */
        return 0;
 }
 
-static int __inject_apic_timer_irq(struct kvm_lapic *apic)
+int kvm_apic_local_deliver(struct kvm_vcpu *vcpu, int lvt_type)
 {
-       int vector;
+       struct kvm_lapic *apic = vcpu->arch.apic;
+       int vector, mode, trig_mode;
+       u32 reg;
+
+       if (apic && apic_enabled(apic)) {
+               reg = apic_get_reg(apic, lvt_type);
+               vector = reg & APIC_VECTOR_MASK;
+               mode = reg & APIC_MODE_MASK;
+               trig_mode = reg & APIC_LVT_LEVEL_TRIGGER;
+               return __apic_accept_irq(apic, mode, vector, 1, trig_mode);
+       }
+       return 0;
+}
 
-       vector = apic_lvt_vector(apic, APIC_LVTT);
-       return __apic_accept_irq(apic, APIC_DM_FIXED, vector, 1, 0);
+static inline int __inject_apic_timer_irq(struct kvm_lapic *apic)
+{
+       return kvm_apic_local_deliver(apic->vcpu, APIC_LVTT);
 }
 
 static enum hrtimer_restart apic_timer_fn(struct hrtimer *data)