From patchwork Tue Oct 27 16:41:07 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Lalancette X-Patchwork-Id: 56136 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n9RGfPkp031090 for ; Tue, 27 Oct 2009 16:41:25 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756157AbZJ0QlO (ORCPT ); Tue, 27 Oct 2009 12:41:14 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756153AbZJ0QlM (ORCPT ); Tue, 27 Oct 2009 12:41:12 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55067 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756154AbZJ0QlK (ORCPT ); Tue, 27 Oct 2009 12:41:10 -0400 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n9RGfE4q022007 for ; Tue, 27 Oct 2009 12:41:15 -0400 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n9RGf8PM005287; Tue, 27 Oct 2009 12:41:14 -0400 From: Chris Lalancette To: kvm@vger.kernel.org Cc: Chris Lalancette Subject: [PATCH 5/5] Fix kdump under KVM. Date: Tue, 27 Oct 2009 17:41:07 +0100 Message-Id: <1256661667-9298-6-git-send-email-clalance@redhat.com> In-Reply-To: <1256661667-9298-1-git-send-email-clalance@redhat.com> References: <1256661667-9298-1-git-send-email-clalance@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index d5c08fa..fe08823 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -299,8 +299,7 @@ static enum hrtimer_restart pit_timer_fn(struct hrtimer *data) if (ktimer->reinject || !atomic_read(&ktimer->pending)) atomic_inc(&ktimer->pending); - if (waitqueue_active(&ktimer->kvm->bsp_vcpu->wq)) - wake_up_interruptible(&ktimer->kvm->bsp_vcpu->wq); + kvm_irq_kick_vcpus(ktimer->kvm); if (ktimer->t_ops->is_periodic(ktimer)) { hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 411110f..5b699c1 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1031,6 +1031,18 @@ void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu) kvm_apic_local_deliver(apic, APIC_LVT0); } +int kvm_apic_in_virtual_wire_mode(struct kvm_vcpu *vcpu) +{ + if (kvm_lapic_enabled(vcpu)) { + u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0); + if ((lvt0 & APIC_LVT_MASKED) == 0 && + GET_APIC_DELIVERY_MODE(lvt0) == APIC_MODE_EXTINT) + return 1; + } + + return 0; +} + static struct kvm_timer_ops lapic_timer_ops = { .is_periodic = lapic_is_periodic, }; diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 40010b0..9c4e52b 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -30,6 +30,7 @@ void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8); void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu); void kvm_apic_set_version(struct kvm_vcpu *vcpu); +int kvm_apic_in_virtual_wire_mode(struct kvm_vcpu *vcpu); int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 053e49f..975b0d6 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -542,6 +542,8 @@ int kvm_set_irq_routing(struct kvm *kvm, unsigned flags); void kvm_free_irq_routing(struct kvm *kvm); +void kvm_irq_kick_vcpus(struct kvm *kvm); + #else static inline void kvm_free_irq_routing(struct kvm *kvm) {} diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index cd6f92b..717d265 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c @@ -163,15 +163,6 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) irqe.level = 1; irqe.shorthand = 0; -#ifdef CONFIG_X86 - /* Always deliver PIT interrupt to vcpu 0 */ - if (irq == 0) { - irqe.dest_mode = 0; /* Physical mode. */ - /* need to read apic_id from apic regiest since - * it can be rewritten */ - irqe.dest_id = ioapic->kvm->bsp_vcpu->vcpu_id; - } -#endif return kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe); } diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 0d454d3..d24ac91 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -293,6 +293,18 @@ void kvm_free_irq_routing(struct kvm *kvm) kfree(kvm->irq_routing); } +void kvm_irq_kick_vcpus(struct kvm *kvm) +{ + int i; + struct kvm_vcpu *vcpu; + + kvm_for_each_vcpu(i, vcpu, kvm) { + if (kvm_apic_in_virtual_wire_mode(vcpu)) + if (waitqueue_active(&vcpu->wq)) + wake_up_interruptible(&vcpu->wq); + } +} + static int setup_routing_entry(struct kvm_irq_routing_table *rt, struct kvm_kernel_irq_routing_entry *e, const struct kvm_irq_routing_entry *ue)