| .. | .. | 
|---|
 | 1 | +// SPDX-License-Identifier: GPL-2.0+  | 
|---|
| 1 | 2 |  /* | 
|---|
| 2 |  | - * linux/kernel/posix-timers.c  | 
|---|
| 3 |  | - *  | 
|---|
| 4 |  | - *  | 
|---|
| 5 | 3 |   * 2002-10-15  Posix Clocks & timers | 
|---|
| 6 | 4 |   *                           by George Anzinger george@mvista.com | 
|---|
| 7 |  | - *  | 
|---|
| 8 | 5 |   *			     Copyright (C) 2002 2003 by MontaVista Software. | 
|---|
| 9 | 6 |   * | 
|---|
| 10 | 7 |   * 2004-06-01  Fix CLOCK_REALTIME clock/timer TIMER_ABSTIME bug. | 
|---|
| 11 | 8 |   *			     Copyright (C) 2004 Boris Hu | 
|---|
| 12 | 9 |   * | 
|---|
| 13 |  | - * This program is free software; you can redistribute it and/or modify  | 
|---|
| 14 |  | - * it under the terms of the GNU General Public License as published by  | 
|---|
| 15 |  | - * the Free Software Foundation; either version 2 of the License, or (at  | 
|---|
| 16 |  | - * your option) any later version.  | 
|---|
| 17 |  | - *  | 
|---|
| 18 |  | - * This program is distributed in the hope that it will be useful, but  | 
|---|
| 19 |  | - * WITHOUT ANY WARRANTY; without even the implied warranty of  | 
|---|
| 20 |  | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  | 
|---|
| 21 |  | - * General Public License for more details.  | 
|---|
| 22 |  | -  | 
|---|
| 23 |  | - * You should have received a copy of the GNU General Public License  | 
|---|
| 24 |  | - * along with this program; if not, write to the Free Software  | 
|---|
| 25 |  | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  | 
|---|
| 26 |  | - *  | 
|---|
| 27 |  | - * MontaVista Software | 1237 East Arques Avenue | Sunnyvale | CA 94085 | USA  | 
|---|
| 28 |  | - */  | 
|---|
| 29 |  | -  | 
|---|
| 30 |  | -/* These are all the functions necessary to implement  | 
|---|
| 31 |  | - * POSIX clocks & timers  | 
|---|
 | 10 | + * These are all the functions necessary to implement POSIX clocks & timers  | 
|---|
| 32 | 11 |   */ | 
|---|
| 33 | 12 |  #include <linux/mm.h> | 
|---|
| 34 | 13 |  #include <linux/interrupt.h> | 
|---|
| .. | .. | 
|---|
| 51 | 30 |  #include <linux/hashtable.h> | 
|---|
| 52 | 31 |  #include <linux/compat.h> | 
|---|
| 53 | 32 |  #include <linux/nospec.h> | 
|---|
 | 33 | +#include <linux/time_namespace.h>  | 
|---|
| 54 | 34 |   | 
|---|
| 55 | 35 |  #include "timekeeping.h" | 
|---|
| 56 | 36 |  #include "posix-timers.h" | 
|---|
| .. | .. | 
|---|
| 141 | 121 |  { | 
|---|
| 142 | 122 |  	struct k_itimer *timer; | 
|---|
| 143 | 123 |   | 
|---|
| 144 |  | -	hlist_for_each_entry_rcu(timer, head, t_hash) {  | 
|---|
 | 124 | +	hlist_for_each_entry_rcu(timer, head, t_hash,  | 
|---|
 | 125 | +				 lockdep_is_held(&hash_lock)) {  | 
|---|
| 145 | 126 |  		if ((timer->it_signal == sig) && (timer->it_id == id)) | 
|---|
| 146 | 127 |  			return timer; | 
|---|
| 147 | 128 |  	} | 
|---|
| .. | .. | 
|---|
| 186 | 167 |  } | 
|---|
| 187 | 168 |   | 
|---|
| 188 | 169 |  /* Get clock_realtime */ | 
|---|
| 189 |  | -static int posix_clock_realtime_get(clockid_t which_clock, struct timespec64 *tp)  | 
|---|
 | 170 | +static int posix_get_realtime_timespec(clockid_t which_clock, struct timespec64 *tp)  | 
|---|
| 190 | 171 |  { | 
|---|
| 191 | 172 |  	ktime_get_real_ts64(tp); | 
|---|
| 192 | 173 |  	return 0; | 
|---|
 | 174 | +}  | 
|---|
 | 175 | +  | 
|---|
 | 176 | +static ktime_t posix_get_realtime_ktime(clockid_t which_clock)  | 
|---|
 | 177 | +{  | 
|---|
 | 178 | +	return ktime_get_real();  | 
|---|
| 193 | 179 |  } | 
|---|
| 194 | 180 |   | 
|---|
| 195 | 181 |  /* Set clock_realtime */ | 
|---|
| .. | .. | 
|---|
| 200 | 186 |  } | 
|---|
| 201 | 187 |   | 
|---|
| 202 | 188 |  static int posix_clock_realtime_adj(const clockid_t which_clock, | 
|---|
| 203 |  | -				    struct timex *t)  | 
|---|
 | 189 | +				    struct __kernel_timex *t)  | 
|---|
| 204 | 190 |  { | 
|---|
| 205 | 191 |  	return do_adjtimex(t); | 
|---|
| 206 | 192 |  } | 
|---|
| .. | .. | 
|---|
| 208 | 194 |  /* | 
|---|
| 209 | 195 |   * Get monotonic time for posix timers | 
|---|
| 210 | 196 |   */ | 
|---|
| 211 |  | -static int posix_ktime_get_ts(clockid_t which_clock, struct timespec64 *tp)  | 
|---|
 | 197 | +static int posix_get_monotonic_timespec(clockid_t which_clock, struct timespec64 *tp)  | 
|---|
| 212 | 198 |  { | 
|---|
| 213 | 199 |  	ktime_get_ts64(tp); | 
|---|
 | 200 | +	timens_add_monotonic(tp);  | 
|---|
| 214 | 201 |  	return 0; | 
|---|
 | 202 | +}  | 
|---|
 | 203 | +  | 
|---|
 | 204 | +static ktime_t posix_get_monotonic_ktime(clockid_t which_clock)  | 
