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: 1623891 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id A277F400E8 for ; Mon, 22 Oct 2012 06:52:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755382Ab2JVGwD (ORCPT ); Mon, 22 Oct 2012 02:52:03 -0400 Received: from mail-vc0-f174.google.com ([209.85.220.174]:53511 "EHLO mail-vc0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755376Ab2JVGwA (ORCPT ); Mon, 22 Oct 2012 02:52:00 -0400 Received: by mail-vc0-f174.google.com with SMTP id fk26so2577234vcb.19 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=F7i4LT4YhFg68B8tEiC/7MgK8P2WkkAAeiVF1//UqHBpwbBx4s4SGTkKbqUGUuztMQ nlNC4xheXwKZSAwcIiILU2Yg8NdaQ9f/UtftIbOtIEnl1q9fXG1XfD87i3JqHRy7n4wr oBTpFvEj8cbCTdS0eprs4Uf4Xl+fvyQfNmZzjhUAPNJ+//IoZHnLVUKtWo4a5E96brJ1 0KhRsCS7jbstPp93PiSn6lkGAyr6+C9u8l3Cnzkcjx+Q3ZON9Nui6r1EjOSiPmsxoeVC Defe+zcPAItWU9EpPQ7mfoZ5nASdoMhZ5tD2O0gOzfepjW101VsOGVOYEoq3NUDbKmws XO+A== 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 Cc: Marc Zyngier 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: ALoCoQnVLkCcdEb/c7Zf+jjPVoY5D9lcTdkWgozCqIEkMvqMcadbSw8JxUMAWpxoDGwwEN2wsjtZ Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.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(+) -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html 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,