From: Don Slutz Date: Fri, 2 May 2014 20:18:06 +0000 (-0400) Subject: hvm/hpet: comparator can only change when master clock is enabled. X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=d03f3f93888e837e1ed2f98d9a6254ee177988eb;p=people%2Froyger%2Fxen.git hvm/hpet: comparator can only change when master clock is enabled. This is based on software-developers-hpet-spec-1-0a.pdf saying: When the main counter value matches the value in the timer's comparator register, an interrupt can be generated. The hardware will then automatically increase the value in the compare register by the last value written to that register. When the overall enable is off (the main count is halted), none of the compare registers should change. The code lines: elapsed = hpet_read_maincounter(h, guest_time) + period - 1 - comparator; comparator += (elapsed / period) * period; are what matter here. They will always adjust comparator to be no more then one period away. Using some numbers to help show the issue: hpet_read_maincounter(h, guest_time) = 67752 period = 62500 comparator = 255252 == 67752 + 3 * 62500 comparator : 255252 elapsed : -125001 elapsed/period : -2 comparator_delta : -125000 new comparator : 130252 Signed-off-by: Don Slutz Acked-by: Jan Beulich Acked-by: Tim Deegan --- diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c index 741fb7ae9d..f938da977a 100644 --- a/xen/arch/x86/hvm/hpet.c +++ b/xen/arch/x86/hvm/hpet.c @@ -92,7 +92,7 @@ static uint64_t hpet_get_comparator(HPETState *h, unsigned int tn, uint64_t elapsed; comparator = h->hpet.comparator64[tn]; - if ( timer_is_periodic(h, tn) ) + if ( hpet_enabled(h) && timer_is_periodic(h, tn) ) { /* update comparator by number of periods elapsed since last update */ uint64_t period = h->hpet.period[tn];