Re: Broken udelay() on KVM host with a vcpu loaded

Will Deacon
2026-02-13T11:50:22Z

On Tue, Feb 10, 2026 at 07:54:36PM +0000, Marc Zyngier wrote:
> On Tue, 10 Feb 2026 15:58:14 +0000,
> Quentin Perret <qperret@google.com> wrote:
> >
> > Ouch, it does seem that the SET_ONE_REG stuff allows to mess with that
> > value _out of vcpu context_, so yeah userspace could change the value
> > while a vcpu thread is preempted in the middle of a udelay loop ...
>
> I don't think so. You can only do that on the vcpu fd, and if the vcpu
> is loaded, it means that you are already holding the vcpu mutex. And
> if you do that from the vcpu thread, then you already have done a
> vcpu_put().

Just working this through, I think you're right that the vCPU mutex
saves us here (thanks!), although that's because it's held across the
duration of the KVM_RUN ioctl() and not because of the vcpu_put() (which
would run off the back of the preempt notifier if we were preempted
anyway). It would be good to capture that in a comment if we go with
your approach of using the virtual counter on the host.

There's also a VM ioctl for messing with the offset
(KVM_ARM_SET_COUNTER_OFFSET) but that uses kvm_trylock_all_vcpus() so
it's fine.

Will