--- /dev/null
+From d911e03d097bdc01363df5d81c43f69432eb785c Mon Sep 17 00:00:00 2001
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+Date: Tue, 29 Jan 2013 09:16:28 +0100
+Subject: s390/timer: avoid overflow when programming clock comparator
+
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+
+commit d911e03d097bdc01363df5d81c43f69432eb785c upstream.
+
+Since ed4f209 "s390/time: fix sched_clock() overflow" a new helper function
+is used to avoid overflows when converting TOD format values to nanosecond
+values.
+The kvm interrupt code formerly however only worked by accident because of
+an overflow. It tried to program a timer that would expire in more than ~29
+years. Because of the old TOD-to-nanoseconds overflow bug the real expiry
+value however was much smaller, but now it isn't anymore.
+This however triggers yet another bug in the function that programs the clock
+comparator s390_next_ktime(): if the absolute "expires" value is after 2042
+this will result in an overflow and the programmed value is lower than the
+current TOD value which immediatly triggers a clock comparator (= timer)
+interrupt.
+Since the timer isn't expired it will be programmed immediately again and so
+on... the result is a dead system.
+To fix this simply program the maximum possible value if an overflow is
+detected.
+
+Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/kernel/time.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/s390/kernel/time.c
++++ b/arch/s390/kernel/time.c
+@@ -121,6 +121,9 @@ static int s390_next_ktime(ktime_t expir
+ nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));
+ do_div(nsecs, 125);
+ S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9);
++ /* Program the maximum value if we have an overflow (== year 2042) */
++ if (unlikely(S390_lowcore.clock_comparator < sched_clock_base_cc))
++ S390_lowcore.clock_comparator = -1ULL;
+ set_clock_comparator(S390_lowcore.clock_comparator);
+ return 0;
+ }