From patchwork Wed Sep 6 12:26:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9940549 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 27DBB60350 for ; Wed, 6 Sep 2017 12:26:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F05AA28BC0 for ; Wed, 6 Sep 2017 12:26:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E54E728BC3; Wed, 6 Sep 2017 12:26:27 +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=ham 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 87B3428BC0 for ; Wed, 6 Sep 2017 12:26:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753496AbdIFM0Z (ORCPT ); Wed, 6 Sep 2017 08:26:25 -0400 Received: from mail-wm0-f41.google.com ([74.125.82.41]:34990 "EHLO mail-wm0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753484AbdIFM0Y (ORCPT ); Wed, 6 Sep 2017 08:26:24 -0400 Received: by mail-wm0-f41.google.com with SMTP id f199so8823717wme.0 for ; Wed, 06 Sep 2017 05:26:23 -0700 (PDT) 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=lqafpuMGG1uLdP0yI1kXtklV1aWB62cc8H7kMTyoVHg=; b=I2FAnVDf4V0ieTDx2yW4xnhbHkwKJtbWdG67n71jM61NjSttOe/cmYiqULpJ4x2Lik iENVvzEnVftik+q4fYNaAKVXVHsMfAviSHZ5JmD5tgDUla4zjdEjF6mrLWq55oRxUULW AQH7YPl83j4/5BU6r8KsifGdnbozbizQ+E3Jg= 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=lqafpuMGG1uLdP0yI1kXtklV1aWB62cc8H7kMTyoVHg=; b=Yhj323hR9wkCBgHlcGEjnVdyX5z6X0Y/pwo+Jb0vZFLhv3uqTgJppgYW2XbVemKTqB 3Fxw20tsulP1SG+Oi9jxPGorr34D6pYe4AM83lU7iUUiq9idISpv8MyjhX9CzQCxM3OD kq5DX8e8DjxqzY4oF9XceKgYJ+geBl3gewcoV6kdSOegLw1EXwg+HEX2Hx5WB9dtRmrc iX1bPmBHtNia9BGWiq9ceBb+PwKznOeEJSQPOF9rBvBvqyrpGQ3ZB9tSEyGA6Q6bahuy xtyx1VASz48V4IbSfcxvVkuMeNCi0h7EBdXZmk0ZTyHVSvodUJKUCoWxVizSCHykQQE5 5Wug== X-Gm-Message-State: AHPjjUgamOb4mzc2OVk8K0q8oCpm93j/7+gpyTFIr6vLpyAkTG3uDC5n iob0+G0irdepBBO0 X-Google-Smtp-Source: ADKCNb54RwFAzwYuQr7R9m7b0kwjEoq/yX7JzQ2h4/TZoRoHNs1mhX6BcY0nZUf6DHWfwH5HbzRBgQ== X-Received: by 10.80.187.46 with SMTP id y43mr674174ede.137.1504700782780; Wed, 06 Sep 2017 05:26:22 -0700 (PDT) Received: from localhost.localdomain (xd93ddc2d.cust.hiper.dk. [217.61.220.45]) by smtp.gmail.com with ESMTPSA id e12sm1251954edm.85.2017.09.06.05.26.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 06 Sep 2017 05:26:21 -0700 (PDT) From: Christoffer Dall To: kvmarm@lists.cs.columbia.edu, Eric Auger , Marc Zyngier Cc: Andre Przywara , linux-arm-kernel@lists.infradead.org, kvm@vger.kernel.org, Christoffer Dall Subject: [PATCH v3 1/5] KVM: arm/arm64: Don't cache the timer IRQ level Date: Wed, 6 Sep 2017 14:26:08 +0200 Message-Id: <20170906122612.18050-2-cdall@linaro.org> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170906122612.18050-1-cdall@linaro.org> References: <20170906122612.18050-1-cdall@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 was modeled after a strict idea of modelling an interrupt line level in software, meaning that only transitions in the level needed 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 for level triggered mapped interrupts to the GIC, 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 on every entry to the guest, and the VGIC can ignore notifications using its validate mechanism. Signed-off-by: Christoffer Dall --- virt/kvm/arm/arch_timer.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 8e89d63..2a5f877 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c @@ -219,9 +219,10 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level, int ret; timer_ctx->active_cleared_last = false; + if (timer_ctx->irq.level != new_level) + trace_kvm_timer_update_irq(vcpu->vcpu_id, timer_ctx->irq.irq, + new_level); timer_ctx->irq.level = new_level; - trace_kvm_timer_update_irq(vcpu->vcpu_id, timer_ctx->irq.irq, - timer_ctx->irq.level); if (likely(irqchip_in_kernel(vcpu->kvm))) { ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, @@ -241,6 +242,7 @@ 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 userspace modified the timer registers via SET_ONE_REG before @@ -251,11 +253,11 @@ static void kvm_timer_update_state(struct kvm_vcpu *vcpu) if (unlikely(!timer->enabled)) return; - if (kvm_timer_should_fire(vtimer) != vtimer->irq.level) - kvm_timer_update_irq(vcpu, !vtimer->irq.level, vtimer); + 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); + level = kvm_timer_should_fire(ptimer); + kvm_timer_update_irq(vcpu, level, ptimer); } /* Schedule the background timer for the emulated timer. */