Merge branches 'work.misc' and 'work.dcache' of git://git.kernel.org/pub/scm/linux...
[sfrench/cifs-2.6.git] / kernel / time / posix-timers.c
index 66321cbdf90cd5b94e3db7390a4a19866c05b0c0..f23cc46ecf3ed10bbd0bd940c87f3e813dd5bf4c 100644 (file)
@@ -219,21 +219,21 @@ static int posix_ktime_get_ts(clockid_t which_clock, struct timespec64 *tp)
  */
 static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec64 *tp)
 {
-       getrawmonotonic64(tp);
+       ktime_get_raw_ts64(tp);
        return 0;
 }
 
 
 static int posix_get_realtime_coarse(clockid_t which_clock, struct timespec64 *tp)
 {
-       *tp = current_kernel_time64();
+       ktime_get_coarse_real_ts64(tp);
        return 0;
 }
 
 static int posix_get_monotonic_coarse(clockid_t which_clock,
                                                struct timespec64 *tp)
 {
-       *tp = get_monotonic_coarse64();
+       ktime_get_coarse_ts64(tp);
        return 0;
 }
 
@@ -245,13 +245,13 @@ static int posix_get_coarse_res(const clockid_t which_clock, struct timespec64 *
 
 static int posix_get_boottime(const clockid_t which_clock, struct timespec64 *tp)
 {
-       get_monotonic_boottime64(tp);
+       ktime_get_boottime_ts64(tp);
        return 0;
 }
 
 static int posix_get_tai(clockid_t which_clock, struct timespec64 *tp)
 {
-       timekeeping_clocktai64(tp);
+       ktime_get_clocktai_ts64(tp);
        return 0;
 }
 
@@ -274,6 +274,17 @@ static __init int init_posix_timers(void)
 }
 __initcall(init_posix_timers);
 
+/*
+ * The siginfo si_overrun field and the return value of timer_getoverrun(2)
+ * are of type int. Clamp the overrun value to INT_MAX
+ */
+static inline int timer_overrun_to_int(struct k_itimer *timr, int baseval)
+{
+       s64 sum = timr->it_overrun_last + (s64)baseval;
+
+       return sum > (s64)INT_MAX ? INT_MAX : (int)sum;
+}
+
 static void common_hrtimer_rearm(struct k_itimer *timr)
 {
        struct hrtimer *timer = &timr->it.real.timer;
@@ -281,9 +292,8 @@ static void common_hrtimer_rearm(struct k_itimer *timr)
        if (!timr->it_interval)
                return;
 
-       timr->it_overrun += (unsigned int) hrtimer_forward(timer,
-                                               timer->base->get_time(),
-                                               timr->it_interval);
+       timr->it_overrun += hrtimer_forward(timer, timer->base->get_time(),
+                                           timr->it_interval);
        hrtimer_restart(timer);
 }
 
@@ -312,10 +322,10 @@ void posixtimer_rearm(struct siginfo *info)
 
                timr->it_active = 1;
                timr->it_overrun_last = timr->it_overrun;
-               timr->it_overrun = -1;
+               timr->it_overrun = -1LL;
                ++timr->it_requeue_pending;
 
-               info->si_overrun += timr->it_overrun_last;
+               info->si_overrun = timer_overrun_to_int(timr, info->si_overrun);
        }
 
        unlock_timer(timr, flags);
@@ -409,9 +419,8 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
                                        now = ktime_add(now, kj);
                        }
 #endif
-                       timr->it_overrun += (unsigned int)
-                               hrtimer_forward(timer, now,
-                                               timr->it_interval);
+                       timr->it_overrun += hrtimer_forward(timer, now,
+                                                           timr->it_interval);
                        ret = HRTIMER_RESTART;
                        ++timr->it_requeue_pending;
                        timr->it_active = 1;
@@ -515,7 +524,7 @@ static int do_timer_create(clockid_t which_clock, struct sigevent *event,
        new_timer->it_id = (timer_t) new_timer_id;
        new_timer->it_clock = which_clock;
        new_timer->kclock = kc;
-       new_timer->it_overrun = -1;
+       new_timer->it_overrun = -1LL;
 
        if (event) {
                rcu_read_lock();
@@ -636,11 +645,11 @@ static ktime_t common_hrtimer_remaining(struct k_itimer *timr, ktime_t now)
        return __hrtimer_expires_remaining_adjusted(timer, now);
 }
 
-static int common_hrtimer_forward(struct k_itimer *timr, ktime_t now)
+static s64 common_hrtimer_forward(struct k_itimer *timr, ktime_t now)
 {
        struct hrtimer *timer = &timr->it.real.timer;
 
-       return (int)hrtimer_forward(timer, now, timr->it_interval);
+       return hrtimer_forward(timer, now, timr->it_interval);
 }
 
 /*
@@ -734,7 +743,7 @@ static int do_timer_gettime(timer_t timer_id,  struct itimerspec64 *setting)
 
 /* Get the time remaining on a POSIX.1b interval timer. */
 SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
-               struct itimerspec __user *, setting)
+               struct __kernel_itimerspec __user *, setting)
 {
        struct itimerspec64 cur_setting;
 
@@ -746,7 +755,8 @@ SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
        return ret;
 }
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_COMPAT_32BIT_TIME
+
 COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
                       struct compat_itimerspec __user *, setting)
 {
@@ -759,6 +769,7 @@ COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,
        }
        return ret;
 }
+
 #endif
 
 /*
@@ -780,7 +791,7 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)
        if (!timr)
                return -EINVAL;
 
-       overrun = timr->it_overrun_last;
+       overrun = timer_overrun_to_int(timr, 0);
        unlock_timer(timr, flags);
 
        return overrun;
@@ -897,8 +908,8 @@ retry:
 
 /* Set a POSIX.1b interval timer */
 SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
-               const struct itimerspec __user *, new_setting,
-               struct itimerspec __user *, old_setting)
+               const struct __kernel_itimerspec __user *, new_setting,
+               struct __kernel_itimerspec __user *, old_setting)
 {
        struct itimerspec64 new_spec, old_spec;
        struct itimerspec64 *rtn = old_setting ? &old_spec : NULL;
@@ -918,7 +929,7 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
        return error;
 }
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_COMPAT_32BIT_TIME
 COMPAT_SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
                       struct compat_itimerspec __user *, new,
                       struct compat_itimerspec __user *, old)