aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/time/ntp.c16
-rw-r--r--kernel/time/ntp_internal.h2
2 files changed, 10 insertions, 8 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index e947bfddd2c2..36f2ca09aa5e 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -16,6 +16,7 @@
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/rtc.h> 18#include <linux/rtc.h>
19#include <linux/math64.h>
19 20
20#include "ntp_internal.h" 21#include "ntp_internal.h"
21#include "timekeeping_internal.h" 22#include "timekeeping_internal.h"
@@ -394,10 +395,11 @@ ktime_t ntp_get_next_leap(void)
394 * 395 *
395 * Also handles leap second processing, and returns leap offset 396 * Also handles leap second processing, and returns leap offset
396 */ 397 */
397int second_overflow(unsigned long secs) 398int second_overflow(time64_t secs)
398{ 399{
399 s64 delta; 400 s64 delta;
400 int leap = 0; 401 int leap = 0;
402 s32 rem;
401 403
402 /* 404 /*
403 * Leap second processing. If in leap-insert state at the end of the 405 * Leap second processing. If in leap-insert state at the end of the
@@ -408,19 +410,19 @@ int second_overflow(unsigned long secs)
408 case TIME_OK: 410 case TIME_OK:
409 if (time_status & STA_INS) { 411 if (time_status & STA_INS) {
410 time_state = TIME_INS; 412 time_state = TIME_INS;
411 ntp_next_leap_sec = secs + SECS_PER_DAY - 413 div_s64_rem(secs, SECS_PER_DAY, &rem);
412 (secs % SECS_PER_DAY); 414 ntp_next_leap_sec = secs + SECS_PER_DAY - rem;
413 } else if (time_status & STA_DEL) { 415 } else if (time_status & STA_DEL) {
414 time_state = TIME_DEL; 416 time_state = TIME_DEL;
415 ntp_next_leap_sec = secs + SECS_PER_DAY - 417 div_s64_rem(secs + 1, SECS_PER_DAY, &rem);
416 ((secs+1) % SECS_PER_DAY); 418 ntp_next_leap_sec = secs + SECS_PER_DAY - rem;
417 } 419 }
418 break; 420 break;
419 case TIME_INS: 421 case TIME_INS:
420 if (!(time_status & STA_INS)) { 422 if (!(time_status & STA_INS)) {
421 ntp_next_leap_sec = TIME64_MAX; 423 ntp_next_leap_sec = TIME64_MAX;
422 time_state = TIME_OK; 424 time_state = TIME_OK;
423 } else if (secs % SECS_PER_DAY == 0) { 425 } else if (secs == ntp_next_leap_sec) {
424 leap = -1; 426 leap = -1;
425 time_state = TIME_OOP; 427 time_state = TIME_OOP;
426 printk(KERN_NOTICE 428 printk(KERN_NOTICE
@@ -431,7 +433,7 @@ int second_overflow(unsigned long secs)
431 if (!(time_status & STA_DEL)) { 433 if (!(time_status & STA_DEL)) {
432 ntp_next_leap_sec = TIME64_MAX; 434 ntp_next_leap_sec = TIME64_MAX;
433 time_state = TIME_OK; 435 time_state = TIME_OK;
434 } else if ((secs + 1) % SECS_PER_DAY == 0) { 436 } else if (secs == ntp_next_leap_sec) {
435 leap = 1; 437 leap = 1;
436 ntp_next_leap_sec = TIME64_MAX; 438 ntp_next_leap_sec = TIME64_MAX;
437 time_state = TIME_WAIT; 439 time_state = TIME_WAIT;
diff --git a/kernel/time/ntp_internal.h b/kernel/time/ntp_internal.h
index af924470eac0..d8a7c11fa71a 100644
--- a/kernel/time/ntp_internal.h
+++ b/kernel/time/ntp_internal.h
@@ -6,7 +6,7 @@ extern void ntp_clear(void);
6/* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */ 6/* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */
7extern u64 ntp_tick_length(void); 7extern u64 ntp_tick_length(void);
8extern ktime_t ntp_get_next_leap(void); 8extern ktime_t ntp_get_next_leap(void);
9extern int second_overflow(unsigned long secs); 9extern int second_overflow(time64_t secs);
10extern int ntp_validate_timex(struct timex *); 10extern int ntp_validate_timex(struct timex *);
11extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *); 11extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *);
12extern void __hardpps(const struct timespec64 *, const struct timespec64 *); 12extern void __hardpps(const struct timespec64 *, const struct timespec64 *);