|---|
 | 205 | +{  | 
|---|
 | 206 | +	return ktime_get();  | 
|---|
| 215 | 207 |  } | 
|---|
| 216 | 208 |   | 
|---|
| 217 | 209 |  /* | 
|---|
| .. | .. | 
|---|
| 220 | 212 |  static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec64 *tp) | 
|---|
| 221 | 213 |  { | 
|---|
| 222 | 214 |  	ktime_get_raw_ts64(tp); | 
|---|
 | 215 | +	timens_add_monotonic(tp);  | 
|---|
| 223 | 216 |  	return 0; | 
|---|
| 224 | 217 |  } | 
|---|
| 225 | 218 |   | 
|---|
| .. | .. | 
|---|
| 234 | 227 |  						struct timespec64 *tp) | 
|---|
| 235 | 228 |  { | 
|---|
| 236 | 229 |  	ktime_get_coarse_ts64(tp); | 
|---|
 | 230 | +	timens_add_monotonic(tp);  | 
|---|
| 237 | 231 |  	return 0; | 
|---|
| 238 | 232 |  } | 
|---|
| 239 | 233 |   | 
|---|
| .. | .. | 
|---|
| 243 | 237 |  	return 0; | 
|---|
| 244 | 238 |  } | 
|---|
| 245 | 239 |   | 
|---|
| 246 |  | -static int posix_get_boottime(const clockid_t which_clock, struct timespec64 *tp)  | 
|---|
 | 240 | +static int posix_get_boottime_timespec(const clockid_t which_clock, struct timespec64 *tp)  | 
|---|
| 247 | 241 |  { | 
|---|
| 248 | 242 |  	ktime_get_boottime_ts64(tp); | 
|---|
 | 243 | +	timens_add_boottime(tp);  | 
|---|
| 249 | 244 |  	return 0; | 
|---|
| 250 | 245 |  } | 
|---|
| 251 | 246 |   | 
|---|
| 252 |  | -static int posix_get_tai(clockid_t which_clock, struct timespec64 *tp)  | 
|---|
 | 247 | +static ktime_t posix_get_boottime_ktime(const clockid_t which_clock)  | 
|---|
 | 248 | +{  | 
|---|
 | 249 | +	return ktime_get_boottime();  | 
|---|
 | 250 | +}  | 
|---|
 | 251 | +  | 
|---|
 | 252 | +static int posix_get_tai_timespec(clockid_t which_clock, struct timespec64 *tp)  | 
|---|
| 253 | 253 |  { | 
|---|
| 254 | 254 |  	ktime_get_clocktai_ts64(tp); | 
|---|
| 255 | 255 |  	return 0; | 
|---|
 | 256 | +}  | 
|---|
 | 257 | +  | 
|---|
 | 258 | +static ktime_t posix_get_tai_ktime(clockid_t which_clock)  | 
|---|
 | 259 | +{  | 
|---|
 | 260 | +	return ktime_get_clocktai();  | 
|---|
| 256 | 261 |  } | 
|---|
| 257 | 262 |   | 
|---|
| 258 | 263 |  static int posix_get_hrtimer_res(clockid_t which_clock, struct timespec64 *tp) | 
|---|
| .. | .. | 
|---|
| 305 | 310 |   * To protect against the timer going away while the interrupt is queued, | 
|---|
| 306 | 311 |   * we require that the it_requeue_pending flag be set. | 
|---|
| 307 | 312 |   */ | 
|---|
| 308 |  | -void posixtimer_rearm(struct siginfo *info)  | 
|---|
 | 313 | +void posixtimer_rearm(struct kernel_siginfo *info)  | 
|---|
| 309 | 314 |  { | 
|---|
| 310 | 315 |  	struct k_itimer *timr; | 
|---|
| 311 | 316 |  	unsigned long flags; | 
|---|
| .. | .. | 
|---|
| 434 | 439 |  		rtn = pid_task(pid, PIDTYPE_PID); | 
|---|
| 435 | 440 |  		if (!rtn || !same_thread_group(rtn, current)) | 
|---|
| 436 | 441 |  			return NULL; | 
|---|
| 437 |  | -		/* FALLTHRU */  | 
|---|
 | 442 | +		fallthrough;  | 
|---|
| 438 | 443 |  	case SIGEV_SIGNAL: | 
|---|
| 439 | 444 |  	case SIGEV_THREAD: | 
|---|
| 440 | 445 |  		if (event->sigev_signo <= 0 || event->sigev_signo > SIGRTMAX) | 
|---|
| 441 | 446 |  			return NULL; | 
|---|
| 442 |  | -		/* FALLTHRU */  | 
|---|
 | 447 | +		fallthrough;  | 
|---|
| 443 | 448 |  	case SIGEV_NONE: | 
|---|
| 444 | 449 |  		return pid; | 
|---|
| 445 | 450 |  	default: | 
|---|
| .. | .. | 
|---|
| 463 | 468 |   | 
|---|
| 464 | 469 |  static void k_itimer_rcu_free(struct rcu_head *head) | 
|---|
| 465 | 470 |  { | 
|---|
| 466 |  | -	struct k_itimer *tmr = container_of(head, struct k_itimer, it.rcu);  | 
|---|
 | 471 | +	struct k_itimer *tmr = container_of(head, struct k_itimer, rcu);  | 
|---|
| 467 | 472 |   | 
|---|
| 468 | 473 |  	kmem_cache_free(posix_timers_cache, tmr); | 
|---|
| 469 | 474 |  } | 
|---|
| .. | .. | 
|---|
| 480 | 485 |  	} | 
|---|
| 481 | 486 |  	put_pid(tmr->it_pid); | 
|---|
| 482 | 487 |  	sigqueue_free(tmr->sigq); | 
|---|
| 483 |  | -	call_rcu(&tmr->it.rcu, k_itimer_rcu_free);  | 
|---|
 | 488 | +	call_rcu(&tmr->rcu, k_itimer_rcu_free);  | 
