Skip to content
  • Peter Maydell's avatar
    target/arm: Handle overflow in calculation of next timer tick · 8d37a142
    Peter Maydell authored
    In commit edac4d8a back in 2015 when we added support for
    the virtual timer offset CNTVOFF_EL2, we didn't correctly update
    the timer-recalculation code that figures out when the timer
    interrupt is next going to change state. We got it wrong in
    two ways:
     * for the 0->1 transition, we didn't notice that gt->cval + offset
       can overflow a uint64_t
     * for the 1->0 transition, we didn't notice that the transition
       might now happen before the count rolls over, if offset > count
    
    In the former case, we end up trying to set the next interrupt
    for a time in the past, which results in QEMU hanging as the
    timer fires continuously.
    
    In the latter case, we would fail to update the interrupt
    status when we are supposed to.
    
    Fix the calculations in both cases.
    
    The test case is Alex Bennée's from the bug report, and tests
    the 0->1 transition overflow case.
    
    Fixes: edac4d8a ("target-arm: Add CNTVOFF_EL2")
    Cc: qemu-stable@nongnu.org
    Resolves: #60
    
    
    Signed-off-by: default avatarAlex Bennée <alex.bennee@linaro.org>
    Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
    Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
    Message-id: 20231120173506.3729884-1-peter.maydell@linaro.org
    Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
    8d37a142