1/* 2 * linux/kernel/itimer.c 3 * 4 * Copyright (C) 1992 Darren Senn 5 */ 6 7/* These are all the functions necessary to implement itimers */ 8 9#include <linux/mm.h> 10#include <linux/interrupt.h> 11#include <linux/syscalls.h> 12#include <linux/time.h> 13#include <linux/posix-timers.h> 14#include <linux/hrtimer.h> 15 16#include <asm/uaccess.h> 17 18/** 19 * itimer_get_remtime - get remaining time for the timer 20 * 21 * @timer: the timer to read 22 * 23 * Returns the delta between the expiry time and now, which can be 24 * less than zero or 1usec for an pending expired timer 25 */ 26static struct timeval itimer_get_remtime(struct hrtimer *timer) 27{ 28 ktime_t rem = hrtimer_get_remaining(timer); 29 30 /* 31 * Racy but safe: if the itimer expires after the above 32 * hrtimer_get_remtime() call but before this condition 33 * then we return 0 - which is correct. 34 */ 35 if (hrtimer_active(timer)) { 36 if (rem.tv64 <= 0) 37 rem.tv64 = NSEC_PER_USEC; 38 } else 39 rem.tv64 = 0; 40 41 return ktime_to_timeval(rem); 42} 43 44int do_getitimer(int which, struct itimerval *value) 45{ 46 struct task_struct *tsk = current; 47 cputime_t cinterval, cval; 48 49 switch (which) { 50 case ITIMER_REAL: 51 spin_lock_irq(&tsk->sighand->siglock); 52 value->it_value = itimer_get_remtime(&tsk->signal->real_timer); 53 value->it_interval = 54 ktime_to_timeval(tsk->signal->it_real_incr); 55 spin_unlock_irq(&tsk->sighand->siglock); 56 break; 57 case ITIMER_VIRTUAL: 58 read_lock(&tasklist_lock); 59 spin_lock_irq(&tsk->sighand->siglock); 60 cval = tsk->signal->it_virt_expires; 61 cinterval = tsk->signal->it_virt_incr; 62 if (!cputime_eq(cval, cputime_zero)) { 63 struct task_struct *t = tsk; 64 cputime_t utime = tsk->signal->utime; 65 do { 66 utime = cputime_add(utime, t->utime); 67 t = next_thread(t); 68 } while (t != tsk); 69 if (cputime_le(cval, utime)) { /* about to fire */ 70 cval = jiffies_to_cputime(1); 71 } else { 72 cval = cputime_sub(cval, utime); 73 } 74 } 75 spin_unlock_irq(&tsk->sighand->siglock); 76 read_unlock(&tasklist_lock); 77 cputime_to_timeval(cval, &value->it_value); 78 cputime_to_timeval(cinterval, &value->it_interval); 79 break; 80 case ITIMER_PROF: 81 read_lock(&tasklist_lock); 82 spin_lock_irq(&tsk->sighand->siglock); 83 cval = tsk->signal->it_prof_expires; 84 cinterval = tsk->signal->it_prof_incr; 85 if (!cputime_eq(cval, cputime_zero)) { 86 struct task_struct *t = tsk; 87 cputime_t ptime = cputime_add(tsk->signal->utime, 88 tsk->signal->stime); 89 do { 90 ptime = cputime_add(ptime, 91 cputime_add(t->utime, 92 t->stime)); 93 t = next_thread(t); 94 } while (t != tsk); 95 if (cputime_le(cval, ptime)) { /* about to fire */ 96 cval = jiffies_to_cputime(1); 97 } else { 98 cval = cputime_sub(cval, ptime); 99 } 100 } 101 spin_unlock_irq(&tsk->sighand->siglock); 102 read_unlock(&tasklist_lock); 103 cputime_to_timeval(cval, &value->it_value); 104 cputime_to_timeval(cinterval, &value->it_interval); 105 break; 106 default: 107 return(-EINVAL); 108 } 109 return 0; 110} 111 112asmlinkage long sys_getitimer(int which, struct itimerval __user *value) 113{ 114 int error = -EFAULT; 115 struct itimerval get_buffer; 116 117 if (value) { 118 error = do_getitimer(which, &get_buffer); 119 if (!error && 120 copy_to_user(value, &get_buffer, sizeof(get_buffer))) 121 error = -EFAULT; 122 } 123 return error; 124} 125 126 127/* 128 * The timer is automagically restarted, when interval != 0 129 */ 130enum hrtimer_restart it_real_fn(struct hrtimer *timer) 131{ 132 struct signal_struct *sig = 133 container_of(timer, struct signal_struct, real_timer); 134 135 send_group_sig_info(SIGALRM, SEND_SIG_PRIV, sig->tsk); 136 137 return HRTIMER_NORESTART; 138} 139 140/* 141 * Returns true if the timeval is in canonical form 142 */ 143#define timeval_valid(t) \ 144 (((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC)) 145 146int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) 147{ 148 struct task_struct *tsk = current; 149 struct hrtimer *timer; 150 ktime_t expires; 151 cputime_t cval, cinterval, nval, ninterval; 152 153 /* 154 * Validate the timevals in value. 155 */ 156 if (!timeval_valid(&value->it_value) || 157 !timeval_valid(&value->it_interval)) 158 return -EINVAL; 159 160 switch (which) { 161 case ITIMER_REAL: 162again: 163 spin_lock_irq(&tsk->sighand->siglock); 164 timer = &tsk->signal->real_timer; 165 if (ovalue) { 166 ovalue->it_value = itimer_get_remtime(timer); 167 ovalue->it_interval 168 = ktime_to_timeval(tsk->signal->it_real_incr); 169 } 170 /* We are sharing ->siglock with it_real_fn() */ 171 if (hrtimer_try_to_cancel(timer) < 0) { 172 spin_unlock_irq(&tsk->sighand->siglock); 173 goto again; 174 } 175 expires = timeval_to_ktime(value->it_value); 176 if (expires.tv64 != 0) { 177 tsk->signal->it_real_incr = 178 timeval_to_ktime(value->it_interval); 179 hrtimer_start(timer, expires, HRTIMER_MODE_REL); 180 } else 181 tsk->signal->it_real_incr.tv64 = 0; 182 183 spin_unlock_irq(&tsk->sighand->siglock); 184 break; 185 case ITIMER_VIRTUAL: 186 nval = timeval_to_cputime(&value->it_value); 187 ninterval = timeval_to_cputime(&value->it_interval); 188 read_lock(&tasklist_lock); 189 spin_lock_irq(&tsk->sighand->siglock); 190 cval = tsk->signal->it_virt_expires; 191 cinterval = tsk->signal->it_virt_incr; 192 if (!cputime_eq(cval, cputime_zero) || 193 !cputime_eq(nval, cputime_zero)) { 194 if (cputime_gt(nval, cputime_zero)) 195 nval = cputime_add(nval, 196 jiffies_to_cputime(1)); 197 set_process_cpu_timer(tsk, CPUCLOCK_VIRT, 198 &nval, &cval); 199 } 200 tsk->signal->it_virt_expires = nval; 201 tsk->signal->it_virt_incr = ninterval; 202 spin_unlock_irq(&tsk->sighand->siglock); 203 read_unlock(&tasklist_lock); 204 if (ovalue) { 205 cputime_to_timeval(cval, &ovalue->it_value); 206 cputime_to_timeval(cinterval, &ovalue->it_interval); 207 } 208 break; 209 case ITIMER_PROF: 210 nval = timeval_to_cputime(&value->it_value); 211 ninterval = timeval_to_cputime(&value->it_interval); 212 read_lock(&tasklist_lock); 213 spin_lock_irq(&tsk->sighand->siglock); 214 cval = tsk->signal->it_prof_expires; 215 cinterval = tsk->signal->it_prof_incr; 216 if (!cputime_eq(cval, cputime_zero) || 217 !cputime_eq(nval, cputime_zero)) { 218 if (cputime_gt(nval, cputime_zero)) 219 nval = cputime_add(nval, 220 jiffies_to_cputime(1)); 221 set_process_cpu_timer(tsk, CPUCLOCK_PROF, 222 &nval, &cval); 223 } 224 tsk->signal->it_prof_expires = nval; 225 tsk->signal->it_prof_incr = ninterval; 226 spin_unlock_irq(&tsk->sighand->siglock); 227 read_unlock(&tasklist_lock); 228 if (ovalue) { 229 cputime_to_timeval(cval, &ovalue->it_value); 230 cputime_to_timeval(cinterval, &ovalue->it_interval); 231 } 232 break; 233 default: 234 return -EINVAL; 235 } 236 return 0; 237} 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 */ 251unsigned 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 276asmlinkage long sys_setitimer(int which, 277 struct itimerval __user *value, 278 struct itimerval __user *ovalue) 279{ 280 struct itimerval set_buffer, get_buffer; 281 int error; 282 283 if (value) { 284 if(copy_from_user(&set_buffer, value, sizeof(set_buffer))) 285 return -EFAULT; 286 } else 287 memset((char *) &set_buffer, 0, sizeof(set_buffer)); 288 289 error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL); 290 if (error || !ovalue) 291 return error; 292 293 if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer))) 294 return -EFAULT; 295 return 0; 296} 297