|---|
| 484 | 489 |  } | 
|---|
| 485 | 490 |   | 
|---|
| 486 | 491 |  static int common_timer_create(struct k_itimer *new_timer) | 
|---|
| .. | .. | 
|---|
| 666 | 671 |  { | 
|---|
| 667 | 672 |  	const struct k_clock *kc = timr->kclock; | 
|---|
| 668 | 673 |  	ktime_t now, remaining, iv; | 
|---|
| 669 |  | -	struct timespec64 ts64;  | 
|---|
| 670 | 674 |  	bool sig_none; | 
|---|
| 671 | 675 |   | 
|---|
| 672 | 676 |  	sig_none = timr->it_sigev_notify == SIGEV_NONE; | 
|---|
| .. | .. | 
|---|
| 684 | 688 |  			return; | 
|---|
| 685 | 689 |  	} | 
|---|
| 686 | 690 |   | 
|---|
| 687 |  | -	/*  | 
|---|
| 688 |  | -	 * The timespec64 based conversion is suboptimal, but it's not  | 
|---|
| 689 |  | -	 * worth to implement yet another callback.  | 
|---|
| 690 |  | -	 */  | 
|---|
| 691 |  | -	kc->clock_get(timr->it_clock, &ts64);  | 
|---|
| 692 |  | -	now = timespec64_to_ktime(ts64);  | 
|---|
 | 691 | +	now = kc->clock_get_ktime(timr->it_clock);  | 
|---|
| 693 | 692 |   | 
|---|
| 694 | 693 |  	/* | 
|---|
| 695 | 694 |  	 * When a requeue is pending or this is a SIGEV_NONE timer move the | 
|---|
| .. | .. | 
|---|
| 751 | 750 |   | 
|---|
| 752 | 751 |  #ifdef CONFIG_COMPAT_32BIT_TIME | 
|---|
| 753 | 752 |   | 
|---|
| 754 |  | -COMPAT_SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id,  | 
|---|
| 755 |  | -		       struct compat_itimerspec __user *, setting)  | 
|---|
 | 753 | +SYSCALL_DEFINE2(timer_gettime32, timer_t, timer_id,  | 
|---|
 | 754 | +		struct old_itimerspec32 __user *, setting)  | 
|---|
| 756 | 755 |  { | 
|---|
| 757 | 756 |  	struct itimerspec64 cur_setting; | 
|---|
| 758 | 757 |   | 
|---|
| 759 | 758 |  	int ret = do_timer_gettime(timer_id, &cur_setting); | 
|---|
| 760 | 759 |  	if (!ret) { | 
|---|
| 761 |  | -		if (put_compat_itimerspec64(&cur_setting, setting))  | 
|---|
 | 760 | +		if (put_old_itimerspec32(&cur_setting, setting))  | 
|---|
| 762 | 761 |  			ret = -EFAULT; | 
|---|
| 763 | 762 |  	} | 
|---|
| 764 | 763 |  	return ret; | 
|---|
| .. | .. | 
|---|
| 802 | 801 |  	 * Posix magic: Relative CLOCK_REALTIME timers are not affected by | 
|---|
| 803 | 802 |  	 * clock modifications, so they become CLOCK_MONOTONIC based under the | 
|---|
| 804 | 803 |  	 * hood. See hrtimer_init(). Update timr->kclock, so the generic | 
|---|
| 805 |  | -	 * functions which use timr->kclock->clock_get() work.  | 
|---|
 | 804 | +	 * functions which use timr->kclock->clock_get_*() work.  | 
|---|
| 806 | 805 |  	 * | 
|---|
| 807 | 806 |  	 * Note: it_clock stays unmodified, because the next timer_set() might | 
|---|
| 808 | 807 |  	 * use ABSTIME, so it needs to switch back. | 
|---|
| .. | .. | 
|---|
| 824 | 823 |  static int common_hrtimer_try_to_cancel(struct k_itimer *timr) | 
|---|
| 825 | 824 |  { | 
|---|
| 826 | 825 |  	return hrtimer_try_to_cancel(&timr->it.real.timer); | 
|---|
 | 826 | +}  | 
|---|
 | 827 | +  | 
|---|
 | 828 | +static void common_timer_wait_running(struct k_itimer *timer)  | 
|---|
 | 829 | +{  | 
|---|
 | 830 | +	hrtimer_cancel_wait_running(&timer->it.real.timer);  | 
|---|
 | 831 | +}  | 
|---|
 | 832 | +  | 
|---|
 | 833 | +/*  | 
|---|
 | 834 | + * On PREEMPT_RT this prevent priority inversion against softirq kthread in  | 
|---|
 | 835 | + * case it gets preempted while executing a timer callback. See comments in  | 
|---|
 | 836 | + * hrtimer_cancel_wait_running. For PREEMPT_RT=n this just results in a  | 
|---|
 | 837 | + * cpu_relax().  | 
|---|
 | 838 | + */  | 
|---|
 | 839 | +static struct k_itimer *timer_wait_running(struct k_itimer *timer,  | 
|---|
 | 840 | +					   unsigned long *flags)  | 
|---|
 | 841 | +{  | 
|---|
 | 842 | +	const struct k_clock *kc = READ_ONCE(timer->kclock);  | 
|---|
 | 843 | +	timer_t timer_id = READ_ONCE(timer->it_id);  | 
|---|
 | 844 | +  | 
|---|
 | 845 | +	/* Prevent kfree(timer) after dropping the lock */  | 
|---|
 | 846 | +	rcu_read_lock();  | 
|---|
 | 847 | +	unlock_timer(timer, *flags);  | 
|---|
 | 848 | +  | 
|---|
 | 849 | +	if (!WARN_ON_ONCE(!kc->timer_wait_running))  | 
|---|
 | 850 | +		kc->timer_wait_running(timer);  | 
|---|
 | 851 | +  | 
|---|
 | 852 | +	rcu_read_unlock();  | 
|---|
 | 853 | +	/* Relock the timer. It might be not longer hashed. */  | 
|---|
 | 854 | +	return lock_timer(timer_id, flags);  | 
|---|
| 827 | 855 |  } | 
|---|
| 828 | 856 |   | 
|---|
| 829 | 857 |  /* Set a POSIX.1b interval timer. */ | 
|---|
| .. | .. | 
|---|
| 858 | 886 |   | 
|---|
| 859 | 887 |  	timr->it_interval = timespec64_to_ktime(new_setting->it_interval); | 
|---|
| 860 | 888 |  	expires = timespec64_to_ktime(new_setting->it_value); | 
|---|
 | 889 | +	if (flags & TIMER_ABSTIME)  | 
|---|
 | 890 | +		expires = timens_ktime_to_host(timr->it_clock, expires);  | 
