From patchwork Mon Dec 26 17:12:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jintack Lim X-Patchwork-Id: 9488683 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 8397862AAD for ; Mon, 26 Dec 2016 17:24:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 77AE4204C1 for ; Mon, 26 Dec 2016 17:24:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6AECA26224; Mon, 26 Dec 2016 17:24:25 +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=-6.4 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM 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 B91F026223 for ; Mon, 26 Dec 2016 17:24:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755427AbcLZRYV (ORCPT ); Mon, 26 Dec 2016 12:24:21 -0500 Received: from outprodmail02.cc.columbia.edu ([128.59.72.51]:54298 "EHLO outprodmail02.cc.columbia.edu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755411AbcLZRYT (ORCPT ); Mon, 26 Dec 2016 12:24:19 -0500 Received: from hazelnut (hazelnut.cc.columbia.edu [128.59.213.250]) by outprodmail02.cc.columbia.edu (8.14.4/8.14.4) with ESMTP id uBQHM5Vh032480 for ; Mon, 26 Dec 2016 12:24:18 -0500 Received: from hazelnut (localhost.localdomain [127.0.0.1]) by hazelnut (Postfix) with ESMTP id A8BAE84 for ; Mon, 26 Dec 2016 12:24:18 -0500 (EST) Received: from sendprodmail04.cc.columbia.edu (sendprodmail04.cc.columbia.edu [128.59.72.16]) by hazelnut (Postfix) with ESMTP id 8135885 for ; Mon, 26 Dec 2016 12:24:18 -0500 (EST) Received: from mail-qt0-f199.google.com (mail-qt0-f199.google.com [209.85.216.199]) by sendprodmail04.cc.columbia.edu (8.14.4/8.14.4) with ESMTP id uBQHOII5052943 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 26 Dec 2016 12:24:18 -0500 Received: by mail-qt0-f199.google.com with SMTP id c47so65159851qtc.4 for ; Mon, 26 Dec 2016 09:24:18 -0800 (PST) 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=0yF8BJnPtRYEpTBT7goqjgm1wiXAUj//LS5Ur+m34XE=; b=NEHBOqrC5X86oH6l4ENxhPlDvvkx/QecnSUNp7HE0NkzIpunQdhgg7xHMTS75afVk4 NrPikSaX+nzPhg5wJiojFW5e/anBldApk+ruzzWSXHui4nruJNK6nhVXqsjwb8B2WIkR Zi6VzhbDiY3/28M607YDo/pdINnI9R8kH/rqZt4sm6bL2wzZujNRQeAq343QgEZ4E1ku zY2E/jqAYwGLBqTwP9+++I3PhHMfn1QxJwzs3JV7hwd2+4J+BF8pJpS4PVDUNKpLE0xf dT+0b8cVl2/GUfRSSZLs6O034Wc2mU7Nx4xhWiZthV9Upm3Bg5J65XJlUAfWzIE0kg03 Ztfw== X-Gm-Message-State: AIkVDXILvgXmi5621w3hggllWNQU68QPhIUe+eNv3qWat5R4G/ZCOZC89LKMfrjdaT0uAJyx5PbHM7lYMlPWIABjQ0TGSoTCa40Huqg+ecr0HlKqNATDJ4pKc67/dQNzpVY8Z4tbBNqU848= X-Received: by 10.55.112.65 with SMTP id l62mr31471581qkc.76.1482773058091; Mon, 26 Dec 2016 09:24:18 -0800 (PST) X-Received: by 10.55.112.65 with SMTP id l62mr31471563qkc.76.1482773057911; Mon, 26 Dec 2016 09:24:17 -0800 (PST) Received: from jintack.cs.columbia.edu ([2001:18d8:ffff:16:21a:4aff:feaa:f900]) by smtp.gmail.com with ESMTPSA id n79sm26731463qkn.15.2016.12.26.09.24.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 26 Dec 2016 09:24:17 -0800 (PST) From: Jintack Lim To: kvmarm@lists.cs.columbia.edu, christoffer.dall@linaro.org, marc.zyngier@arm.com Cc: pbonzini@redhat.com, rkrcmar@redhat.com, linux@armlinux.org.uk, catalin.marinas@arm.com, will.deacon@arm.com, andre.przywara@arm.com, linux-arm-kernel@lists.infradead.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Jintack Lim Subject: [RFC 2/8] KVM: arm/arm64: Decouple kvm timer functions from virtual timer Date: Mon, 26 Dec 2016 12:12:00 -0500 Message-Id: <1482772326-29110-3-git-send-email-jintack@cs.columbia.edu> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1482772326-29110-1-git-send-email-jintack@cs.columbia.edu> References: <1482772326-29110-1-git-send-email-jintack@cs.columbia.edu> X-No-Spam-Score: Local X-Scanned-By: MIMEDefang 2.78 on 128.59.72.16 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Now that we have a separate structure for timer context, make functions general so that they can work on any timer context, not just the virtual timer context. This does not change the virtual timer functionality. Signed-off-by: Jintack Lim --- arch/arm/kvm/arm.c | 2 +- include/kvm/arm_arch_timer.h | 3 +- virt/kvm/arm/arch_timer.c | 65 +++++++++++++++++++++++++------------------- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 19b5f5c..37d1623 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -295,7 +295,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) { - return kvm_timer_should_fire(vcpu); + return kvm_timer_should_fire(vcpu, vcpu_vtimer(vcpu)); } void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h index 7dabe56..cf84145 100644 --- a/include/kvm/arm_arch_timer.h +++ b/include/kvm/arm_arch_timer.h @@ -69,7 +69,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid); int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value); -bool kvm_timer_should_fire(struct kvm_vcpu *vcpu); +bool kvm_timer_should_fire(struct kvm_vcpu *vcpu, + struct arch_timer_context *timer_ctx); void kvm_timer_schedule(struct kvm_vcpu *vcpu); void kvm_timer_unschedule(struct kvm_vcpu *vcpu); diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 30a64df..3bd6063 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c @@ -91,7 +91,7 @@ static void kvm_timer_inject_irq_work(struct work_struct *work) vcpu = container_of(work, struct kvm_vcpu, arch.timer_cpu.expired); vcpu->arch.timer_cpu.armed = false; - WARN_ON(!kvm_timer_should_fire(vcpu)); + WARN_ON(!kvm_timer_should_fire(vcpu, vcpu_vtimer(vcpu))); /* * If the vcpu is blocked we want to wake it up so that it will see @@ -100,12 +100,22 @@ static void kvm_timer_inject_irq_work(struct work_struct *work) kvm_vcpu_kick(vcpu); } -static u64 kvm_timer_compute_delta(struct kvm_vcpu *vcpu) +static u64 kvm_timer_cntvoff(struct kvm_vcpu *vcpu, + struct arch_timer_context *timer_ctx) +{ + if (timer_ctx == vcpu_vtimer(vcpu)) + return vcpu->kvm->arch.timer.cntvoff; + + return 0; +} + +static u64 kvm_timer_compute_delta(struct kvm_vcpu *vcpu, + struct arch_timer_context *timer_ctx) { cycle_t cval, now; - cval = vcpu_vtimer(vcpu)->cnt_cval; - now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; + cval = timer_ctx->cnt_cval; + now = kvm_phys_timer_read() - kvm_timer_cntvoff(vcpu, timer_ctx); if (now < cval) { u64 ns; @@ -134,7 +144,7 @@ static enum hrtimer_restart kvm_timer_expire(struct hrtimer *hrt) * PoV (NTP on the host may have forced it to expire * early). If we should have slept longer, restart it. */ - ns = kvm_timer_compute_delta(vcpu); + ns = kvm_timer_compute_delta(vcpu, vcpu_vtimer(vcpu)); if (unlikely(ns)) { hrtimer_forward_now(hrt, ns_to_ktime(ns)); return HRTIMER_RESTART; @@ -144,42 +154,40 @@ static enum hrtimer_restart kvm_timer_expire(struct hrtimer *hrt) return HRTIMER_NORESTART; } -static bool kvm_timer_irq_can_fire(struct kvm_vcpu *vcpu) +static bool kvm_timer_irq_can_fire(struct arch_timer_context *timer_ctx) { - struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); - - return !(vtimer->cnt_ctl & ARCH_TIMER_CTRL_IT_MASK) && - (vtimer->cnt_ctl & ARCH_TIMER_CTRL_ENABLE); + return !(timer_ctx->cnt_ctl & ARCH_TIMER_CTRL_IT_MASK) && + (timer_ctx->cnt_ctl & ARCH_TIMER_CTRL_ENABLE); } -bool kvm_timer_should_fire(struct kvm_vcpu *vcpu) +bool kvm_timer_should_fire(struct kvm_vcpu *vcpu, + struct arch_timer_context *timer_ctx) { - struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); cycle_t cval, now; - if (!kvm_timer_irq_can_fire(vcpu)) + if (!kvm_timer_irq_can_fire(timer_ctx)) return false; - cval = vtimer->cnt_cval; - now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; + cval = timer_ctx->cnt_cval; + now = kvm_phys_timer_read() - kvm_timer_cntvoff(vcpu, timer_ctx); return cval <= now; } -static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level) +static void kvm_timer_update_mapped_irq(struct kvm_vcpu *vcpu, bool new_level, + struct arch_timer_context *timer_ctx) { int ret; - struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); BUG_ON(!vgic_initialized(vcpu->kvm)); - vtimer->active_cleared_last = false; - vtimer->irq.level = new_level; - trace_kvm_timer_update_irq(vcpu->vcpu_id, vtimer->irq.irq, - vtimer->irq.level); + timer_ctx->active_cleared_last = false; + timer_ctx->irq.level = new_level; + trace_kvm_timer_update_irq(vcpu->vcpu_id, timer_ctx->irq.irq, + timer_ctx->irq.level); ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id, - vtimer->irq.irq, - vtimer->irq.level); + timer_ctx->irq.irq, + timer_ctx->irq.level); WARN_ON(ret); } @@ -200,8 +208,8 @@ static int kvm_timer_update_state(struct kvm_vcpu *vcpu) if (!vgic_initialized(vcpu->kvm) || !vtimer->enabled) return -ENODEV; - if (kvm_timer_should_fire(vcpu) != vtimer->irq.level) - kvm_timer_update_irq(vcpu, !vtimer->irq.level); + if (kvm_timer_should_fire(vcpu, vtimer) != vtimer->irq.level) + kvm_timer_update_mapped_irq(vcpu, !vtimer->irq.level, vtimer); return 0; } @@ -214,6 +222,7 @@ static int kvm_timer_update_state(struct kvm_vcpu *vcpu) void kvm_timer_schedule(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; + struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); BUG_ON(timer_is_armed(timer)); @@ -222,18 +231,18 @@ void kvm_timer_schedule(struct kvm_vcpu *vcpu) * already expired, because kvm_vcpu_block will return before putting * the thread to sleep. */ - if (kvm_timer_should_fire(vcpu)) + if (kvm_timer_should_fire(vcpu, vtimer)) return; /* * If the timer is not capable of raising interrupts (disabled or * masked), then there's no more work for us to do. */ - if (!kvm_timer_irq_can_fire(vcpu)) + if (!kvm_timer_irq_can_fire(vtimer)) return; /* The timer has not yet expired, schedule a background timer */ - timer_arm(timer, kvm_timer_compute_delta(vcpu)); + timer_arm(timer, kvm_timer_compute_delta(vcpu, vtimer)); } void kvm_timer_unschedule(struct kvm_vcpu *vcpu)