| .. | .. |
|---|
| 26 | 26 | #include <linux/syscalls.h> |
|---|
| 27 | 27 | #include <linux/compat.h> |
|---|
| 28 | 28 | #include <linux/rcupdate.h> |
|---|
| 29 | +#include <linux/time_namespace.h> |
|---|
| 30 | + |
|---|
| 31 | +#include <trace/hooks/fs.h> |
|---|
| 29 | 32 | |
|---|
| 30 | 33 | struct timerfd_ctx { |
|---|
| 31 | 34 | union { |
|---|
| .. | .. |
|---|
| 196 | 199 | } |
|---|
| 197 | 200 | |
|---|
| 198 | 201 | if (texp != 0) { |
|---|
| 202 | + if (flags & TFD_TIMER_ABSTIME) |
|---|
| 203 | + texp = timens_ktime_to_host(clockid, texp); |
|---|
| 199 | 204 | if (isalarm(ctx)) { |
|---|
| 200 | 205 | if (flags & TFD_TIMER_ABSTIME) |
|---|
| 201 | 206 | alarm_start(&ctx->t.alarm, texp); |
|---|
| .. | .. |
|---|
| 302 | 307 | static void timerfd_show(struct seq_file *m, struct file *file) |
|---|
| 303 | 308 | { |
|---|
| 304 | 309 | struct timerfd_ctx *ctx = file->private_data; |
|---|
| 305 | | - struct itimerspec t; |
|---|
| 310 | + struct timespec64 value, interval; |
|---|
| 306 | 311 | |
|---|
| 307 | 312 | spin_lock_irq(&ctx->wqh.lock); |
|---|
| 308 | | - t.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); |
|---|
| 309 | | - t.it_interval = ktime_to_timespec(ctx->tintv); |
|---|
| 313 | + value = ktime_to_timespec64(timerfd_get_remaining(ctx)); |
|---|
| 314 | + interval = ktime_to_timespec64(ctx->tintv); |
|---|
| 310 | 315 | spin_unlock_irq(&ctx->wqh.lock); |
|---|
| 311 | 316 | |
|---|
| 312 | 317 | seq_printf(m, |
|---|
| .. | .. |
|---|
| 318 | 323 | ctx->clockid, |
|---|
| 319 | 324 | (unsigned long long)ctx->ticks, |
|---|
| 320 | 325 | ctx->settime_flags, |
|---|
| 321 | | - (unsigned long long)t.it_value.tv_sec, |
|---|
| 322 | | - (unsigned long long)t.it_value.tv_nsec, |
|---|
| 323 | | - (unsigned long long)t.it_interval.tv_sec, |
|---|
| 324 | | - (unsigned long long)t.it_interval.tv_nsec); |
|---|
| 326 | + (unsigned long long)value.tv_sec, |
|---|
| 327 | + (unsigned long long)value.tv_nsec, |
|---|
| 328 | + (unsigned long long)interval.tv_sec, |
|---|
| 329 | + (unsigned long long)interval.tv_nsec); |
|---|
| 325 | 330 | } |
|---|
| 326 | 331 | #else |
|---|
| 327 | 332 | #define timerfd_show NULL |
|---|
| .. | .. |
|---|
| 388 | 393 | { |
|---|
| 389 | 394 | int ufd; |
|---|
| 390 | 395 | struct timerfd_ctx *ctx; |
|---|
| 396 | + char file_name_buf[32]; |
|---|
| 391 | 397 | |
|---|
| 392 | 398 | /* Check the TFD_* constants for consistency. */ |
|---|
| 393 | 399 | BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC); |
|---|
| .. | .. |
|---|
| 424 | 430 | |
|---|
| 425 | 431 | ctx->moffs = ktime_mono_to_real(0); |
|---|
| 426 | 432 | |
|---|
| 427 | | - ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, |
|---|
| 433 | + strlcpy(file_name_buf, "[timerfd]", sizeof(file_name_buf)); |
|---|
| 434 | + trace_android_vh_timerfd_create(file_name_buf, sizeof(file_name_buf)); |
|---|
| 435 | + ufd = anon_inode_getfd(file_name_buf, &timerfd_fops, ctx, |
|---|
| 428 | 436 | O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS)); |
|---|
| 429 | 437 | if (ufd < 0) |
|---|
| 430 | 438 | kfree(ctx); |
|---|
| .. | .. |
|---|
| 432 | 440 | return ufd; |
|---|
| 433 | 441 | } |
|---|
| 434 | 442 | |
|---|
| 435 | | -static int do_timerfd_settime(int ufd, int flags, |
|---|
| 443 | +static int do_timerfd_settime(int ufd, int flags, |
|---|
| 436 | 444 | const struct itimerspec64 *new, |
|---|
| 437 | 445 | struct itimerspec64 *old) |
|---|
| 438 | 446 | { |
|---|
| .. | .. |
|---|
| 471 | 479 | break; |
|---|
| 472 | 480 | } |
|---|
| 473 | 481 | spin_unlock_irq(&ctx->wqh.lock); |
|---|
| 474 | | - cpu_relax(); |
|---|
| 482 | + |
|---|
| 483 | + if (isalarm(ctx)) |
|---|
| 484 | + hrtimer_cancel_wait_running(&ctx->t.alarm.timer); |
|---|
| 485 | + else |
|---|
| 486 | + hrtimer_cancel_wait_running(&ctx->t.tmr); |
|---|
| 475 | 487 | } |
|---|
| 476 | 488 | |
|---|
| 477 | 489 | /* |
|---|
| .. | .. |
|---|
| 560 | 572 | } |
|---|
| 561 | 573 | |
|---|
| 562 | 574 | #ifdef CONFIG_COMPAT_32BIT_TIME |
|---|
| 563 | | -COMPAT_SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, |
|---|
| 564 | | - const struct compat_itimerspec __user *, utmr, |
|---|
| 565 | | - struct compat_itimerspec __user *, otmr) |
|---|
| 575 | +SYSCALL_DEFINE4(timerfd_settime32, int, ufd, int, flags, |
|---|
| 576 | + const struct old_itimerspec32 __user *, utmr, |
|---|
| 577 | + struct old_itimerspec32 __user *, otmr) |
|---|
| 566 | 578 | { |
|---|
| 567 | 579 | struct itimerspec64 new, old; |
|---|
| 568 | 580 | int ret; |
|---|
| 569 | 581 | |
|---|
| 570 | | - if (get_compat_itimerspec64(&new, utmr)) |
|---|
| 582 | + if (get_old_itimerspec32(&new, utmr)) |
|---|
| 571 | 583 | return -EFAULT; |
|---|
| 572 | 584 | ret = do_timerfd_settime(ufd, flags, &new, &old); |
|---|
| 573 | 585 | if (ret) |
|---|
| 574 | 586 | return ret; |
|---|
| 575 | | - if (otmr && put_compat_itimerspec64(&old, otmr)) |
|---|
| 587 | + if (otmr && put_old_itimerspec32(&old, otmr)) |
|---|
| 576 | 588 | return -EFAULT; |
|---|
| 577 | 589 | return ret; |
|---|
| 578 | 590 | } |
|---|
| 579 | 591 | |
|---|
| 580 | | -COMPAT_SYSCALL_DEFINE2(timerfd_gettime, int, ufd, |
|---|
| 581 | | - struct compat_itimerspec __user *, otmr) |
|---|
| 592 | +SYSCALL_DEFINE2(timerfd_gettime32, int, ufd, |
|---|
| 593 | + struct old_itimerspec32 __user *, otmr) |
|---|
| 582 | 594 | { |
|---|
| 583 | 595 | struct itimerspec64 kotmr; |
|---|
| 584 | 596 | int ret = do_timerfd_gettime(ufd, &kotmr); |
|---|
| 585 | 597 | if (ret) |
|---|
| 586 | 598 | return ret; |
|---|
| 587 | | - return put_compat_itimerspec64(&kotmr, otmr) ? -EFAULT : 0; |
|---|
| 599 | + return put_old_itimerspec32(&kotmr, otmr) ? -EFAULT : 0; |
|---|
| 588 | 600 | } |
|---|
| 589 | 601 | #endif |
|---|