root/kernel/time/itimer.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. itimer_get_remtime
  2. get_cpu_itimer
  3. do_getitimer
  4. SYSCALL_DEFINE2
  5. COMPAT_SYSCALL_DEFINE2
  6. it_real_fn
  7. set_cpu_itimer
  8. do_setitimer
  9. alarm_setitimer
  10. SYSCALL_DEFINE1
  11. SYSCALL_DEFINE3
  12. COMPAT_SYSCALL_DEFINE3

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) 1992 Darren Senn
   4  */
   5 
   6 /* These are all the functions necessary to implement itimers */
   7 
   8 #include <linux/mm.h>
   9 #include <linux/interrupt.h>
  10 #include <linux/syscalls.h>
  11 #include <linux/time.h>
  12 #include <linux/sched/signal.h>
  13 #include <linux/sched/cputime.h>
  14 #include <linux/posix-timers.h>
  15 #include <linux/hrtimer.h>
  16 #include <trace/events/timer.h>
  17 #include <linux/compat.h>
  18 
  19 #include <linux/uaccess.h>
  20 
  21 /**
  22  * itimer_get_remtime - get remaining time for the timer
  23  *
  24  * @timer: the timer to read
  25  *
  26  * Returns the delta between the expiry time and now, which can be
  27  * less than zero or 1usec for an pending expired timer
  28  */
  29 static struct timeval itimer_get_remtime(struct hrtimer *timer)
  30 {
  31         ktime_t rem = __hrtimer_get_remaining(timer, true);
  32 
  33         /*
  34          * Racy but safe: if the itimer expires after the above
  35          * hrtimer_get_remtime() call but before this condition
  36          * then we return 0 - which is correct.
  37          */
  38         if (hrtimer_active(timer)) {
  39                 if (rem <= 0)
  40                         rem = NSEC_PER_USEC;
  41         } else
  42                 rem = 0;
  43 
  44         return ktime_to_timeval(rem);
  45 }
  46 
  47 static void get_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
  48                            struct itimerval *const value)
  49 {
  50         u64 val, interval;
  51         struct cpu_itimer *it = &tsk->signal->it[clock_id];
  52 
  53         spin_lock_irq(&tsk->sighand->siglock);
  54 
  55         val = it->expires;
  56         interval = it->incr;
  57         if (val) {
  58                 u64 t, samples[CPUCLOCK_MAX];
  59 
  60                 thread_group_sample_cputime(tsk, samples);
  61                 t = samples[clock_id];
  62 
  63                 if (val < t)
  64                         /* about to fire */
  65                         val = TICK_NSEC;
  66                 else
  67                         val -= t;
  68         }
  69 
  70         spin_unlock_irq(&tsk->sighand->siglock);
  71 
  72         value->it_value = ns_to_timeval(val);
  73         value->it_interval = ns_to_timeval(interval);
  74 }
  75 
  76 int do_getitimer(int which, struct itimerval *value)
  77 {
  78         struct task_struct *tsk = current;
  79 
  80         switch (which) {
  81         case ITIMER_REAL:
  82                 spin_lock_irq(&tsk->sighand->siglock);
  83                 value->it_value = itimer_get_remtime(&tsk->signal->real_timer);
  84                 value->it_interval =
  85                         ktime_to_timeval(tsk->signal->it_real_incr);
  86                 spin_unlock_irq(&tsk->sighand->siglock);
  87                 break;
  88         case ITIMER_VIRTUAL:
  89                 get_cpu_itimer(tsk, CPUCLOCK_VIRT, value);
  90                 break;
  91         case ITIMER_PROF:
  92                 get_cpu_itimer(tsk, CPUCLOCK_PROF, value);
  93                 break;
  94         default:
  95                 return(-EINVAL);
  96         }
  97         return 0;
  98 }
  99 
 100 SYSCALL_DEFINE2(getitimer, int, which, struct itimerval __user *, value)
 101 {
 102         int error = -EFAULT;
 103         struct itimerval get_buffer;
 104 
 105         if (value) {
 106                 error = do_getitimer(which, &get_buffer);
 107                 if (!error &&
 108                     copy_to_user(value, &get_buffer, sizeof(get_buffer)))
 109                         error = -EFAULT;
 110         }
 111         return error;
 112 }
 113 
 114 #ifdef CONFIG_COMPAT
 115 COMPAT_SYSCALL_DEFINE2(getitimer, int, which,
 116                        struct compat_itimerval __user *, it)
 117 {
 118         struct itimerval kit;
 119         int error = do_getitimer(which, &kit);
 120 
 121         if (!error && put_compat_itimerval(it, &kit))
 122                 error = -EFAULT;
 123         return error;
 124 }
 125 #endif
 126 
 127 
 128 /*
 129  * The timer is automagically restarted, when interval != 0
 130  */
 131 enum hrtimer_restart it_real_fn(struct hrtimer *timer)
 132 {
 133         struct signal_struct *sig =
 134                 container_of(timer, struct signal_struct, real_timer);
 135         struct pid *leader_pid = sig->pids[PIDTYPE_TGID];
 136 
 137         trace_itimer_expire(ITIMER_REAL, leader_pid, 0);
 138         kill_pid_info(SIGALRM, SEND_SIG_PRIV, leader_pid);
 139 
 140         return HRTIMER_NORESTART;
 141 }
 142 
 143 static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
 144                            const struct itimerval *const value,
 145                            struct itimerval *const ovalue)
 146 {
 147         u64 oval, nval, ointerval, ninterval;
 148         struct cpu_itimer *it = &tsk->signal->it[clock_id];
 149 
 150         /*
 151          * Use the to_ktime conversion because that clamps the maximum
 152          * value to KTIME_MAX and avoid multiplication overflows.
 153          */
 154         nval = ktime_to_ns(timeval_to_ktime(value->it_value));
 155         ninterval = ktime_to_ns(timeval_to_ktime(value->it_interval));
 156 
 157         spin_lock_irq(&tsk->sighand->siglock);
 158 
 159         oval = it->expires;
 160         ointerval = it->incr;
 161         if (oval || nval) {
 162                 if (nval > 0)
 163                         nval += TICK_NSEC;
 164                 set_process_cpu_timer(tsk, clock_id, &nval, &oval);
 165         }
 166         it->expires = nval;
 167         it->incr = ninterval;
 168         trace_itimer_state(clock_id == CPUCLOCK_VIRT ?
 169                            ITIMER_VIRTUAL : ITIMER_PROF, value, nval);
 170 
 171         spin_unlock_irq(&tsk->sighand->siglock);
 172 
 173         if (ovalue) {
 174                 ovalue->it_value = ns_to_timeval(oval);
 175                 ovalue->it_interval = ns_to_timeval(ointerval);
 176         }
 177 }
 178 
 179 /*
 180  * Returns true if the timeval is in canonical form
 181  */
 182 #define timeval_valid(t) \
 183         (((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
 184 
 185 int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
 186 {
 187         struct task_struct *tsk = current;
 188         struct hrtimer *timer;
 189         ktime_t expires;
 190 
 191         /*
 192          * Validate the timevals in value.
 193          */
 194         if (!timeval_valid(&value->it_value) ||
 195             !timeval_valid(&value->it_interval))
 196                 return -EINVAL;
 197 
 198         switch (which) {
 199         case ITIMER_REAL:
 200 again:
 201                 spin_lock_irq(&tsk->sighand->siglock);
 202                 timer = &tsk->signal->real_timer;
 203                 if (ovalue) {
 204                         ovalue->it_value = itimer_get_remtime(timer);
 205                         ovalue->it_interval
 206                                 = ktime_to_timeval(tsk->signal->it_real_incr);
 207                 }
 208                 /* We are sharing ->siglock with it_real_fn() */
 209                 if (hrtimer_try_to_cancel(timer) < 0) {
 210                         spin_unlock_irq(&tsk->sighand->siglock);
 211                         hrtimer_cancel_wait_running(timer);
 212                         goto again;
 213                 }
 214                 expires = timeval_to_ktime(value->it_value);
 215                 if (expires != 0) {
 216                         tsk->signal->it_real_incr =
 217                                 timeval_to_ktime(value->it_interval);
 218                         hrtimer_start(timer, expires, HRTIMER_MODE_REL);
 219                 } else
 220                         tsk->signal->it_real_incr = 0;
 221 
 222                 trace_itimer_state(ITIMER_REAL, value, 0);
 223                 spin_unlock_irq(&tsk->sighand->siglock);
 224                 break;
 225         case ITIMER_VIRTUAL:
 226                 set_cpu_itimer(tsk, CPUCLOCK_VIRT, value, ovalue);
 227                 break;
 228         case ITIMER_PROF:
 229                 set_cpu_itimer(tsk, CPUCLOCK_PROF, value, ovalue);
 230                 break;
 231         default:
 232                 return -EINVAL;
 233         }
 234         return 0;
 235 }
 236 
 237 #ifdef __ARCH_WANT_SYS_ALARM
 238 
 239 /**
 240  * alarm_setitimer - set alarm in seconds
 241  *
 242  * @seconds:    number of seconds until alarm
 243  *              0 disables the alarm
 244  *
 245  * Returns the remaining time in seconds of a pending timer or 0 when
 246  * the timer is not active.
 247  *
 248  * On 32 bit machines the seconds value is limited to (INT_MAX/2) to avoid
 249  * negative timeval settings which would cause immediate expiry.
 250  */
 251 static unsigned int alarm_setitimer(unsigned int seconds)
 252 {
 253         struct itimerval it_new, it_old;
 254 
 255 #if BITS_PER_LONG < 64
 256         if (seconds > INT_MAX)
 257                 seconds = INT_MAX;
 258 #endif
 259         it_new.it_value.tv_sec = seconds;
 260         it_new.it_value.tv_usec = 0;
 261         it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
 262 
 263         do_setitimer(ITIMER_REAL, &it_new, &it_old);
 264 
 265         /*
 266          * We can't return 0 if we have an alarm pending ...  And we'd
 267          * better return too much than too little anyway
 268          */
 269         if ((!it_old.it_value.tv_sec && it_old.it_value.tv_usec) ||
 270               it_old.it_value.tv_usec >= 500000)
 271                 it_old.it_value.tv_sec++;
 272 
 273         return it_old.it_value.tv_sec;
 274 }
 275 
 276 /*
 277  * For backwards compatibility?  This can be done in libc so Alpha
 278  * and all newer ports shouldn't need it.
 279  */
 280 SYSCALL_DEFINE1(alarm, unsigned int, seconds)
 281 {
 282         return alarm_setitimer(seconds);
 283 }
 284 
 285 #endif
 286 
 287 SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value,
 288                 struct itimerval __user *, ovalue)
 289 {
 290         struct itimerval set_buffer, get_buffer;
 291         int error;
 292 
 293         if (value) {
 294                 if(copy_from_user(&set_buffer, value, sizeof(set_buffer)))
 295                         return -EFAULT;
 296         } else {
 297                 memset(&set_buffer, 0, sizeof(set_buffer));
 298                 printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer."
 299                             " Misfeature support will be removed\n",
 300                             current->comm);
 301         }
 302 
 303         error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL);
 304         if (error || !ovalue)
 305                 return error;
 306 
 307         if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer)))
 308                 return -EFAULT;
 309         return 0;
 310 }
 311 
 312 #ifdef CONFIG_COMPAT
 313 COMPAT_SYSCALL_DEFINE3(setitimer, int, which,
 314                        struct compat_itimerval __user *, in,
 315                        struct compat_itimerval __user *, out)
 316 {
 317         struct itimerval kin, kout;
 318         int error;
 319 
 320         if (in) {
 321                 if (get_compat_itimerval(&kin, in))
 322                         return -EFAULT;
 323         } else {
 324                 memset(&kin, 0, sizeof(kin));
 325         }
 326 
 327         error = do_setitimer(which, &kin, out ? &kout : NULL);
 328         if (error || !out)
 329                 return error;
 330         if (put_compat_itimerval(out, &kout))
 331                 return -EFAULT;
 332         return 0;
 333 }
 334 #endif

/* [<][>][^][v][top][bottom][index][help] */