case APIC_DM_SMI:
                printk(KERN_DEBUG "Ignoring guest SMI\n");
                break;
+
        case APIC_DM_NMI:
-               printk(KERN_DEBUG "Ignoring guest NMI\n");
+               kvm_inject_nmi(vcpu);
                break;
 
        case APIC_DM_INIT:
 
        kvm_queue_exception_e(vcpu, PF_VECTOR, error_code);
 }
 
+void kvm_inject_nmi(struct kvm_vcpu *vcpu)
+{
+       vcpu->arch.nmi_pending = 1;
+}
+EXPORT_SYMBOL_GPL(kvm_inject_nmi);
+
 void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
 {
        WARN_ON(vcpu->arch.exception.pending);
 
 int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
 void kvm_sal_emul(struct kvm_vcpu *vcpu);
 
+static inline void kvm_inject_nmi(struct kvm_vcpu *vcpu) {}
+
 #endif
 
        unsigned int hv_clock_tsc_khz;
        unsigned int time_offset;
        struct page *time_page;
+
+       bool nmi_pending;
 };
 
 struct kvm_mem_alias {
 void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
                           u32 error_code);
 
+void kvm_inject_nmi(struct kvm_vcpu *vcpu);
+
 void fx_init(struct kvm_vcpu *vcpu);
 
 int emulator_read_std(unsigned long addr,
 
        return kvm_apic_set_irq(vcpu, vector, trig_mode);
 }
 
+static void ioapic_inj_nmi(struct kvm_vcpu *vcpu)
+{
+       kvm_inject_nmi(vcpu);
+}
+
 static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest,
                                       u8 dest_mode)
 {
                        }
                }
                break;
-
-               /* TODO: NMI */
+       case IOAPIC_NMI:
+               for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) {
+                       if (!(deliver_bitmask & (1 << vcpu_id)))
+                               continue;
+                       deliver_bitmask &= ~(1 << vcpu_id);
+                       vcpu = ioapic->kvm->vcpus[vcpu_id];
+                       if (vcpu)
+                               ioapic_inj_nmi(vcpu);
+                       else
+                               ioapic_debug("NMI to vcpu %d failed\n",
+                                               vcpu->vcpu_id);
+               }
+               break;
        default:
                printk(KERN_WARNING "Unsupported delivery mode %d\n",
                       delivery_mode);