aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2011-11-09 05:18:09 +0400
committerAnthony Liguori <aliguori@us.ibm.com>2011-11-09 12:06:20 -0600
commit4f61927a41a098d06e642ffdea5fc285dc3a0e6b (patch)
treed713bf00ea6d6c8e2d0bf0039b7a53605807abdc /hw
parentc0465d1a1d4c9562cfa7e91f6c31ea1bce22052c (diff)
hpet: fix infinite loop in qemu_run_timers with -icount enabled
hpet_timer timer callback rearms itself based on difference between current HPET tick counter and comparator value. Difference calculated by the hpet_calculate_diff function is limited to non-negative values. cur_tick is calculated via hpet_get_ticks that uses qemu_get_clock_ns(vm_clock). With -icount enabled vm_clock doesn't advance during qemu_run_timers loop thus once difference is zero, qemu_run_timers loops forever handling hpet_timer. Limit hpet_calculate_diff results to positive only values to avoid that infinite loop. This fixes the following qemu-system-x86_64 hang when it reaches timer_irq_works() in the linux bootup: [ 0.000000] Fast TSC calibration using PIT [ 0.000000] Detected 1000.054 MHz processor. [ 0.000031] Calibrating delay loop (skipped), value calculated using timer frequency.. 2000.10 BogoMIPS (lpj=10000540) [ 0.000404] pid_max: default: 32768 minimum: 301 [ 0.001138] Mount-cache hash table entries: 256 [ 0.003883] Initializing cgroup subsys ns [ 0.004035] Initializing cgroup subsys cpuacct [ 0.004280] Initializing cgroup subsys freezer [ 0.004790] Performance Events: AMD PMU driver. [ 0.004985] ... version: 0 [ 0.005134] ... bit width: 48 [ 0.005285] ... generic registers: 4 [ 0.005437] ... value mask: 0000ffffffffffff [ 0.005625] ... max period: 00007fffffffffff [ 0.005807] ... fixed-purpose events: 0 [ 0.005957] ... event mask: 000000000000000f [ 0.006275] SMP alternatives: switching to UP code Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/hpet.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/hw/hpet.c b/hw/hpet.c
index 12bd64d8b1..6e6ea520bc 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -157,14 +157,14 @@ static inline uint64_t hpet_calculate_diff(HPETTimer *t, uint64_t current)
cmp = (uint32_t)t->cmp;
diff = cmp - (uint32_t)current;
- diff = (int32_t)diff > 0 ? diff : (uint32_t)0;
+ diff = (int32_t)diff > 0 ? diff : (uint32_t)1;
return (uint64_t)diff;
} else {
uint64_t diff, cmp;
cmp = t->cmp;
diff = cmp - current;
- diff = (int64_t)diff > 0 ? diff : (uint64_t)0;
+ diff = (int64_t)diff > 0 ? diff : (uint64_t)1;
return diff;
}
}