From patchwork Sat Nov 10 15:45:11 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 1724391 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id ABC54DFE7E for ; Sat, 10 Nov 2012 15:56:55 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TXDNt-00063y-P6; Sat, 10 Nov 2012 15:54:16 +0000 Received: from mail-wi0-f171.google.com ([209.85.212.171]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TXDFC-0008Al-QY for linux-arm-kernel@lists.infradead.org; Sat, 10 Nov 2012 15:45:16 +0000 Received: by mail-wi0-f171.google.com with SMTP id c10so185451wiw.0 for ; Sat, 10 Nov 2012 07:45:13 -0800 (PST) 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=Dc8j8iyLvYiheEWd5lCghxrXdUcyKWX7cCWk//3x0ZqfQmtlR8FtZnpKi+dRZ8IhNo 0NFoWQC6AxhYK/RA4C0HOGrdonH3ijKrK+bVvFrcyZFQwDgVDvVhsdyDrj/Z5ULTAxIN IJ+k/IqZshInhWqT1kpd8wyAvVrMzvZhJVszARZWkoUho7vB0XkvzPare2sakCTGaw41 e9j/kAYwCMudfqhAQpo+de27uLEQZ5R1KU14MzikNnaiMTPc6f1QOAsvr6LIivbJRf4Z OEG/QdQ8oek1+zftFEIikBd5qLgGyxoLlmYUGkodts2RqCi3UsslfJGMsFeNC0dwddek afiQ== Received: by 10.180.79.37 with SMTP id g5mr7601592wix.7.1352562313593; Sat, 10 Nov 2012 07:45:13 -0800 (PST) Received: from [127.0.1.1] (ip1.c116.obr91.cust.comxnet.dk. [87.72.8.103]) by mx.google.com with ESMTPS id w8sm6725883wiv.8.2012.11.10.07.45.12 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 10 Nov 2012 07:45:12 -0800 (PST) Subject: [PATCH v4 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: Sat, 10 Nov 2012 16:45:11 +0100 Message-ID: <20121110154511.3061.36715.stgit@chazy-air> In-Reply-To: <20121110154358.3061.16338.stgit@chazy-air> References: <20121110154358.3061.16338.stgit@chazy-air> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQncIUczkU+HkLQYjLBVw/MC1QRAK0HRoqDydLZ/fZUAgZcTqfS6KIpLIoCmqK1thAQlN1Jq X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20121110_104515_598772_E7A704D7 X-CRM114-Status: GOOD ( 14.25 ) 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.212.171 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,