9ae3a8
From 5918245d224a7a527052ed30af2627187777a282 Mon Sep 17 00:00:00 2001
9ae3a8
From: Richard Jones <rjones@redhat.com>
9ae3a8
Date: Wed, 1 Nov 2017 11:33:01 +0100
9ae3a8
Subject: [PATCH 6/7] i6300esb: fix timer overflow
9ae3a8
9ae3a8
RH-Author: Richard Jones <rjones@redhat.com>
9ae3a8
Message-id: <1509535982-27927-3-git-send-email-rjones@redhat.com>
9ae3a8
Patchwork-id: 77460
9ae3a8
O-Subject: [RHEL-7.5 qemu-kvm PATCH v3 2/3] i6300esb: fix timer overflow
9ae3a8
Bugzilla: 1470244
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
RH-Acked-by: Thomas Huth <thuth@redhat.com>
9ae3a8
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
9ae3a8
From: Laurent Vivier <lvivier@redhat.com>
9ae3a8
9ae3a8
We use muldiv64() to compute the time to wait:
9ae3a8
9ae3a8
    timeout = muldiv64(get_ticks_per_sec(), timeout, 33000000);
9ae3a8
9ae3a8
but get_ticks_per_sec() is 10^9 (30 bit value) and timeout
9ae3a8
is a 35 bit value.
9ae3a8
9ae3a8
Whereas muldiv64 is:
9ae3a8
9ae3a8
    uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
9ae3a8
9ae3a8
So we loose 3 bits of timeout.
9ae3a8
9ae3a8
Swapping get_ticks_per_sec() and timeout fixes it.
9ae3a8
9ae3a8
We can also replace it by a multiplication by 30 ns,
9ae3a8
but this changes PCI clock frequency from 33MHz to 33.333333MHz
9ae3a8
and we need to do this on all the QEMU PCI devices (later...)
9ae3a8
9ae3a8
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
9ae3a8
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
9ae3a8
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
9ae3a8
(cherry picked from commit fee562e9e41290a22623de83b673a8929ec5280d)
9ae3a8
9ae3a8
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1470244
9ae3a8
Upstream-status: fee562e9e41290a22623de83b673a8929ec5280d
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 hw/watchdog/wdt_i6300esb.c | 2 +-
9ae3a8
 1 file changed, 1 insertion(+), 1 deletion(-)
9ae3a8
9ae3a8
diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
9ae3a8
index be35034..fa8e3b9 100644
9ae3a8
--- a/hw/watchdog/wdt_i6300esb.c
9ae3a8
+++ b/hw/watchdog/wdt_i6300esb.c
9ae3a8
@@ -132,7 +132,7 @@ static void i6300esb_restart_timer(I6300State *d, int stage)
9ae3a8
      * multiply here can exceed 64-bits, before we divide by 33MHz, so
9ae3a8
      * we use a higher-precision intermediate result.
9ae3a8
      */
9ae3a8
-    timeout = muldiv64(get_ticks_per_sec(), timeout, 33000000);
9ae3a8
+    timeout = muldiv64(timeout, get_ticks_per_sec(), 33000000);
9ae3a8
 
9ae3a8
     i6300esb_debug("stage %d, timeout %" PRIi64 "\n", d->stage, timeout);
9ae3a8
 
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8