From patchwork Wed Aug 27 14:05:31 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Wei W" X-Patchwork-Id: 4786271 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A87E4C0338 for ; Wed, 27 Aug 2014 05:41:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7E4C82015A for ; Wed, 27 Aug 2014 05:41:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2B62720142 for ; Wed, 27 Aug 2014 05:41:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755006AbaH0Fl1 (ORCPT ); Wed, 27 Aug 2014 01:41:27 -0400 Received: from mga11.intel.com ([192.55.52.93]:43280 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751000AbaH0Fl0 (ORCPT ); Wed, 27 Aug 2014 01:41:26 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 26 Aug 2014 22:41:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.04,408,1406617200"; d="scan'208";a="582210888" Received: from unknown (HELO otc.sh.intel.com) ([10.239.48.14]) by fmsmga001.fm.intel.com with ESMTP; 26 Aug 2014 22:41:25 -0700 From: Wei Wang To: kvm@vger.kernel.org Cc: pbonzini@redhat.com, alex.williamson@redhat.com, Wei Wang , Yang Zhang Subject: [PATCH v2] KVM: x86: keep eoi exit bitmap accurate before loading it. Date: Wed, 27 Aug 2014 22:05:31 +0800 Message-Id: <1409148331-5964-1-git-send-email-wei.w.wang@intel.com> X-Mailer: git-send-email 1.7.1 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00, DATE_IN_FUTURE_06_12, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Guest may mask the IOAPIC entry before issue EOI. In such case, EOI will not be intercepted by the hypervisor, since the corresponding bit in eoi_exit_bitmap is not set after the masking of IOAPIC entry. The solution here is to OR eoi_exit_bitmap with tmr to make sure that all level-triggered interrupts have their bits in eoi_exit_bitmap set. Tested-by: Rongrong Liu Signed-off-by: Yang Zhang Signed-off-by: Wei Wang --- arch/x86/kvm/lapic.c | 12 ++++++++++++ arch/x86/kvm/lapic.h | 1 + arch/x86/kvm/x86.c | 1 + virt/kvm/ioapic.c | 7 ++++--- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 8c1162d..0fcac3c 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -539,6 +539,18 @@ void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr) } } +void kvm_apic_update_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + u32 i; + u32 tmr; + + for (i = 0; i < 8; i++) { + tmr = kvm_apic_get_reg(apic, APIC_TMR + 0x10 * i); + *((u32 *)eoi_exit_bitmap + i) |= tmr; + } +} + static void apic_update_ppr(struct kvm_lapic *apic) { u32 tpr, isrv, ppr, old_ppr; diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 6a11845..d2b96f2 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -55,6 +55,7 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu); void kvm_apic_update_tmr(struct kvm_vcpu *vcpu, u32 *tmr); void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir); +void kvm_apic_update_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap); int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d401684..d23b558 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5992,6 +5992,7 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) kvm_ioapic_scan_entry(vcpu, eoi_exit_bitmap, tmr); kvm_apic_update_tmr(vcpu, tmr); + kvm_apic_update_eoi_exitmap(vcpu, eoi_exit_bitmap); kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap); } diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index e8ce34c..ed15936 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c @@ -254,9 +254,10 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap, spin_lock(&ioapic->lock); for (index = 0; index < IOAPIC_NUM_PINS; index++) { e = &ioapic->redirtbl[index]; - if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG || - kvm_irq_has_notifier(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index) || - index == RTC_GSI) { + if ((!e->fields.mask + && e->fields.trig_mode == IOAPIC_LEVEL_TRIG) + || kvm_irq_has_notifier(ioapic->kvm, KVM_IRQCHIP_IOAPIC, + index) || index == RTC_GSI) { if (kvm_apic_match_dest(vcpu, NULL, 0, e->fields.dest_id, e->fields.dest_mode)) { __set_bit(e->fields.vector,