From patchwork Mon Oct 22 06:52:10 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 1624181 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 8BD35400E8 for ; Mon, 22 Oct 2012 07:04:46 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TQC1I-0007CB-2U; Mon, 22 Oct 2012 07:01:52 +0000 Received: from mail-vc0-f177.google.com ([209.85.220.177]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TQBrk-000054-Oo for linux-arm-kernel@lists.infradead.org; Mon, 22 Oct 2012 06:52:04 +0000 Received: by mail-vc0-f177.google.com with SMTP id p16so2567841vcq.36 for ; Sun, 21 Oct 2012 23:52:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=subject:to:from:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-type:content-transfer-encoding :x-gm-message-state; bh=4YdoLEHNA3QGiOu8T92ZBKYKbi1/qGHJtfOQ006GRTY=; b=MTdcO6td+rLPhxHUhMBNsCHyYf4yYZ2TiMW8xjrAa1nA9TqvDOEsf5CqZOqLNIdIQ2 9Hb8El18mbHW8CnIlM7roLngtZiuJlGX5eyuD25XC7ucjaIpme4T2OkxE5fqR8PTgsMZ 7a2oJpk1OM/MDiUVfWWr9b1IB3SAJc4BEv5cz1fEuAxPMNFoTG7PVCLWVX9F2VE1yQIt Heg3IbCgDzV7kae9iTq5RH4Ub+mo2A4s4dADClWj65D4CiB8S0wWcIoHrS7pPeHzR1Ku bNPZBi9qu02EPchfVsXaFdvN30PDG31igwbF3bwIWBDQgbShX7RdYP3T6aU8m5eFcioQ ngog== Received: by 10.220.205.200 with SMTP id fr8mr13216459vcb.34.1350888720545; Sun, 21 Oct 2012 23:52:00 -0700 (PDT) Received: from [127.0.1.1] (pool-72-80-83-148.nycmny.fios.verizon.net. [72.80.83.148]) by mx.google.com with ESMTPS id g5sm8974964vez.6.2012.10.21.23.51.59 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 21 Oct 2012 23:52:00 -0700 (PDT) Subject: [PATCH v3 08/13] ARM: KVM: vgic: retire queued, disabled interrupts To: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu From: Christoffer Dall Date: Mon, 22 Oct 2012 02:52:10 -0400 Message-ID: <20121022065209.18672.42742.stgit@ubuntu> In-Reply-To: <20121022065104.18672.52989.stgit@ubuntu> References: <20121022065104.18672.52989.stgit@ubuntu> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQlUFbdQIFnqS6Adq9b+be2CjB7hUH7fq9sb+1VfsZDTlzBwxAgMQILmn6Cdl7E8l+HGyzu6 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.220.177 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Marc Zyngier X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Marc Zyngier An interrupt may have been disabled after being made pending on the CPU interface (the classic case is a timer running while we're rebooting the guest - the interrupt would kick as soon as the CPU interface gets enabled, with deadly consequences). The solution is to examine already active LRs, and check the interrupt is still enabled. If not, just retire it. Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall --- arch/arm/kvm/vgic.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c index d7cdec5..dda5623 100644 --- a/arch/arm/kvm/vgic.c +++ b/arch/arm/kvm/vgic.c @@ -633,6 +633,34 @@ static void vgic_update_state(struct kvm *kvm) #define LR_PHYSID(lr) (((lr) & VGIC_LR_PHYSID_CPUID) >> 10) #define MK_LR_PEND(src, irq) (VGIC_LR_PENDING_BIT | ((src) << 10) | (irq)) + +/* + * An interrupt may have been disabled after being made pending on the + * CPU interface (the classic case is a timer running while we're + * rebooting the guest - the interrupt would kick as soon as the CPU + * interface gets enabled, with deadly consequences). + * + * The solution is to examine already active LRs, and check the + * interrupt is still enabled. If not, just retire it. + */ +static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu) +{ + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + struct vgic_dist *dist = &vcpu->kvm->arch.vgic; + int lr; + + for_each_set_bit(lr, vgic_cpu->lr_used, vgic_cpu->nr_lr) { + int irq = vgic_cpu->vgic_lr[lr] & VGIC_LR_VIRTUALID; + + if (!vgic_bitmap_get_irq_val(&dist->irq_enabled, + vcpu->vcpu_id, irq)) { + vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; + clear_bit(lr, vgic_cpu->lr_used); + vgic_cpu->vgic_lr[lr] &= ~VGIC_LR_STATE; + } + } +} + /* * Queue an interrupt to a CPU virtual interface. Return true on success, * or false if it wasn't possible to queue it. @@ -696,6 +724,8 @@ static void __kvm_vgic_sync_to_cpu(struct kvm_vcpu *vcpu) vcpu_id = vcpu->vcpu_id; + vgic_retire_disabled_irqs(vcpu); + /* * We may not have any pending interrupt, or the interrupts * may have been serviced from another vcpu. In all cases,