debuggers.hg
changeset 16735:1b2be7cf0b7b
hvm: hpet: Clamp period to sane values to prevent excessive looping in
hpet_timer_fn(), or excessive numbers of set_timer() callbacks.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
hpet_timer_fn(), or excessive numbers of set_timer() callbacks.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Jan 09 10:32:13 2008 +0000 (2008-01-09) |
parents | b5b3e27f1af3 |
children | f983aa8e4b26 |
files | xen/arch/x86/hvm/hpet.c |
line diff
1.1 --- a/xen/arch/x86/hvm/hpet.c Wed Jan 09 10:11:31 2008 +0000 1.2 +++ b/xen/arch/x86/hvm/hpet.c Wed Jan 09 10:32:13 2008 +0000 1.3 @@ -303,7 +303,10 @@ static void hpet_write( 1.4 } 1.5 1.6 if ( new_val & HPET_TN_32BIT ) 1.7 + { 1.8 h->hpet.timers[tn].cmp = (uint32_t)h->hpet.timers[tn].cmp; 1.9 + h->hpet.period[tn] = (uint32_t)h->hpet.period[tn]; 1.10 + } 1.11 1.12 break; 1.13 1.14 @@ -317,7 +320,17 @@ static void hpet_write( 1.15 (h->hpet.timers[tn].config & HPET_TN_SETVAL) ) 1.16 h->hpet.timers[tn].cmp = new_val; 1.17 else 1.18 + { 1.19 + /* 1.20 + * Clamp period to reasonable min/max values: 1.21 + * - minimum is 900us, same as timers controlled by vpt.c 1.22 + * - maximum is to prevent overflow in time_after() calculations 1.23 + */ 1.24 + if ( hpet_tick_to_ns(h, new_val) < MICROSECS(900) ) 1.25 + new_val = (MICROSECS(900) << 10) / h->hpet_to_ns_scale; 1.26 + new_val &= (timer_is_32bit(h, tn) ? ~0u : ~0ull) >> 1; 1.27 h->hpet.period[tn] = new_val; 1.28 + } 1.29 h->hpet.timers[tn].config &= ~HPET_TN_SETVAL; 1.30 if ( hpet_enabled(h) ) 1.31 hpet_set_timer(h, tn); 1.32 @@ -376,7 +389,7 @@ static void hpet_route_interrupt(HPETSta 1.33 return; 1.34 } 1.35 1.36 - /* We only support edge-triggered interrupt now */ 1.37 + /* We support only edge-triggered interrupt. */ 1.38 spin_lock(&d->arch.hvm_domain.irq_lock); 1.39 vioapic_irq_positive_edge(d, tn_int_route); 1.40 spin_unlock(&d->arch.hvm_domain.irq_lock); 1.41 @@ -401,20 +414,19 @@ static void hpet_timer_fn(void *opaque) 1.42 1.43 if ( timer_is_periodic(h, tn) && (h->hpet.period[tn] != 0) ) 1.44 { 1.45 - uint64_t mc = hpet_read_maincounter(h); 1.46 + uint64_t mc = hpet_read_maincounter(h), period = h->hpet.period[tn]; 1.47 if ( timer_is_32bit(h, tn) ) 1.48 { 1.49 while ( hpet_time_after(mc, h->hpet.timers[tn].cmp) ) 1.50 h->hpet.timers[tn].cmp = (uint32_t)( 1.51 - h->hpet.timers[tn].cmp + h->hpet.period[tn]); 1.52 + h->hpet.timers[tn].cmp + period); 1.53 } 1.54 else 1.55 { 1.56 while ( hpet_time_after64(mc, h->hpet.timers[tn].cmp) ) 1.57 - h->hpet.timers[tn].cmp += h->hpet.period[tn]; 1.58 + h->hpet.timers[tn].cmp += period; 1.59 } 1.60 - set_timer(&h->timers[tn], 1.61 - NOW() + hpet_tick_to_ns(h, h->hpet.period[tn])); 1.62 + set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, period)); 1.63 } 1.64 1.65 spin_unlock(&h->lock);