• Nickolai Zeldovich's avatar
    kvm: fix i8254 counter 0 wraparound · d4b06c2d
    Nickolai Zeldovich authored
    The kvm i8254 emulation for counter 0 (but not for counters 1 and 2)
    has at least two bugs in mode 0:
    
    1. The OUT bit, computed by pit_get_out(), is never set high.
    
    2. The counter value, computed by pit_get_count(), wraps back around to
       the initial counter value, rather than wrapping back to 0xFFFF
       (which is the behavior described in the comment in __kpit_elapsed,
       the behavior implemented by qemu, and the behavior observed on AMD
       hardware).
    
    The bug stems from __kpit_elapsed computing the elapsed time mod the
    initial counter value (stored as nanoseconds in ps->period).  This is both
    unnecessary (none of the callers of kpit_elapsed expect the value to be
    at most the initial counter value) and incorrect (it causes pit_get_count
    to appear to wrap around to the initial counter value rather than 0xFFFF).
    Removing this mod from __kpit_elapsed fixes both of the above bugs.
    Signed-off-by: default avatarNickolai Zeldovich <nickolai@csail.mit.edu>
    Reviewed-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
    Signed-off-by: default avatarGleb Natapov <gleb@redhat.com>
    d4b06c2d
i8254.c 18.7 KB