Skip to content

Commit 2c8aea5

Browse files
committed
timekeeping: Add auxiliary clock support to __timekeeping_inject_offset()
Redirect the relative offset adjustment to the auxiliary clock offset instead of modifying CLOCK_REALTIME, which has no meaning in context of these clocks. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: John Stultz <jstultz@google.com> Link: https://lore.kernel.org/all/20250625183758.124057787@linutronix.de
1 parent e8db3a5 commit 2c8aea5

1 file changed

Lines changed: 31 additions & 8 deletions

File tree

kernel/time/timekeeping.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,6 +1431,11 @@ int do_settimeofday64(const struct timespec64 *ts)
14311431
}
14321432
EXPORT_SYMBOL(do_settimeofday64);
14331433

1434+
static inline bool timekeeper_is_core_tk(struct timekeeper *tk)
1435+
{
1436+
return !IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS) || tk->id == TIMEKEEPER_CORE;
1437+
}
1438+
14341439
/**
14351440
* __timekeeping_inject_offset - Adds or subtracts from the current time.
14361441
* @tkd: Pointer to the timekeeper to modify
@@ -1448,16 +1453,34 @@ static int __timekeeping_inject_offset(struct tk_data *tkd, const struct timespe
14481453

14491454
timekeeping_forward_now(tks);
14501455

1451-
/* Make sure the proposed value is valid */
1452-
tmp = timespec64_add(tk_xtime(tks), *ts);
1453-
if (timespec64_compare(&tks->wall_to_monotonic, ts) > 0 ||
1454-
!timespec64_valid_settod(&tmp)) {
1455-
timekeeping_restore_shadow(tkd);
1456-
return -EINVAL;
1456+
if (timekeeper_is_core_tk(tks)) {
1457+
/* Make sure the proposed value is valid */
1458+
tmp = timespec64_add(tk_xtime(tks), *ts);
1459+
if (timespec64_compare(&tks->wall_to_monotonic, ts) > 0 ||
1460+
!timespec64_valid_settod(&tmp)) {
1461+
timekeeping_restore_shadow(tkd);
1462+
return -EINVAL;
1463+
}
1464+
1465+
tk_xtime_add(tks, ts);
1466+
tk_set_wall_to_mono(tks, timespec64_sub(tks->wall_to_monotonic, *ts));
1467+
} else {
1468+
struct tk_read_base *tkr_mono = &tks->tkr_mono;
1469+
ktime_t now, offs;
1470+
1471+
/* Get the current time */
1472+
now = ktime_add_ns(tkr_mono->base, timekeeping_get_ns(tkr_mono));
1473+
/* Add the relative offset change */
1474+
offs = ktime_add(tks->offs_aux, timespec64_to_ktime(*ts));
1475+
1476+
/* Prevent that the resulting time becomes negative */
1477+
if (ktime_add(now, offs) < 0) {
1478+
timekeeping_restore_shadow(tkd);
1479+
return -EINVAL;
1480+
}
1481+
tks->offs_aux = offs;
14571482
}
14581483

1459-
tk_xtime_add(tks, ts);
1460-
tk_set_wall_to_mono(tks, timespec64_sub(tks->wall_to_monotonic, *ts));
14611484
timekeeping_update_from_shadow(tkd, TK_UPDATE_ALL);
14621485
return 0;
14631486
}

0 commit comments

Comments
 (0)