From patchwork Mon Dec 26 17:12:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jintack Lim X-Patchwork-Id: 9488697 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 C2305604B9 for ; Mon, 26 Dec 2016 17:24:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B56C6204C1 for ; Mon, 26 Dec 2016 17:24:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A917C26224; Mon, 26 Dec 2016 17:24:41 +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 32B65204C1 for ; Mon, 26 Dec 2016 17:24:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755443AbcLZRYi (ORCPT ); Mon, 26 Dec 2016 12:24:38 -0500 Received: from outprodmail01.cc.columbia.edu ([128.59.72.39]:49627 "EHLO outprodmail01.cc.columbia.edu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755451AbcLZRYZ (ORCPT ); Mon, 26 Dec 2016 12:24:25 -0500 Received: from hazelnut (hazelnut.cc.columbia.edu [128.59.213.250]) by outprodmail01.cc.columbia.edu (8.14.4/8.14.4) with ESMTP id uBQHK6kn061710 for ; Mon, 26 Dec 2016 12:24:24 -0500 Received: from hazelnut (localhost.localdomain [127.0.0.1]) by hazelnut (Postfix) with ESMTP id 170F382 for ; Mon, 26 Dec 2016 12:24:24 -0500 (EST) Received: from sendprodmail04.cc.columbia.edu (sendprodmail04.cc.columbia.edu [128.59.72.16]) by hazelnut (Postfix) with ESMTP id DF4B781 for ; Mon, 26 Dec 2016 12:24:23 -0500 (EST) Received: from mail-qt0-f198.google.com (mail-qt0-f198.google.com [209.85.216.198]) by sendprodmail04.cc.columbia.edu (8.14.4/8.14.4) with ESMTP id uBQHONfN053033 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 26 Dec 2016 12:24:23 -0500 Received: by mail-qt0-f198.google.com with SMTP id c47so65160539qtc.4 for ; Mon, 26 Dec 2016 09:24:23 -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=041CGS9slIrH5DlwIoHQC0+p8J/9Xy/9j5Ivd/OKUAw=; b=YkAfsH7YNoxI26uHxTsNzX5GKQxum0nOf0w6hqTdCLbJxbEOWNOFNkXq2/B/+EcPSr zSfisxfP+Sw60+9gzG6WibSWXI3QVLdHOdhIG5vbVZqFnKS6nogHMiz5c1WyrJCAn29K tD/OZPoWlt5/DudazMQMS+WLJpUrHVUSTTAVFiPjATGwQmxjTvFGKcZ2z5Y3YdmfRs5B RoseEwNChmfCEZ6IkQ8MUsr9qxCgixcm0d12Bfu28YwtAbJqGXPWods4rDFtybrAJ93l z/kTcxiv+jBr084fFhVa1x5aezwZHjIyZhQwcNg2Sz514+cZ01go6Wce5Qso0kK9F0To odsg== X-Gm-Message-State: AIkVDXKTwgm4lrZy1L0lVFv586SmSze2aCl+uivqrwHkxvFbseDC7Gn2usWUkYWsMjqZW9dVkgO2ToPxLAdSYeT4ukK1T/NpN/B4Jb1ybSM2tXqS7u7Wo7M0/UFdlgkaBStb/m7RyGYgshc= X-Received: by 10.200.42.93 with SMTP id l29mr29844043qtl.289.1482773063472; Mon, 26 Dec 2016 09:24:23 -0800 (PST) X-Received: by 10.200.42.93 with SMTP id l29mr29844031qtl.289.1482773063219; Mon, 26 Dec 2016 09:24:23 -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.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 26 Dec 2016 09:24:22 -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 7/8] KVM: arm/arm64: Set up a background timer for the physical timer emulation Date: Mon, 26 Dec 2016 12:12:05 -0500 Message-Id: <1482772326-29110-8-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 Set a background timer for the EL1 physical timer emulation while VMs are running, so that VMs get interrupts for the physical timer in a timely manner. We still use just one background timer. When a VM is runnable, we use the background timer for the physical timer emulation. When the VM is about to be blocked, we use the background timer to wake up the vcpu at the earliest timer expiration among timers the VM is using. As a result, the assumption that the background timer is not armed while VMs are running does not hold any more. So, remove BUG_ON()s and WARN_ON()s accordingly. Signed-off-by: Jintack Lim --- virt/kvm/arm/arch_timer.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index aa7e243..be8d953 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c @@ -91,9 +91,6 @@ 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, vcpu_vtimer(vcpu)) && - !kvm_timer_should_fire(vcpu, vcpu_ptimer(vcpu))); - /* * If the vcpu is blocked we want to wake it up so that it will see * the timer has expired when entering the guest. @@ -139,7 +136,6 @@ static bool kvm_timer_irq_can_fire(struct arch_timer_context *timer_ctx) /* * Returns minimal timer expiration time in ns among guest timers. - * Note that it will return inf time if none of timers can fire. */ static u64 kvm_timer_min_block(struct kvm_vcpu *vcpu) { @@ -153,7 +149,9 @@ static u64 kvm_timer_min_block(struct kvm_vcpu *vcpu) if (kvm_timer_irq_can_fire(ptimer)) min_phys = kvm_timer_compute_delta(vcpu, ptimer); - WARN_ON((min_virt == ULLONG_MAX) && (min_phys == ULLONG_MAX)); + /* If none of timers can fire, then return 0 */ + if ((min_virt == ULLONG_MAX) && (min_phys == ULLONG_MAX)) + return 0; return min(min_virt, min_phys); } @@ -257,6 +255,26 @@ static int kvm_timer_update_state(struct kvm_vcpu *vcpu) } /* + * Schedule the background timer for the emulated timer. The background timer + * runs whenever vcpu is runnable and the timer is not expired. + */ +static void kvm_timer_emulate(struct kvm_vcpu *vcpu, + struct arch_timer_context *timer_ctx) +{ + struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; + + if (kvm_timer_should_fire(vcpu, timer_ctx)) + return; + + if (!kvm_timer_irq_can_fire(timer_ctx)) + return; + + /* The timer has not yet expired, schedule a background timer */ + timer_disarm(timer); + timer_arm(timer, kvm_timer_compute_delta(vcpu, timer_ctx)); +} + +/* * Schedule the background timer before calling kvm_vcpu_block, so that this * thread is removed from its waitqueue and made runnable when there's a timer * interrupt to handle. @@ -267,8 +285,6 @@ void kvm_timer_schedule(struct kvm_vcpu *vcpu) struct arch_timer_context *vtimer = vcpu_vtimer(vcpu); struct arch_timer_context *ptimer = vcpu_ptimer(vcpu); - BUG_ON(timer_is_armed(timer)); - /* * No need to schedule a background timer if any guest timer has * already expired, because kvm_vcpu_block will return before putting @@ -290,13 +306,21 @@ void kvm_timer_schedule(struct kvm_vcpu *vcpu) * The guest timers have not yet expired, schedule a background timer. * Pick smaller expiration time between phys and virt timer. */ + timer_disarm(timer); timer_arm(timer, kvm_timer_min_block(vcpu)); } void kvm_timer_unschedule(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; + timer_disarm(timer); + + /* + * Now we return from the blocking. If we have any timer to emulate, + * and it's not expired, set the background timer for it. + */ + kvm_timer_emulate(vcpu, vcpu_ptimer(vcpu)); } /** @@ -375,10 +399,6 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) */ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) { - struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; - - BUG_ON(timer_is_armed(timer)); - /* * The guest could have modified the timer registers or the timer * could have expired, update the timer state.