Commit 87ace39b authored by John Stultz's avatar John Stultz

ntp: Rework do_adjtimex to take timespec and tai arguments

In order to change the locking rules, we need to provide
the timespec and tai values rather then having the ntp
logic acquire these values itself.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
parent e4085693
...@@ -662,10 +662,8 @@ int ntp_validate_timex(struct timex *txc) ...@@ -662,10 +662,8 @@ int ntp_validate_timex(struct timex *txc)
* adjtimex mainly allows reading (and writing, if superuser) of * adjtimex mainly allows reading (and writing, if superuser) of
* kernel time-keeping variables. used by xntpd. * kernel time-keeping variables. used by xntpd.
*/ */
int __do_adjtimex(struct timex *txc) int __do_adjtimex(struct timex *txc, struct timespec *ts, s32 *time_tai)
{ {
struct timespec ts;
u32 time_tai, orig_tai;
int result; int result;
if (txc->modes & ADJ_SETOFFSET) { if (txc->modes & ADJ_SETOFFSET) {
...@@ -679,9 +677,6 @@ int __do_adjtimex(struct timex *txc) ...@@ -679,9 +677,6 @@ int __do_adjtimex(struct timex *txc)
return result; return result;
} }
getnstimeofday(&ts);
orig_tai = time_tai = timekeeping_get_tai_offset();
raw_spin_lock_irq(&ntp_lock); raw_spin_lock_irq(&ntp_lock);
if (txc->modes & ADJ_ADJTIME) { if (txc->modes & ADJ_ADJTIME) {
...@@ -697,7 +692,7 @@ int __do_adjtimex(struct timex *txc) ...@@ -697,7 +692,7 @@ int __do_adjtimex(struct timex *txc)
/* If there are input parameters, then process them: */ /* If there are input parameters, then process them: */
if (txc->modes) if (txc->modes)
process_adjtimex_modes(txc, &ts, &time_tai); process_adjtimex_modes(txc, ts, time_tai);
txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ, txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
NTP_SCALE_SHIFT); NTP_SCALE_SHIFT);
...@@ -719,18 +714,15 @@ int __do_adjtimex(struct timex *txc) ...@@ -719,18 +714,15 @@ int __do_adjtimex(struct timex *txc)
txc->precision = 1; txc->precision = 1;
txc->tolerance = MAXFREQ_SCALED / PPM_SCALE; txc->tolerance = MAXFREQ_SCALED / PPM_SCALE;
txc->tick = tick_usec; txc->tick = tick_usec;
txc->tai = time_tai; txc->tai = *time_tai;
/* fill PPS status fields */ /* fill PPS status fields */
pps_fill_timex(txc); pps_fill_timex(txc);
raw_spin_unlock_irq(&ntp_lock); raw_spin_unlock_irq(&ntp_lock);
if (time_tai != orig_tai) txc->time.tv_sec = ts->tv_sec;
timekeeping_set_tai_offset(time_tai); txc->time.tv_usec = ts->tv_nsec;
txc->time.tv_sec = ts.tv_sec;
txc->time.tv_usec = ts.tv_nsec;
if (!(time_status & STA_NANO)) if (!(time_status & STA_NANO))
txc->time.tv_usec /= NSEC_PER_USEC; txc->time.tv_usec /= NSEC_PER_USEC;
......
...@@ -7,6 +7,6 @@ extern void ntp_clear(void); ...@@ -7,6 +7,6 @@ extern void ntp_clear(void);
extern u64 ntp_tick_length(void); extern u64 ntp_tick_length(void);
extern int second_overflow(unsigned long secs); extern int second_overflow(unsigned long secs);
extern int ntp_validate_timex(struct timex *); extern int ntp_validate_timex(struct timex *);
extern int __do_adjtimex(struct timex *); extern int __do_adjtimex(struct timex *, struct timespec *, s32 *);
extern void __hardpps(const struct timespec *, const struct timespec *); extern void __hardpps(const struct timespec *, const struct timespec *);
#endif /* _LINUX_NTP_INTERNAL_H */ #endif /* _LINUX_NTP_INTERNAL_H */
...@@ -1618,6 +1618,8 @@ EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset); ...@@ -1618,6 +1618,8 @@ EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset);
*/ */
int do_adjtimex(struct timex *txc) int do_adjtimex(struct timex *txc)
{ {
struct timespec ts;
s32 tai, orig_tai;
int ret; int ret;
/* Validate the data before disabling interrupts */ /* Validate the data before disabling interrupts */
...@@ -1625,9 +1627,16 @@ int do_adjtimex(struct timex *txc) ...@@ -1625,9 +1627,16 @@ int do_adjtimex(struct timex *txc)
if (ret) if (ret)
return ret; return ret;
return __do_adjtimex(txc); getnstimeofday(&ts);
} orig_tai = tai = timekeeping_get_tai_offset();
ret = __do_adjtimex(txc, &ts, &tai);
if (tai != orig_tai)
timekeeping_set_tai_offset(tai);
return ret;
}
#ifdef CONFIG_NTP_PPS #ifdef CONFIG_NTP_PPS
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment