• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
itimer_get_remtime(struct hrtimer * timer)26 static 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 
do_getitimer(int which,struct itimerval * value)44 int 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 		spin_lock_irq(&tsk->sighand->siglock);
59 		cval = tsk->signal->it_virt_expires;
60 		cinterval = tsk->signal->it_virt_incr;
61 		if (!cputime_eq(cval, cputime_zero)) {
62 			struct task_cputime cputime;
63 			cputime_t utime;
64 
65 			thread_group_cputimer(tsk, &cputime);
66 			utime = cputime.utime;
67 			if (cputime_le(cval, utime)) { /* about to fire */
68 				cval = jiffies_to_cputime(1);
69 			} else {
70 				cval = cputime_sub(cval, utime);
71 			}
72 		}
73 		spin_unlock_irq(&tsk->sighand->siglock);
74 		cputime_to_timeval(cval, &value->it_value);
75 		cputime_to_timeval(cinterval, &value->it_interval);
76 		break;
77 	case ITIMER_PROF:
78 		spin_lock_irq(&tsk->sighand->siglock);
79 		cval = tsk->signal->it_prof_expires;
80 		cinterval = tsk->signal->it_prof_incr;
81 		if (!cputime_eq(cval, cputime_zero)) {
82 			struct task_cputime times;
83 			cputime_t ptime;
84 
85 			thread_group_cputimer(tsk, &times);
86 			ptime = cputime_add(times.utime, times.stime);
87 			if (cputime_le(cval, ptime)) { /* about to fire */
88 				cval = jiffies_to_cputime(1);
89 			} else {
90 				cval = cputime_sub(cval, ptime);
91 			}
92 		}
93 		spin_unlock_irq(&tsk->sighand->siglock);
94 		cputime_to_timeval(cval, &value->it_value);
95 		cputime_to_timeval(cinterval, &value->it_interval);
96 		break;
97 	default:
98 		return(-EINVAL);
99 	}
100 	return 0;
101 }
102 
SYSCALL_DEFINE2(getitimer,int,which,struct itimerval __user *,value)103 SYSCALL_DEFINE2(getitimer, int, which, struct itimerval __user *, value)
104 {
105 	int error = -EFAULT;
106 	struct itimerval get_buffer;
107 
108 	if (value) {
109 		error = do_getitimer(which, &get_buffer);
110 		if (!error &&
111 		    copy_to_user(value, &get_buffer, sizeof(get_buffer)))
112 			error = -EFAULT;
113 	}
114 	return error;
115 }
116 
117 
118 /*
119  * The timer is automagically restarted, when interval != 0
120  */
it_real_fn(struct hrtimer * timer)121 enum hrtimer_restart it_real_fn(struct hrtimer *timer)
122 {
123 	struct signal_struct *sig =
124 		container_of(timer, struct signal_struct, real_timer);
125 
126 	kill_pid_info(SIGALRM, SEND_SIG_PRIV, sig->leader_pid);
127 
128 	return HRTIMER_NORESTART;
129 }
130 
131 /*
132  * Returns true if the timeval is in canonical form
133  */
134 #define timeval_valid(t) \
135 	(((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
136 
do_setitimer(int which,struct itimerval * value,struct itimerval * ovalue)137 int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
138 {
139 	struct task_struct *tsk = current;
140 	struct hrtimer *timer;
141 	ktime_t expires;
142 	cputime_t cval, cinterval, nval, ninterval;
143 
144 	/*
145 	 * Validate the timevals in value.
146 	 */
147 	if (!timeval_valid(&value->it_value) ||
148 	    !timeval_valid(&value->it_interval))
149 		return -EINVAL;
150 
151 	switch (which) {
152 	case ITIMER_REAL:
153 again:
154 		spin_lock_irq(&tsk->sighand->siglock);
155 		timer = &tsk->signal->real_timer;
156 		if (ovalue) {
157 			ovalue->it_value = itimer_get_remtime(timer);
158 			ovalue->it_interval
159 				= ktime_to_timeval(tsk->signal->it_real_incr);
160 		}
161 		/* We are sharing ->siglock with it_real_fn() */
162 		if (hrtimer_try_to_cancel(timer) < 0) {
163 			spin_unlock_irq(&tsk->sighand->siglock);
164 			goto again;
165 		}
166 		expires = timeval_to_ktime(value->it_value);
167 		if (expires.tv64 != 0) {
168 			tsk->signal->it_real_incr =
169 				timeval_to_ktime(value->it_interval);
170 			hrtimer_start(timer, expires, HRTIMER_MODE_REL);
171 		} else
172 			tsk->signal->it_real_incr.tv64 = 0;
173 
174 		spin_unlock_irq(&tsk->sighand->siglock);
175 		break;
176 	case ITIMER_VIRTUAL:
177 		nval = timeval_to_cputime(&value->it_value);
178 		ninterval = timeval_to_cputime(&value->it_interval);
179 		spin_lock_irq(&tsk->sighand->siglock);
180 		cval = tsk->signal->it_virt_expires;
181 		cinterval = tsk->signal->it_virt_incr;
182 		if (!cputime_eq(cval, cputime_zero) ||
183 		    !cputime_eq(nval, cputime_zero)) {
184 			if (cputime_gt(nval, cputime_zero))
185 				nval = cputime_add(nval,
186 						   jiffies_to_cputime(1));
187 			set_process_cpu_timer(tsk, CPUCLOCK_VIRT,
188 					      &nval, &cval);
189 		}
190 		tsk->signal->it_virt_expires = nval;
191 		tsk->signal->it_virt_incr = ninterval;
192 		spin_unlock_irq(&tsk->sighand->siglock);
193 		if (ovalue) {
194 			cputime_to_timeval(cval, &ovalue->it_value);
195 			cputime_to_timeval(cinterval, &ovalue->it_interval);
196 		}
197 		break;
198 	case ITIMER_PROF:
199 		nval = timeval_to_cputime(&value->it_value);
200 		ninterval = timeval_to_cputime(&value->it_interval);
201 		spin_lock_irq(&tsk->sighand->siglock);
202 		cval = tsk->signal->it_prof_expires;
203 		cinterval = tsk->signal->it_prof_incr;
204 		if (!cputime_eq(cval, cputime_zero) ||
205 		    !cputime_eq(nval, cputime_zero)) {
206 			if (cputime_gt(nval, cputime_zero))
207 				nval = cputime_add(nval,
208 						   jiffies_to_cputime(1));
209 			set_process_cpu_timer(tsk, CPUCLOCK_PROF,
210 					      &nval, &cval);
211 		}
212 		tsk->signal->it_prof_expires = nval;
213 		tsk->signal->it_prof_incr = ninterval;
214 		spin_unlock_irq(&tsk->sighand->siglock);
215 		if (ovalue) {
216 			cputime_to_timeval(cval, &ovalue->it_value);
217 			cputime_to_timeval(cinterval, &ovalue->it_interval);
218 		}
219 		break;
220 	default:
221 		return -EINVAL;
222 	}
223 	return 0;
224 }
225 
226 /**
227  * alarm_setitimer - set alarm in seconds
228  *
229  * @seconds:	number of seconds until alarm
230  *		0 disables the alarm
231  *
232  * Returns the remaining time in seconds of a pending timer or 0 when
233  * the timer is not active.
234  *
235  * On 32 bit machines the seconds value is limited to (INT_MAX/2) to avoid
236  * negative timeval settings which would cause immediate expiry.
237  */
alarm_setitimer(unsigned int seconds)238 unsigned int alarm_setitimer(unsigned int seconds)
239 {
240 	struct itimerval it_new, it_old;
241 
242 #if BITS_PER_LONG < 64
243 	if (seconds > INT_MAX)
244 		seconds = INT_MAX;
245 #endif
246 	it_new.it_value.tv_sec = seconds;
247 	it_new.it_value.tv_usec = 0;
248 	it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
249 
250 	do_setitimer(ITIMER_REAL, &it_new, &it_old);
251 
252 	/*
253 	 * We can't return 0 if we have an alarm pending ...  And we'd
254 	 * better return too much than too little anyway
255 	 */
256 	if ((!it_old.it_value.tv_sec && it_old.it_value.tv_usec) ||
257 	      it_old.it_value.tv_usec >= 500000)
258 		it_old.it_value.tv_sec++;
259 
260 	return it_old.it_value.tv_sec;
261 }
262 
SYSCALL_DEFINE3(setitimer,int,which,struct itimerval __user *,value,struct itimerval __user *,ovalue)263 SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value,
264 		struct itimerval __user *, ovalue)
265 {
266 	struct itimerval set_buffer, get_buffer;
267 	int error;
268 
269 	if (value) {
270 		if(copy_from_user(&set_buffer, value, sizeof(set_buffer)))
271 			return -EFAULT;
272 	} else
273 		memset((char *) &set_buffer, 0, sizeof(set_buffer));
274 
275 	error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL);
276 	if (error || !ovalue)
277 		return error;
278 
279 	if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer)))
280 		return -EFAULT;
281 	return 0;
282 }
283