From patchwork Wed Jan 31 09:34:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 10193717 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6C747603EE for ; Wed, 31 Jan 2018 09:41:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4DF5728606 for ; Wed, 31 Jan 2018 09:41:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 427BA28609; Wed, 31 Jan 2018 09:41:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E33C828606 for ; Wed, 31 Jan 2018 09:41:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753675AbeAaJf2 (ORCPT ); Wed, 31 Jan 2018 04:35:28 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:54502 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753631AbeAaJfV (ORCPT ); Wed, 31 Jan 2018 04:35:21 -0500 Received: by mail-wm0-f66.google.com with SMTP id i186so6665612wmi.4 for ; Wed, 31 Jan 2018 01:35:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=u3RqKC0/+9wUEE4dMyUff8jAybQZs1qeG9RnYLH7G6E=; b=ARtCWY70rAoyuVcnPF6ZWZBOzDzz09PuJBXbQp20zpGWr8jCpSs3QcJLrGR6F9gbTx msTJmQVeeikJKvXLJ+BPbCBjUtEDA16o05kcojP8hgehL7GuVjFxvM5Px1K/aMgzPkG/ BYj8HUz2DpVZRo/8VHV30U1ktL37CWebysRAg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=u3RqKC0/+9wUEE4dMyUff8jAybQZs1qeG9RnYLH7G6E=; b=BYG0iacGkJ/+venXibQwHVFc79aeVI0ZhSAjqvieBF4DSRYXL9CNeJj8Zw1evq0xYY zorMk7tAqb4qNkkg+0dQpjEKbnQ/X7ARS7moZQq7NqnAjYyj5q5eb7OSq3xFAqD3zGdu ZCOZykjUsniS/7x6B2hAAeowaF3Uth4QJLWeLMdWt+yE/XmU0q/wxTFybOh4+z5fjACM oE3UoxlmW0heti19wYv1aglef1pbVsJhQ+mMWVk7eq5iuDlorx2UWoZddTwJiF567QeP 4GKhVHY6/MnCwbW2ep5HmyChpPIbFgR1t2CwvuKfiUueT4Fu9xd7jEMDSDo/r8ZAwuUx UfqA== X-Gm-Message-State: AKwxytdx1zyRE1/K4IdfweDRywB6oKjdYOkh3+NuCva9Hyml5z1tz5D0 VR7mRb7FdT9NfOngRppMgxU4ulKVe8c= X-Google-Smtp-Source: AH8x224zJj5lkhAiuEgcBJazlenM+Ek4dPgGwOXou39YZU8vfzLTGxGhzNE9mGmgNIIBxGdgThankg== X-Received: by 10.80.144.92 with SMTP id z28mr22902400edz.235.1517391320337; Wed, 31 Jan 2018 01:35:20 -0800 (PST) Received: from localhost.localdomain (x50d2404e.cust.hiper.dk. [80.210.64.78]) by smtp.gmail.com with ESMTPSA id z2sm10247837edc.50.2018.01.31.01.35.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 31 Jan 2018 01:35:19 -0800 (PST) From: Christoffer Dall To: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, Marc Zyngier , Christoffer Dall Subject: [PULL 05/28] KVM: arm/arm64: Don't cache the timer IRQ level Date: Wed, 31 Jan 2018 10:34:44 +0100 Message-Id: <20180131093507.22219-6-christoffer.dall@linaro.org> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20180131093507.22219-1-christoffer.dall@linaro.org> References: <20180131093507.22219-1-christoffer.dall@linaro.org> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The timer logic was designed after a strict idea of modeling an interrupt line level in software, meaning that only transitions in the level need to be reported to the VGIC. This works well for the timer, because the arch timer code is in complete control of the device and can track the transitions of the line. However, as we are about to support using the HW bit in the VGIC not just for the timer, but also for VFIO which cannot track transitions of the interrupt line, we have to decide on an interface between the GIC and other subsystems for level triggered mapped interrupts, which both the timer and VFIO can use. VFIO only sees an asserting transition of the physical interrupt line, and tells the VGIC when that happens. That means that part of the interrupt flow is offloaded to the hardware. To use the same interface for VFIO devices and the timer, we therefore have to change the timer (we cannot change VFIO because it doesn't know the details of the device it is assigning to a VM). Luckily, changing the timer is simple, we just need to stop 'caching' the line level, but instead let the VGIC know the state of the timer every time there is a potential change in the line level, and when the line level should be asserted from the timer ISR. The VGIC can ignore extra notifications using its validate mechanism. Reviewed-by: Marc Zyngier Reviewed-by: Andre Przywara Reviewed-by: Julien Thierry Signed-off-by: Christoffer Dall --- virt/kvm/arm/arch_timer.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index f9555b1e7f15..9376fe03bf2e 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c @@ -99,11 +99,9 @@ static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) } vtimer = vcpu_vtimer(vcpu); - if (!vtimer->irq.level) { - vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl); - if (kvm_timer_irq_can_fire(vtimer)) - kvm_timer_update_irq(vcpu, true, vtimer); - } + vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl); + if (kvm_timer_irq_can_fire(vtimer)) + kvm_timer_update_irq(vcpu, true, vtimer); if (unlikely(!irqchip_in_kernel(vcpu->kvm))) kvm_vtimer_update_mask_user(vcpu); @@ -324,12 +322,20 @@ static void kvm_timer_update_state(struct kvm_vcpu *vcpu) struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); struct arch_timer_context *ptimer = vcpu_ptimer(vcpu); + bool level; if (unlikely(!timer->enabled)) return; - if (kvm_timer_should_fire(vtimer) != vtimer->irq.level) - kvm_timer_update_irq(vcpu, !vtimer->irq.level, vtimer); + /* + * The vtimer virtual interrupt is a 'mapped' interrupt, meaning part + * of its lifecycle is offloaded to the hardware, and we therefore may + * not have lowered the irq.level value before having to signal a new + * interrupt, but have to signal an interrupt every time the level is + * asserted. + */ + level = kvm_timer_should_fire(vtimer); + kvm_timer_update_irq(vcpu, level, vtimer); if (kvm_timer_should_fire(ptimer) != ptimer->irq.level) kvm_timer_update_irq(vcpu, !ptimer->irq.level, ptimer);