// SPDX-License-Identifier: GPL-2.0
/*
* NTP state machine interfaces and logic.
*
* This code was mainly moved from kernel/timer.c and kernel/time.c
* Please see those files for relevant copyright info and historical
* changelogs.
*/
#include <linux/capability.h>
#include <linux/clocksource.h>
#include <linux/workqueue.h>
#include <linux/hrtimer.h>
#include <linux/jiffies.h>
#include <linux/math64.h>
#include <linux/timex.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/rtc.h>
#include <linux/audit.h>
#include "ntp_internal.h"
#include "timekeeping_internal.h"
/**
* struct ntp_data - Structure holding all NTP related state
* @tick_usec: USER_HZ period in microseconds
* @tick_length: Adjusted tick length
* @tick_length_base: Base value for @tick_length
* @time_state: State of the clock synchronization
* @time_status: Clock status bits
* @time_offset: Time adjustment in nanoseconds
* @time_constant: PLL time constant
* @time_maxerror: Maximum error in microseconds holding the NTP sync distance
* (NTP dispersion + delay / 2)
* @time_esterror: Estimated error in microseconds holding NTP dispersion
* @time_freq: Frequency offset scaled nsecs/secs
* @time_reftime: Time at last adjustment in seconds
* @time_adjust: Adjustment value
* @ntp_tick_adj: Constant boot-param configurable NTP tick adjustment (upscaled)
* @ntp_next_leap_sec: Second value of the next pending leapsecond, or TIME64_MAX if no leap
*
* @pps_valid: PPS signal watchdog counter
* @pps_tf: PPS phase median filter
* @pps_jitter: PPS current jitter in nanoseconds
* @pps_fbase: PPS beginning of the last freq interval
* @pps_shift: PPS current interval duration in seconds (shift value)
* @pps_intcnt: PPS interval counter
* @pps_freq: PPS frequency offset in scaled ns/s
* @pps_stabil: PPS current stability in scaled ns/s
* @pps_calcnt: PPS monitor: calibration intervals
* @pps_jitcnt: PPS monitor: jitter limit exceeded
* @pps_stbcnt: PPS monitor: stability limit exceeded
* @pps_errcnt: PPS monitor: calibration errors
*
* Protected by the timekeeping locks.
*/
struct ntp_data {
unsigned long tick_usec;
u64 tick_length;
u64 tick_length_base;
int time_state;
int time_status;
s64 time_offset;
long time_constant;
long time_maxerror;
long time_esterror;
s64 time_freq;
time64_t time_reftime;
long time_adjust;
s64 ntp_tick_adj;
time64_t ntp_next_leap_sec;
#ifdef CONFIG_NTP_PPS
int pps_valid;
long pps_tf[3];
long pps_jitter;
struct timespec64 pps_fbase;
int pps_shift;
int pps_intcnt;
s64 pps_freq;
long pps_stabil;
long pps_calcnt;
long pps_jitcnt;
long pps_stbcnt;
long pps_errcnt;
#endif
};
static struct ntp_data tk_ntp_data = {
.tick_usec = USER_TICK_USEC,
.time_state = TIME_OK,
.time_status = STA_UNSYNC,
.time_constant = 2,
.time_maxerror = NTP_PHASE_LIMIT,
.time_esterror = NTP_PHASE_LIMIT,
.ntp_next_leap_sec = TIME64_MAX,
};
#define SECS_PER_DAY 86400
#define MAX_TICKADJ 500LL /* usecs */
#define MAX_TICKADJ_SCALED \
(((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ)
#define MAX_TAI_OFFSET 100000
#ifdef CONFIG_NTP_PPS
/*
* The following variables are used when a pulse-per-second (PPS) signal
* is available. They establish the engineering parameters of the clock
* discipline loop when controlled by the PPS signal.
*/
#define PPS_VALID 10 /* PPS signal watchdog max (s) */
#define PPS_POPCORN 4 /* popcorn spike threshold (shift) */
#define PPS_INTMIN 2 /* min freq interval (s) (shift) */
#define PPS_INTMAX 8 /* max freq interval (s) (shift) */
#define PPS_INTCOUNT 4 /* number of consecutive good intervals to
increase pps_shift or consecutive bad
intervals to decrease it */
#define PPS_MAXWANDER 100000 /* max PPS freq wander (ns/s) */
/*
* PPS kernel consumer compensates the whole phase error immediately.
* Otherwise, reduce the offset by a fixed factor times the time constant.
*/
static inline s64 ntp_offset_chunk(struct ntp_data *ntpdata, s64 offset)
{
if (ntpdata->time_status & STA_PPSTIME && ntpdata->time_status & STA_PPSSIGNAL)
return offset;
else
return shift_right(offset, SHIFT_PLL + ntpdata->time_constant);
}
static inline void pps_reset_freq_interval(struct ntp_data *ntpdata)
{
/* The PPS calibration interval may end surprisingly early */
ntpdata->pps_shift = PPS_INTMIN;
ntpdata->pps_intcnt = 0;
}
/**
* pps_clear - Clears the PPS state variables
* @ntpdata: Pointer to ntp data
*/
static inline void pps_clear(struct ntp_data *ntpdata)
{
pps_reset_freq_interval(ntpdata);
ntpdata->pps_tf[0] = 0;
ntpdata->pps_tf[1] = 0;
ntpdata->pps_tf[2] = 0;
ntpdata->pps_fbase.tv_sec = ntpdata->pps_fbase.tv_nsec = 0;
ntpdata->pps_freq = 0;
}
/*
* Decrease pps_valid to indicate that another second has passed since the
* last PPS signal. When it reaches 0, indicate that PPS signal is missing.
*/
static inline void pps_dec_valid(struct ntp_data *ntpdata)
{
if (ntpdata->pps_valid > 0) {
ntpdata->pps_valid--;
} else {
ntpdata->time_status