Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

timekeeping: Prepare do_adtimex() for auxiliary clocks

Exclude ADJ_TAI, leap seconds and PPS functionality as they make no sense
in the context of auxiliary clocks and provide a time stamp based on the
actual clock.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: John Stultz <jstultz@google.com>
Link: https://lore.kernel.org/all/20250625183758.253203783@linutronix.de

+33 -3
+33 -3
kernel/time/timekeeping.c
··· 58 58 /* The core timekeeper */ 59 59 #define tk_core (timekeeper_data[TIMEKEEPER_CORE]) 60 60 61 + #ifdef CONFIG_POSIX_AUX_CLOCKS 62 + static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *ts) 63 + { 64 + return ktime_get_aux_ts64(CLOCK_AUX + tkid - TIMEKEEPER_AUX_FIRST, ts); 65 + } 66 + #else 67 + static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *ts) 68 + { 69 + return false; 70 + } 71 + #endif 61 72 62 73 /* flag for if timekeeping is suspended */ 63 74 int __read_mostly timekeeping_suspended; ··· 2519 2508 /* 2520 2509 * timekeeping_validate_timex - Ensures the timex is ok for use in do_adjtimex 2521 2510 */ 2522 - static int timekeeping_validate_timex(const struct __kernel_timex *txc) 2511 + static int timekeeping_validate_timex(const struct __kernel_timex *txc, bool aux_clock) 2523 2512 { 2524 2513 if (txc->modes & ADJ_ADJTIME) { 2525 2514 /* singleshot must not be used with any other mode bits */ ··· 2578 2567 return -EINVAL; 2579 2568 } 2580 2569 2570 + if (aux_clock) { 2571 + /* Auxiliary clocks are similar to TAI and do not have leap seconds */ 2572 + if (txc->status & (STA_INS | STA_DEL)) 2573 + return -EINVAL; 2574 + 2575 + /* No TAI offset setting */ 2576 + if (txc->modes & ADJ_TAI) 2577 + return -EINVAL; 2578 + 2579 + /* No PPS support either */ 2580 + if (txc->status & (STA_PPSFREQ | STA_PPSTIME)) 2581 + return -EINVAL; 2582 + } 2583 + 2581 2584 return 0; 2582 2585 } 2583 2586 ··· 2620 2595 struct adjtimex_result *result) 2621 2596 { 2622 2597 struct timekeeper *tks = &tkd->shadow_timekeeper; 2598 + bool aux_clock = !timekeeper_is_core_tk(tks); 2623 2599 struct timespec64 ts; 2624 2600 s32 orig_tai, tai; 2625 2601 int ret; 2626 2602 2627 2603 /* Validate the data before disabling interrupts */ 2628 - ret = timekeeping_validate_timex(txc); 2604 + ret = timekeeping_validate_timex(txc, aux_clock); 2629 2605 if (ret) 2630 2606 return ret; 2631 2607 add_device_randomness(txc, sizeof(*txc)); 2632 2608 2633 - ktime_get_real_ts64(&ts); 2609 + if (!aux_clock) 2610 + ktime_get_real_ts64(&ts); 2611 + else 2612 + tk_get_aux_ts64(tkd->timekeeper.id, &ts); 2613 + 2634 2614 add_device_randomness(&ts, sizeof(ts)); 2635 2615 2636 2616 guard(raw_spinlock_irqsave)(&tkd->lock);