]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - kernel/time/posix-timers.c
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[karo-tx-linux.git] / kernel / time / posix-timers.c
index 1e6623d7675019ae9c1dcc3dc273c03d761d5931..4d7b2ce09c27cb6b77b1b2d18e379c4efed48d71 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/mutex.h>
+#include <linux/sched/task.h>
 
 #include <linux/uaccess.h>
 #include <linux/list.h>
@@ -129,12 +130,12 @@ static struct k_clock posix_clocks[MAX_CLOCKS];
 /*
  * These ones are defined below.
  */
-static int common_nsleep(const clockid_t, int flags, struct timespec *t,
+static int common_nsleep(const clockid_t, int flags, struct timespec64 *t,
                         struct timespec __user *rmtp);
 static int common_timer_create(struct k_itimer *new_timer);
-static void common_timer_get(struct k_itimer *, struct itimerspec *);
+static void common_timer_get(struct k_itimer *, struct itimerspec64 *);
 static int common_timer_set(struct k_itimer *, int,
-                           struct itimerspec *, struct itimerspec *);
+                           struct itimerspec64 *, struct itimerspec64 *);
 static int common_timer_del(struct k_itimer *timer);
 
 static enum hrtimer_restart posix_timer_fn(struct hrtimer *data);
@@ -203,17 +204,17 @@ static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
 }
 
 /* Get clock_realtime */
-static int posix_clock_realtime_get(clockid_t which_clock, struct timespec *tp)
+static int posix_clock_realtime_get(clockid_t which_clock, struct timespec64 *tp)
 {
-       ktime_get_real_ts(tp);
+       ktime_get_real_ts64(tp);
        return 0;
 }
 
 /* Set clock_realtime */
 static int posix_clock_realtime_set(const clockid_t which_clock,
-                                   const struct timespec *tp)
+                                   const struct timespec64 *tp)
 {
-       return do_sys_settimeofday(tp, NULL);
+       return do_sys_settimeofday64(tp, NULL);
 }
 
 static int posix_clock_realtime_adj(const clockid_t which_clock,
@@ -225,54 +226,54 @@ static int posix_clock_realtime_adj(const clockid_t which_clock,
 /*
  * Get monotonic time for posix timers
  */
-static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp)
+static int posix_ktime_get_ts(clockid_t which_clock, struct timespec64 *tp)
 {
-       ktime_get_ts(tp);
+       ktime_get_ts64(tp);
        return 0;
 }
 
 /*
  * Get monotonic-raw time for posix timers
  */
-static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp)
+static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec64 *tp)
 {
-       getrawmonotonic(tp);
+       getrawmonotonic64(tp);
        return 0;
 }
 
 
-static int posix_get_realtime_coarse(clockid_t which_clock, struct timespec *tp)
+static int posix_get_realtime_coarse(clockid_t which_clock, struct timespec64 *tp)
 {
-       *tp = current_kernel_time();
+       *tp = current_kernel_time64();
        return 0;
 }
 
 static int posix_get_monotonic_coarse(clockid_t which_clock,
-                                               struct timespec *tp)
+                                               struct timespec64 *tp)
 {
-       *tp = get_monotonic_coarse();
+       *tp = get_monotonic_coarse64();
        return 0;
 }
 
-static int posix_get_coarse_res(const clockid_t which_clock, struct timespec *tp)
+static int posix_get_coarse_res(const clockid_t which_clock, struct timespec64 *tp)
 {
-       *tp = ktime_to_timespec(KTIME_LOW_RES);
+       *tp = ktime_to_timespec64(KTIME_LOW_RES);
        return 0;
 }
 
-static int posix_get_boottime(const clockid_t which_clock, struct timespec *tp)
+static int posix_get_boottime(const clockid_t which_clock, struct timespec64 *tp)
 {
-       get_monotonic_boottime(tp);
+       get_monotonic_boottime64(tp);
        return 0;
 }
 
