From mboxrd@z Thu Jan 1 00:00:00 1970 From: Don Slutz Subject: [PATCH v3 08/11] hvm/hpet: Use signed divide in hpet_get_comparator. Date: Thu, 17 Apr 2014 13:43:02 -0400 Message-ID: <1397756585-27091-9-git-send-email-dslutz@verizon.com> References: <1397756585-27091-1-git-send-email-dslutz@verizon.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1397756585-27091-1-git-send-email-dslutz@verizon.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: Keir Fraser , Don Slutz , Jan Beulich List-Id: xen-devel@lists.xenproject.org This is done so that when comparator is less then or equal to one period it does not change. The code lines: elapsed = hpet_read_maincounter(h, guest_time) + period - 1 - comparator; comparator += (elapsed / period) * period; are what matter here. For almost all cases where "hpet_read_maincounter() + period - 1" is greater then "comparator", a signed divide will produce the same answer as an unsigned divide. One of the problem areas is when "hpet_read_maincounter() + period - 1" needs more then 64 bits to represent it. It includes cases where hpet_read_maincounter() has wrapped (I.E. needs more then 64 bits to correctly represent it), but "comparator" has not wrapped. However "elapsed" is correctly greater then zero as long as the mathematical result only takes 63 bits to represent it. It is safe to declare period as a signed integer because the code already limits it to 63 bits. Using some numbers to help show the issue: hpet_read_maincounter(h, guest_time) = 67752 period = 62500 comparator = 130252 == 67752 + 62500 what unsigned signed comparator : 130252 130252 elapsed : 18446744073709551615 -1 elapsed/period : 295147905179352 0 comparator_delta : 18446744073709500000 0 new comparator : 78636 130252 Signed-off-by: Don Slutz --- xen/arch/x86/hvm/hpet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c index 7964df2..e24bc46 100644 --- a/xen/arch/x86/hvm/hpet.c +++ b/xen/arch/x86/hvm/hpet.c @@ -89,13 +89,13 @@ static uint64_t hpet_get_comparator(HPETState *h, unsigned int tn, uint64_t guest_time) { uint64_t comparator; - uint64_t elapsed; + int64_t elapsed; comparator = h->hpet.comparator64[tn]; if ( timer_is_periodic(h, tn) ) { /* update comparator by number of periods elapsed since last update */ - uint64_t period = h->hpet.period[tn]; + int64_t period = h->hpet.period[tn]; if (period) { elapsed = hpet_read_maincounter(h, guest_time) + -- 1.8.4