KVM: arm64: Work around x1e's CNTVOFF_EL2 bogosity
authorMarc Zyngier <maz@kernel.org>
Tue, 17 Dec 2024 14:23:19 +0000 (14:23 +0000)
committerMarc Zyngier <maz@kernel.org>
Thu, 2 Jan 2025 19:19:10 +0000 (19:19 +0000)
commit0bc9a9e85fcf4ffb69846b961273fde4eb0d03ab
tree4ac9a821ff5cad979e7844d54a955d5757fe81ab
parentd1e37a50e1d781201768c89314532f6ab87e5a42
KVM: arm64: Work around x1e's CNTVOFF_EL2 bogosity

It appears that on Qualcomm's x1e CPU, CNTVOFF_EL2 doesn't really
work, specially with HCR_EL2.E2H=1.

A non-zero offset results in a screaming virtual timer interrupt,
to the tune of a few 100k interrupts per second on a 4 vcpu VM.
This is also evidenced by this CPU's inability to correctly run
any of the timer selftests.

The only case this doesn't break is when this register is set to 0,
which breaks VM migration.

When HCR_EL2.E2H=0, the timer seems to behave normally, and does
not result in an interrupt storm.

As a workaround, use the fact that this CPU implements FEAT_ECV,
and trap all accesses to the virtual timer and counter, keeping
CNTVOFF_EL2 set to zero, and emulate accesses to CVAL/TVAL/CTL
and the counter itself, fixing up the timer to account for the
missing offset.

And if you think this is disgusting, you'd probably be right.

Acked-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20241217142321.763801-12-maz@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/cputype.h
arch/arm64/kernel/cpu_errata.c
arch/arm64/kernel/image-vars.h
arch/arm64/kvm/arch_timer.c
arch/arm64/kvm/hyp/nvhe/timer-sr.c
arch/arm64/kvm/sys_regs.c
arch/arm64/tools/cpucaps
include/kvm/arm_arch_timer.h