From 4c09a4cebd0320c5381afad3fb6f997f20082a3b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 1 Jul 2025 15:27:00 +0200 Subject: [PATCH 1/2] ptp: Use ktime_get_clock_ts64() for timestamping The inlined ptp_read_system_[pre|post]ts() switch cases expand to a copious amount of text in drivers, e.g. ~500 bytes in e1000e. Adding auxiliary clock support to the inlines would increase it further. Replace the inline switch case with a call to ktime_get_clock_ts64(), which reduces the code size in drivers and allows to access auxiliary clocks once they are enabled in the IOCTL parameter filter. No functional change. Signed-off-by: Thomas Gleixner Reviewed-by: Vadim Fedorenko Acked-by: John Stultz Link: https://patch.msgid.link/20250701132628.426168092@linutronix.de Signed-off-by: Paolo Abeni --- include/linux/ptp_clock_kernel.h | 34 ++++---------------------------- 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h index eced7e9bf69a..3d089bd4d5e9 100644 --- a/include/linux/ptp_clock_kernel.h +++ b/include/linux/ptp_clock_kernel.h @@ -477,40 +477,14 @@ static inline ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, static inline void ptp_read_system_prets(struct ptp_system_timestamp *sts) { - if (sts) { - switch (sts->clockid) { - case CLOCK_REALTIME: - ktime_get_real_ts64(&sts->pre_ts); - break; - case CLOCK_MONOTONIC: - ktime_get_ts64(&sts->pre_ts); - break; - case CLOCK_MONOTONIC_RAW: - ktime_get_raw_ts64(&sts->pre_ts); - break; - default: - break; - } - } + if (sts) + ktime_get_clock_ts64(sts->clockid, &sts->pre_ts); } static inline void ptp_read_system_postts(struct ptp_system_timestamp *sts) { - if (sts) { - switch (sts->clockid) { - case CLOCK_REALTIME: - ktime_get_real_ts64(&sts->post_ts); - break; - case CLOCK_MONOTONIC: - ktime_get_ts64(&sts->post_ts); - break; - case CLOCK_MONOTONIC_RAW: - ktime_get_raw_ts64(&sts->post_ts); - break; - default: - break; - } - } + if (sts) + ktime_get_clock_ts64(sts->clockid, &sts->post_ts); } #endif From 17c395bba1a3983b1b1918286979bae5f6851f33 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 1 Jul 2025 15:27:02 +0200 Subject: [PATCH 2/2] ptp: Enable auxiliary clocks for PTP_SYS_OFFSET_EXTENDED Allow ioctl(PTP_SYS_OFFSET_EXTENDED*) to select CLOCK_AUX clock ids for generating the pre and post hardware readout timestamps. Aside of adding these clocks to the clock ID validation, this also requires to check the timestamp to be valid, i.e. the seconds value being greater than or equal zero. This is necessary because AUX clocks can be asynchronously enabled or disabled, so there is no way to validate the availability upfront. The same could have been achieved by handing the return value of ktime_get_aux_ts64() all the way down to the IOCTL call site, but that'd require to modify all existing ptp::gettimex64() callbacks and their inner call chains. The timestamp check achieves the same with less churn and less complicated code all over the place. Signed-off-by: Thomas Gleixner Reviewed-by: Vadim Fedorenko Link: https://patch.msgid.link/20250701132628.491315452@linutronix.de Signed-off-by: Paolo Abeni --- drivers/ptp/ptp_chardev.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index 6b611fe5a95e..4ca5a464a46a 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c @@ -325,13 +325,22 @@ static long ptp_sys_offset_extended(struct ptp_clock *ptp, void __user *arg) if (IS_ERR(extoff)) return PTR_ERR(extoff); - if (extoff->n_samples > PTP_MAX_SAMPLES || - extoff->rsv[0] || extoff->rsv[1] || - (extoff->clockid != CLOCK_REALTIME && - extoff->clockid != CLOCK_MONOTONIC && - extoff->clockid != CLOCK_MONOTONIC_RAW)) + if (extoff->n_samples > PTP_MAX_SAMPLES || extoff->rsv[0] || extoff->rsv[1]) return -EINVAL; + switch (extoff->clockid) { + case CLOCK_REALTIME: + case CLOCK_MONOTONIC: + case CLOCK_MONOTONIC_RAW: + break; + case CLOCK_AUX ... CLOCK_AUX_LAST: + if (IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS)) + break; + fallthrough; + default: + return -EINVAL; + } + sts.clockid = extoff->clockid; for (unsigned int i = 0; i < extoff->n_samples; i++) { struct timespec64 ts; @@ -340,6 +349,11 @@ static long ptp_sys_offset_extended(struct ptp_clock *ptp, void __user *arg) err = ptp->info->gettimex64(ptp->info, &ts, &sts); if (err) return err; + + /* Filter out disabled or unavailable clocks */ + if (sts.pre_ts.tv_sec < 0 || sts.post_ts.tv_sec < 0) + return -EINVAL; + extoff->ts[i][0].sec = sts.pre_ts.tv_sec; extoff->ts[i][0].nsec = sts.pre_ts.tv_nsec; extoff->ts[i][1].sec = ts.tv_sec;