From patchwork Wed Nov 4 14:49:47 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 55982 Delivered-To: patch@linaro.org Received: by 10.112.61.134 with SMTP id p6csp2460689lbr; Wed, 4 Nov 2015 06:56:12 -0800 (PST) X-Received: by 10.68.57.171 with SMTP id j11mr2355310pbq.17.1446648972628; Wed, 04 Nov 2015 06:56:12 -0800 (PST) Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [198.137.202.9]) by mx.google.com with ESMTPS id eo16si673707pab.209.2015.11.04.06.56.12 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Nov 2015 06:56:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 198.137.202.9 as permitted sender) client-ip=198.137.202.9; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 198.137.202.9 as permitted sender) smtp.mailfrom=linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@linaro_org.20150623.gappssmtp.com Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZtzSh-0006BH-M8; Wed, 04 Nov 2015 14:54:55 +0000 Received: from mail-wi0-x231.google.com ([2a00:1450:400c:c05::231]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZtzRI-00057k-6Q for linux-arm-kernel@lists.infradead.org; Wed, 04 Nov 2015 14:53:31 +0000 Received: by wijp11 with SMTP id p11so93940307wij.0 for ; Wed, 04 Nov 2015 06:53:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro_org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xo7eY76KRDTY115hvWqna90B1kqK1u23dhmhWgtpVoo=; b=jW3UuGELe8JzaCdb+zMHYjkxmm+xcE9oVLfc79N+XqtiXbNSU0LCYLnKIyaKUUxT1m gEUSuMsnz/wDMuwDvAiZOMtv3xOBcPPUeh1YNSXkFvl3eGLbHvoOIQaWNF13iwtb507F DEUEbHTOVENta0VY/5IR2832SKCDKJhQs3DOXMP/bSpyBrbZzw/vL3tFSm2jCFBBb4fa WtvzcJswo9TYaVCTjUD7P0M3b1XSHVq0mdPd9L8uN4JVV3tZ9O9/Rz0UNugafxmmEujb fExeLD+aXf/uX18MM/lXGbIINZlvmVNtU4h9vg3/vh5kss7wLzlnK87E2sLvEMGPZ9gK F0zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xo7eY76KRDTY115hvWqna90B1kqK1u23dhmhWgtpVoo=; b=WlgCpf/rXaVNkee98TaK0vMPoDSXVA5bfbrhtVlHTCYlr1CV3HbWo6cFKzpoDDAqrX 1RfOuDWMmjW8DpM2w32oU/Ir8QpNY8Wy+1MXGzy25xpvnCDebraygcZb4WckXTd8b7Ig pErBuLbzaaC8h2iqOzgRwuyTsBEIpGpQPtKXrYCEpy7APt5NGjwgIvdNmz1YBB95H4rg 5GtftpQ08JVjEPk/vX7JY7QJeS+Eg0nt5LHHYH4vErSkRotxI7nA4TyzYzphYsLf2EhT +hn3unFwL68hRLpN6bYVWflKYZ2xnv80bVAuGoa+8SVIuh6WBS1BjzuU/dc+FvTpcWv8 xzKg== X-Gm-Message-State: ALoCoQnJ41oRRMcFTRYP0UEmrCHsCBQxav58RogWroCpKV/edcNH5B36pEkVnz0CQKWzwgRAVLS5 X-Received: by 10.194.52.72 with SMTP id r8mr2515029wjo.8.1446648786529; Wed, 04 Nov 2015 06:53:06 -0800 (PST) Received: from localhost.localdomain ([94.18.191.146]) by smtp.gmail.com with ESMTPSA id e9sm1985081wjw.8.2015.11.04.06.53.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 04 Nov 2015 06:53:06 -0800 (PST) From: Christoffer Dall To: Paolo Bonzini , kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PULL 08/21] arm/arm64: KVM: Support edge-triggered forwarded interrupts Date: Wed, 4 Nov 2015 15:49:47 +0100 Message-Id: <1446648600-27297-9-git-send-email-christoffer.dall@linaro.org> X-Mailer: git-send-email 2.1.2.330.g565301e.dirty In-Reply-To: <1446648600-27297-1-git-send-email-christoffer.dall@linaro.org> References: <1446648600-27297-1-git-send-email-christoffer.dall@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151104_065328_623232_CCBC8D83 X-CRM114-Status: GOOD ( 19.65 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.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 [2a00:1450:400c:c05:0:0:0:231 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marc Zyngier , Christoffer Dall MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org We mark edge-triggered interrupts with the HW bit set as queued to prevent the VGIC code from injecting LRs with both the Active and Pending bits set at the same time while also setting the HW bit, because the hardware does not support this. However, this means that we must also clear the queued flag when we sync back a LR where the state on the physical distributor went from active to inactive because the guest deactivated the interrupt. At this point we must also check if the interrupt is pending on the distributor, and tell the VGIC to queue it again if it is. Since these actions on the sync path are extremely close to those for level-triggered interrupts, rename process_level_irq to process_queued_irq, allowing it to cater for both cases. Signed-off-by: Christoffer Dall --- virt/kvm/arm/vgic.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) -- 2.1.2.330.g565301e.dirty _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 3c2909c..84abc6f 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -1313,13 +1313,10 @@ epilog: } } -static int process_level_irq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr) +static int process_queued_irq(struct kvm_vcpu *vcpu, + int lr, struct vgic_lr vlr) { - int level_pending = 0; - - vlr.state = 0; - vlr.hwirq = 0; - vgic_set_lr(vcpu, lr, vlr); + int pending = 0; /* * If the IRQ was EOIed (called from vgic_process_maintenance) or it @@ -1335,26 +1332,35 @@ static int process_level_irq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr) vgic_dist_irq_clear_soft_pend(vcpu, vlr.irq); /* - * Tell the gic to start sampling the line of this interrupt again. + * Tell the gic to start sampling this interrupt again. */ vgic_irq_clear_queued(vcpu, vlr.irq); /* Any additional pending interrupt? */ - if (vgic_dist_irq_get_level(vcpu, vlr.irq)) { - vgic_cpu_irq_set(vcpu, vlr.irq); - level_pending = 1; + if (vgic_irq_is_edge(vcpu, vlr.irq)) { + BUG_ON(!(vlr.state & LR_HW)); + pending = vgic_dist_irq_is_pending(vcpu, vlr.irq); } else { - vgic_dist_irq_clear_pending(vcpu, vlr.irq); - vgic_cpu_irq_clear(vcpu, vlr.irq); + if (vgic_dist_irq_get_level(vcpu, vlr.irq)) { + vgic_cpu_irq_set(vcpu, vlr.irq); + pending = 1; + } else { + vgic_dist_irq_clear_pending(vcpu, vlr.irq); + vgic_cpu_irq_clear(vcpu, vlr.irq); + } } /* * Despite being EOIed, the LR may not have * been marked as empty. */ + vlr.state = 0; + vlr.hwirq = 0; + vgic_set_lr(vcpu, lr, vlr); + vgic_sync_lr_elrsr(vcpu, lr, vlr); - return level_pending; + return pending; } static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) @@ -1391,7 +1397,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) vlr.irq - VGIC_NR_PRIVATE_IRQS); spin_lock(&dist->lock); - level_pending |= process_level_irq(vcpu, lr, vlr); + level_pending |= process_queued_irq(vcpu, lr, vlr); spin_unlock(&dist->lock); } } @@ -1413,7 +1419,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) /* * Save the physical active state, and reset it to inactive. * - * Return true if there's a pending level triggered interrupt line to queue. + * Return true if there's a pending forwarded interrupt to queue. */ static bool vgic_sync_hwirq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr) { @@ -1438,10 +1444,8 @@ static bool vgic_sync_hwirq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr) if (phys_active) return 0; - /* Mapped edge-triggered interrupts not yet supported. */ - WARN_ON(vgic_irq_is_edge(vcpu, vlr.irq)); spin_lock(&dist->lock); - level_pending = process_level_irq(vcpu, lr, vlr); + level_pending = process_queued_irq(vcpu, lr, vlr); spin_unlock(&dist->lock); return level_pending; }