]> Git Repo - qemu.git/commitdiff
aspeed/timer: Ensure positive muldiv delta
authorChristian Svensson <[email protected]>
Mon, 1 Jul 2019 16:26:17 +0000 (17:26 +0100)
committerPeter Maydell <[email protected]>
Mon, 1 Jul 2019 16:28:59 +0000 (17:28 +0100)
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 delta being operated on is positive.

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]>
Reviewed-by: Joel Stanley <[email protected]>
Reviewed-by: Andrew Jeffery <[email protected]>
Message-id: 20190618165311[email protected]
Signed-off-by: Peter Maydell <[email protected]>
hw/timer/aspeed_timer.c

index 745eb8608b56bb4df8f7e7e765416706a303a37e..29cc5e807081bdc239fcb32297869b3875ca73f1 100644 (file)
@@ -275,7 +275,11 @@ 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);
+            if (delta >= 0) {
+                t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
+            } else {
+                t->start -= muldiv64(-delta, NANOSECONDS_PER_SECOND, rate);
+            }
             aspeed_timer_mod(t);
         }
         break;
This page took 0.021807 seconds and 4 git commands to generate.