From patchwork Wed Dec 20 11:36:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 10125551 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 774AD6019C for ; Wed, 20 Dec 2017 11:38:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6FD5529711 for ; Wed, 20 Dec 2017 11:38:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 64A8129716; Wed, 20 Dec 2017 11:38:06 +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=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 09AD929711 for ; Wed, 20 Dec 2017 11:38:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=9M09ubJgWV48fXGJ953yvXeXYkqRmR3UYgDc9kyBiCw=; b=o5Xq/iIC1/z5cX+ipDbVABvI+e juFB1XwxgkuJMBEwZSapgmkzHcNIvsHtbFjS6E87aoJ7LEJTEg8vEfUih1vsFPWD6lWNQ2GPyWP+b IF5dEkQJ0WMDuHzviPyhPjXEEieArInFd/dJcgwMzBwSL7vg8lycvsVAMtwcXRsAQLhKkTTp84aWm X063ens8jvurgpeXKkj7jyEJmIrppPS9zXkgi4I7JVrLfwTILaD/ja2cVrZzoofcdUQH5PxVzZ0kr 8NbDlbcTEjI6Sw4dg9bVyWVZKgclPakEyJ1V30vyxufIAto3tGoN5qT/rS+aYJX0Cyl5DOVTGWdKT bdcmBE7g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eRchF-00079y-H9; Wed, 20 Dec 2017 11:38:01 +0000 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eRcfk-0006P5-Gk for linux-arm-kernel@lists.infradead.org; Wed, 20 Dec 2017 11:36:33 +0000 Received: by mail-wm0-x242.google.com with SMTP id 64so9106141wme.3 for ; Wed, 20 Dec 2017 03:36:22 -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=KbGGIpgaEaqeuDvufHp9iEtZHLtXcxn8GTkv4qUDMj0oJ8tk5Mvd+YIVYG9hfKCgp3 qS9udjqgwtQXQsZahkHxBnj9kT92aCrK3op8xxcgwKXw+zpvavLj7TJaOk1EglcMKWoO 7xWAU8nb8UqMIqKbYMPVQ0mcnOrDXL3IQDZGA= 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=GLHfBtZfL/rGCX+E7UoxUFQI3FRNzqdyY/DNMN7Beihhql9Gb6wQJgpjR+qIQHhyx9 Fvdu5xscLuGytNiu8cmfEe1y4VxrOWROmQb29KKqv4BhZzvn5JzIsmrJKTAid3B0ACOY Tqw6NDJALE8aOxE/ByNHLfPoh+jBmrNRUhoe6Pr+KzJskFCIZ+ugreB5A2IypgqncETN nLASI4HxLLuig+WYk9xC7dyJ8Z3s/1Fihr3Rn/k7/ggQoiB+b38P+Une4JAX2wfdnino 6G8B4CzmVbnzm7iJN3jene3tp+yDqxC0k12jrJPIO65YkLNqkm0bd8xLo2WysmR2DPbT kk4w== X-Gm-Message-State: AKGB3mLTE1vw4C+Kcn6IxJCR+x+IpAlt+zaKYYUi0r+7rXb3Pkrsg2X/ WwiD26ofknQeUGpwWGIJKXTVfg== X-Google-Smtp-Source: ACJfBot0/rY7oqRlKEURU9qaRN04zHHevjgWp17KZ0wBKRKHmbmCBnNZz/X3JDXt/mgrsRxZD3ExEA== X-Received: by 10.80.174.143 with SMTP id e15mr5227777edd.10.1513769781221; Wed, 20 Dec 2017 03:36:21 -0800 (PST) Received: from localhost.localdomain (x50d2404e.cust.hiper.dk. [80.210.64.78]) by smtp.gmail.com with ESMTPSA id v15sm13978880edb.41.2017.12.20.03.36.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Dec 2017 03:36:20 -0800 (PST) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Subject: [PATCH v9 3/9] KVM: arm/arm64: Don't cache the timer IRQ level Date: Wed, 20 Dec 2017 12:36:00 +0100 Message-Id: <20171220113606.7030-4-christoffer.dall@linaro.org> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171220113606.7030-1-christoffer.dall@linaro.org> References: <20171220113606.7030-1-christoffer.dall@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171220_033628_668273_D7676C01 X-CRM114-Status: GOOD ( 18.62 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marc Zyngier , Andre Przywara , Christoffer Dall , kvm@vger.kernel.org, Eric Auger MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.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);