aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/lapic.c3
-rw-r--r--arch/x86/kvm/x86.c6
-rw-r--r--include/asm-ia64/kvm_host.h2
-rw-r--r--include/asm-x86/kvm_host.h4
-rw-r--r--virt/kvm/ioapic.c20
5 files changed, 32 insertions, 3 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index f9201fbc61d1..e48d19394031 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -356,8 +356,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
356 case APIC_DM_SMI: 356 case APIC_DM_SMI:
357 printk(KERN_DEBUG "Ignoring guest SMI\n"); 357 printk(KERN_DEBUG "Ignoring guest SMI\n");
358 break; 358 break;
359
359 case APIC_DM_NMI: 360 case APIC_DM_NMI:
360 printk(KERN_DEBUG "Ignoring guest NMI\n"); 361 kvm_inject_nmi(vcpu);
361 break; 362 break;
362 363
363 case APIC_DM_INIT: 364 case APIC_DM_INIT:
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5f00c60f0aff..19974dde6567 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -173,6 +173,12 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr,
173 kvm_queue_exception_e(vcpu, PF_VECTOR, error_code); 173 kvm_queue_exception_e(vcpu, PF_VECTOR, error_code);
174} 174}
175 175
176void kvm_inject_nmi(struct kvm_vcpu *vcpu)
177{
178 vcpu->arch.nmi_pending = 1;
179}
180EXPORT_SYMBOL_GPL(kvm_inject_nmi);
181
176void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code) 182void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
177{ 183{
178 WARN_ON(vcpu->arch.exception.pending); 184 WARN_ON(vcpu->arch.exception.pending);
diff --git a/include/asm-ia64/kvm_host.h b/include/asm-ia64/kvm_host.h
index c082c208c1f3..5c958b0c46b1 100644
--- a/include/asm-ia64/kvm_host.h
+++ b/include/asm-ia64/kvm_host.h
@@ -521,4 +521,6 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu);
521int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run); 521int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
522void kvm_sal_emul(struct kvm_vcpu *vcpu); 522void kvm_sal_emul(struct kvm_vcpu *vcpu);
523 523
524static inline void kvm_inject_nmi(struct kvm_vcpu *vcpu) {}
525
524#endif 526#endif
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 4bcdc7de07b5..b66621935eb7 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -288,6 +288,8 @@ struct kvm_vcpu_arch {
288 unsigned int hv_clock_tsc_khz; 288 unsigned int hv_clock_tsc_khz;
289 unsigned int time_offset; 289 unsigned int time_offset;
290 struct page *time_page; 290 struct page *time_page;
291
292 bool nmi_pending;
291}; 293};
292 294
293struct kvm_mem_alias { 295struct kvm_mem_alias {
@@ -515,6 +517,8 @@ void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
515void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2, 517void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
516 u32 error_code); 518 u32 error_code);
517 519
520void kvm_inject_nmi(struct kvm_vcpu *vcpu);
521
518void fx_init(struct kvm_vcpu *vcpu); 522void fx_init(struct kvm_vcpu *vcpu);
519 523
520int emulator_read_std(unsigned long addr, 524int emulator_read_std(unsigned long addr,
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 44589088941f..d0c668c6959e 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -146,6 +146,11 @@ static int ioapic_inj_irq(struct kvm_ioapic *ioapic,
146 return kvm_apic_set_irq(vcpu, vector, trig_mode); 146 return kvm_apic_set_irq(vcpu, vector, trig_mode);
147} 147}
148 148
149static void ioapic_inj_nmi(struct kvm_vcpu *vcpu)
150{
151 kvm_inject_nmi(vcpu);
152}
153
149static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, 154static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest,
150 u8 dest_mode) 155 u8 dest_mode)
151{ 156{
@@ -239,8 +244,19 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
239 } 244 }
240 } 245 }
241 break; 246 break;
242 247 case IOAPIC_NMI:
243 /* TODO: NMI */ 248 for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) {
249 if (!(deliver_bitmask & (1 << vcpu_id)))
250 continue;
251 deliver_bitmask &= ~(1 << vcpu_id);
252 vcpu = ioapic->kvm->vcpus[vcpu_id];
253 if (vcpu)
254 ioapic_inj_nmi(vcpu);
255 else
256 ioapic_debug("NMI to vcpu %d failed\n",
257 vcpu->vcpu_id);
258 }
259 break;
244 default: 260 default:
245 printk(KERN_WARNING "Unsupported delivery mode %d\n", 261 printk(KERN_WARNING "Unsupported delivery mode %d\n",
246 delivery_mode); 262 delivery_mode);