|---|
| 861 | 891 |  	sigev_none = timr->it_sigev_notify == SIGEV_NONE; | 
|---|
| 862 | 892 |   | 
|---|
| 863 | 893 |  	kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none); | 
|---|
| .. | .. | 
|---|
| 865 | 895 |  	return 0; | 
|---|
| 866 | 896 |  } | 
|---|
| 867 | 897 |   | 
|---|
| 868 |  | -static int do_timer_settime(timer_t timer_id, int flags,  | 
|---|
 | 898 | +static int do_timer_settime(timer_t timer_id, int tmr_flags,  | 
|---|
| 869 | 899 |  			    struct itimerspec64 *new_spec64, | 
|---|
| 870 | 900 |  			    struct itimerspec64 *old_spec64) | 
|---|
| 871 | 901 |  { | 
|---|
| 872 | 902 |  	const struct k_clock *kc; | 
|---|
| 873 | 903 |  	struct k_itimer *timr; | 
|---|
| 874 |  | -	unsigned long flag;  | 
|---|
 | 904 | +	unsigned long flags;  | 
|---|
| 875 | 905 |  	int error = 0; | 
|---|
| 876 | 906 |   | 
|---|
| 877 | 907 |  	if (!timespec64_valid(&new_spec64->it_interval) || | 
|---|
| .. | .. | 
|---|
| 880 | 910 |   | 
|---|
| 881 | 911 |  	if (old_spec64) | 
|---|
| 882 | 912 |  		memset(old_spec64, 0, sizeof(*old_spec64)); | 
|---|
 | 913 | +  | 
|---|
 | 914 | +	timr = lock_timer(timer_id, &flags);  | 
|---|
| 883 | 915 |  retry: | 
|---|
| 884 |  | -	timr = lock_timer(timer_id, &flag);  | 
|---|
| 885 | 916 |  	if (!timr) | 
|---|
| 886 | 917 |  		return -EINVAL; | 
|---|
| 887 | 918 |   | 
|---|
| .. | .. | 
|---|
| 889 | 920 |  	if (WARN_ON_ONCE(!kc || !kc->timer_set)) | 
|---|
| 890 | 921 |  		error = -EINVAL; | 
|---|
| 891 | 922 |  	else | 
|---|
| 892 |  | -		error = kc->timer_set(timr, flags, new_spec64, old_spec64);  | 
|---|
 | 923 | +		error = kc->timer_set(timr, tmr_flags, new_spec64, old_spec64);  | 
|---|
| 893 | 924 |   | 
|---|
| 894 |  | -	unlock_timer(timr, flag);  | 
|---|
| 895 | 925 |  	if (error == TIMER_RETRY) { | 
|---|
| 896 |  | -		old_spec64 = NULL;	// We already got the old time...  | 
|---|
 | 926 | +		// We already got the old time...  | 
|---|
 | 927 | +		old_spec64 = NULL;  | 
|---|
 | 928 | +		/* Unlocks and relocks the timer if it still exists */  | 
|---|
 | 929 | +		timr = timer_wait_running(timr, &flags);  | 
|---|
| 897 | 930 |  		goto retry; | 
|---|
| 898 | 931 |  	} | 
|---|
 | 932 | +	unlock_timer(timr, flags);  | 
|---|
| 899 | 933 |   | 
|---|
| 900 | 934 |  	return error; | 
|---|
| 901 | 935 |  } | 
|---|
| .. | .. | 
|---|
| 924 | 958 |  } | 
|---|
| 925 | 959 |   | 
|---|
| 926 | 960 |  #ifdef CONFIG_COMPAT_32BIT_TIME | 
|---|
| 927 |  | -COMPAT_SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,  | 
|---|
| 928 |  | -		       struct compat_itimerspec __user *, new,  | 
|---|
| 929 |  | -		       struct compat_itimerspec __user *, old)  | 
|---|
 | 961 | +SYSCALL_DEFINE4(timer_settime32, timer_t, timer_id, int, flags,  | 
|---|
 | 962 | +		struct old_itimerspec32 __user *, new,  | 
|---|
 | 963 | +		struct old_itimerspec32 __user *, old)  | 
