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: Make do_adjtimex() reusable

Split out the actual functionality of adjtimex() and make do_adjtimex() a
wrapper which feeds the core timekeeper into it and handles the result
including audit at the call site.

This allows to reuse the actual functionality for auxiliary clocks.

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

+58 -48
+58 -48
kernel/time/timekeeping.c
··· 2585 2585 } 2586 2586 EXPORT_SYMBOL_GPL(random_get_entropy_fallback); 2587 2587 2588 - /** 2589 - * do_adjtimex() - Accessor function to NTP __do_adjtimex function 2590 - * @txc: Pointer to kernel_timex structure containing NTP parameters 2591 - */ 2592 - int do_adjtimex(struct __kernel_timex *txc) 2588 + struct adjtimex_result { 2589 + struct audit_ntp_data ad; 2590 + struct timespec64 delta; 2591 + bool clock_set; 2592 + }; 2593 + 2594 + static int __do_adjtimex(struct tk_data *tkd, struct __kernel_timex *txc, 2595 + struct adjtimex_result *result) 2593 2596 { 2594 - struct tk_data *tkd = &tk_core; 2595 - struct timespec64 delta, ts; 2596 - struct audit_ntp_data ad; 2597 - bool offset_set = false; 2598 - bool clock_set = false; 2597 + struct timekeeper *tks = &tkd->shadow_timekeeper; 2598 + struct timespec64 ts; 2599 + s32 orig_tai, tai; 2599 2600 int ret; 2600 2601 2601 2602 /* Validate the data before disabling interrupts */ ··· 2605 2604 return ret; 2606 2605 add_device_randomness(txc, sizeof(*txc)); 2607 2606 2608 - audit_ntp_init(&ad); 2609 - 2610 2607 ktime_get_real_ts64(&ts); 2611 2608 add_device_randomness(&ts, sizeof(ts)); 2612 2609 2613 - scoped_guard (raw_spinlock_irqsave, &tkd->lock) { 2614 - struct timekeeper *tks = &tkd->shadow_timekeeper; 2615 - s32 orig_tai, tai; 2610 + guard(raw_spinlock_irqsave)(&tkd->lock); 2616 2611 2617 - if (!tks->clock_valid) 2618 - return -ENODEV; 2612 + if (!tks->clock_valid) 2613 + return -ENODEV; 2619 2614 2620 - if (txc->modes & ADJ_SETOFFSET) { 2621 - delta.tv_sec = txc->time.tv_sec; 2622 - delta.tv_nsec = txc->time.tv_usec; 2623 - if (!(txc->modes & ADJ_NANO)) 2624 - delta.tv_nsec *= 1000; 2625 - ret = __timekeeping_inject_offset(tkd, &delta); 2626 - if (ret) 2627 - return ret; 2628 - 2629 - offset_set = delta.tv_sec != 0; 2630 - clock_set = true; 2631 - } 2632 - 2633 - orig_tai = tai = tks->tai_offset; 2634 - ret = ntp_adjtimex(tks->id, txc, &ts, &tai, &ad); 2635 - 2636 - if (tai != orig_tai) { 2637 - __timekeeping_set_tai_offset(tks, tai); 2638 - timekeeping_update_from_shadow(tkd, TK_CLOCK_WAS_SET); 2639 - clock_set = true; 2640 - } else { 2641 - tk_update_leap_state_all(&tk_core); 2642 - } 2643 - 2644 - /* Update the multiplier immediately if frequency was set directly */ 2645 - if (txc->modes & (ADJ_FREQUENCY | ADJ_TICK)) 2646 - clock_set |= __timekeeping_advance(tkd, TK_ADV_FREQ); 2615 + if (txc->modes & ADJ_SETOFFSET) { 2616 + result->delta.tv_sec = txc->time.tv_sec; 2617 + result->delta.tv_nsec = txc->time.tv_usec; 2618 + if (!(txc->modes & ADJ_NANO)) 2619 + result->delta.tv_nsec *= 1000; 2620 + ret = __timekeeping_inject_offset(tkd, &result->delta); 2621 + if (ret) 2622 + return ret; 2623 + result->clock_set = true; 2647 2624 } 2648 2625 2626 + orig_tai = tai = tks->tai_offset; 2627 + ret = ntp_adjtimex(tks->id, txc, &ts, &tai, &result->ad); 2628 + 2629 + if (tai != orig_tai) { 2630 + __timekeeping_set_tai_offset(tks, tai); 2631 + timekeeping_update_from_shadow(tkd, TK_CLOCK_WAS_SET); 2632 + result->clock_set = true; 2633 + } else { 2634 + tk_update_leap_state_all(&tk_core); 2635 + } 2636 + 2637 + /* Update the multiplier immediately if frequency was set directly */ 2638 + if (txc->modes & (ADJ_FREQUENCY | ADJ_TICK)) 2639 + result->clock_set |= __timekeeping_advance(tkd, TK_ADV_FREQ); 2640 + 2641 + return ret; 2642 + } 2643 + 2644 + /** 2645 + * do_adjtimex() - Accessor function to NTP __do_adjtimex function 2646 + * @txc: Pointer to kernel_timex structure containing NTP parameters 2647 + */ 2648 + int do_adjtimex(struct __kernel_timex *txc) 2649 + { 2650 + struct adjtimex_result result = { }; 2651 + int ret; 2652 + 2653 + ret = __do_adjtimex(&tk_core, txc, &result); 2654 + if (ret < 0) 2655 + return ret; 2656 + 2649 2657 if (txc->modes & ADJ_SETOFFSET) 2650 - audit_tk_injoffset(delta); 2658 + audit_tk_injoffset(result.delta); 2651 2659 2652 - audit_ntp_log(&ad); 2660 + audit_ntp_log(&result.ad); 2653 2661 2654 - if (clock_set) 2662 + if (result.clock_set) 2655 2663 clock_was_set(CLOCK_SET_WALL); 2656 2664 2657 - ntp_notify_cmos_timer(offset_set); 2665 + ntp_notify_cmos_timer(result.delta.tv_sec != 0); 2658 2666 2659 2667 return ret; 2660 2668 }