diff options
author | Bharat Bhushan <r65777@freescale.com> | 2013-06-12 18:00:50 +0530 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2013-07-01 01:11:16 +0200 |
commit | ab8131afee34d6aa427bd56ac18c4d3b6df80728 (patch) | |
tree | a058046b9d6d557926841306dee6536c279b0164 | |
parent | f1ff0e89c8287de79c804ec7a50d43f39a9f65dc (diff) | |
download | qemu-ab8131afee34d6aa427bd56ac18c4d3b6df80728.zip qemu-ab8131afee34d6aa427bd56ac18c4d3b6df80728.tar.gz qemu-ab8131afee34d6aa427bd56ac18c4d3b6df80728.tar.bz2 |
booke_ppc: limit booke timer to max when timeout overflow
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>
Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r-- | hw/ppc/ppc_booke.c | 24 |
1 files changed, 20 insertions, 4 deletions
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. |