If gt_timer is enabled before cval initialization on a virtualized setup on QEMU, cval equals (UINT64_MAX - 1). Adding an offset value to this causes an overflow that sets timer into the past, which leads to infinite loop, because this timer fires immediately and calls gt_recalc_timer() once more, which in turn sets the timer into the past again and as a result, QEMU hangs. This patch adds check for overflowing of the nexttick variable.
Suggested-by: Volodymyr Babchuk <volodymyr_babc...@epam.com> Co-Authored-By: Dmytro Firsov <dmytro_fir...@epam.com> Signed-off-by: Leonid Komarianskyi <leonid_komarians...@epam.com> --- target/arm/helper.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/target/arm/helper.c b/target/arm/helper.c index 3b22596eab..b4aaa2965b 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -2665,6 +2665,16 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx) } else { /* Next transition is when we hit cval */ nexttick = gt->cval + offset; + if (nexttick < gt->cval) { + /* + * If gt->cval value is close to UINT64_MAX then adding + * to it offset can lead to overflow of nexttick variable. + * So, this check tests that arguments sum is less than any + * addend, and in case it is overflowed we have to mod timer + * to INT64_MAX. + */ + nexttick = UINT64_MAX; + } } /* * Note that the desired next expiry time might be beyond the -- 2.25.1