|---|
| 930 | 964 |  { | 
|---|
| 931 | 965 |  	struct itimerspec64 new_spec, old_spec; | 
|---|
| 932 | 966 |  	struct itimerspec64 *rtn = old ? &old_spec : NULL; | 
|---|
| .. | .. | 
|---|
| 934 | 968 |   | 
|---|
| 935 | 969 |  	if (!new) | 
|---|
| 936 | 970 |  		return -EINVAL; | 
|---|
| 937 |  | -	if (get_compat_itimerspec64(&new_spec, new))  | 
|---|
 | 971 | +	if (get_old_itimerspec32(&new_spec, new))  | 
|---|
| 938 | 972 |  		return -EFAULT; | 
|---|
| 939 | 973 |   | 
|---|
| 940 | 974 |  	error = do_timer_settime(timer_id, flags, &new_spec, rtn); | 
|---|
| 941 | 975 |  	if (!error && old) { | 
|---|
| 942 |  | -		if (put_compat_itimerspec64(&old_spec, old))  | 
|---|
 | 976 | +		if (put_old_itimerspec32(&old_spec, old))  | 
|---|
| 943 | 977 |  			error = -EFAULT; | 
|---|
| 944 | 978 |  	} | 
|---|
| 945 | 979 |  	return error; | 
|---|
| .. | .. | 
|---|
| 972 | 1006 |  	struct k_itimer *timer; | 
|---|
| 973 | 1007 |  	unsigned long flags; | 
|---|
| 974 | 1008 |   | 
|---|
| 975 |  | -retry_delete:  | 
|---|
| 976 | 1009 |  	timer = lock_timer(timer_id, &flags); | 
|---|
 | 1010 | +  | 
|---|
 | 1011 | +retry_delete:  | 
|---|
| 977 | 1012 |  	if (!timer) | 
|---|
| 978 | 1013 |  		return -EINVAL; | 
|---|
| 979 | 1014 |   | 
|---|
| 980 |  | -	if (timer_delete_hook(timer) == TIMER_RETRY) {  | 
|---|
| 981 |  | -		unlock_timer(timer, flags);  | 
|---|
 | 1015 | +	if (unlikely(timer_delete_hook(timer) == TIMER_RETRY)) {  | 
|---|
 | 1016 | +		/* Unlocks and relocks the timer if it still exists */  | 
|---|
 | 1017 | +		timer = timer_wait_running(timer, &flags);  | 
|---|
| 982 | 1018 |  		goto retry_delete; | 
|---|
| 983 | 1019 |  	} | 
|---|
| 984 | 1020 |   | 
|---|
| .. | .. | 
|---|
| 1001 | 1037 |   */ | 
|---|
| 1002 | 1038 |  static void itimer_delete(struct k_itimer *timer) | 
|---|
| 1003 | 1039 |  { | 
|---|
| 1004 |  | -	unsigned long flags;  | 
|---|
| 1005 |  | -  | 
|---|
| 1006 | 1040 |  retry_delete: | 
|---|
| 1007 |  | -	spin_lock_irqsave(&timer->it_lock, flags);  | 
|---|
 | 1041 | +	spin_lock_irq(&timer->it_lock);  | 
|---|
| 1008 | 1042 |   | 
|---|
| 1009 | 1043 |  	if (timer_delete_hook(timer) == TIMER_RETRY) { | 
|---|
| 1010 |  | -		unlock_timer(timer, flags);  | 
|---|
 | 1044 | +		spin_unlock_irq(&timer->it_lock);  | 
|---|
| 1011 | 1045 |  		goto retry_delete; | 
|---|
| 1012 | 1046 |  	} | 
|---|
| 1013 | 1047 |  	list_del(&timer->list); | 
|---|
| 1014 |  | -	/*  | 
|---|
| 1015 |  | -	 * This keeps any tasks waiting on the spin lock from thinking  | 
|---|
| 1016 |  | -	 * they got something (see the lock code above).  | 
|---|
| 1017 |  | -	 */  | 
|---|
| 1018 |  | -	timer->it_signal = NULL;  | 
|---|
| 1019 | 1048 |   | 
|---|
| 1020 |  | -	unlock_timer(timer, flags);  | 
|---|
 | 1049 | +	spin_unlock_irq(&timer->it_lock);  | 
|---|
| 1021 | 1050 |  	release_posix_timer(timer, IT_ID_SET); | 
|---|
| 1022 | 1051 |  } | 
|---|
| 1023 | 1052 |   | 
|---|
| 1024 | 1053 |  /* | 
|---|
| 1025 |  | - * This is called by do_exit or de_thread, only when there are no more  | 
|---|
| 1026 |  | - * references to the shared signal_struct.  | 
|---|
 | 1054 | + * This is called by do_exit or de_thread, only when nobody else can  | 
|---|
 | 1055 | + * modify the signal->posix_timers list. Yet we need sighand->siglock  | 
|---|
 | 1056 | + * to prevent the race with /proc/pid/timers.  | 
|---|
| 1027 | 1057 |   */ | 
|---|
| 1028 |  | -void exit_itimers(struct signal_struct *sig)  | 
|---|
 | 1058 | +void exit_itimers(struct task_struct *tsk)  | 
|---|
| 1029 | 1059 |  { | 
|---|
 | 1060 | +	struct list_head timers;  | 
|---|
| 1030 | 1061 |  	struct k_itimer *tmr; | 
|---|
| 1031 | 1062 |   | 
|---|
| 1032 |  | -	while (!list_empty(&sig->posix_timers)) {  | 
|---|
| 1033 |  | -		tmr = list_entry(sig->posix_timers.next, struct k_itimer, list);  | 
|---|
 | 1063 | +	if (list_empty(&tsk->signal->posix_timers))  | 
|---|
 | 1064 | +		return;  | 
|---|
 | 1065 | +  | 
|---|
 | 1066 | +	spin_lock_irq(&tsk->sighand->siglock);  | 
|---|
 | 1067 | +	list_replace_init(&tsk->signal->posix_timers, &timers);  | 
|---|
 | 1068 | +	spin_unlock_irq(&tsk->sighand->siglock);  | 
|---|
 | 1069 | +  | 
|---|
 | 1070 | +	while (!list_empty(&timers)) {  | 
|---|
 | 1071 | +		tmr = list_first_entry(&timers, struct k_itimer, list);  | 
|---|
| 1034 | 1072 |  		itimer_delete(tmr); | 
|---|
| 1035 | 1073 |  	} | 
|---|
| 1036 | 1074 |  } | 
|---|
| .. | .. | 
|---|
| 1060 | 1098 |  	if (!kc) | 
|---|
| 1061 | 1099 |  		return -EINVAL; | 
|---|
| 1062 | 1100 |   | 
|---|
| 1063 |  | -	error = kc->clock_get(which_clock, &kernel_tp);  | 
|---|
 | 1101 | +	error = kc->clock_get_timespec(which_clock, &kernel_tp);  | 
|---|
| 1064 | 1102 |   | 
|---|
| 1065 | 1103 |  	if (!error && put_timespec64(&kernel_tp, tp)) | 
|---|
| 1066 | 1104 |  		error = -EFAULT; | 
|---|
| .. | .. | 
|---|
| 1068 | 1106 |  	return error; | 
|---|
| 1069 | 1107 |  } | 
|---|
| 1070 | 1108 |   | 
|---|
| 1071 |  | -SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,  | 
|---|
| 1072 |  | -		struct timex __user *, utx)  | 
|---|
 | 1109 | +int do_clock_adjtime(const clockid_t which_clock, struct __kernel_timex * ktx)  | 
|---|
| 1073 | 1110 |  { | 
|---|
| 1074 | 1111 |  	const struct k_clock *kc = clockid_to_kclock(which_clock); | 
|---|
| 1075 |  | -	struct timex ktx;  | 
|---|
| 1076 |  | -	int err;  | 
|---|
| 1077 | 1112 |   | 
|---|
| 1078 | 1113 |  	if (!kc) | 
|---|
| 1079 | 1114 |  		return -EINVAL; | 
|---|
| 1080 | 1115 |  	if (!kc->clock_adj) | 
|---|
| 1081 | 1116 |  		return -EOPNOTSUPP; | 
|---|
| 1082 | 1117 |   | 
|---|
 | 1118 | +	return kc->clock_adj(which_clock, ktx);  | 
|---|
 | 1119 | +}  | 
|---|
 | 1120 | +  | 
|---|
 | 1121 | +SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,  | 
|---|
 | 1122 | +		struct __kernel_timex __user *, utx)  | 
