diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-07 04:42:36 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-06-13 18:00:43 -0400 |
commit | b0dc12426ec404de99d7e75a12a22d9201d90914 (patch) | |
tree | 60927afef817fa4364bcc4e6206f6a4c1624e53c | |
parent | 1acbe7708b0313b33287bb4ffcbf26462ea3c588 (diff) |
posix-timers: Take compat timer_gettime(2) to native one
... and get rid of set_fs() in there
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20170607084241.28657-11-viro@ZenIV.linux.org.uk
-rw-r--r-- | kernel/compat.c | 17 | ||||
-rw-r--r-- | kernel/time/posix-stubs.c | 1 | ||||
-rw-r--r-- | kernel/time/posix-timers.c | 43 |
3 files changed, 35 insertions, 26 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index df39e2e00c47..1fb8cf7e691e 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -635,23 +635,6 @@ COMPAT_SYSCALL_DEFINE3(timer_create, clockid_t, which_clock, | |||
635 | return sys_timer_create(which_clock, event, created_timer_id); | 635 | return sys_timer_create(which_clock, event, created_timer_id); |
636 | } | 636 | } |
637 | 637 | ||
638 | COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, | ||
639 | struct compat_itimerspec __user *, setting) | ||
640 | { | ||
641 | long err; | ||
642 | mm_segment_t oldfs; | ||
643 | struct itimerspec ts; | ||
644 | |||
645 | oldfs = get_fs(); | ||
646 | set_fs(KERNEL_DS); | ||
647 | err = sys_timer_gettime(timer_id, | ||
648 | (struct itimerspec __user *) &ts); | ||
649 | set_fs(oldfs); | ||
650 | if (!err && put_compat_itimerspec(setting, &ts)) | ||
651 | return -EFAULT; | ||
652 | return err; | ||
653 | } | ||
654 | |||
655 | COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock, | 638 | COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock, |
656 | struct compat_timespec __user *, tp) | 639 | struct compat_timespec __user *, tp) |
657 | { | 640 | { |
diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c index ad263df132d6..f4a1962d1729 100644 --- a/kernel/time/posix-stubs.c +++ b/kernel/time/posix-stubs.c | |||
@@ -43,6 +43,7 @@ SYS_NI(alarm); | |||
43 | #endif | 43 | #endif |
44 | COMPAT_SYS_NI(clock_adjtime); | 44 | COMPAT_SYS_NI(clock_adjtime); |
45 | COMPAT_SYS_NI(timer_settime); | 45 | COMPAT_SYS_NI(timer_settime); |
46 | COMPAT_SYS_NI(timer_gettime); | ||
46 | 47 | ||
47 | /* | 48 | /* |
48 | * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC | 49 | * We preserve minimal support for CLOCK_REALTIME and CLOCK_MONOTONIC |
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index a73feac191f9..e82bb1fd614e 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c | |||
@@ -690,11 +690,8 @@ void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting) | |||
690 | } | 690 | } |
691 | 691 | ||
692 | /* Get the time remaining on a POSIX.1b interval timer. */ | 692 | /* Get the time remaining on a POSIX.1b interval timer. */ |
693 | SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, | 693 | static int do_timer_gettime(timer_t timer_id, struct itimerspec64 *setting) |
694 | struct itimerspec __user *, setting) | ||
695 | { | 694 | { |
696 | struct itimerspec64 cur_setting64; | ||
697 | struct itimerspec cur_setting; | ||
698 | struct k_itimer *timr; | 695 | struct k_itimer *timr; |
699 | const struct k_clock *kc; | 696 | const struct k_clock *kc; |
700 | unsigned long flags; | 697 | unsigned long flags; |
@@ -704,21 +701,49 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, | |||
704 | if (!timr) | 701 | if (!timr) |
705 | return -EINVAL; | 702 | return -EINVAL; |
706 | 703 | ||
707 | memset(&cur_setting64, 0, sizeof(cur_setting64)); | 704 | memset(setting, 0, sizeof(*setting)); |
708 | kc = timr->kclock; | 705 | kc = timr->kclock; |
709 | if (WARN_ON_ONCE(!kc || !kc->timer_get)) | 706 | if (WARN_ON_ONCE(!kc || !kc->timer_get)) |
710 | ret = -EINVAL; | 707 | ret = -EINVAL; |
711 | else | 708 | else |
712 | kc->timer_get(timr, &cur_setting64); | 709 | kc->timer_get(timr, setting); |
713 | 710 | ||
714 | unlock_timer(timr, flags); | 711 | unlock_timer(timr, flags); |
712 | return ret; | ||
713 | } | ||
715 | 714 | ||
716 | cur_setting = itimerspec64_to_itimerspec(&cur_setting64); | 715 | /* Get the time remaining on a POSIX.1b interval timer. */ |
717 | if (!ret && copy_to_user(setting, &cur_setting, sizeof (cur_setting))) | 716 | SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, |
718 | return -EFAULT; | 717 | struct itimerspec __user *, setting) |
718 | { | ||
719 | struct itimerspec64 cur_setting64; | ||
719 | 720 | ||
721 | int ret = do_timer_gettime(timer_id, &cur_setting64); | ||
722 | if (!ret) { | ||
723 | struct itimerspec cur_setting; | ||
724 | cur_setting = itimerspec64_to_itimerspec(&cur_setting64); | ||
725 | if (copy_to_user(setting, &cur_setting, sizeof (cur_setting))) | ||
726 | ret = -EFAULT; | ||
727 | } | ||
728 | return ret; | ||
729 | } | ||
730 | |||
731 | #ifdef CONFIG_COMPAT | ||
732 | COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, | ||
733 | struct compat_itimerspec __user *, setting) | ||
734 | { | ||
735 | struct itimerspec64 cur_setting64; | ||
736 | |||
737 | int ret = do_timer_gettime(timer_id, &cur_setting64); | ||
738 | if (!ret) { | ||
739 | struct itimerspec cur_setting; | ||
740 | cur_setting = itimerspec64_to_itimerspec(&cur_setting64); | ||
741 | if (put_compat_itimerspec(setting, &cur_setting)) | ||
742 | ret = -EFAULT; | ||
743 | } | ||
720 | return ret; | 744 | return ret; |
721 | } | 745 | } |
746 | #endif | ||
722 | 747 | ||
723 | /* | 748 | /* |
724 | * Get the number of overruns of a POSIX.1b interval timer. This is to | 749 | * Get the number of overruns of a POSIX.1b interval timer. This is to |