Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1295202

[PATCH 03/11] time: Avoid signed overflow in timekeeping_get_ns()

From John Stultz <john.stultz@linaro.org>
Newsgroups linux.kernel
Subject [PATCH 03/11] time: Avoid signed overflow in timekeeping_get_ns()
Date 2015-12-18 22:50 +0100
Message-ID <qHb4t-2GQ-7@gated-at.bofh.it> (permalink)
References <qHaUO-2Dm-11@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


From: David Gibson <david@gibson.dropbear.id.au>

1e75fa8 "time: Condense timekeeper.xtime into xtime_sec" replaced a call to
clocksource_cyc2ns() from timekeeping_get_ns() with an open-coded version
of the same logic to avoid keeping a semi-redundant struct timespec
in struct timekeeper.

However, the commit also introduced a subtle semantic change - where
clocksource_cyc2ns() uses purely unsigned math, the new version introduces
a signed temporary, meaning that if (delta * tk->mult) has a 63-bit
overflow the following shift will still give a negative result.  The
choice of 'maxsec' in __clocksource_updatefreq_scale() means this will
generally happen if there's a ~10 minute pause in examining the
clocksource.

This can be triggered on a powerpc KVM guest by stopping it from qemu for
a bit over 10 minutes.  After resuming time has jumped backwards several
minutes causing numerous problems (jiffies does not advance, msleep()s can
be extended by minutes..).  It doesn't happen on x86 KVM guests, because
the guest TSC is effectively frozen while the guest is stopped, which is
not the case for the powerpc timebase.

Obviously an unsigned (64 bit) overflow will only take twice as long as a
signed, 63-bit overflow.  I don't know the time code well enough to know
if that will still cause incorrect calculations, or if a 64-bit overflow
is avoided elsewhere.

Still, an incorrect forwards clock adjustment will cause less trouble than
time going backwards.  So, this patch removes the potential for
intermediate signed overflow.

Cc: stable@vger.kernel.org  (3.7+ after 4.5-rc2)
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Suggested-by: Laurent Vivier <lvivier@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 kernel/time/timekeeping.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index d563c19..99188ee 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -305,8 +305,7 @@ static inline s64 timekeeping_get_ns(struct tk_read_base *tkr)
 
 	delta = timekeeping_get_delta(tkr);
 
-	nsec = delta * tkr->mult + tkr->xtime_nsec;
-	nsec >>= tkr->shift;
+	nsec = (delta * tkr->mult + tkr->xtime_nsec) >> tkr->shift;
 
 	/* If arch requires, add in get_arch_timeoffset() */
 	return nsec + arch_gettimeoffset();
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 00/11][GIT PULL] Timekeeping items for 4.5 John Stultz <john.stultz@linaro.org> - 2015-12-18 22:40 +0100
  [PATCH 07/11] time: Verify time values in adjtimex ADJ_SETOFFSET to avoid overflow John Stultz <john.stultz@linaro.org> - 2015-12-18 22:40 +0100
  [PATCH 06/11] ntp: Verify offset doesn't overflow in ntp_update_offset John Stultz <john.stultz@linaro.org> - 2015-12-18 22:40 +0100
  [PATCH 01/11] MAINTAINERS: Add entry for kernel/time/alarmtimer.c John Stultz <john.stultz@linaro.org> - 2015-12-18 22:50 +0100
  [PATCH 09/11] ntp: Change time_reftime to time64_t and utilize 64bit __ktime_get_real_seconds John Stultz <john.stultz@linaro.org> - 2015-12-18 22:50 +0100
  [PATCH 03/11] time: Avoid signed overflow in timekeeping_get_ns() John Stultz <john.stultz@linaro.org> - 2015-12-18 22:50 +0100
  [PATCH 04/11] clocksource: Add CPU info to clocksource watchdog reporting John Stultz <john.stultz@linaro.org> - 2015-12-18 22:50 +0100
  [PATCH 10/11] ntp: Fix second_overflow's input parameter type to be 64bits John Stultz <john.stultz@linaro.org> - 2015-12-18 22:50 +0100
  [PATCH 08/11] timekeeping: Provide internal function __ktime_get_real_seconds John Stultz <john.stultz@linaro.org> - 2015-12-18 22:50 +0100
  [PATCH 05/11] selftests/timers: fix write return value handlng John Stultz <john.stultz@linaro.org> - 2015-12-18 22:50 +0100
  [PATCH 02/11] alarmtimer: Avoid unexpected rtc interrupt when system resume from S3 John Stultz <john.stultz@linaro.org> - 2015-12-18 22:50 +0100

csiph-web