hvm/hpet: Prevent master clock equal to comparator while enabled
authorDon Slutz <dslutz@verizon.com>
Fri, 2 May 2014 20:18:07 +0000 (16:18 -0400)
committerTim Deegan <tim@xen.org>
Thu, 8 May 2014 11:03:53 +0000 (12:03 +0100)
commit62d514c2e7943490ffdc140996c02c9ba2059790
treeed15172beec62f76fb8c6d069f8dfa4c8f27b3c4
parentd03f3f93888e837e1ed2f98d9a6254ee177988eb
hvm/hpet: Prevent master clock equal to comparator while enabled

Based on the software-developers-hpet-spec-1-0a.pdf, the comparator
for a periodic timer will change to the new value when it matches
the master clock.  The current code here uses a very standard
rounding formula of "((x + y - 1) / y) * y".  This is wrong because
in this case you need to go to the next comparator value when "x"
equals "y". Not when "x + 1" equals "y".  In this case "y" is the
period and "x" is the master clock.

The code lines:

    elapsed = hpet_read_maincounter(h, guest_time) +
        period - 1 - comparator;
    comparator += (elapsed / period) * period;

are what matter here.

Using some numbers to help show the issue:

hpet_read_maincounter(h, guest_time) = 130252
period = 62500

comparator       : 130252
elapsed          : 62499
elapsed/period   : 0
comparator_delta : 0
new comparator   : 130252

Signed-off-by: Don Slutz <dslutz@verizon.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Tim Deegan <tim@xen.org>
xen/arch/x86/hvm/hpet.c