From: Mostafa Saleh <smostafa@google.com>
To: linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev,
linux-arm-kernel@lists.infradead.org
Cc: maz@kernel.org, oupton@kernel.org, seiden@linux.ibm.com,
joey.gouly@arm.com, suzuki.poulose@arm.com,
yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org,
vdonnefort@google.com, tabba@google.com,
sebastianene@google.com, keirf@google.com,
Mostafa Saleh <smostafa@google.com>
Subject: [PATCH] KVM: arm64: Fix hvhe and broken CNTVOFF_EL2
Date: Thu, 6 Aug 2026 15:01:05 +0000 [thread overview]
Message-ID: <20260806150105.4010701-1-smostafa@google.com> (raw)
When running on a setup affected with broken CNTVOFF_EL2
(has_broken_cntvoff())
Booting with VHE or protected mode(nvhe) (id_aa64mmfr1.vh=0
and arm64_sw.hvhe=0) works fine.
However launching a protected VM with protected hvhe mode panics the
guest kernel:
[ 0.000000] Internal error: Oops - Undefined instruction: 0000000000000000 [#1] SMP
[ 0.000000] Modules linked in:
[ 0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.2.0-rc3-g05f75bd71e0e-dirty #29 PREEMPT
[ 0.000000] Hardware name: linux,dummy-virt (DT)
[ 0.000000] pstate: 000003c5 (nzcv DAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 0.000000] pc : arch_timer_shutdown_virt+0x4/0x1c
[ 0.000000] lr : arch_timer_starting_cpu+0x1c4/0x2d4
[ 0.000000] sp : ffffa6bd9a193c00
[ 0.000000] x29: ffffa6bd9a193c20 x28: ffffa6bd9a1bcf88 x27: 0000000000000000
[ 0.000000] x26: ffff00001be70dd8 x25: ffffa6bd99d85000 x24: ffffa6bd99d85ee4
[ 0.000000] x23: ffffa6bd99d85000 x22: ffffa6bd9a1499c0 x21: ffffa6bd9a1ab900
[ 0.000000] x20: 00ffffffffffffff x19: ffff00001be8b600 x18: 000000000000028c
[ 0.000000] x17: 00000000510f0010 x16: 00000000510f0010 x15: 00000000500f0000
[ 0.000000] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000018
[ 0.000000] x11: ffffa6bd9a8ac000 x10: 0000000000f0000f x9 : ffffffffffffffff
[ 0.000000] x8 : ffffa6bd98822e18 x7 : 0070752d65746174 x6 : 00111ff76e007261
[ 0.000000] x5 : ffffa6bd9ad68078 x4 : 0000000000000000 x3 : ffffa6bd98822a0c
[ 0.000000] x2 : 0000000000000073 x1 : 0000000000000001 x0 : ffff00001be8b600
[ 0.000000] Call trace:
[ 0.000000] arch_timer_shutdown_virt+0x4/0x1c (P)
[ 0.000000] cpuhp_invoke_callback+0x11c/0x280
[ 0.000000] cpuhp_issue_call+0x1e8/0x224
[ 0.000000] __cpuhp_setup_state_cpuslocked+0x1d8/0x2b8
[ 0.000000] __cpuhp_setup_state+0x50/0x74
[ 0.000000] arch_timer_register+0xc0/0x148
[ 0.000000] arch_timer_of_init+0x148/0x170
[ 0.000000] timer_probe+0x74/0x124
[ 0.000000] time_init+0x18/0x58
[ 0.000000] start_kernel+0x1c0/0x3ac
[ 0.000000] __primary_switched+0x88/0x90
[ 0.000000] Code: c80b7d2a 35ffffab 17ffffeb d503245f (d53be328)
And for non protected VMs seems to hang or progress really slowly.
The workaround avoids setting non-zero CNTVOFF_EL2 and trapping the
virtual counter to emulate the offset.
In the VHE path (timer_set_traps()), traps are only enabled when the
guest actually has a non-zero virtual timer offset.
However, __timer_enable_traps() in hyp/nvhe/timer-sr.c unconditionally
set CNTHCTL_EL1TVT and CNTHCTL_EL1TVCT whenever has_broken_cntvoff()
was true.
Which causes 2 issues:
1) Protected VMs: kvm_handle_pvm_sysreg() does not find "cntv_ctl_el0"
in pvm_sys_reg_descs and injects undefined instruction exceptions.
2) non-protected guests are trapped all the time even with offset of
zero.
Fix this by adding a check in __timer_enable_traps() similar to the one in
timer_set_traps()
Fixes: 0bc9a9e85fcf ("KVM: arm64: Work around x1e's CNTVOFF_EL2 bogosity")
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
arch/arm64/kvm/hyp/nvhe/timer-sr.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
index ff176f4ce7de..98b6e37ee8fa 100644
--- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
@@ -10,6 +10,7 @@
#include <asm/kvm_hyp.h>
#include <asm/kvm_mmu.h>
+#include <hyp/switch.h>
void __kvm_timer_set_cntvoff(u64 cntvoff)
{
@@ -63,7 +64,7 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
* Trap the virtual counter/timer if we have a broken cntvoff
* implementation.
*/
- if (has_broken_cntvoff())
+ if (has_broken_cntvoff() && hyp_timer_get_offset(vcpu_vtimer(vcpu)))
set |= CNTHCTL_EL1TVT | CNTHCTL_EL1TVCT;
sysreg_clear_set(cnthctl_el2, clr, set);
--
2.55.0.654.g21b8a5bc05-goog
next reply other threads:[~2026-08-06 15:01 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 15:01 Mostafa Saleh [this message]
2026-08-06 16:55 ` [PATCH] KVM: arm64: Fix hvhe and broken CNTVOFF_EL2 Fuad Tabba
2026-08-07 1:37 ` Yao Yuan
2026-08-07 10:50 ` Marc Zyngier
2026-08-07 15:27 ` Mostafa Saleh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260806150105.4010701-1-smostafa@google.com \
--to=smostafa@google.com \
--cc=catalin.marinas@arm.com \
--cc=joey.gouly@arm.com \
--cc=keirf@google.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=sebastianene@google.com \
--cc=seiden@linux.ibm.com \
--cc=suzuki.poulose@arm.com \
--cc=tabba@google.com \
--cc=vdonnefort@google.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox