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: 9488711 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 BFA3B60838 for ; Mon, 26 Dec 2016 17:27:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B2FCF26223 for ; Mon, 26 Dec 2016 17:27:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A6126204C1; Mon, 26 Dec 2016 17:27:33 +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=-3.7 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_SPAM autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2A364204C1 for ; Mon, 26 Dec 2016 17:27:33 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1cLZ2H-0005HK-3t; Mon, 26 Dec 2016 17:26:09 +0000 Received: from outprodmail02.cc.columbia.edu ([128.59.72.51]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1cLZ10-0003Y0-8t for linux-arm-kernel@lists.infradead.org; Mon, 26 Dec 2016 17:24:53 +0000 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 uBQHM5XT032472 for ; Mon, 26 Dec 2016 12:24:24 -0500 Received: from hazelnut (localhost.localdomain [127.0.0.1]) by hazelnut (Postfix) with ESMTP id 16A846D for ; Mon, 26 Dec 2016 12:24:24 -0500 (EST) Received: from sendprodmail02.cc.columbia.edu (sendprodmail02.cc.columbia.edu [128.59.72.14]) by hazelnut (Postfix) with ESMTP id E48BA85 for ; Mon, 26 Dec 2016 12:24:23 -0500 (EST) Received: from mail-qt0-f199.google.com (mail-qt0-f199.google.com [209.85.216.199]) by sendprodmail02.cc.columbia.edu (8.14.4/8.14.4) with ESMTP id uBQHONXN015351 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NOT) for ; Mon, 26 Dec 2016 12:24:23 -0500 Received: by mail-qt0-f199.google.com with SMTP id c47so65160543qtc.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=nA8vyyAeFpW6b0gEP8+LPJ+qBJfKSoQvMcZlNNVk5t8QMsM+uYZYTIv9gL618QimgE aaQro+USfGXXxkHN7P4miIgpHSeoueOSs8aRbncPJERJNXf+V+vi3wUbEd4LQEZIu1Mq okL1nKaK53vmCB1ChOIw2XEaSt+BkrSPkhdCQ0gF2BCWyixjRmgB//93iN/wdN+EQDVF aG0Es6P4Q2gNUaLGKUIE1m0rBbgf1UH1xlyFBwRAND54lmm5zf+GFpPkvdQ93/pLLvc8 OlzPrqeKeLWW1pp/EqJ+Dz77luq+4/u8j6ngecxq0lh1MCq5QdafqoSggbw9wxPbCJZk 5cNg== X-Gm-Message-State: AIkVDXI00eiB4o60hwLSFafOQwsyl2+IvCpn5uYhX0S6UkLPAKi9qF5xQBoo8LVIdRUUtj2zHfmM+NPUjJ7arTVvvOxlXGysFL8MKVR7Aofd+Lyc+9byVD7Z106oHNc2S2KvTLcFbD0Y8q+Wm5i5WGDc3aYtSna1sqlYIA== X-Received: by 10.200.42.93 with SMTP id l29mr29844052qtl.289.1482773063476; 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 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.14 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161226_092450_726151_67E51EB4 X-CRM114-Status: GOOD ( 18.68 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kvm@vger.kernel.org, rkrcmar@redhat.com, andre.przywara@arm.com, will.deacon@arm.com, linux@armlinux.org.uk, linux-kernel@vger.kernel.org, catalin.marinas@arm.com, pbonzini@redhat.com, Jintack Lim , linux-arm-kernel@lists.infradead.org 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 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.