Branch data Line data Source code
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 : : #include <trace/events/timer.h>
16 : :
17 : : #include <asm/uaccess.h>
18 : :
19 : : /**
20 : : * itimer_get_remtime - get remaining time for the timer
21 : : *
22 : : * @timer: the timer to read
23 : : *
24 : : * Returns the delta between the expiry time and now, which can be
25 : : * less than zero or 1usec for an pending expired timer
26 : : */
27 : 0 : static struct timeval itimer_get_remtime(struct hrtimer *timer)
28 : : {
29 : 5312 : ktime_t rem = hrtimer_get_remaining(timer);
30 : :
31 : : /*
32 : : * Racy but safe: if the itimer expires after the above
33 : : * hrtimer_get_remtime() call but before this condition
34 : : * then we return 0 - which is correct.
35 : : */
36 [ + + ]: 5312 : if (hrtimer_active(timer)) {
37 [ - + ]: 1991 : if (rem.tv64 <= 0)
38 : : rem.tv64 = NSEC_PER_USEC;
39 : : } else
40 : : rem.tv64 = 0;
41 : :
42 : 5312 : return ktime_to_timeval(rem);
43 : : }
44 : :
45 : 0 : static void get_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
46 : : struct itimerval *const value)
47 : : {
48 : : cputime_t cval, cinterval;
49 : 2 : struct cpu_itimer *it = &tsk->signal->it[clock_id];
50 : :
51 : 2 : spin_lock_irq(&tsk->sighand->siglock);
52 : :
53 : 2 : cval = it->expires;
54 : 2 : cinterval = it->incr;
55 [ - + ]: 2 : if (cval) {
56 : : struct task_cputime cputime;
57 : : cputime_t t;
58 : :
59 : 0 : thread_group_cputimer(tsk, &cputime);
60 [ + - ]: 2 : if (clock_id == CPUCLOCK_PROF)
61 : 2 : t = cputime.utime + cputime.stime;
62 : : else
63 : : /* CPUCLOCK_VIRT */
64 : 0 : t = cputime.utime;
65 : :
66 [ # # ]: 0 : if (cval < t)
67 : : /* about to fire */
68 : : cval = cputime_one_jiffy;
69 : : else
70 : 0 : cval = cval - t;
71 : : }
72 : :
73 : 2 : spin_unlock_irq(&tsk->sighand->siglock);
74 : :
75 : 2 : cputime_to_timeval(cval, &value->it_value);
76 : 2 : cputime_to_timeval(cinterval, &value->it_interval);
77 : 2 : }
78 : :
79 : 0 : int do_getitimer(int which, struct itimerval *value)
80 : : {
81 : 5 : struct task_struct *tsk = current;
82 : :
83 [ + + + + ]: 5 : switch (which) {
84 : : case ITIMER_REAL:
85 : 2 : spin_lock_irq(&tsk->sighand->siglock);
86 : 2 : value->it_value = itimer_get_remtime(&tsk->signal->real_timer);
87 : 2 : value->it_interval =
88 : 2 : ktime_to_timeval(tsk->signal->it_real_incr);
89 : 2 : spin_unlock_irq(&tsk->sighand->siglock);
90 : : break;
91 : : case ITIMER_VIRTUAL:
92 : 1 : get_cpu_itimer(tsk, CPUCLOCK_VIRT, value);
93 : 1 : break;
94 : : case ITIMER_PROF:
95 : 1 : get_cpu_itimer(tsk, CPUCLOCK_PROF, value);
96 : 1 : break;
97 : : default:
98 : : return(-EINVAL);
99 : : }
100 : : return 0;
101 : : }
102 : :
103 : 0 : SYSCALL_DEFINE2(getitimer, int, which, struct itimerval __user *, value)
104 : : {
105 : : int error = -EFAULT;
106 : : struct itimerval get_buffer;
107 : :
108 [ + - ]: 5 : if (value) {
109 : 5 : error = do_getitimer(which, &get_buffer);
110 [ + + ][ + + ]: 14 : 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 : : */
121 : 0 : 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 : 8746 : trace_itimer_expire(ITIMER_REAL, sig->leader_pid, 0);
127 : 8746 : kill_pid_info(SIGALRM, SEND_SIG_PRIV, sig->leader_pid);
128 : :
129 : 8672 : return HRTIMER_NORESTART;
130 : : }
131 : :
132 : : static inline u32 cputime_sub_ns(cputime_t ct, s64 real_ns)
133 : : {
134 : : struct timespec ts;
135 : : s64 cpu_ns;
136 : :
137 : 14 : cputime_to_timespec(ct, &ts);
138 : : cpu_ns = timespec_to_ns(&ts);
139 : :
140 [ + + ][ + + ]: 14 : return (cpu_ns <= real_ns) ? 0 : cpu_ns - real_ns;
141 : : }
142 : :
143 : 0 : 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 : : cputime_t cval, nval, cinterval, ninterval;
148 : : s64 ns_ninterval, ns_nval;
149 : : u32 error, incr_error;
150 : 7 : struct cpu_itimer *it = &tsk->signal->it[clock_id];
151 : :
152 : 7 : nval = timeval_to_cputime(&value->it_value);
153 : : ns_nval = timeval_to_ns(&value->it_value);
154 : 7 : ninterval = timeval_to_cputime(&value->it_interval);
155 : : ns_ninterval = timeval_to_ns(&value->it_interval);
156 : :
157 : 7 : error = cputime_sub_ns(nval, ns_nval);
158 : : incr_error = cputime_sub_ns(ninterval, ns_ninterval);
159 : :
160 : 7 : spin_lock_irq(&tsk->sighand->siglock);
161 : :
162 : 7 : cval = it->expires;
163 : 7 : cinterval = it->incr;
164 [ + - ]: 7 : if (cval || nval) {
165 [ + + ]: 7 : if (nval > 0)
166 : 4 : nval += cputime_one_jiffy;
167 : 7 : set_process_cpu_timer(tsk, clock_id, &nval, &cval);
168 : : }
169 : 7 : it->expires = nval;
170 : 7 : it->incr = ninterval;
171 : 7 : it->error = error;
172 : 7 : it->incr_error = incr_error;
173 [ + - ]: 14 : trace_itimer_state(clock_id == CPUCLOCK_VIRT ?
174 : : ITIMER_VIRTUAL : ITIMER_PROF, value, nval);
175 : :
176 : 7 : spin_unlock_irq(&tsk->sighand->siglock);
177 : :
178 [ + + ]: 7 : if (ovalue) {
179 : 4 : cputime_to_timeval(cval, &ovalue->it_value);
180 : 4 : cputime_to_timeval(cinterval, &ovalue->it_interval);
181 : : }
182 : 7 : }
183 : :
184 : : /*
185 : : * Returns true if the timeval is in canonical form
186 : : */
187 : : #define timeval_valid(t) \
188 : : (((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
189 : :
190 : 0 : int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
191 : : {
192 : 13983 : struct task_struct *tsk = current;
193 : : struct hrtimer *timer;
194 : : ktime_t expires;
195 : :
196 : : /*
197 : : * Validate the timevals in value.
198 : : */
199 [ + + ][ + ]: 13983 : if (!timeval_valid(&value->it_value) ||
[ + + ]
200 [ + ]: 13465 : !timeval_valid(&value->it_interval))
201 : : return -EINVAL;
202 : :
203 [ + - + ]: 13982 : switch (which) {
204 : : case ITIMER_REAL:
205 : : again:
206 : 14265 : spin_lock_irq(&tsk->sighand->siglock);
207 : 14234 : timer = &tsk->signal->real_timer;
208 [ + + ]: 14234 : if (ovalue) {
209 : 5310 : ovalue->it_value = itimer_get_remtime(timer);
210 : : ovalue->it_interval
211 : 5310 : = ktime_to_timeval(tsk->signal->it_real_incr);
212 : : }
213 : : /* We are sharing ->siglock with it_real_fn() */
214 [ - + ]: 14234 : if (hrtimer_try_to_cancel(timer) < 0) {
215 : 0 : spin_unlock_irq(&tsk->sighand->siglock);
216 : : goto again;
217 : : }
218 : : expires = timeval_to_ktime(value->it_value);
219 [ + + ]: 14285 : if (expires.tv64 != 0) {
220 : 22052 : tsk->signal->it_real_incr =
221 : : timeval_to_ktime(value->it_interval);
222 : 11026 : hrtimer_start(timer, expires, HRTIMER_MODE_REL);
223 : : } else
224 : 3259 : tsk->signal->it_real_incr.tv64 = 0;
225 : :
226 : : trace_itimer_state(ITIMER_REAL, value, 0);
227 : 14298 : spin_unlock_irq(&tsk->sighand->siglock);
228 : : break;
229 : : case ITIMER_VIRTUAL:
230 : 0 : set_cpu_itimer(tsk, CPUCLOCK_VIRT, value, ovalue);
231 : 0 : break;
232 : : case ITIMER_PROF:
233 : 7 : set_cpu_itimer(tsk, CPUCLOCK_PROF, value, ovalue);
234 : 7 : break;
235 : : default:
236 : : return -EINVAL;
237 : : }
238 : : return 0;
239 : : }
240 : :
241 : : /**
242 : : * alarm_setitimer - set alarm in seconds
243 : : *
244 : : * @seconds: number of seconds until alarm
245 : : * 0 disables the alarm
246 : : *
247 : : * Returns the remaining time in seconds of a pending timer or 0 when
248 : : * the timer is not active.
249 : : *
250 : : * On 32 bit machines the seconds value is limited to (INT_MAX/2) to avoid
251 : : * negative timeval settings which would cause immediate expiry.
252 : : */
253 : 0 : unsigned int alarm_setitimer(unsigned int seconds)
254 : : {
255 : : struct itimerval it_new, it_old;
256 : :
257 : : #if BITS_PER_LONG < 64
258 [ # # ]: 0 : if (seconds > INT_MAX)
259 : : seconds = INT_MAX;
260 : : #endif
261 : 0 : it_new.it_value.tv_sec = seconds;
262 : 0 : it_new.it_value.tv_usec = 0;
263 : 0 : it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
264 : :
265 : 0 : do_setitimer(ITIMER_REAL, &it_new, &it_old);
266 : :
267 : : /*
268 : : * We can't return 0 if we have an alarm pending ... And we'd
269 : : * better return too much than too little anyway
270 : : */
271 [ # # ][ # # ]: 0 : if ((!it_old.it_value.tv_sec && it_old.it_value.tv_usec) ||
[ # # ]
272 : 0 : it_old.it_value.tv_usec >= 500000)
273 : 0 : it_old.it_value.tv_sec++;
274 : :
275 : 0 : return it_old.it_value.tv_sec;
276 : : }
277 : :
278 : 0 : SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value,
279 : : struct itimerval __user *, ovalue)
280 : : {
281 : : struct itimerval set_buffer, get_buffer;
282 : : int error;
283 : :
284 [ + - ]: 14228 : if (value) {
285 [ + - ]: 28434 : if(copy_from_user(&set_buffer, value, sizeof(set_buffer)))
286 : : return -EFAULT;
287 : : } else {
288 : 0 : memset(&set_buffer, 0, sizeof(set_buffer));
289 [ # # ]: 0 : printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer."
290 : : " Misfeature support will be removed\n",
291 : : current->comm);
292 : : }
293 : :
294 [ + + ]: 14206 : error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL);
295 [ + + ]: 14272 : if (error || !ovalue)
296 : : return error;
297 : :
298 [ + + ]: 5314 : if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer)))
299 : : return -EFAULT;
300 : : return 0;
301 : : }
|