Broken udelay() on KVM host with a vcpu loaded

Quentin Perret
2026-02-10T12:27:54Z

Hi all,

I have just received a report from a partner of udelay misbehaving when
running on the host whilst a vCPU is loaded. This hardware has FEAT_WFxT
and uses the matching implementation of udelay. Interestingly, WFIT
triggers using CNTVCT_EL0 unconditionally, but with KVM the host/guest
switch for that happens from the preempt notifiers/vcpu_put which aren't
invoked when e.g. handling an IRQ. Interestingly, udelay reads the arch
timer to set the waiting time for WFIT using an absolute value, and that
gets compared to CNTVCT_EL0 which in the aforementioned
IRQ-with-vCPU-loaded case uses the _guest's_ CNTVCT_EL0.

I can think of two approaches to address the problem:
1. have KVM context switch cntvoff proactively prior to re-enabling
preemption when handling a guest exit;
2. modify the WFIT-based udelay implementation to read from CNTVCT_EL0
instead of the arch_timer to be a bit more self-consitent;

Other ideas welcome!

Thanks,
Quentin