aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clocksource/Kconfig12
-rw-r--r--drivers/clocksource/tcb_clksrc.c3
-rw-r--r--fs/timerfd.c2
-rw-r--r--include/linux/hrtimer.h34
-rw-r--r--kernel/time/hrtimer.c55
-rw-r--r--kernel/time/itimer.c2
-rw-r--r--kernel/time/ntp.c14
-rw-r--r--kernel/time/posix-timers.c2
-rw-r--r--kernel/time/tick-sched.c16
-rw-r--r--kernel/time/timer_list.c2
-rw-r--r--tools/testing/selftests/timers/valid-adjtimex.c139
11 files changed, 245 insertions, 36 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 56777f04d2d9..33db7406c0e2 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -30,6 +30,8 @@ config CLKSRC_MMIO
30config DIGICOLOR_TIMER 30config DIGICOLOR_TIMER
31 bool "Digicolor timer driver" if COMPILE_TEST 31 bool "Digicolor timer driver" if COMPILE_TEST
32 depends on GENERIC_CLOCKEVENTS 32 depends on GENERIC_CLOCKEVENTS
33 select CLKSRC_MMIO
34 depends on HAS_IOMEM
33 help 35 help
34 Enables the support for the digicolor timer driver. 36 Enables the support for the digicolor timer driver.
35 37
@@ -55,6 +57,7 @@ config ARMADA_370_XP_TIMER
55 bool "Armada 370 and XP timer driver" if COMPILE_TEST 57 bool "Armada 370 and XP timer driver" if COMPILE_TEST
56 depends on ARM 58 depends on ARM
57 select CLKSRC_OF 59 select CLKSRC_OF
60 select CLKSRC_MMIO
58 help 61 help
59 Enables the support for the Armada 370 and XP timer driver. 62 Enables the support for the Armada 370 and XP timer driver.
60 63
@@ -76,6 +79,7 @@ config ORION_TIMER
76config SUN4I_TIMER 79config SUN4I_TIMER
77 bool "Sun4i timer driver" if COMPILE_TEST 80 bool "Sun4i timer driver" if COMPILE_TEST
78 depends on GENERIC_CLOCKEVENTS 81 depends on GENERIC_CLOCKEVENTS
82 depends on HAS_IOMEM
79 select CLKSRC_MMIO 83 select CLKSRC_MMIO
80 help 84 help
81 Enables support for the Sun4i timer. 85 Enables support for the Sun4i timer.
@@ -89,6 +93,7 @@ config SUN5I_HSTIMER
89 93
90config TEGRA_TIMER 94config TEGRA_TIMER
91 bool "Tegra timer driver" if COMPILE_TEST 95 bool "Tegra timer driver" if COMPILE_TEST
96 select CLKSRC_MMIO
92 depends on ARM 97 depends on ARM
93 help 98 help
94 Enables support for the Tegra driver. 99 Enables support for the Tegra driver.
@@ -96,6 +101,7 @@ config TEGRA_TIMER
96config VT8500_TIMER 101config VT8500_TIMER
97 bool "VT8500 timer driver" if COMPILE_TEST 102 bool "VT8500 timer driver" if COMPILE_TEST
98 depends on GENERIC_CLOCKEVENTS 103 depends on GENERIC_CLOCKEVENTS
104 depends on HAS_IOMEM
99 help 105 help
100 Enables support for the VT8500 driver. 106 Enables support for the VT8500 driver.
101 107
@@ -131,6 +137,7 @@ config CLKSRC_NOMADIK_MTU_SCHED_CLOCK
131config CLKSRC_DBX500_PRCMU 137config CLKSRC_DBX500_PRCMU
132 bool "Clocksource PRCMU Timer" if COMPILE_TEST 138 bool "Clocksource PRCMU Timer" if COMPILE_TEST
133 depends on GENERIC_CLOCKEVENTS 139 depends on GENERIC_CLOCKEVENTS
140 depends on HAS_IOMEM
134 help 141 help
135 Use the always on PRCMU Timer as clocksource 142 Use the always on PRCMU Timer as clocksource
136 143
@@ -248,6 +255,7 @@ config CLKSRC_EXYNOS_MCT
248config CLKSRC_SAMSUNG_PWM 255config CLKSRC_SAMSUNG_PWM
249 bool "PWM timer drvier for Samsung S3C, S5P" if COMPILE_TEST 256 bool "PWM timer drvier for Samsung S3C, S5P" if COMPILE_TEST
250 depends on GENERIC_CLOCKEVENTS 257 depends on GENERIC_CLOCKEVENTS
258 depends on HAS_IOMEM
251 help 259 help
252 This is a new clocksource driver for the PWM timer found in 260 This is a new clocksource driver for the PWM timer found in
253 Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver 261 Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver
@@ -257,12 +265,14 @@ config CLKSRC_SAMSUNG_PWM
257config FSL_FTM_TIMER 265config FSL_FTM_TIMER
258 bool "Freescale FlexTimer Module driver" if COMPILE_TEST 266 bool "Freescale FlexTimer Module driver" if COMPILE_TEST
259 depends on GENERIC_CLOCKEVENTS 267 depends on GENERIC_CLOCKEVENTS
268 depends on HAS_IOMEM
260 select CLKSRC_MMIO 269 select CLKSRC_MMIO
261 help 270 help
262 Support for Freescale FlexTimer Module (FTM) timer. 271 Support for Freescale FlexTimer Module (FTM) timer.
263 272
264config VF_PIT_TIMER 273config VF_PIT_TIMER
265 bool 274 bool
275 select CLKSRC_MMIO
266 help 276 help
267 Support for Period Interrupt Timer on Freescale Vybrid Family SoCs. 277 Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.
268 278
@@ -360,6 +370,7 @@ config CLKSRC_TANGO_XTAL
360config CLKSRC_PXA 370config CLKSRC_PXA
361 bool "Clocksource for PXA or SA-11x0 platform" if COMPILE_TEST 371 bool "Clocksource for PXA or SA-11x0 platform" if COMPILE_TEST
362 depends on GENERIC_CLOCKEVENTS 372 depends on GENERIC_CLOCKEVENTS
373 depends on HAS_IOMEM
363 select CLKSRC_MMIO 374 select CLKSRC_MMIO
364 help 375 help
365 This enables OST0 support available on PXA and SA-11x0 376 This enables OST0 support available on PXA and SA-11x0
@@ -394,6 +405,7 @@ config CLKSRC_ST_LPC
394 bool "Low power clocksource found in the LPC" if COMPILE_TEST 405 bool "Low power clocksource found in the LPC" if COMPILE_TEST
395 select CLKSRC_OF if OF 406 select CLKSRC_OF if OF
396 depends on HAS_IOMEM 407 depends on HAS_IOMEM
408 select CLKSRC_MMIO
397 help 409 help
398 Enable this option to use the Low Power controller timer 410 Enable this option to use the Low Power controller timer
399 as clocksource. 411 as clocksource.
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
index 6ee91401918e..4da2af9694a2 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -98,7 +98,8 @@ static int tc_shutdown(struct clock_event_device *d)
98 98
99 __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR)); 99 __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR));
100 __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR)); 100 __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR));
101 clk_disable(tcd->clk); 101 if (!clockevent_state_detached(d))
102 clk_disable(tcd->clk);
102 103
103 return 0; 104 return 0;
104} 105}
diff --git a/fs/timerfd.c b/fs/timerfd.c
index b94fa6c3c6eb..053818dd6c18 100644
--- a/fs/timerfd.c
+++ b/fs/timerfd.c
@@ -153,7 +153,7 @@ static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
153 if (isalarm(ctx)) 153 if (isalarm(ctx))
154 remaining = alarm_expires_remaining(&ctx->t.alarm); 154 remaining = alarm_expires_remaining(&ctx->t.alarm);
155 else 155 else
156 remaining = hrtimer_expires_remaining(&ctx->t.tmr); 156 remaining = hrtimer_expires_remaining_adjusted(&ctx->t.tmr);
157 157
158 return remaining.tv64 < 0 ? ktime_set(0, 0): remaining; 158 return remaining.tv64 < 0 ? ktime_set(0, 0): remaining;
159} 159}
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 76dd4f0da5ca..2ead22dd74a0 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -87,7 +87,8 @@ enum hrtimer_restart {
87 * @function: timer expiry callback function 87 * @function: timer expiry callback function
88 * @base: pointer to the timer base (per cpu and per clock) 88 * @base: pointer to the timer base (per cpu and per clock)
89 * @state: state information (See bit values above) 89 * @state: state information (See bit values above)
90 * @start_pid: timer statistics field to store the pid of the task which 90 * @is_rel: Set if the timer was armed relative
91 * @start_pid: timer statistics field to store the pid of the task which
91 * started the timer 92 * started the timer
92 * @start_site: timer statistics field to store the site where the timer 93 * @start_site: timer statistics field to store the site where the timer
93 * was started 94 * was started
@@ -101,7 +102,8 @@ struct hrtimer {
101 ktime_t _softexpires; 102 ktime_t _softexpires;
102 enum hrtimer_restart (*function)(struct hrtimer *); 103 enum hrtimer_restart (*function)(struct hrtimer *);
103 struct hrtimer_clock_base *base; 104 struct hrtimer_clock_base *base;
104 unsigned long state; 105 u8 state;
106 u8 is_rel;
105#ifdef CONFIG_TIMER_STATS 107#ifdef CONFIG_TIMER_STATS
106 int start_pid; 108 int start_pid;
107 void *start_site; 109 void *start_site;
@@ -321,6 +323,27 @@ static inline void clock_was_set_delayed(void) { }
321 323
322#endif 324#endif
323 325
326static inline ktime_t
327__hrtimer_expires_remaining_adjusted(const struct hrtimer *timer, ktime_t now)
328{
329 ktime_t rem = ktime_sub(timer->node.expires, now);
330
331 /*
332 * Adjust relative timers for the extra we added in
333 * hrtimer_start_range_ns() to prevent short timeouts.
334 */
335 if (IS_ENABLED(CONFIG_TIME_LOW_RES) && timer->is_rel)
336 rem.tv64 -= hrtimer_resolution;
337 return rem;
338}
339
340static inline ktime_t
341hrtimer_expires_remaining_adjusted(const struct hrtimer *timer)
342{
343 return __hrtimer_expires_remaining_adjusted(timer,
344 timer->base->get_time());
345}
346
324extern void clock_was_set(void); 347extern void clock_was_set(void);
325#ifdef CONFIG_TIMERFD 348#ifdef CONFIG_TIMERFD
326extern void timerfd_clock_was_set(void); 349extern void timerfd_clock_was_set(void);
@@ -390,7 +413,12 @@ static inline void hrtimer_restart(struct hrtimer *timer)
390} 413}
391 414
392/* Query timers: */ 415/* Query timers: */
393extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer); 416extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust);
417
418static inline ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
419{
420 return __hrtimer_get_remaining(timer, false);
421}
394 422
395extern u64 hrtimer_get_next_event(void); 423extern u64 hrtimer_get_next_event(void);
396 424
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 435b8850dd80..fa909f9fd559 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -897,10 +897,10 @@ static int enqueue_hrtimer(struct hrtimer *timer,
897 */ 897 */
898static void __remove_hrtimer(struct hrtimer *timer, 898static void __remove_hrtimer(struct hrtimer *timer,
899 struct hrtimer_clock_base *base, 899 struct hrtimer_clock_base *base,
900 unsigned long newstate, int reprogram) 900 u8 newstate, int reprogram)
901{ 901{
902 struct hrtimer_cpu_base *cpu_base = base->cpu_base; 902 struct hrtimer_cpu_base *cpu_base = base->cpu_base;
903 unsigned int state = timer->state; 903 u8 state = timer->state;
904 904
905 timer->state = newstate; 905 timer->state = newstate;
906 if (!(state & HRTIMER_STATE_ENQUEUED)) 906 if (!(state & HRTIMER_STATE_ENQUEUED))
@@ -930,7 +930,7 @@ static inline int
930remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool restart) 930remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool restart)
931{ 931{
932 if (hrtimer_is_queued(timer)) { 932 if (hrtimer_is_queued(timer)) {
933 unsigned long state = timer->state; 933 u8 state = timer->state;
934 int reprogram; 934 int reprogram;
935 935
936 /* 936 /*
@@ -954,6 +954,22 @@ remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool rest
954 return 0; 954 return 0;
955} 955}
956 956
957static inline ktime_t hrtimer_update_lowres(struct hrtimer *timer, ktime_t tim,
958 const enum hrtimer_mode mode)
959{
960#ifdef CONFIG_TIME_LOW_RES
961 /*
962 * CONFIG_TIME_LOW_RES indicates that the system has no way to return
963 * granular time values. For relative timers we add hrtimer_resolution
964 * (i.e. one jiffie) to prevent short timeouts.
965 */
966 timer->is_rel = mode & HRTIMER_MODE_REL;
967 if (timer->is_rel)
968 tim = ktime_add_safe(tim, ktime_set(0, hrtimer_resolution));
969#endif
970 return tim;
971}
972
957/** 973/**
958 * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU 974 * hrtimer_start_range_ns - (re)start an hrtimer on the current CPU
959 * @timer: the timer to be added 975 * @timer: the timer to be added
@@ -974,19 +990,10 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
974 /* Remove an active timer from the queue: */ 990 /* Remove an active timer from the queue: */
975 remove_hrtimer(timer, base, true); 991 remove_hrtimer(timer, base, true);
976 992
977 if (mode & HRTIMER_MODE_REL) { 993 if (mode & HRTIMER_MODE_REL)
978 tim = ktime_add_safe(tim, base->get_time()); 994 tim = ktime_add_safe(tim, base->get_time());
979 /* 995
980 * CONFIG_TIME_LOW_RES is a temporary way for architectures 996 tim = hrtimer_update_lowres(timer, tim, mode);
981 * to signal that they simply return xtime in
982 * do_gettimeoffset(). In this case we want to round up by
983 * resolution when starting a relative timer, to avoid short
984 * timeouts. This will go away with the GTOD framework.
985 */
986#ifdef CONFIG_TIME_LOW_RES
987 tim = ktime_add_safe(tim, ktime_set(0, hrtimer_resolution));
988#endif
989 }
990 997
991 hrtimer_set_expires_range_ns(timer, tim, delta_ns); 998 hrtimer_set_expires_range_ns(timer, tim, delta_ns);
992 999
@@ -1074,19 +1081,23 @@ EXPORT_SYMBOL_GPL(hrtimer_cancel);
1074/** 1081/**
1075 * hrtimer_get_remaining - get remaining time for the timer 1082 * hrtimer_get_remaining - get remaining time for the timer
1076 * @timer: the timer to read 1083 * @timer: the timer to read
1084 * @adjust: adjust relative timers when CONFIG_TIME_LOW_RES=y
1077 */ 1085 */
1078ktime_t hrtimer_get_remaining(const struct hrtimer *timer) 1086ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust)
1079{ 1087{
1080 unsigned long flags; 1088 unsigned long flags;
1081 ktime_t rem; 1089 ktime_t rem;
1082 1090
1083 lock_hrtimer_base(timer, &flags); 1091 lock_hrtimer_base(timer, &flags);
1084 rem = hrtimer_expires_remaining(timer); 1092 if (IS_ENABLED(CONFIG_TIME_LOW_RES) && adjust)
1093 rem = hrtimer_expires_remaining_adjusted(timer);
1094 else
1095 rem = hrtimer_expires_remaining(timer);
1085 unlock_hrtimer_base(timer, &flags); 1096 unlock_hrtimer_base(timer, &flags);
1086 1097
1087 return rem; 1098 return rem;
1088} 1099}
1089EXPORT_SYMBOL_GPL(hrtimer_get_remaining); 1100EXPORT_SYMBOL_GPL(__hrtimer_get_remaining);
1090 1101
1091#ifdef CONFIG_NO_HZ_COMMON 1102#ifdef CONFIG_NO_HZ_COMMON
1092/** 1103/**
@@ -1220,6 +1231,14 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
1220 fn = timer->function; 1231 fn = timer->function;
1221 1232
1222 /* 1233 /*
1234 * Clear the 'is relative' flag for the TIME_LOW_RES case. If the
1235 * timer is restarted with a period then it becomes an absolute
1236 * timer. If its not restarted it does not matter.
1237 */
1238 if (IS_ENABLED(CONFIG_TIME_LOW_RES))
1239 timer->is_rel = false;
1240
1241 /*
1223 * Because we run timers from hardirq context, there is no chance 1242 * Because we run timers from hardirq context, there is no chance
1224 * they get migrated to another cpu, therefore its safe to unlock 1243 * they get migrated to another cpu, therefore its safe to unlock
1225 * the timer base. 1244 * the timer base.
diff --git a/kernel/time/itimer.c b/kernel/time/itimer.c
index 8d262b467573..1d5c7204ddc9 100644
--- a/kernel/time/itimer.c
+++ b/kernel/time/itimer.c
@@ -26,7 +26,7 @@
26 */ 26 */
27static struct timeval itimer_get_remtime(struct hrtimer *timer) 27static struct timeval itimer_get_remtime(struct hrtimer *timer)
28{ 28{
29 ktime_t rem = hrtimer_get_remaining(timer); 29 ktime_t rem = __hrtimer_get_remaining(timer, true);
30 30
31 /* 31 /*
32 * Racy but safe: if the itimer expires after the above 32 * Racy but safe: if the itimer expires after the above
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 36f2ca09aa5e..6df8927c58a5 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -685,8 +685,18 @@ int ntp_validate_timex(struct timex *txc)
685 if (!capable(CAP_SYS_TIME)) 685 if (!capable(CAP_SYS_TIME))
686 return -EPERM; 686 return -EPERM;
687 687
688 if (!timeval_inject_offset_valid(&txc->time)) 688 if (txc->modes & ADJ_NANO) {
689 return -EINVAL; 689 struct timespec ts;
690
691 ts.tv_sec = txc->time.tv_sec;
692 ts.tv_nsec = txc->time.tv_usec;
693 if (!timespec_inject_offset_valid(&ts))
694 return -EINVAL;
695
696 } else {
697 if (!timeval_inject_offset_valid(&txc->time))
698 return -EINVAL;
699 }
690 } 700 }
691 701
692 /* 702 /*
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 31d11ac9fa47..f2826c35e918 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -760,7 +760,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
760 (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) 760 (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
761 timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv); 761 timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv);
762 762
763 remaining = ktime_sub(hrtimer_get_expires(timer), now); 763 remaining = __hrtimer_expires_remaining_adjusted(timer, now);
764 /* Return 0 only, when the timer is expired and not pending */ 764 /* Return 0 only, when the timer is expired and not pending */
765 if (remaining.tv64 <= 0) { 765 if (remaining.tv64 <= 0) {
766 /* 766 /*
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 9d7a053545f5..0b17424349eb 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -36,16 +36,17 @@
36 */ 36 */
37static DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched); 37static DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched);
38 38
39/*
40 * The time, when the last jiffy update happened. Protected by jiffies_lock.
41 */
42static ktime_t last_jiffies_update;
43
44struct tick_sched *tick_get_tick_sched(int cpu) 39struct tick_sched *tick_get_tick_sched(int cpu)
45{ 40{
46 return &per_cpu(tick_cpu_sched, cpu); 41 return &per_cpu(tick_cpu_sched, cpu);
47} 42}
48 43
44#if defined(CONFIG_NO_HZ_COMMON) || defined(CONFIG_HIGH_RES_TIMERS)
45/*
46 * The time, when the last jiffy update happened. Protected by jiffies_lock.
47 */
48static ktime_t last_jiffies_update;
49
49/* 50/*
50 * Must be called with interrupts disabled ! 51 * Must be called with interrupts disabled !
51 */ 52 */
@@ -151,6 +152,7 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)
151 update_process_times(user_mode(regs)); 152 update_process_times(user_mode(regs));
152 profile_tick(CPU_PROFILING); 153 profile_tick(CPU_PROFILING);
153} 154}
155#endif
154 156
155#ifdef CONFIG_NO_HZ_FULL 157#ifdef CONFIG_NO_HZ_FULL
156cpumask_var_t tick_nohz_full_mask; 158cpumask_var_t tick_nohz_full_mask;
@@ -993,9 +995,9 @@ static void tick_nohz_switch_to_nohz(void)
993 /* Get the next period */ 995 /* Get the next period */
994 next = tick_init_jiffy_update(); 996 next = tick_init_jiffy_update();
995 997
996 hrtimer_forward_now(&ts->sched_timer, tick_period);
997 hrtimer_set_expires(&ts->sched_timer, next); 998 hrtimer_set_expires(&ts->sched_timer, next);
998 tick_program_event(next, 1); 999 hrtimer_forward_now(&ts->sched_timer, tick_period);
1000 tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1);
999 tick_nohz_activate(ts, NOHZ_MODE_LOWRES); 1001 tick_nohz_activate(ts, NOHZ_MODE_LOWRES);
1000} 1002}
1001 1003
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index f75e35b60149..ba7d8b288bb3 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -69,7 +69,7 @@ print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer,
69 print_name_offset(m, taddr); 69 print_name_offset(m, taddr);
70 SEQ_printf(m, ", "); 70 SEQ_printf(m, ", ");
71 print_name_offset(m, timer->function); 71 print_name_offset(m, timer->function);
72 SEQ_printf(m, ", S:%02lx", timer->state); 72 SEQ_printf(m, ", S:%02x", timer->state);
73#ifdef CONFIG_TIMER_STATS 73#ifdef CONFIG_TIMER_STATS
74 SEQ_printf(m, ", "); 74 SEQ_printf(m, ", ");
75 print_name_offset(m, timer->start_site); 75 print_name_offset(m, timer->start_site);
diff --git a/tools/testing/selftests/timers/valid-adjtimex.c b/tools/testing/selftests/timers/valid-adjtimex.c
index e86d937cc22c..60fe3c569bd9 100644
--- a/tools/testing/selftests/timers/valid-adjtimex.c
+++ b/tools/testing/selftests/timers/valid-adjtimex.c
@@ -45,7 +45,17 @@ static inline int ksft_exit_fail(void)
45} 45}
46#endif 46#endif
47 47
48#define NSEC_PER_SEC 1000000000L 48#define NSEC_PER_SEC 1000000000LL
49#define USEC_PER_SEC 1000000LL
50
51#define ADJ_SETOFFSET 0x0100
52
53#include <sys/syscall.h>
54static int clock_adjtime(clockid_t id, struct timex *tx)
55{
56 return syscall(__NR_clock_adjtime, id, tx);
57}
58
49 59
50/* clear NTP time_status & time_state */ 60/* clear NTP time_status & time_state */
51int clear_time_state(void) 61int clear_time_state(void)
@@ -193,10 +203,137 @@ out:
193} 203}
194 204
195 205
206int set_offset(long long offset, int use_nano)
207{
208 struct timex tmx = {};
209 int ret;
210
211 tmx.modes = ADJ_SETOFFSET;
212 if (use_nano) {
213 tmx.modes |= ADJ_NANO;
214
215 tmx.time.tv_sec = offset / NSEC_PER_SEC;
216 tmx.time.tv_usec = offset % NSEC_PER_SEC;
217
218 if (offset < 0 && tmx.time.tv_usec) {
219 tmx.time.tv_sec -= 1;
220 tmx.time.tv_usec += NSEC_PER_SEC;
221 }
222 } else {
223 tmx.time.tv_sec = offset / USEC_PER_SEC;
224 tmx.time.tv_usec = offset % USEC_PER_SEC;
225
226 if (offset < 0 && tmx.time.tv_usec) {
227 tmx.time.tv_sec -= 1;
228 tmx.time.tv_usec += USEC_PER_SEC;
229 }
230 }
231
232 ret = clock_adjtime(CLOCK_REALTIME, &tmx);
233 if (ret < 0) {
234 printf("(sec: %ld usec: %ld) ", tmx.time.tv_sec, tmx.time.tv_usec);
235 printf("[FAIL]\n");
236 return -1;
237 }
238 return 0;
239}
240
241int set_bad_offset(long sec, long usec, int use_nano)
242{
243 struct timex tmx = {};
244 int ret;
245
246 tmx.modes = ADJ_SETOFFSET;
247 if (use_nano)
248 tmx.modes |= ADJ_NANO;
249
250 tmx.time.tv_sec = sec;
251 tmx.time.tv_usec = usec;
252 ret = clock_adjtime(CLOCK_REALTIME, &tmx);
253 if (ret >= 0) {
254 printf("Invalid (sec: %ld usec: %ld) did not fail! ", tmx.time.tv_sec, tmx.time.tv_usec);
255 printf("[FAIL]\n");
256 return -1;
257 }
258 return 0;
259}
260
261int validate_set_offset(void)
262{
263 printf("Testing ADJ_SETOFFSET... ");
264
265 /* Test valid values */
266 if (set_offset(NSEC_PER_SEC - 1, 1))
267 return -1;
268
269 if (set_offset(-NSEC_PER_SEC + 1, 1))
270 return -1;
271
272 if (set_offset(-NSEC_PER_SEC - 1, 1))
273 return -1;
274
275 if (set_offset(5 * NSEC_PER_SEC, 1))
276 return -1;
277
278 if (set_offset(-5 * NSEC_PER_SEC, 1))
279 return -1;
280
281 if (set_offset(5 * NSEC_PER_SEC + NSEC_PER_SEC / 2, 1))
282 return -1;
283
284 if (set_offset(-5 * NSEC_PER_SEC - NSEC_PER_SEC / 2, 1))
285 return -1;
286
287 if (set_offset(USEC_PER_SEC - 1, 0))
288 return -1;
289
290 if (set_offset(-USEC_PER_SEC + 1, 0))
291 return -1;
292
293 if (set_offset(-USEC_PER_SEC - 1, 0))
294 return -1;
295
296 if (set_offset(5 * USEC_PER_SEC, 0))
297 return -1;
298
299 if (set_offset(-5 * USEC_PER_SEC, 0))
300 return -1;
301
302 if (set_offset(5 * USEC_PER_SEC + USEC_PER_SEC / 2, 0))
303 return -1;
304
305 if (set_offset(-5 * USEC_PER_SEC - USEC_PER_SEC / 2, 0))
306 return -1;
307
308 /* Test invalid values */
309 if (set_bad_offset(0, -1, 1))
310 return -1;
311 if (set_bad_offset(0, -1, 0))
312 return -1;
313 if (set_bad_offset(0, 2 * NSEC_PER_SEC, 1))
314 return -1;
315 if (set_bad_offset(0, 2 * USEC_PER_SEC, 0))
316 return -1;
317 if (set_bad_offset(0, NSEC_PER_SEC, 1))
318 return -1;
319 if (set_bad_offset(0, USEC_PER_SEC, 0))
320 return -1;
321 if (set_bad_offset(0, -NSEC_PER_SEC, 1))
322 return -1;
323 if (set_bad_offset(0, -USEC_PER_SEC, 0))
324 return -1;
325
326 printf("[OK]\n");
327 return 0;
328}
329
196int main(int argc, char **argv) 330int main(int argc, char **argv)
197{ 331{
198 if (validate_freq()) 332 if (validate_freq())
199 return ksft_exit_fail(); 333 return ksft_exit_fail();
200 334
335 if (validate_set_offset())
336 return ksft_exit_fail();
337
201 return ksft_exit_pass(); 338 return ksft_exit_pass();
202} 339}