Lines Matching +full:signal +full:- +full:guard

1 // SPDX-License-Identifier: GPL-2.0+
3 * 2002-10-15 Posix Clocks & timers
7 * 2004-06-01 Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug.
20 #include <linux/posix-clock.h>
21 #include <linux/posix-timers.h>
31 #include "posix-timers.h"
35 * constructed from current::signal and the timer ID and the timer is
36 * matched against current::signal and the timer ID when walking the hash
73 __cond_lock(&__timr->it_lock, __timr = __lock_timer(tid)); \
80 spin_unlock_irq(&timr->it_lock); in unlock_timer()
84 scoped_cond_guard(lock_timer, return -EINVAL, _id)
98 struct signal_struct *sig = current->signal; in posix_timer_by_id()
102 hlist_for_each_entry_rcu(timer, &bucket->head, t_hash) { in posix_timer_by_id()
103 /* timer->it_signal can be set concurrently */ in posix_timer_by_id()
104 if ((READ_ONCE(timer->it_signal) == sig) && (timer->it_id == id)) in posix_timer_by_id()
112 unsigned long val = (unsigned long)timer->it_signal; in posix_sig_owner()
124 struct hlist_head *head = &bucket->head; in posix_timer_hashed()
127 hlist_for_each_entry_rcu(timer, head, t_hash, lockdep_is_held(&bucket->lock)) { in posix_timer_hashed()
128 if ((posix_sig_owner(timer) == sig) && (timer->it_id == id)) in posix_timer_hashed()
138 scoped_guard (spinlock, &bucket->lock) { in posix_timer_add_at()
146 * Set the timer ID and the signal pointer to make in posix_timer_add_at()
147 * it identifiable in the hash table. The signal in posix_timer_add_at()
155 timer->it_id = (timer_t)id; in posix_timer_add_at()
156 timer->it_signal = (struct signal_struct *)((unsigned long)sig | 1UL); in posix_timer_add_at()
157 hlist_add_head_rcu(&timer->t_hash, &bucket->head); in posix_timer_add_at()
166 struct signal_struct *sig = current->signal; in posix_timer_add()
170 return -EBUSY; in posix_timer_add()
178 atomic_set(&sig->next_posix_timer_id, req_id + 1); in posix_timer_add()
184 unsigned int id = atomic_fetch_inc(&sig->next_posix_timer_id) & INT_MAX; in posix_timer_add()
191 return -EAGAIN; in posix_timer_add()
281 tp->tv_sec = 0; in posix_get_hrtimer_res()
282 tp->tv_nsec = hrtimer_resolution; in posix_get_hrtimer_res()
292 if (timr->it_overrun_last > (s64)INT_MAX) in timer_overrun_to_int()
295 return (int)timr->it_overrun_last; in timer_overrun_to_int()
300 struct hrtimer *timer = &timr->it.real.timer; in common_hrtimer_rearm()
302 timr->it_overrun += hrtimer_forward_now(timer, timr->it_interval); in common_hrtimer_rearm()
308 guard(spinlock)(&timr->it_lock); in __posixtimer_deliver_signal()
312 * since the signal was queued. In either case, don't rearm and in __posixtimer_deliver_signal()
313 * drop the signal. in __posixtimer_deliver_signal()
315 if (timr->it_signal_seq != timr->it_sigqueue_seq || WARN_ON_ONCE(!posixtimer_valid(timr))) in __posixtimer_deliver_signal()
318 if (!timr->it_interval || WARN_ON_ONCE(timr->it_status != POSIX_TIMER_REQUEUE_PENDING)) in __posixtimer_deliver_signal()
321 timr->kclock->timer_rearm(timr); in __posixtimer_deliver_signal()
322 timr->it_status = POSIX_TIMER_ARMED; in __posixtimer_deliver_signal()
323 timr->it_overrun_last = timr->it_overrun; in __posixtimer_deliver_signal()
324 timr->it_overrun = -1LL; in __posixtimer_deliver_signal()
325 ++timr->it_signal_seq; in __posixtimer_deliver_signal()
326 info->si_overrun = timer_overrun_to_int(timr); in __posixtimer_deliver_signal()
331 * This function is called from the signal delivery code. It decides
332 * whether the signal should be dropped and rearms interval timers. The
345 spin_unlock(&current->sighand->siglock); in posixtimer_deliver_signal()
349 /* Drop the reference which was acquired when the signal was queued */ in posixtimer_deliver_signal()
352 spin_lock(&current->sighand->siglock); in posixtimer_deliver_signal()
358 lockdep_assert_held(&timr->it_lock); in posix_timer_queue_signal()
363 timr->it_status = timr->it_interval ? POSIX_TIMER_REQUEUE_PENDING : POSIX_TIMER_DISARMED; in posix_timer_queue_signal()
378 guard(spinlock_irqsave)(&timr->it_lock); in posix_timer_fn()
387 current->signal->timer_create_restore_ids = 0; in posixtimer_create_prctl()
390 current->signal->timer_create_restore_ids = 1; in posixtimer_create_prctl()
393 return current->signal->timer_create_restore_ids; in posixtimer_create_prctl()
395 return -EINVAL; in posixtimer_create_prctl()
403 switch (event->sigev_notify) { in good_sigevent()
405 pid = find_vpid(event->sigev_notify_thread_id); in good_sigevent()
412 if (event->sigev_signo <= 0 || event->sigev_signo > SIGRTMAX) in good_sigevent()
433 if (unlikely(!posixtimer_init_sigqueue(&tmr->sigq))) { in alloc_posix_timer()
437 rcuref_init(&tmr->rcuref, 1); in alloc_posix_timer()
443 put_pid(tmr->it_pid); in posixtimer_free_timer()
444 if (tmr->sigq.ucounts) in posixtimer_free_timer()
445 dec_rlimit_put_ucounts(tmr->sigq.ucounts, UCOUNT_RLIMIT_SIGPENDING); in posixtimer_free_timer()
451 struct timer_hash_bucket *bucket = hash_bucket(posix_sig_owner(tmr), tmr->it_id); in posix_timer_unhash_and_free()
453 scoped_guard (spinlock, &bucket->lock) in posix_timer_unhash_and_free()
454 hlist_del_rcu(&tmr->t_hash); in posix_timer_unhash_and_free()
460 hrtimer_setup(&new_timer->it.real.timer, posix_timer_fn, new_timer->it_clock, 0); in common_timer_create()
474 return -EINVAL; in do_timer_create()
475 if (!kc->timer_create) in do_timer_create()
476 return -EOPNOTSUPP; in do_timer_create()
480 return -EAGAIN; in do_timer_create()
482 spin_lock_init(&new_timer->it_lock); in do_timer_create()
485 if (unlikely(current->signal->timer_create_restore_ids)) { in do_timer_create()
487 return -EFAULT; in do_timer_create()
490 return -EINVAL; in do_timer_create()
503 new_timer->it_clock = which_clock; in do_timer_create()
504 new_timer->kclock = kc; in do_timer_create()
505 new_timer->it_overrun = -1LL; in do_timer_create()
509 new_timer->it_pid = get_pid(good_sigevent(event)); in do_timer_create()
510 if (!new_timer->it_pid) { in do_timer_create()
511 error = -EINVAL; in do_timer_create()
514 new_timer->it_sigev_notify = event->sigev_notify; in do_timer_create()
515 new_timer->sigq.info.si_signo = event->sigev_signo; in do_timer_create()
516 new_timer->sigq.info.si_value = event->sigev_value; in do_timer_create()
518 new_timer->it_sigev_notify = SIGEV_SIGNAL; in do_timer_create()
519 new_timer->sigq.info.si_signo = SIGALRM; in do_timer_create()
520 new_timer->sigq.info.si_value.sival_int = new_timer->it_id; in do_timer_create()
521 new_timer->it_pid = get_pid(task_tgid(current)); in do_timer_create()
524 if (new_timer->it_sigev_notify & SIGEV_THREAD_ID) in do_timer_create()
525 new_timer->it_pid_type = PIDTYPE_PID; in do_timer_create()
527 new_timer->it_pid_type = PIDTYPE_TGID; in do_timer_create()
529 new_timer->sigq.info.si_tid = new_timer->it_id; in do_timer_create()
530 new_timer->sigq.info.si_code = SI_TIMER; in do_timer_create()
533 error = -EFAULT; in do_timer_create()
538 * now but not yet valid because new_timer::signal low order bit is 1. in do_timer_create()
543 error = kc->timer_create(new_timer); in do_timer_create()
551 * sighand::siglock is required to protect signal::posix_timers. in do_timer_create()
553 scoped_guard (spinlock_irq, &new_timer->it_lock) { in do_timer_create()
554 guard(spinlock)(&current->sighand->siglock); in do_timer_create()
556 * new_timer::it_signal contains the signal pointer with in do_timer_create()
558 * Store the unmodified signal pointer to make it valid. in do_timer_create()
560 WRITE_ONCE(new_timer->it_signal, current->signal); in do_timer_create()
561 hlist_add_head_rcu(&new_timer->list, &current->signal->posix_timers); in do_timer_create()
581 return -EFAULT; in SYSCALL_DEFINE3()
596 return -EFAULT; in COMPAT_SYSCALL_DEFINE3()
628 * queued. In that case the signal delivery or flush will put the in __lock_timer()
642 guard(rcu)(); in __lock_timer()
645 spin_lock_irq(&timr->it_lock); in __lock_timer()
650 if (timr->it_signal == current->signal) in __lock_timer()
652 spin_unlock_irq(&timr->it_lock); in __lock_timer()
659 struct hrtimer *timer = &timr->it.real.timer; in common_hrtimer_remaining()
666 struct hrtimer *timer = &timr->it.real.timer; in common_hrtimer_forward()
668 return hrtimer_forward(timer, now, timr->it_interval); in common_hrtimer_forward()
685 const struct k_clock *kc = timr->kclock; in common_timer_get()
689 sig_none = timr->it_sigev_notify == SIGEV_NONE; in common_timer_get()
690 iv = timr->it_interval; in common_timer_get()
694 cur_setting->it_interval = ktime_to_timespec64(iv); in common_timer_get()
695 } else if (timr->it_status == POSIX_TIMER_DISARMED) { in common_timer_get()
698 * timr->it_status is always DISARMED. The check below in common_timer_get()
708 now = kc->clock_get_ktime(timr->it_clock); in common_timer_get()
715 if (iv && timr->it_status != POSIX_TIMER_ARMED) in common_timer_get()
716 timr->it_overrun += kc->timer_forward(timr, now); in common_timer_get()
718 remaining = kc->timer_remaining(timr, now); in common_timer_get()
731 * expired! Timers which have a real signal delivery mode in common_timer_get()
733 * signal has not yet been delivered. in common_timer_get()
736 cur_setting->it_value.tv_nsec = 1; in common_timer_get()
738 cur_setting->it_value = ktime_to_timespec64(remaining); in common_timer_get()
746 scoped_timer->kclock->timer_get(scoped_timer, setting); in do_timer_gettime()
759 ret = -EFAULT; in SYSCALL_DEFINE2()
774 ret = -EFAULT; in SYSCALL_DEFINE2()
782 * sys_timer_getoverrun - Get the number of overruns of a POSIX.1b interval timer
787 * signal and the actual signal delivery. On signal delivery the "overrun
790 * As this is relative to the last queued signal the returned overrun count
791 * is meaningless outside of the signal delivery path and even there it
796 * -EINVAL @timer_id is invalid
797 * 1..INT_MAX The number of overruns related to the last delivered signal
808 struct hrtimer *timer = &timr->it.real.timer; in common_hrtimer_arm()
815 * hood. See hrtimer_setup(). Update timr->kclock, so the generic in common_hrtimer_arm()
816 * functions which use timr->kclock->clock_get_*() work. in common_hrtimer_arm()
821 if (timr->it_clock == CLOCK_REALTIME) in common_hrtimer_arm()
822 timr->kclock = absolute ? &clock_realtime : &clock_monotonic; in common_hrtimer_arm()
824 hrtimer_setup(&timr->it.real.timer, posix_timer_fn, timr->it_clock, mode); in common_hrtimer_arm()
836 return hrtimer_try_to_cancel(&timr->it.real.timer); in common_hrtimer_try_to_cancel()
841 hrtimer_cancel_wait_running(&timer->it.real.timer); in common_timer_wait_running()
861 * kc->timer_wait_running() might drop RCU lock. So @timer in timer_wait_running()
864 timer->kclock->timer_wait_running(timer); in timer_wait_running()
868 * Set up the new interval and reset the signal delivery data
872 if (new_setting->it_value.tv_sec || new_setting->it_value.tv_nsec) in posix_timer_set_common()
873 timer->it_interval = timespec64_to_ktime(new_setting->it_interval); in posix_timer_set_common()
875 timer->it_interval = 0; in posix_timer_set_common()
878 timer->it_overrun_last = 0; in posix_timer_set_common()
879 timer->it_overrun = -1LL; in posix_timer_set_common()
887 const struct k_clock *kc = timr->kclock; in common_timer_set()
896 * active and spinning on timr->it_lock. in common_timer_set()
898 if (kc->timer_try_to_cancel(timr) < 0) in common_timer_set()
901 timr->it_status = POSIX_TIMER_DISARMED; in common_timer_set()
905 if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec) in common_timer_set()
908 expires = timespec64_to_ktime(new_setting->it_value); in common_timer_set()
910 expires = timens_ktime_to_host(timr->it_clock, expires); in common_timer_set()
911 sigev_none = timr->it_sigev_notify == SIGEV_NONE; in common_timer_set()
913 kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none); in common_timer_set()
915 timr->it_status = POSIX_TIMER_ARMED; in common_timer_set()
922 if (!timespec64_valid(&new_spec64->it_interval) || in do_timer_settime()
923 !timespec64_valid(&new_spec64->it_value)) in do_timer_settime()
924 return -EINVAL; in do_timer_settime()
936 old_spec64->it_interval = ktime_to_timespec64(timr->it_interval); in do_timer_settime()
938 /* Prevent signal delivery and rearming. */ in do_timer_settime()
939 timr->it_signal_seq++; in do_timer_settime()
941 int ret = timr->kclock->timer_set(timr, tmr_flags, new_spec64, old_spec64); in do_timer_settime()
962 return -EINVAL; in SYSCALL_DEFINE4()
965 return -EFAULT; in SYSCALL_DEFINE4()
971 error = -EFAULT; in SYSCALL_DEFINE4()
986 return -EINVAL; in SYSCALL_DEFINE4()
988 return -EFAULT; in SYSCALL_DEFINE4()
993 error = -EFAULT; in SYSCALL_DEFINE4()
1001 const struct k_clock *kc = timer->kclock; in common_timer_del()
1003 if (kc->timer_try_to_cancel(timer) < 0) in common_timer_del()
1005 timer->it_status = POSIX_TIMER_DISARMED; in common_timer_del()
1015 if (!hlist_unhashed(&tmr->ignored_list)) { in posix_timer_cleanup_ignored()
1016 hlist_del_init(&tmr->ignored_list); in posix_timer_cleanup_ignored()
1028 * signal code observes the invalidated timer::it_signal in in posix_timer_delete()
1029 * do_sigaction(), which prevents it from moving a pending signal in posix_timer_delete()
1032 * The invalidation also prevents signal queueing, signal delivery in posix_timer_delete()
1033 * and therefore rearming from the signal delivery path. in posix_timer_delete()
1040 timer->it_signal_seq++; in posix_timer_delete()
1042 scoped_guard (spinlock, &current->sighand->siglock) { in posix_timer_delete()
1043 unsigned long sig = (unsigned long)timer->it_signal | 1UL; in posix_timer_delete()
1045 WRITE_ONCE(timer->it_signal, (struct signal_struct *)sig); in posix_timer_delete()
1046 hlist_del_rcu(&timer->list); in posix_timer_delete()
1050 while (timer->kclock->timer_del(timer) == TIMER_RETRY) { in posix_timer_delete()
1051 guard(rcu)(); in posix_timer_delete()
1052 spin_unlock_irq(&timer->it_lock); in posix_timer_delete()
1054 spin_lock_irq(&timer->it_lock); in posix_timer_delete()
1084 tsk->signal->timer_create_restore_ids = 0; in exit_itimers()
1086 if (hlist_empty(&tsk->signal->posix_timers)) in exit_itimers()
1090 scoped_guard (spinlock_irq, &tsk->sighand->siglock) in exit_itimers()
1091 hlist_move_list(&tsk->signal->posix_timers, &timers); in exit_itimers()
1093 /* The timers are not longer accessible via tsk::signal */ in exit_itimers()
1095 scoped_guard (spinlock_irq, &timer->it_lock) in exit_itimers()
1105 if (!WARN_ON_ONCE(!hlist_empty(&tsk->signal->ignored_posix_timers))) in exit_itimers()
1108 hlist_move_list(&tsk->signal->ignored_posix_timers, &timers); in exit_itimers()
1121 if (!kc || !kc->clock_set) in SYSCALL_DEFINE2()
1122 return -EINVAL; in SYSCALL_DEFINE2()
1125 return -EFAULT; in SYSCALL_DEFINE2()
1131 return kc->clock_set(which_clock, &new_tp); in SYSCALL_DEFINE2()
1142 return -EINVAL; in SYSCALL_DEFINE2()
1144 error = kc->clock_get_timespec(which_clock, &kernel_tp); in SYSCALL_DEFINE2()
1147 error = -EFAULT; in SYSCALL_DEFINE2()
1157 return -EINVAL; in do_clock_adjtime()
1158 if (!kc->clock_adj) in do_clock_adjtime()
1159 return -EOPNOTSUPP; in do_clock_adjtime()
1161 return kc->clock_adj(which_clock, ktx); in do_clock_adjtime()
1171 return -EFAULT; in SYSCALL_DEFINE2()
1176 return -EFAULT; in SYSCALL_DEFINE2()
1182 * sys_clock_getres - Get the resolution of a clock
1189 * clock. Clock resolutions are implementation-defined and cannot be set by
1249 * -EINVAL @which_clock is not a valid clock ID
1250 * -EFAULT Copying the resolution to @tp faulted
1251 * -ENODEV Dynamic POSIX clock is not backed by a device
1252 * -EOPNOTSUPP Dynamic POSIX clock does not support getres()
1262 return -EINVAL; in SYSCALL_DEFINE2()
1264 error = kc->clock_getres(which_clock, &rtn_tp); in SYSCALL_DEFINE2()
1267 error = -EFAULT; in SYSCALL_DEFINE2()
1280 if (!kc || !kc->clock_set) in SYSCALL_DEFINE2()
1281 return -EINVAL; in SYSCALL_DEFINE2()
1284 return -EFAULT; in SYSCALL_DEFINE2()
1286 return kc->clock_set(which_clock, &ts); in SYSCALL_DEFINE2()
1297 return -EINVAL; in SYSCALL_DEFINE2()
1299 err = kc->clock_get_timespec(which_clock, &ts); in SYSCALL_DEFINE2()
1302 err = -EFAULT; in SYSCALL_DEFINE2()
1320 return -EFAULT; in SYSCALL_DEFINE2()
1333 return -EINVAL; in SYSCALL_DEFINE2()
1335 err = kc->clock_getres(which_clock, &ts); in SYSCALL_DEFINE2()
1337 return -EFAULT; in SYSCALL_DEFINE2()
1360 * Absolute nanosleeps for these clocks are time-namespace adjusted.
1383 return -EINVAL; in SYSCALL_DEFINE4()
1384 if (!kc->nsleep) in SYSCALL_DEFINE4()
1385 return -EOPNOTSUPP; in SYSCALL_DEFINE4()
1388 return -EFAULT; in SYSCALL_DEFINE4()
1391 return -EINVAL; in SYSCALL_DEFINE4()
1394 current->restart_block.fn = do_no_restart_syscall; in SYSCALL_DEFINE4()
1395 current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; in SYSCALL_DEFINE4()
1396 current->restart_block.nanosleep.rmtp = rmtp; in SYSCALL_DEFINE4()
1398 return kc->nsleep(which_clock, flags, &t); in SYSCALL_DEFINE4()
1411 return -EINVAL; in SYSCALL_DEFINE4()
1412 if (!kc->nsleep) in SYSCALL_DEFINE4()
1413 return -EOPNOTSUPP; in SYSCALL_DEFINE4()
1416 return -EFAULT; in SYSCALL_DEFINE4()
1419 return -EINVAL; in SYSCALL_DEFINE4()
1422 current->restart_block.fn = do_no_restart_syscall; in SYSCALL_DEFINE4()
1423 current->restart_block.nanosleep.type = rmtp ? TT_COMPAT : TT_NONE; in SYSCALL_DEFINE4()
1424 current->restart_block.nanosleep.compat_rmtp = rmtp; in SYSCALL_DEFINE4()
1426 return kc->nsleep(which_clock, flags, &t); in SYSCALL_DEFINE4()
1566 timer_hashmask = size - 1; in posixtimer_init()