-static int posix_get_tai(clockid_t which_clock, struct timespec *tp)
+static int posix_get_tai(clockid_t which_clock, struct timespec64 *tp)
 {
-       timekeeping_clocktai(tp);
+       timekeeping_clocktai64(tp);
        return 0;
 }
 
-static int posix_get_hrtimer_res(clockid_t which_clock, struct timespec *tp)
+static int posix_get_hrtimer_res(clockid_t which_clock, struct timespec64 *tp)
 {
        tp->tv_sec = 0;
        tp->tv_nsec = hrtimer_resolution;
@@ -733,18 +734,18 @@ static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags)
  * report.
  */
 static void
-common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
+common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
 {
        ktime_t now, remaining, iv;
        struct hrtimer *timer = &timr->it.real.timer;
 
-       memset(cur_setting, 0, sizeof(struct itimerspec));
+       memset(cur_setting, 0, sizeof(*cur_setting));
 
        iv = timr->it.real.interval;
 
        /* interval timer ? */
        if (iv)
-               cur_setting->it_interval = ktime_to_timespec(iv);
+               cur_setting->it_interval = ktime_to_timespec64(iv);
        else if (!hrtimer_active(timer) &&
                 (timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
                return;
@@ -770,13 +771,14 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
                if ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)
                        cur_setting->it_value.tv_nsec = 1;
        } else
-               cur_setting->it_value = ktime_to_timespec(remaining);
+               cur_setting->it_value = ktime_to_timespec64(remaining);
 }
 
 /* Get the time remaining on a POSIX.1b interval timer. */
 SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
                struct itimerspec __user *, setting)
 {
+       struct itimerspec64 cur_setting64;
        struct itimerspec cur_setting;
        struct k_itimer *timr;
        struct k_clock *kc;
@@ -791,10 +793,11 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
        if (WARN_ON_ONCE(!kc || !kc->timer_get))
                ret = -EINVAL;
        else
-               kc->timer_get(timr, &cur_setting);
+               kc->timer_get(timr, &cur_setting64);
 
        unlock_timer(timr, flags);
 
+       cur_setting = itimerspec64_to_itimerspec(&cur_setting64);
        if (!ret && copy_to_user(setting, &cur_setting, sizeof (cur_setting)))
                return -EFAULT;
 
@@ -830,7 +833,7 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)
 /* timr->it_lock is taken. */
 static int
 common_timer_set(struct k_itimer *timr, int flags,
-                struct itimerspec *new_setting, struct itimerspec *old_setting)
+                struct itimerspec64 *new_setting, struct itimerspec64 *old_setting)
 {
        struct hrtimer *timer = &timr->it.real.timer;
        enum hrtimer_mode mode;
@@ -859,10 +862,10 @@ common_timer_set(struct k_itimer *timr, int flags,
        hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
        timr->it.real.timer.function = posix_timer_fn;
 
-       hrtimer_set_expires(timer, timespec_to_ktime(new_setting->it_value));
+       hrtimer_set_expires(timer, timespec64_to_ktime(new_setting->it_value));
 
        /* Convert interval */
-       timr->it.real.interval = timespec_to_ktime(new_setting->it_interval);
+       timr->it.real.interval = timespec64_to_ktime(new_setting->it_interval);
 
        /* SIGEV_NONE timers are not queued ! See common_timer_get */
        if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) {
@@ -882,21 +885,23 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
                const struct itimerspec __user *, new_setting,
                struct itimerspec __user *, old_setting)
 {
-       struct k_itimer *timr;
+       struct itimerspec64 new_spec64, old_spec64;
+       struct itimerspec64 *rtn = old_setting ? &old_spec64 : NULL;
        struct itimerspec new_spec, old_spec;
-       int error = 0;
+       struct k_itimer *timr;
        unsigned long flag;
-       struct itimerspec *rtn = old_setting ? &old_spec : NULL;
        struct k_clock *kc;
+       int error = 0;
 
        if (!new_setting)
                return -EINVAL;
 
        if (copy_from_user(&new_spec, new_setting, sizeof (new_spec)))
                return -EFAULT;
+       new_spec64 = itimerspec_to_itimerspec64(&new_spec);
 
-       if (!timespec_valid(&new_spec.it_interval) ||
-           !timespec_valid(&new_spec.it_value))
+       if (!timespec64_valid(&new_spec64.it_interval) ||
+           !timespec64_valid(&new_spec64.it_value))
                return -EINVAL;
 retry:
        timr = lock_timer(timer_id, &flag);
@@ -907,7 +912,7 @@ retry:
        if (WARN_ON_ONCE(!kc || !kc->timer_set))
                error = -EINVAL;
        else
-               error = kc->timer_set(timr, flags, &new_spec, rtn);
+               error = kc->timer_set(timr, flags, &new_spec64, rtn);
 
        unlock_timer(timr, flag);
        if (error == TIMER_RETRY) {
@@ -915,6 +920,7 @@ retry:
                goto retry;
        }
 
+       old_spec = itimerspec64_to_itimerspec(&old_spec64);
        if (old_setting && !error &&
            copy_to_user(old_setting, &old_spec, sizeof (old_spec)))
                error = -EFAULT;
@@ -1013,6 +1019,7 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
                const struct timespec __user *, tp)
 {
        struct k_clock *kc = clockid_to_kclock(which_clock);
+       struct timespec64 new_tp64;
        struct timespec new_tp;
 
        if (!kc || !kc->clock_set)
@@ -1020,21 +1027,24 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
 
        if (copy_from_user(&new_tp, tp, sizeof (*tp)))
                return -EFAULT;
+       new_tp64 = timespec_to_timespec64(new_tp);
 
-       return kc->clock_set(which_clock, &new_tp);
+       return kc->clock_set(which_clock, &new_tp64);
 }
 
 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
                struct timespec __user *,tp)
 {
        struct k_clock *kc = clockid_to_kclock(which_clock);
+       struct timespec64 kernel_tp64;
        struct timespec kernel_tp;
        int error;
 
        if (!kc)
                return -EINVAL;
 
-       error = kc->clock_get(which_clock, &kernel_tp);
+       error = kc->clock_get(which_clock, &kernel_tp64);
+       kernel_tp = timespec64_to_timespec(kernel_tp64);
 
        if (!error && copy_to_user(tp, &kernel_tp, sizeof (kernel_tp)))
                error = -EFAULT;
@@ -1069,13 +1079,15 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
                struct timespec __user *, tp)
 {
        struct k_clock *kc = clockid_to_kclock(which_clock);
+       struct timespec64 rtn_tp64;
        struct timespec rtn_tp;
        int error;
 
        if (!kc)
                return -EINVAL;
 
-       error = kc->clock_getres(which_clock, &rtn_tp);
+       error = kc->clock_getres(which_clock, &rtn_tp64);
+       rtn_tp = timespec64_to_timespec(rtn_tp64);
 
        if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp)))
                error = -EFAULT;
@@ -1087,7 +1099,7 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock,
  * nanosleep for monotonic and realtime clocks
  */
 static int common_nsleep(const clockid_t which_clock, int flags,
-                        struct timespec *tsave, struct timespec __user *rmtp)
+                        struct timespec64 *tsave, struct timespec __user *rmtp)
 {
        return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
                                 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
@@ -1099,6 +1111,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
                struct timespec __user *, rmtp)
 {
        struct k_clock *kc = clockid_to_kclock(which_clock);
+       struct timespec64 t64;
        struct timespec t;
 
        if (!kc)
@@ -1109,10 +1122,11 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
        if (copy_from_user(&t, rqtp, sizeof (struct timespec)))
                return -EFAULT;
 
-       if (!timespec_valid(&t))
+       t64 = timespec_to_timespec64(t);
+       if (!timespec64_valid(&t64))
                return -EINVAL;
 
-       return kc->nsleep(which_clock, flags, &t, rmtp);
+       return kc->nsleep(which_clock, flags, &t64, rmtp);
 }
 
 /*