diff mbox

booke_ppc: limit booke timer to max when timeout overflow

Message ID 1371040250-23336-1-git-send-email-Bharat.Bhushan@freescale.com
State New
Headers show

Commit Message

Bharat Bhushan June 12, 2013, 12:30 p.m. UTC
Limit watchdog and fit timer to maximum timeout value which
qemu timer can support (INT64_MAX). This maximum timeout will be
hundreds of years, so limiting to max timeout is pretty safe.

Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
 hw/ppc/ppc_booke.c |   24 ++++++++++++++++++++----
 1 files changed, 20 insertions(+), 4 deletions(-)

Comments

Alexander Graf June 20, 2013, 10:46 p.m. UTC | #1
On 12.06.2013, at 14:30, Bharat Bhushan wrote:

> Limit watchdog and fit timer to maximum timeout value which
> qemu timer can support (INT64_MAX). This maximum timeout will be
> hundreds of years, so limiting to max timeout is pretty safe.
> 
> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>

Thanks, applied to ppc-next.


Alex
diff mbox

Patch

diff --git a/hw/ppc/ppc_booke.c b/hw/ppc/ppc_booke.c
index e41b036..000c27f 100644
--- a/hw/ppc/ppc_booke.c
+++ b/hw/ppc/ppc_booke.c
@@ -131,17 +131,33 @@  static void booke_update_fixed_timer(CPUPPCState         *env,
                                      struct QEMUTimer *timer)
 {
     ppc_tb_t *tb_env = env->tb_env;
-    uint64_t lapse;
+    uint64_t delta_tick, ticks = 0;
     uint64_t tb;
-    uint64_t period = 1 << (target_bit + 1);
+    uint64_t period;
     uint64_t now;
 
     now = qemu_get_clock_ns(vm_clock);
     tb  = cpu_ppc_get_tb(tb_env, now, tb_env->tb_offset);
+    period = 1ULL << target_bit;
+    delta_tick = period - (tb & (period - 1));
 
-    lapse = period - ((tb - (1 << target_bit)) & (period - 1));
+    /* the timer triggers only when the selected bit toggles from 0 to 1 */
+    if (tb & period) {
+        ticks = period;
+    }
 
-    *next = now + muldiv64(lapse, get_ticks_per_sec(), tb_env->tb_freq);
+    if (ticks + delta_tick < ticks) {
+        /* Overflow, so assume the biggest number we can express. */
+        ticks = UINT64_MAX;
+    } else {
+        ticks += delta_tick;
+    }
+
+    *next = now + muldiv64(ticks, get_ticks_per_sec(), tb_env->tb_freq);
+    if ((*next < now) || (*next > INT64_MAX)) {
+        /* Overflow, so assume the biggest number the qemu timer supports. */
+        *next = INT64_MAX;
+    }
 
     /* XXX: If expire time is now. We can't run the callback because we don't
      * have access to it. So we just set the timer one nanosecond later.