[kernel] r19751 - in dists/squeeze/linux-2.6/debian: . patches/bugfix/s390 patches/series

Ben Hutchings benh at alioth.debian.org
Sat Jan 19 19:57:58 UTC 2013


Author: benh
Date: Sat Jan 19 19:57:57 2013
New Revision: 19751

Log:
[s390] s390/time: fix sched_clock() overflow

Added:
   dists/squeeze/linux-2.6/debian/patches/bugfix/s390/s390-time-fix-sched_clock-overflow.patch
   dists/squeeze/linux-2.6/debian/patches/series/48
Modified:
   dists/squeeze/linux-2.6/debian/changelog

Modified: dists/squeeze/linux-2.6/debian/changelog
==============================================================================
--- dists/squeeze/linux-2.6/debian/changelog	Sat Jan 19 19:29:08 2013	(r19750)
+++ dists/squeeze/linux-2.6/debian/changelog	Sat Jan 19 19:57:57 2013	(r19751)
@@ -1,3 +1,10 @@
+linux-2.6 (2.6.32-48) UNRELEASED; urgency=low
+
+  [ Ben Hutchings ]
+  * [s390] s390/time: fix sched_clock() overflow
+
+ -- Ben Hutchings <ben at decadent.org.uk>  Sat, 19 Jan 2013 19:57:27 +0000
+
 linux-2.6 (2.6.32-47) stable; urgency=low
 
   [ Ben Hutchings ]

Added: dists/squeeze/linux-2.6/debian/patches/bugfix/s390/s390-time-fix-sched_clock-overflow.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/bugfix/s390/s390-time-fix-sched_clock-overflow.patch	Sat Jan 19 19:57:57 2013	(r19751)
@@ -0,0 +1,84 @@
+From: Heiko Carstens <heiko.carstens at de.ibm.com>
+Date: Mon, 14 Jan 2013 16:55:55 +0100
+Subject: s390/time: fix sched_clock() overflow
+
+commit ed4f20943cd4c7b55105c04daedf8d63ab6d499c upstream.
+
+Converting a 64 Bit TOD format value to nanoseconds means that the value
+must be divided by 4.096. In order to achieve that we multiply with 125
+and divide by 512.
+When used within sched_clock() this triggers an overflow after appr.
+417 days. Resulting in a sched_clock() return value that is much smaller
+than previously and therefore may cause all sort of weird things in
+subsystems that rely on a monotonic sched_clock() behaviour.
+
+To fix this implement a tod_to_ns() helper function which converts TOD
+values without overflow and call this function from both places that
+open coded the conversion: sched_clock() and kvm_s390_handle_wait().
+
+Reviewed-by: Martin Schwidefsky <schwidefsky at de.ibm.com>
+Signed-off-by: Heiko Carstens <heiko.carstens at de.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky at de.ibm.com>
+---
+ arch/s390/include/asm/timex.h |   28 ++++++++++++++++++++++++++++
+ arch/s390/kernel/time.c       |    2 +-
+ arch/s390/kvm/interrupt.c     |    2 +-
+ 3 files changed, 30 insertions(+), 2 deletions(-)
+
+--- a/arch/s390/include/asm/timex.h
++++ b/arch/s390/include/asm/timex.h
+@@ -112,4 +112,32 @@ static inline unsigned long long get_clock_monotonic(void)
+ 	return get_clock_xt() - sched_clock_base_cc;
+ }
+ 
++/**
++ * tod_to_ns - convert a TOD format value to nanoseconds
++ * @todval: to be converted TOD format value
++ * Returns: number of nanoseconds that correspond to the TOD format value
++ *
++ * Converting a 64 Bit TOD format value to nanoseconds means that the value
++ * must be divided by 4.096. In order to achieve that we multiply with 125
++ * and divide by 512:
++ *
++ *    ns = (todval * 125) >> 9;
++ *
++ * In order to avoid an overflow with the multiplication we can rewrite this.
++ * With a split todval == 2^32 * th + tl (th upper 32 bits, tl lower 32 bits)
++ * we end up with
++ *
++ *    ns = ((2^32 * th + tl) * 125 ) >> 9;
++ * -> ns = (2^23 * th * 125) + ((tl * 125) >> 9);
++ *
++ */
++static inline unsigned long long tod_to_ns(unsigned long long todval)
++{
++	unsigned long long ns;
++
++	ns = ((todval >> 32) << 23) * 125;
++	ns += ((todval & 0xffffffff) * 125) >> 9;
++	return ns;
++}
++
+ #endif
+--- a/arch/s390/kernel/time.c
++++ b/arch/s390/kernel/time.c
+@@ -69,7 +69,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators);
+  */
+ unsigned long long notrace sched_clock(void)
+ {
+-	return (get_clock_monotonic() * 125) >> 9;
++	return tod_to_ns(get_clock_monotonic());
+ }
+ 
+ /*
+--- a/arch/s390/kvm/interrupt.c
++++ b/arch/s390/kvm/interrupt.c
+@@ -357,7 +357,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
+ 		return 0;
+ 	}
+ 
+-	sltime = ((vcpu->arch.sie_block->ckc - now)*125)>>9;
++	sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
+ 
+ 	hrtimer_start(&vcpu->arch.ckc_timer, ktime_set (0, sltime) , HRTIMER_MODE_REL);
+ 	VCPU_EVENT(vcpu, 5, "enabled wait via clock comparator: %llx ns", sltime);

Added: dists/squeeze/linux-2.6/debian/patches/series/48
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/squeeze/linux-2.6/debian/patches/series/48	Sat Jan 19 19:57:57 2013	(r19751)
@@ -0,0 +1 @@
++ bugfix/s390/s390-time-fix-sched_clock-overflow.patch



More information about the Kernel-svn-changes mailing list