|---|
 | 1123 | +{  | 
|---|
 | 1124 | +	struct __kernel_timex ktx;  | 
|---|
 | 1125 | +	int err;  | 
|---|
 | 1126 | +  | 
|---|
| 1083 | 1127 |  	if (copy_from_user(&ktx, utx, sizeof(ktx))) | 
|---|
| 1084 | 1128 |  		return -EFAULT; | 
|---|
| 1085 | 1129 |   | 
|---|
| 1086 |  | -	err = kc->clock_adj(which_clock, &ktx);  | 
|---|
 | 1130 | +	err = do_clock_adjtime(which_clock, &ktx);  | 
|---|
| 1087 | 1131 |   | 
|---|
| 1088 | 1132 |  	if (err >= 0 && copy_to_user(utx, &ktx, sizeof(ktx))) | 
|---|
| 1089 | 1133 |  		return -EFAULT; | 
|---|
| .. | .. | 
|---|
| 1111 | 1155 |   | 
|---|
| 1112 | 1156 |  #ifdef CONFIG_COMPAT_32BIT_TIME | 
|---|
| 1113 | 1157 |   | 
|---|
| 1114 |  | -COMPAT_SYSCALL_DEFINE2(clock_settime, clockid_t, which_clock,  | 
|---|
| 1115 |  | -		       struct compat_timespec __user *, tp)  | 
|---|
 | 1158 | +SYSCALL_DEFINE2(clock_settime32, clockid_t, which_clock,  | 
|---|
 | 1159 | +		struct old_timespec32 __user *, tp)  | 
|---|
| 1116 | 1160 |  { | 
|---|
| 1117 | 1161 |  	const struct k_clock *kc = clockid_to_kclock(which_clock); | 
|---|
| 1118 | 1162 |  	struct timespec64 ts; | 
|---|
| .. | .. | 
|---|
| 1120 | 1164 |  	if (!kc || !kc->clock_set) | 
|---|
| 1121 | 1165 |  		return -EINVAL; | 
|---|
| 1122 | 1166 |   | 
|---|
| 1123 |  | -	if (compat_get_timespec64(&ts, tp))  | 
|---|
 | 1167 | +	if (get_old_timespec32(&ts, tp))  | 
|---|
| 1124 | 1168 |  		return -EFAULT; | 
|---|
| 1125 | 1169 |   | 
|---|
| 1126 | 1170 |  	return kc->clock_set(which_clock, &ts); | 
|---|
| 1127 | 1171 |  } | 
|---|
| 1128 | 1172 |   | 
|---|
| 1129 |  | -COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,  | 
|---|
| 1130 |  | -		       struct compat_timespec __user *, tp)  | 
|---|
 | 1173 | +SYSCALL_DEFINE2(clock_gettime32, clockid_t, which_clock,  | 
|---|
 | 1174 | +		struct old_timespec32 __user *, tp)  | 
|---|
| 1131 | 1175 |  { | 
|---|
| 1132 | 1176 |  	const struct k_clock *kc = clockid_to_kclock(which_clock); | 
|---|
| 1133 | 1177 |  	struct timespec64 ts; | 
|---|
| .. | .. | 
|---|
| 1136 | 1180 |  	if (!kc) | 
|---|
| 1137 | 1181 |  		return -EINVAL; | 
|---|
| 1138 | 1182 |   | 
|---|
| 1139 |  | -	err = kc->clock_get(which_clock, &ts);  | 
|---|
 | 1183 | +	err = kc->clock_get_timespec(which_clock, &ts);  | 
|---|
| 1140 | 1184 |   | 
|---|
| 1141 |  | -	if (!err && compat_put_timespec64(&ts, tp))  | 
|---|
 | 1185 | +	if (!err && put_old_timespec32(&ts, tp))  | 
|---|
| 1142 | 1186 |  		err = -EFAULT; | 
|---|
| 1143 | 1187 |   | 
|---|
| 1144 | 1188 |  	return err; | 
|---|
| 1145 | 1189 |  } | 
|---|
| 1146 | 1190 |   | 
|---|
| 1147 |  | -#endif  | 
|---|
| 1148 |  | -  | 
|---|
| 1149 |  | -#ifdef CONFIG_COMPAT  | 
|---|
| 1150 |  | -  | 
|---|
| 1151 |  | -COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,  | 
|---|
| 1152 |  | -		       struct compat_timex __user *, utp)  | 
|---|
 | 1191 | +SYSCALL_DEFINE2(clock_adjtime32, clockid_t, which_clock,  | 
|---|
 | 1192 | +		struct old_timex32 __user *, utp)  | 
|---|
| 1153 | 1193 |  { | 
|---|
| 1154 |  | -	const struct k_clock *kc = clockid_to_kclock(which_clock);  | 
|---|
| 1155 |  | -	struct timex ktx;  | 
|---|
 | 1194 | +	struct __kernel_timex ktx;  | 
|---|
| 1156 | 1195 |  	int err; | 
|---|
| 1157 | 1196 |   | 
|---|
| 1158 |  | -	if (!kc)  | 
|---|
| 1159 |  | -		return -EINVAL;  | 
|---|
| 1160 |  | -	if (!kc->clock_adj)  | 
|---|
| 1161 |  | -		return -EOPNOTSUPP;  | 
|---|
| 1162 |  | -  | 
|---|
| 1163 |  | -	err = compat_get_timex(&ktx, utp);  | 
|---|
 | 1197 | +	err = get_old_timex32(&ktx, utp);  | 
|---|
| 1164 | 1198 |  	if (err) | 
|---|
| 1165 | 1199 |  		return err; | 
|---|
| 1166 | 1200 |   | 
|---|
| 1167 |  | -	err = kc->clock_adj(which_clock, &ktx);  | 
|---|
 | 1201 | +	err = do_clock_adjtime(which_clock, &ktx);  | 
|---|
| 1168 | 1202 |   | 
|---|
| 1169 |  | -	if (err >= 0 && compat_put_timex(utp, &ktx))  | 
|---|
 | 1203 | +	if (err >= 0 && put_old_timex32(utp, &ktx))  | 
|---|
| 1170 | 1204 |  		return -EFAULT; | 
|---|
| 1171 | 1205 |   | 
|---|
| 1172 | 1206 |  	return err; | 
|---|
| 1173 | 1207 |  } | 
|---|
| 1174 | 1208 |   | 
|---|
| 1175 |  | -#endif  | 
|---|
| 1176 |  | -  | 
|---|
| 1177 |  | -#ifdef CONFIG_COMPAT_32BIT_TIME  | 
|---|
| 1178 |  | -  | 
|---|
| 1179 |  | -COMPAT_SYSCALL_DEFINE2(clock_getres, clockid_t, which_clock,  | 
|---|
| 1180 |  | -		       struct compat_timespec __user *, tp)  | 
|---|
 | 1209 | +SYSCALL_DEFINE2(clock_getres_time32, clockid_t, which_clock,  | 
|---|
 | 1210 | +		struct old_timespec32 __user *, tp)  | 
