diff options
-rw-r--r-- | include/linux/time.h | 1 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 36 |
2 files changed, 37 insertions, 0 deletions
diff --git a/include/linux/time.h b/include/linux/time.h index 7c44e7778033..379b9037b5b4 100644 --- a/include/linux/time.h +++ b/include/linux/time.h | |||
@@ -166,6 +166,7 @@ extern struct timespec timespec_trunc(struct timespec t, unsigned gran); | |||
166 | extern int timekeeping_valid_for_hres(void); | 166 | extern int timekeeping_valid_for_hres(void); |
167 | extern u64 timekeeping_max_deferment(void); | 167 | extern u64 timekeeping_max_deferment(void); |
168 | extern void timekeeping_leap_insert(int leapsecond); | 168 | extern void timekeeping_leap_insert(int leapsecond); |
169 | extern int timekeeping_inject_offset(struct timespec *ts); | ||
169 | 170 | ||
170 | struct tms; | 171 | struct tms; |
171 | extern void do_sys_times(struct tms *); | 172 | extern void do_sys_times(struct tms *); |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 4f9f65b91323..6262c1d18397 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -387,6 +387,42 @@ int do_settimeofday(const struct timespec *tv) | |||
387 | 387 | ||
388 | EXPORT_SYMBOL(do_settimeofday); | 388 | EXPORT_SYMBOL(do_settimeofday); |
389 | 389 | ||
390 | |||
391 | /** | ||
392 | * timekeeping_inject_offset - Adds or subtracts from the current time. | ||
393 | * @tv: pointer to the timespec variable containing the offset | ||
394 | * | ||
395 | * Adds or subtracts an offset value from the current time. | ||
396 | */ | ||
397 | int timekeeping_inject_offset(struct timespec *ts) | ||
398 | { | ||
399 | unsigned long flags; | ||
400 | |||
401 | if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) | ||
402 | return -EINVAL; | ||
403 | |||
404 | write_seqlock_irqsave(&xtime_lock, flags); | ||
405 | |||
406 | timekeeping_forward_now(); | ||
407 | |||
408 | xtime = timespec_add(xtime, *ts); | ||
409 | wall_to_monotonic = timespec_sub(wall_to_monotonic, *ts); | ||
410 | |||
411 | timekeeper.ntp_error = 0; | ||
412 | ntp_clear(); | ||
413 | |||
414 | update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, | ||
415 | timekeeper.mult); | ||
416 | |||
417 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
418 | |||
419 | /* signal hrtimers about time change */ | ||
420 | clock_was_set(); | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | EXPORT_SYMBOL(timekeeping_inject_offset); | ||
425 | |||
390 | /** | 426 | /** |
391 | * change_clocksource - Swaps clocksources if a new one is available | 427 | * change_clocksource - Swaps clocksources if a new one is available |
392 | * | 428 | * |