• James Hogan's avatar
    MIPS: KVM: Fix timer IRQ race when freezing timer · 4355c44f
    James Hogan authored
    There's a particularly narrow and subtle race condition when the
    software emulated guest timer is frozen which can allow a guest timer
    interrupt to be missed.
    
    This happens due to the hrtimer expiry being inexact, so very
    occasionally the freeze time will be after the moment when the emulated
    CP0_Count transitions to the same value as CP0_Compare (so an IRQ should
    be generated), but before the moment when the hrtimer is due to expire
    (so no IRQ is generated). The IRQ won't be generated when the timer is
    resumed either, since the resume CP0_Count will already match CP0_Compare.
    
    With VZ guests in particular this is far more likely to happen, since
    the soft timer may be frozen frequently in order to restore the timer
    state to the hardware guest timer. This happens after 5-10 hours of
    guest soak testing, resulting in an overflow in guest kernel timekeeping
    calculations, hanging the guest. A more focussed test case to
    intentionally hit the race (with the help of a new hypcall to cause the
    timer state to migrated between hardware & software) hits the condition
    fairly reliably within around 30 seconds.
    
    Instead of relying purely on the inexact hrtimer expiry to determine
    whether an IRQ should be generated, read the guest CP0_Compare and
    directly check whether the freeze time is before or after it. Only if
    CP0_Count is on or after CP0_Compare do we check the hrtimer expiry to
    determine whether the last IRQ has already been generated (which will
    have pushed back the expiry by one timer period).
    
    Fixes: e30492bb ("MIPS: KVM: Rewrite count/compare timer emulation")
    Signed-off-by: default avatarJames Hogan <james.hogan@imgtec.com>
    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Cc: "Radim KrčmáÅ" <rkrcmar@redhat.com>
    Cc: Ralf Baechle <ralf@linux-mips.org>
    Cc: linux-mips@linux-mips.org
    Cc: kvm@vger.kernel.org
    Cc: <stable@vger.kernel.org> # 3.16.x-
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    4355c44f
emulate.c 69 KB