|---|
| 1181 | 1211 |  { | 
|---|
| 1182 | 1212 |  	const struct k_clock *kc = clockid_to_kclock(which_clock); | 
|---|
| 1183 | 1213 |  	struct timespec64 ts; | 
|---|
| .. | .. | 
|---|
| 1187 | 1217 |  		return -EINVAL; | 
|---|
| 1188 | 1218 |   | 
|---|
| 1189 | 1219 |  	err = kc->clock_getres(which_clock, &ts); | 
|---|
| 1190 |  | -	if (!err && tp && compat_put_timespec64(&ts, tp))  | 
|---|
 | 1220 | +	if (!err && tp && put_old_timespec32(&ts, tp))  | 
|---|
| 1191 | 1221 |  		return -EFAULT; | 
|---|
| 1192 | 1222 |   | 
|---|
| 1193 | 1223 |  	return err; | 
|---|
| .. | .. | 
|---|
| 1201 | 1231 |  static int common_nsleep(const clockid_t which_clock, int flags, | 
|---|
| 1202 | 1232 |  			 const struct timespec64 *rqtp) | 
|---|
| 1203 | 1233 |  { | 
|---|
| 1204 |  | -	return hrtimer_nanosleep(rqtp, flags & TIMER_ABSTIME ?  | 
|---|
 | 1234 | +	ktime_t texp = timespec64_to_ktime(*rqtp);  | 
|---|
 | 1235 | +  | 
|---|
 | 1236 | +	return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ?  | 
|---|
 | 1237 | +				 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,  | 
|---|
 | 1238 | +				 which_clock);  | 
|---|
 | 1239 | +}  | 
|---|
 | 1240 | +  | 
|---|
 | 1241 | +static int common_nsleep_timens(const clockid_t which_clock, int flags,  | 
|---|
 | 1242 | +			 const struct timespec64 *rqtp)  | 
|---|
 | 1243 | +{  | 
|---|
 | 1244 | +	ktime_t texp = timespec64_to_ktime(*rqtp);  | 
|---|
 | 1245 | +  | 
|---|
 | 1246 | +	if (flags & TIMER_ABSTIME)  | 
|---|
 | 1247 | +		texp = timens_ktime_to_host(which_clock, texp);  | 
|---|
 | 1248 | +  | 
|---|
 | 1249 | +	return hrtimer_nanosleep(texp, flags & TIMER_ABSTIME ?  | 
|---|
| 1205 | 1250 |  				 HRTIMER_MODE_ABS : HRTIMER_MODE_REL, | 
|---|
| 1206 | 1251 |  				 which_clock); | 
|---|
| 1207 | 1252 |  } | 
|---|
| .. | .. | 
|---|
| 1233 | 1278 |   | 
|---|
| 1234 | 1279 |  #ifdef CONFIG_COMPAT_32BIT_TIME | 
|---|
| 1235 | 1280 |   | 
|---|
| 1236 |  | -COMPAT_SYSCALL_DEFINE4(clock_nanosleep, clockid_t, which_clock, int, flags,  | 
|---|
| 1237 |  | -		       struct compat_timespec __user *, rqtp,  | 
|---|
| 1238 |  | -		       struct compat_timespec __user *, rmtp)  | 
|---|
 | 1281 | +SYSCALL_DEFINE4(clock_nanosleep_time32, clockid_t, which_clock, int, flags,  | 
|---|
 | 1282 | +		struct old_timespec32 __user *, rqtp,  | 
|---|
 | 1283 | +		struct old_timespec32 __user *, rmtp)  | 
|---|
| 1239 | 1284 |  { | 
|---|
| 1240 | 1285 |  	const struct k_clock *kc = clockid_to_kclock(which_clock); | 
|---|
| 1241 | 1286 |  	struct timespec64 t; | 
|---|
| .. | .. | 
|---|
| 1245 | 1290 |  	if (!kc->nsleep) | 
|---|
| 1246 | 1291 |  		return -EOPNOTSUPP; | 
|---|
| 1247 | 1292 |   | 
|---|
| 1248 |  | -	if (compat_get_timespec64(&t, rqtp))  | 
|---|
 | 1293 | +	if (get_old_timespec32(&t, rqtp))  | 
|---|
| 1249 | 1294 |  		return -EFAULT; | 
|---|
| 1250 | 1295 |   | 
|---|
| 1251 | 1296 |  	if (!timespec64_valid(&t)) | 
|---|
| .. | .. | 
|---|
| 1262 | 1307 |   | 
|---|
| 1263 | 1308 |  static const struct k_clock clock_realtime = { | 
|---|
| 1264 | 1309 |  	.clock_getres		= posix_get_hrtimer_res, | 
|---|
| 1265 |  | -	.clock_get		= posix_clock_realtime_get,  | 
|---|
 | 1310 | +	.clock_get_timespec	= posix_get_realtime_timespec,  | 
|---|
 | 1311 | +	.clock_get_ktime	= posix_get_realtime_ktime,  | 
|---|
| 1266 | 1312 |  	.clock_set		= posix_clock_realtime_set, | 
|---|
| 1267 | 1313 |  	.clock_adj		= posix_clock_realtime_adj, | 
|---|
| 1268 | 1314 |  	.nsleep			= common_nsleep, | 
|---|
| .. | .. | 
|---|
| 1274 | 1320 |  	.timer_forward		= common_hrtimer_forward, | 
|---|
| 1275 | 1321 |  	.timer_remaining	= common_hrtimer_remaining, | 
|---|
| 1276 | 1322 |  	.timer_try_to_cancel	= common_hrtimer_try_to_cancel, | 
|---|
 | 1323 | +	.timer_wait_running	= common_timer_wait_running,  | 
|---|
| 1277 | 1324 |  	.timer_arm		= common_hrtimer_arm, | 
|---|
| 1278 | 1325 |  }; | 
|---|
| 1279 | 1326 |   | 
|---|
| 1280 | 1327 |  static const struct k_clock clock_monotonic = { | 
|---|
| 1281 | 1328 |  	.clock_getres		= posix_get_hrtimer_res, | 
|---|
| 1282 |  | -	.clock_get		= posix_ktime_get_ts,  | 
|---|
| 1283 |  | -	.nsleep			= common_nsleep,  | 
|---|
 | 1329 | +	.clock_get_timespec	= posix_get_monotonic_timespec,  | 
|---|
 | 1330 | +	.clock_get_ktime	= posix_get_monotonic_ktime,  | 
|---|
 | 1331 | +	.nsleep			= common_nsleep_timens,  | 
|---|
| 1284 | 1332 |  	.timer_create		= common_timer_create, | 
|---|
| 1285 | 1333 |  	.timer_set		= common_timer_set, | 
|---|
| 1286 | 1334 |  	.timer_get		= common_timer_get, | 
|---|
| .. | .. | 
|---|
| 1289 | 1337 |  	.timer_forward		= common_hrtimer_forward, | 
|---|
| 1290 | 1338 |  	.timer_remaining	= common_hrtimer_remaining, | 
|---|
| 1291 | 1339 |  	.timer_try_to_cancel	= common_hrtimer_try_to_cancel, | 
|---|
 | 1340 | +	.timer_wait_running	= common_timer_wait_running,  | 
|---|
| 1292 | 1341 |  	.timer_arm		= common_hrtimer_arm, | 
|---|
| 1293 | 1342 |  }; | 
|---|
| 1294 | 1343 |   | 
|---|
| 1295 | 1344 |  static const struct k_clock clock_monotonic_raw = { | 
|---|
| 1296 | 1345 |  	.clock_getres		= posix_get_hrtimer_res, | 
|---|
| 1297 |  | -	.clock_get		= posix_get_monotonic_raw,  | 
|---|
 | 1346 | +	.clock_get_timespec	= posix_get_monotonic_raw,  | 
|---|
| 1298 | 1347 |  }; | 
|---|
| 1299 | 1348 |   | 
|---|
| 1300 | 1349 |  static const struct k_clock clock_realtime_coarse = { | 
|---|
| 1301 | 1350 |  	.clock_getres		= posix_get_coarse_res, | 
|---|
| 1302 |  | -	.clock_get		= posix_get_realtime_coarse,  | 
|---|
 | 1351 | +	.clock_get_timespec	= posix_get_realtime_coarse,  | 
|---|
| 1303 | 1352 |  }; | 
|---|
| 1304 | 1353 |   | 
|---|
| 1305 | 1354 |  static const struct k_clock clock_monotonic_coarse = { | 
|---|
| 1306 | 1355 |  	.clock_getres		= posix_get_coarse_res, | 
|---|
| 1307 |  | -	.clock_get		= posix_get_monotonic_coarse,  | 
|---|
 | 1356 | +	.clock_get_timespec	= posix_get_monotonic_coarse,  | 
|---|
| 1308 | 1357 |  }; | 
|---|
| 1309 | 1358 |   | 
|---|
| 1310 | 1359 |  static const struct k_clock clock_tai = { | 
|---|
| 1311 | 1360 |  	.clock_getres		= posix_get_hrtimer_res, | 
|---|
| 1312 |  | -	.clock_get		= posix_get_tai,  | 
|---|
 | 1361 | +	.clock_get_ktime	= posix_get_tai_ktime,  | 
|---|
 | 1362 | +	.clock_get_timespec	= posix_get_tai_timespec,  | 
|---|
| 1313 | 1363 |  	.nsleep			= common_nsleep, | 
|---|
| 1314 | 1364 |  	.timer_create		= common_timer_create, | 
|---|
| 1315 | 1365 |  	.timer_set		= common_timer_set, | 
|---|
| .. | .. | 
|---|
| 1319 | 1369 |  	.timer_forward		= common_hrtimer_forward, | 
|---|
| 1320 | 1370 |  	.timer_remaining	= common_hrtimer_remaining, | 
|---|
| 1321 | 1371 |  	.timer_try_to_cancel	= common_hrtimer_try_to_cancel, | 
|---|
 | 1372 | +	.timer_wait_running	= common_timer_wait_running,  | 
|---|
| 1322 | 1373 |  	.timer_arm		= common_hrtimer_arm, | 
|---|
| 1323 | 1374 |  }; | 
|---|
| 1324 | 1375 |   | 
|---|
| 1325 | 1376 |  static const struct k_clock clock_boottime = { | 
|---|
| 1326 | 1377 |  	.clock_getres		= posix_get_hrtimer_res, | 
|---|
| 1327 |  | -	.clock_get		= posix_get_boottime,  | 
|---|
| 1328 |  | -	.nsleep			= common_nsleep,  | 
|---|
 | 1378 | +	.clock_get_ktime	= posix_get_boottime_ktime,  | 
|---|
 | 1379 | +	.clock_get_timespec	= posix_get_boottime_timespec,  | 
|---|
 | 1380 | +	.nsleep			= common_nsleep_timens,  | 
|---|
| 1329 | 1381 |  	.timer_create		= common_timer_create, | 
|---|
| 1330 | 1382 |  	.timer_set		= common_timer_set, | 
|---|
| 1331 | 1383 |  	.timer_get		= common_timer_get, | 
|---|
| .. | .. | 
|---|
| 1334 | 1386 |  	.timer_forward		= common_hrtimer_forward, | 
|---|
| 1335 | 1387 |  	.timer_remaining	= common_hrtimer_remaining, | 
|---|
| 1336 | 1388 |  	.timer_try_to_cancel	= common_hrtimer_try_to_cancel, | 
|---|
 | 1389 | +	.timer_wait_running	= common_timer_wait_running,  | 
|---|
| 1337 | 1390 |  	.timer_arm		= common_hrtimer_arm, | 
|---|
| 1338 | 1391 |  }; | 
|---|
| 1339 | 1392 |   | 
|---|