From patchwork Thu Jan 12 12:38:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 13097919 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0F5B2C54EBC for ; Thu, 12 Jan 2023 12:39:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230155AbjALMjJ (ORCPT ); Thu, 12 Jan 2023 07:39:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60156 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230118AbjALMi6 (ORCPT ); Thu, 12 Jan 2023 07:38:58 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A65B4916B for ; Thu, 12 Jan 2023 04:38:57 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 2AA84B81E5E for ; Thu, 12 Jan 2023 12:38:56 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C1B71C433F1; Thu, 12 Jan 2023 12:38:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673527134; bh=kutdzrND1pid6FPUYt9eecsxom0FpIqL/qLgOv8lCl4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TED+bZMqOLy54eykQ0yuNM2Wt30FHtUyr64JzcKaM9YYOVthRasNEAoKqAjf+LVxV sGvjKsScjNDNRkHVJMI9J18zK394OBFvxqf6UUVxM7ema50HICVOLJrYHYBoTEKIJr vU0anSZHrY+xH0I36bHeK+GZu4OE8J/C8vER2AkIm2IBQ4NDBLMwp0cPH06qAz1tea RrS98p6yEJGryzeCMiROEhr3pcFSk9gakHvKAUuzGVdYTzroNUJIKxVuaHifndfCD/ Rl7+Kjg34lHFEFva+u1asWFpMC7lk9usTJlWYKaeC/yjq7gVaH8C9lDLzYRl392huM c1iHwcPopZ9Aw== Received: from sofa.misterjones.org ([185.219.108.64] helo=valley-girl.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1pFwr6-001BBa-N4; Thu, 12 Jan 2023 12:38:52 +0000 From: Marc Zyngier To: linux-arm-kernel@lists.infradead.org, , , kvm@vger.kernel.org Cc: D Scott Phillips , Ganapatrao Kulkarni , James Morse , Suzuki K Poulose , Oliver Upton , Zenghui Yu Subject: [PATCH 1/3] KVM: arm64: Don't arm a hrtimer for an already pending timer Date: Thu, 12 Jan 2023 12:38:27 +0000 Message-Id: <20230112123829.458912-2-maz@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230112123829.458912-1-maz@kernel.org> References: <20230112123829.458912-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 185.219.108.64 X-SA-Exim-Rcpt-To: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvmarm@lists.linux.dev, kvm@vger.kernel.org, scott@os.amperecomputing.com, gankulkarni@os.amperecomputing.com, james.morse@arm.com, suzuki.poulose@arm.com, oliver.upton@linux.dev, yuzenghui@huawei.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org When fully emulating a timer, we back it with a hrtimer that is armver on vcpu_load(). However, we do this even if the timer is already pending. This causes spurious interrupts to be taken, though the guest doesn't observe them (the interrupt is already pending). Although this is a waste of precious cycles, this isn't the end of the world with the current state of KVM. However, this can lead to a situation where a guest doesn't make forward progress anymore with NV. Fix it by checking that if the timer is already pending before arming a new hrtimer. Also drop the hrtimer cancelling, which is useless, by construction. Reported-by: D Scott Phillips Fixes: bee038a67487 ("KVM: arm/arm64: Rework the timer code to use a timer_map") Signed-off-by: Marc Zyngier --- arch/arm64/kvm/arch_timer.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index bb24a76b4224..587d87aec33f 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -428,10 +428,8 @@ static void timer_emulate(struct arch_timer_context *ctx) * scheduled for the future. If the timer cannot fire at all, * then we also don't need a soft timer. */ - if (!kvm_timer_irq_can_fire(ctx)) { - soft_timer_cancel(&ctx->hrtimer); + if (should_fire || !kvm_timer_irq_can_fire(ctx)) return; - } soft_timer_start(&ctx->hrtimer, kvm_timer_compute_delta(ctx)); } From patchwork Thu Jan 12 12:38:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 13097920 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 42A0FC54EBC for ; Thu, 12 Jan 2023 12:39:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230497AbjALMjN (ORCPT ); Thu, 12 Jan 2023 07:39:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230245AbjALMi6 (ORCPT ); Thu, 12 Jan 2023 07:38:58 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A6F249171 for ; Thu, 12 Jan 2023 04:38:57 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 20EFAB81DD5 for ; Thu, 12 Jan 2023 12:38:56 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BA016C433F0; Thu, 12 Jan 2023 12:38:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673527134; bh=QuIuSKe9BuOyhqawV9dcZNTeA/CmLCt8kn8h7pV5oaI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=acgsMkEjh8QKqnh2cuwadHbb4yl8y5ty0LuiVviZKQ/oHTxgo+A/liLeGuX8Q/osi BGq+3UZyMVOkDcOs6XYAnibun6s16Hyt5XRxGr2zxAkzn4DV4oag1srgJqOYrMoCzj vDjaaAZG9YltT2s7riMaiwMgnOrOqbyFNLICKsNAilBvlgL6e0TaTWtsTPFQLocC8q hndLOTuVHIOMbhLoxeS2lUQpnQjaothczFaBZQL18ENylv6XonhtY4SZkVYIY6igx5 JdqZIj51epDo3/qjjNtcEjvVJtcve+jBjscpClg4p7izek1cfPfJ7yuFP+nLOLIgWx Z0GEkHZeP8MfA== Received: from sofa.misterjones.org ([185.219.108.64] helo=valley-girl.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1pFwr6-001BBa-Tz; Thu, 12 Jan 2023 12:38:52 +0000 From: Marc Zyngier To: linux-arm-kernel@lists.infradead.org, , , kvm@vger.kernel.org Cc: D Scott Phillips , Ganapatrao Kulkarni , James Morse , Suzuki K Poulose , Oliver Upton , Zenghui Yu Subject: [PATCH 2/3] KVM: arm64: Reduce overhead of trapped timer sysreg accesses Date: Thu, 12 Jan 2023 12:38:28 +0000 Message-Id: <20230112123829.458912-3-maz@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230112123829.458912-1-maz@kernel.org> References: <20230112123829.458912-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 185.219.108.64 X-SA-Exim-Rcpt-To: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvmarm@lists.linux.dev, kvm@vger.kernel.org, scott@os.amperecomputing.com, gankulkarni@os.amperecomputing.com, james.morse@arm.com, suzuki.poulose@arm.com, oliver.upton@linux.dev, yuzenghui@huawei.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Each read/write to a trapped timer system register results in a whole kvm_timer_vcpu_put/load() cycle which affects all of the timers, and a bit more. There is no need for such a thing, and we can limit the impact to the timer being affected, and only this one. This drastically simplifies the emulated case, and limits the damage for trapped accesses. This also brings some performance back for NV. Whilst we're at it, fix a comment that didn't quite capture why we always set CNTVOFF_EL2 to 0 when disabling the virtual timer. Signed-off-by: Marc Zyngier --- arch/arm64/kvm/arch_timer.c | 73 ++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 587d87aec33f..1a1d7e258aba 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -434,6 +434,11 @@ static void timer_emulate(struct arch_timer_context *ctx) soft_timer_start(&ctx->hrtimer, kvm_timer_compute_delta(ctx)); } +static void set_cntvoff(u64 cntvoff) +{ + kvm_call_hyp(__kvm_timer_set_cntvoff, cntvoff); +} + static void timer_save_state(struct arch_timer_context *ctx) { struct arch_timer_cpu *timer = vcpu_timer(ctx->vcpu); @@ -457,6 +462,22 @@ static void timer_save_state(struct arch_timer_context *ctx) write_sysreg_el0(0, SYS_CNTV_CTL); isb(); + /* + * The kernel may decide to run userspace after + * calling vcpu_put, so we reset cntvoff to 0 to + * ensure a consistent read between user accesses to + * the virtual counter and kernel access to the + * physical counter of non-VHE case. + * + * For VHE, the virtual counter uses a fixed virtual + * offset of zero, so no need to zero CNTVOFF_EL2 + * register, but this is actually useful when switching + * between EL1/vEL2 with NV. + * + * Do it unconditionally, as this is either unavoidable + * or dirt cheap. + */ + set_cntvoff(0); break; case TIMER_PTIMER: timer_set_ctl(ctx, read_sysreg_el0(SYS_CNTP_CTL)); @@ -530,6 +551,7 @@ static void timer_restore_state(struct arch_timer_context *ctx) switch (index) { case TIMER_VTIMER: + set_cntvoff(timer_get_offset(ctx)); write_sysreg_el0(timer_get_cval(ctx), SYS_CNTV_CVAL); isb(); write_sysreg_el0(timer_get_ctl(ctx), SYS_CNTV_CTL); @@ -550,11 +572,6 @@ static void timer_restore_state(struct arch_timer_context *ctx) local_irq_restore(flags); } -static void set_cntvoff(u64 cntvoff) -{ - kvm_call_hyp(__kvm_timer_set_cntvoff, cntvoff); -} - static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active) { int r; @@ -629,8 +646,6 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu) kvm_timer_vcpu_load_nogic(vcpu); } - set_cntvoff(timer_get_offset(map.direct_vtimer)); - kvm_timer_unblocking(vcpu); timer_restore_state(map.direct_vtimer); @@ -686,15 +701,6 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu) if (kvm_vcpu_is_blocking(vcpu)) kvm_timer_blocking(vcpu); - - /* - * The kernel may decide to run userspace after calling vcpu_put, so - * we reset cntvoff to 0 to ensure a consistent read between user - * accesses to the virtual counter and kernel access to the physical - * counter of non-VHE case. For VHE, the virtual counter uses a fixed - * virtual offset of zero, so no need to zero CNTVOFF_EL2 register. - */ - set_cntvoff(0); } /* @@ -924,14 +930,22 @@ u64 kvm_arm_timer_read_sysreg(struct kvm_vcpu *vcpu, enum kvm_arch_timers tmr, enum kvm_arch_timer_regs treg) { + struct arch_timer_context *timer; + struct timer_map map; u64 val; + get_timer_map(vcpu, &map); + timer = vcpu_get_timer(vcpu, tmr); + + if (timer == map.emul_ptimer) + return kvm_arm_timer_read(vcpu, timer, treg); + preempt_disable(); - kvm_timer_vcpu_put(vcpu); + timer_save_state(timer); - val = kvm_arm_timer_read(vcpu, vcpu_get_timer(vcpu, tmr), treg); + val = kvm_arm_timer_read(vcpu, timer, treg); - kvm_timer_vcpu_load(vcpu); + timer_restore_state(timer); preempt_enable(); return val; @@ -965,13 +979,22 @@ void kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu, enum kvm_arch_timer_regs treg, u64 val) { - preempt_disable(); - kvm_timer_vcpu_put(vcpu); - - kvm_arm_timer_write(vcpu, vcpu_get_timer(vcpu, tmr), treg, val); + struct arch_timer_context *timer; + struct timer_map map; - kvm_timer_vcpu_load(vcpu); - preempt_enable(); + get_timer_map(vcpu, &map); + timer = vcpu_get_timer(vcpu, tmr); + if (timer == map.emul_ptimer) { + soft_timer_cancel(&timer->hrtimer); + kvm_arm_timer_write(vcpu, timer, treg, val); + timer_emulate(timer); + } else { + preempt_disable(); + timer_save_state(timer); + kvm_arm_timer_write(vcpu, timer, treg, val); + timer_restore_state(timer); + preempt_enable(); + } } static int kvm_timer_starting_cpu(unsigned int cpu) From patchwork Thu Jan 12 12:38:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 13097918 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 31355C54EBC for ; Thu, 12 Jan 2023 12:39:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229920AbjALMjH (ORCPT ); Thu, 12 Jan 2023 07:39:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60160 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230187AbjALMi6 (ORCPT ); Thu, 12 Jan 2023 07:38:58 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C99874917D for ; Thu, 12 Jan 2023 04:38:57 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 83AE1B81E60 for ; Thu, 12 Jan 2023 12:38:56 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2239FC433EF; Thu, 12 Jan 2023 12:38:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673527135; bh=TEld5/eWLZ8WYi+kitrePlcWShsqcZJpPVEOUZjvFFI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vEM1wAB4VmrHlB3wy0Rl6rFU9Q5d1dk8qZ8H/1COQWeuz/uTsY4AqHBPLc5qxJqdH zg9aHY6D3oLFdaLLf60jHj/h6CEVYyALEH4cYmu+pwQPkO2bGib6Bj68zkHSF7K5vd HB/o4GO4S1E/j5JEg25mPHY0qUq2I3y121JgFQPPXIgb2wLbSZuhsnCMnwxc5/PGyE 4iHua27VRt3fNhd1ixu78U58BWS8PVrlQcBcOW6Srg59Mw3F3uxWcdX3xt+Jl4NH92 qJj3wBJtlnyeHDSP3syEF8tuU2dAHx0udVR3pRoiBf7YA85VZ4+dXJiG1OKQa1sGPH 6Zg2uUJGW82hg== Received: from sofa.misterjones.org ([185.219.108.64] helo=valley-girl.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1pFwr7-001BBa-3w; Thu, 12 Jan 2023 12:38:53 +0000 From: Marc Zyngier To: linux-arm-kernel@lists.infradead.org, , , kvm@vger.kernel.org Cc: D Scott Phillips , Ganapatrao Kulkarni , James Morse , Suzuki K Poulose , Oliver Upton , Zenghui Yu Subject: [PATCH 3/3] KVM: arm64: timers: Don't BUG() on unhandled timer trap Date: Thu, 12 Jan 2023 12:38:29 +0000 Message-Id: <20230112123829.458912-4-maz@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230112123829.458912-1-maz@kernel.org> References: <20230112123829.458912-1-maz@kernel.org> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 185.219.108.64 X-SA-Exim-Rcpt-To: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvmarm@lists.linux.dev, kvm@vger.kernel.org, scott@os.amperecomputing.com, gankulkarni@os.amperecomputing.com, james.morse@arm.com, suzuki.poulose@arm.com, oliver.upton@linux.dev, yuzenghui@huawei.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Although not handling a trap is a pretty bad situation to be in, panicing the kernel isn't useful and provides no valuable information to help debugging the situation. Instead, dump the encoding of the unhandled sysreg, and inject an UNDEF in the guest. At least, this gives a user an opportunity to report the issue with some information to help debugging it. Signed-off-by: Marc Zyngier --- arch/arm64/kvm/sys_regs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index d5ee52d6bf73..32f4e424b9a5 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1049,7 +1049,9 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu, treg = TIMER_REG_CVAL; break; default: - BUG(); + print_sys_reg_msg(p, "%s", "Unhandled trapped timer register"); + kvm_inject_undefined(vcpu); + return false; } if (p->is_write)