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