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

time: Change posix clocks ops interfaces to use timespec64

struct timespec is not y2038 safe on 32 bit machines.

The posix clocks apis use struct timespec directly and through struct
itimerspec.

Replace the posix clock interfaces to use struct timespec64 and struct
itimerspec64 instead. Also fix up their implementations accordingly.

Note that the clock_getres() interface has also been changed to use
timespec64 even though this particular interface is not affected by the
y2038 problem. This helps verification for internal kernel code for y2038
readiness by getting rid of time_t/ timeval/ timespec.

Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Cc: arnd@arndb.de
Cc: y2038@lists.linaro.org
Cc: netdev@vger.kernel.org
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: john.stultz@linaro.org
Link: http://lkml.kernel.org/r/1490555058-4603-3-git-send-email-deepa.kernel@gmail.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by

Deepa Dinamani and committed by
Thomas Gleixner
d340266e 2ac00f17

+36 -26
+7 -11
drivers/ptp/ptp_clock.c
··· 97 97 98 98 /* posix clock implementation */ 99 99 100 - static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) 100 + static int ptp_clock_getres(struct posix_clock *pc, struct timespec64 *tp) 101 101 { 102 102 tp->tv_sec = 0; 103 103 tp->tv_nsec = 1; 104 104 return 0; 105 105 } 106 106 107 - static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) 107 + static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp) 108 108 { 109 109 struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); 110 - struct timespec64 ts = timespec_to_timespec64(*tp); 111 110 112 - return ptp->info->settime64(ptp->info, &ts); 111 + return ptp->info->settime64(ptp->info, tp); 113 112 } 114 113 115 - static int ptp_clock_gettime(struct posix_clock *pc, struct timespec *tp) 114 + static int ptp_clock_gettime(struct posix_clock *pc, struct timespec64 *tp) 116 115 { 117 116 struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); 118 - struct timespec64 ts; 119 117 int err; 120 118 121 - err = ptp->info->gettime64(ptp->info, &ts); 122 - if (!err) 123 - *tp = timespec64_to_timespec(ts); 119 + err = ptp->info->gettime64(ptp->info, tp); 124 120 return err; 125 121 } 126 122 ··· 129 133 ops = ptp->info; 130 134 131 135 if (tx->modes & ADJ_SETOFFSET) { 132 - struct timespec ts; 136 + struct timespec64 ts; 133 137 ktime_t kt; 134 138 s64 delta; 135 139 ··· 142 146 if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC) 143 147 return -EINVAL; 144 148 145 - kt = timespec_to_ktime(ts); 149 + kt = timespec64_to_ktime(ts); 146 150 delta = ktime_to_ns(kt); 147 151 err = ops->adjtime(ops, delta); 148 152 } else if (tx->modes & ADJ_FREQUENCY) {
+5 -5
include/linux/posix-clock.h
··· 59 59 60 60 int (*clock_adjtime)(struct posix_clock *pc, struct timex *tx); 61 61 62 - int (*clock_gettime)(struct posix_clock *pc, struct timespec *ts); 62 + int (*clock_gettime)(struct posix_clock *pc, struct timespec64 *ts); 63 63 64 - int (*clock_getres) (struct posix_clock *pc, struct timespec *ts); 64 + int (*clock_getres) (struct posix_clock *pc, struct timespec64 *ts); 65 65 66 66 int (*clock_settime)(struct posix_clock *pc, 67 - const struct timespec *ts); 67 + const struct timespec64 *ts); 68 68 69 69 int (*timer_create) (struct posix_clock *pc, struct k_itimer *kit); 70 70 71 71 int (*timer_delete) (struct posix_clock *pc, struct k_itimer *kit); 72 72 73 73 void (*timer_gettime)(struct posix_clock *pc, 74 - struct k_itimer *kit, struct itimerspec *tsp); 74 + struct k_itimer *kit, struct itimerspec64 *tsp); 75 75 76 76 int (*timer_settime)(struct posix_clock *pc, 77 77 struct k_itimer *kit, int flags, 78 - struct itimerspec *tsp, struct itimerspec *old); 78 + struct itimerspec64 *tsp, struct itimerspec64 *old); 79 79 /* 80 80 * Optional character device methods: 81 81 */
+24 -10
kernel/time/posix-clock.c
··· 300 300 static int pc_clock_gettime(clockid_t id, struct timespec *ts) 301 301 { 302 302 struct posix_clock_desc cd; 303 + struct timespec64 ts64; 303 304 int err; 304 305 305 306 err = get_clock_desc(id, &cd); 306 307 if (err) 307 308 return err; 308 309 309 - if (cd.clk->ops.clock_gettime) 310 - err = cd.clk->ops.clock_gettime(cd.clk, ts); 310 + if (cd.clk->ops.clock_gettime) { 311 + err = cd.clk->ops.clock_gettime(cd.clk, &ts64); 312 + *ts = timespec64_to_timespec(ts64); 313 + } 311 314 else 312 315 err = -EOPNOTSUPP; 313 316 ··· 322 319 static int pc_clock_getres(clockid_t id, struct timespec *ts) 323 320 { 324 321 struct posix_clock_desc cd; 322 + struct timespec64 ts64; 325 323 int err; 326 324 327 325 err = get_clock_desc(id, &cd); 328 326 if (err) 329 327 return err; 330 328 331 - if (cd.clk->ops.clock_getres) 332 - err = cd.clk->ops.clock_getres(cd.clk, ts); 329 + if (cd.clk->ops.clock_getres) { 330 + err = cd.clk->ops.clock_getres(cd.clk, &ts64); 331 + *ts = timespec64_to_timespec(ts64); 332 + } 333 333 else 334 334 err = -EOPNOTSUPP; 335 335 ··· 343 337 344 338 static int pc_clock_settime(clockid_t id, const struct timespec *ts) 345 339 { 340 + struct timespec64 ts64 = timespec_to_timespec64(*ts); 346 341 struct posix_clock_desc cd; 347 342 int err; 348 343 ··· 357 350 } 358 351 359 352 if (cd.clk->ops.clock_settime) 360 - err = cd.clk->ops.clock_settime(cd.clk, ts); 353 + err = cd.clk->ops.clock_settime(cd.clk, &ts64); 361 354 else 362 355 err = -EOPNOTSUPP; 363 356 out: ··· 410 403 { 411 404 clockid_t id = kit->it_clock; 412 405 struct posix_clock_desc cd; 406 + struct itimerspec64 ts64; 413 407 414 408 if (get_clock_desc(id, &cd)) 415 409 return; 416 410 417 - if (cd.clk->ops.timer_gettime) 418 - cd.clk->ops.timer_gettime(cd.clk, kit, ts); 419 - 411 + if (cd.clk->ops.timer_gettime) { 412 + cd.clk->ops.timer_gettime(cd.clk, kit, &ts64); 413 + *ts = itimerspec64_to_itimerspec(&ts64); 414 + } 420 415 put_clock_desc(&cd); 421 416 } 422 417 423 418 static int pc_timer_settime(struct k_itimer *kit, int flags, 424 419 struct itimerspec *ts, struct itimerspec *old) 425 420 { 421 + struct itimerspec64 ts64 = itimerspec_to_itimerspec64(ts); 426 422 clockid_t id = kit->it_clock; 427 423 struct posix_clock_desc cd; 424 + struct itimerspec64 old64; 428 425 int err; 429 426 430 427 err = get_clock_desc(id, &cd); 431 428 if (err) 432 429 return err; 433 430 434 - if (cd.clk->ops.timer_settime) 435 - err = cd.clk->ops.timer_settime(cd.clk, kit, flags, ts, old); 431 + if (cd.clk->ops.timer_settime) { 432 + err = cd.clk->ops.timer_settime(cd.clk, kit, flags, &ts64, &old64); 433 + if (old) 434 + *old = itimerspec64_to_itimerspec(&old64); 435 + } 436 436 else 437 437 err = -EOPNOTSUPP; 438 438