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: 1724101 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 265EADFE7E for ; Sat, 10 Nov 2012 15:45:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752184Ab2KJPpQ (ORCPT ); Sat, 10 Nov 2012 10:45:16 -0500 Received: from mail-wi0-f170.google.com ([209.85.212.170]:57438 "EHLO mail-wi0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752162Ab2KJPpP (ORCPT ); Sat, 10 Nov 2012 10:45:15 -0500 Received: by mail-wi0-f170.google.com with SMTP id hm9so1313015wib.1 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=Ca88tIps3dLeUv2k3B5rsharmcPh8nwOweXbsy09GMbz5upY5U/HGZIE+lFHwaA/hK CS1zLnK3PBdLyBPbdIDIzYNRhbkatH6fSTzrf1wb5vICoVy1FxDFfHDGz/P09ccu28wf kGOXBRiLjHJ2X995hjkKri4CYkMyZjA6bHf6HAf5Nq6Ub7D3bgq6dMU7gKkQUM+PhKMP BMyWtNH5T7l4C0z1qiMfgNsBBVDCau4HIjpnaRULBd1GR4YDCBP48QNsqhyJnPu+6Tlb gSKvmouKA1dV9mPXqERurSn5EtKFC0/hq83Yi5hkHj/esrKrFEL7mSkq9Esg1UHpEbRo P4Qg== 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 Cc: Marc Zyngier 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: ALoCoQnOdNWw96x5bHxgxUQdtAssqlLtS0rd80BIcdFe50Qc7jtbCwaSt59ITbeF/bnszOGz4CeD 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,