• Christoffer Dall's avatar
    KVM: arm/arm64: Fix potential loss of ptimer interrupts · 7afc4ddb
    Christoffer Dall authored
    kvm_timer_update_state() is called when changing the phys timer
    configuration registers, either via vcpu reset, as a result of a trap
    from the guest, or when userspace programs the registers.
    
    phys_timer_emulate() is in turn called by kvm_timer_update_state() to
    either cancel an existing software timer, or program a new software
    timer, to emulate the behavior of a real phys timer, based on the change
    in configuration registers.
    
    Unfortunately, the interaction between these two functions left a small
    race; if the conceptual emulated phys timer should actually fire, but
    the soft timer hasn't executed its callback yet, we cancel the timer in
    phys_timer_emulate without injecting an irq.  This only happens if the
    check in kvm_timer_update_state is called before the timer should fire,
    which is relatively unlikely, but possible.
    
    The solution is to update the state of the phys timer after calling
    phys_timer_emulate, which will pick up the pending timer state and
    update the interrupt value.
    
    Note that this leaves the opportunity of raising the interrupt twice,
    once in the just-programmed soft timer, and once in
    kvm_timer_update_state.  Since this always happens synchronously with
    the VCPU execution, there is no harm in this, and the guest ever only
    sees a single timer interrupt.
    
    Cc: Stable <stable@vger.kernel.org> # 4.15+
    Signed-off-by: default avatarChristoffer Dall <christoffer.dall@arm.com>
    Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
    7afc4ddb
arch_timer.c 25.3 KB