Blob Blame History Raw
From 45383e6748287c088d09d7f94dfbac76c38e7329 Mon Sep 17 00:00:00 2001
From: David Hildenbrand <david@redhat.com>
Date: Fri, 21 Dec 2018 15:36:03 +0000
Subject: [PATCH 01/22] s390x/tcg: avoid overflows in time2tod/tod2time

RH-Author: David Hildenbrand <david@redhat.com>
Message-id: <20181221153614.27961-2-david@redhat.com>
Patchwork-id: 83744
O-Subject: [RHEL-8.0 qemu-kvm v2 PATCH 01/12] s390x/tcg: avoid overflows in time2tod/tod2time
Bugzilla: 1653569
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>

Big values for the TOD/ns clock can result in some overflows that can be
avoided. Not all overflows can be handled however, as the conversion either
multiplies by 4.096 or divided by 4.096.

Apply the trick used in the Linux kernel in arch/s390/include/asm/timex.h
for tod_to_ns() and use the same trick also for the conversion in the
other direction.

Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180627134410.4901-2-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 14055ce53c2d901d826ffad7fb7d6bb8ab46bdfd)
Signed-off-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
---
 target/s390x/internal.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index d911e84..d1ed06f 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -243,13 +243,14 @@ enum cc_op {
 /* Converts ns to s390's clock format */
 static inline uint64_t time2tod(uint64_t ns)
 {
-    return (ns << 9) / 125;
+    return (ns << 9) / 125 + (((ns & 0xff10000000000000ull) / 125) << 9);
+
 }
 
 /* Converts s390's clock format to ns */
 static inline uint64_t tod2time(uint64_t t)
 {
-    return (t * 125) >> 9;
+    return ((t >> 9) * 125) + (((t & 0x1ff) * 125) >> 9);
 }
 
 static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb,
-- 
1.8.3.1