Skip to content

Commit

Permalink
qemu: aspeed_timer: Use signed muldiv for timer resets
Browse files Browse the repository at this point in the history
If the host decrements the counter register that results in a negative
delta. This is then passed to muldiv64 which only handles unsigned
numbers resulting in bogus results.

This fix ensures the data being operated on is signed before it is
ultimately casted to the final unsigned value.

Test case: kexec a kernel using aspeed_timer and it will freeze on the
second bootup when the kernel initializes the timer. With this patch
that no longer happens and the timer appears to run OK.

Signed-off-by: Christian Svensson <[email protected]>
Signed-off-by: Cédric Le Goater <[email protected]>
  • Loading branch information
bluecmd authored and legoater committed Dec 12, 2018
1 parent 1b34d04 commit 5ff119d
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion hw/timer/aspeed_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg,
int64_t delta = (int64_t) value - (int64_t) calculate_ticks(t, now);
uint32_t rate = calculate_rate(t);

t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
t->start = (int64_t)t->start + ((__int128_t)delta * NANOSECONDS_PER_SECOND / rate);
aspeed_timer_mod(t);
}
break;
Expand Down

0 comments on commit 5ff119d

Please sign in to comment.