From: Yang, S. <she...@in...> - 2008-05-15 10:44:07
|
From 16680d2556ad065b128412b0f5d81f04de25b3f8 Mon Sep 17 00:00:00 2001 From: Sheng Yang <she...@in...> Date: Thu, 15 May 2008 09:52:48 +0800 Subject: [PATCH] KVM: IOAPIC/LAPIC: Enable NMI support Signed-off-by: Sheng Yang <she...@in...> --- arch/x86/kvm/lapic.c | 3 ++- arch/x86/kvm/x86.c | 6 ++++++ include/asm-x86/kvm_host.h | 4 ++++ virt/kvm/ioapic.c | 20 ++++++++++++++++++-- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 7652f88..2273836 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, 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: diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index dab3d4f..8461da4 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, 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); diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 1466c3f..567d739 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -285,6 +285,8 @@ struct kvm_vcpu_arch { struct kvm_vcpu_time_info hv_clock; unsigned int time_offset; struct page *time_page; + + bool nmi_pending; }; struct kvm_mem_alias { @@ -512,6 +514,8 @@ void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); 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, diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 4232fd7..99a1736 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c @@ -146,6 +146,11 @@ static void ioapic_inj_irq(struct kvm_ioapic *ioapic, 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) { @@ -239,8 +244,19 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) } } 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); -- 1.5.5 |