.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * Alarmtimer interface |
---|
3 | 4 | * |
---|
.. | .. |
---|
10 | 11 | * Copyright (C) 2010 IBM Corperation |
---|
11 | 12 | * |
---|
12 | 13 | * Author: John Stultz <john.stultz@linaro.org> |
---|
13 | | - * |
---|
14 | | - * This program is free software; you can redistribute it and/or modify |
---|
15 | | - * it under the terms of the GNU General Public License version 2 as |
---|
16 | | - * published by the Free Software Foundation. |
---|
17 | 14 | */ |
---|
18 | 15 | #include <linux/time.h> |
---|
19 | 16 | #include <linux/hrtimer.h> |
---|
.. | .. |
---|
29 | 26 | #include <linux/freezer.h> |
---|
30 | 27 | #include <linux/compat.h> |
---|
31 | 28 | #include <linux/module.h> |
---|
| 29 | +#include <linux/time_namespace.h> |
---|
32 | 30 | |
---|
33 | 31 | #include "posix-timers.h" |
---|
34 | 32 | |
---|
.. | .. |
---|
39 | 37 | * struct alarm_base - Alarm timer bases |
---|
40 | 38 | * @lock: Lock for syncrhonized access to the base |
---|
41 | 39 | * @timerqueue: Timerqueue head managing the list of events |
---|
42 | | - * @gettime: Function to read the time correlating to the base |
---|
| 40 | + * @get_ktime: Function to read the time correlating to the base |
---|
| 41 | + * @get_timespec: Function to read the namespace time correlating to the base |
---|
43 | 42 | * @base_clockid: clockid for the base |
---|
44 | 43 | */ |
---|
45 | 44 | static struct alarm_base { |
---|
46 | 45 | spinlock_t lock; |
---|
47 | 46 | struct timerqueue_head timerqueue; |
---|
48 | | - ktime_t (*gettime)(void); |
---|
| 47 | + ktime_t (*get_ktime)(void); |
---|
| 48 | + void (*get_timespec)(struct timespec64 *tp); |
---|
49 | 49 | clockid_t base_clockid; |
---|
50 | 50 | } alarm_bases[ALARM_NUMTYPE]; |
---|
51 | 51 | |
---|
.. | .. |
---|
58 | 58 | #endif |
---|
59 | 59 | |
---|
60 | 60 | #ifdef CONFIG_RTC_CLASS |
---|
61 | | -static struct wakeup_source *ws; |
---|
62 | | - |
---|
63 | 61 | /* rtc timer and device for setting alarm wakeups at suspend */ |
---|
64 | 62 | static struct rtc_timer rtctimer; |
---|
65 | 63 | static struct rtc_device *rtcdev; |
---|
.. | .. |
---|
69 | 67 | * alarmtimer_get_rtcdev - Return selected rtcdevice |
---|
70 | 68 | * |
---|
71 | 69 | * This function returns the rtc device to use for wakealarms. |
---|
72 | | - * If one has not already been chosen, it checks to see if a |
---|
73 | | - * functional rtc device is available. |
---|
74 | 70 | */ |
---|
75 | 71 | struct rtc_device *alarmtimer_get_rtcdev(void) |
---|
76 | 72 | { |
---|
.. | .. |
---|
90 | 86 | { |
---|
91 | 87 | unsigned long flags; |
---|
92 | 88 | struct rtc_device *rtc = to_rtc_device(dev); |
---|
93 | | - struct wakeup_source *__ws; |
---|
| 89 | + struct platform_device *pdev; |
---|
94 | 90 | int ret = 0; |
---|
95 | 91 | |
---|
96 | 92 | if (rtcdev) |
---|
.. | .. |
---|
101 | 97 | if (!device_may_wakeup(rtc->dev.parent)) |
---|
102 | 98 | return -1; |
---|
103 | 99 | |
---|
104 | | - __ws = wakeup_source_register(dev, "alarmtimer"); |
---|
| 100 | + pdev = platform_device_register_data(dev, "alarmtimer", |
---|
| 101 | + PLATFORM_DEVID_AUTO, NULL, 0); |
---|
| 102 | + if (!IS_ERR(pdev)) |
---|
| 103 | + device_init_wakeup(&pdev->dev, true); |
---|
105 | 104 | |
---|
106 | 105 | spin_lock_irqsave(&rtcdev_lock, flags); |
---|
107 | | - if (!rtcdev) { |
---|
| 106 | + if (!IS_ERR(pdev) && !rtcdev) { |
---|
108 | 107 | if (!try_module_get(rtc->owner)) { |
---|
109 | 108 | ret = -1; |
---|
110 | 109 | goto unlock; |
---|
.. | .. |
---|
113 | 112 | rtcdev = rtc; |
---|
114 | 113 | /* hold a reference so it doesn't go away */ |
---|
115 | 114 | get_device(dev); |
---|
116 | | - ws = __ws; |
---|
117 | | - __ws = NULL; |
---|
| 115 | + pdev = NULL; |
---|
| 116 | + } else { |
---|
| 117 | + ret = -1; |
---|
118 | 118 | } |
---|
119 | 119 | unlock: |
---|
120 | 120 | spin_unlock_irqrestore(&rtcdev_lock, flags); |
---|
121 | 121 | |
---|
122 | | - wakeup_source_unregister(__ws); |
---|
| 122 | + platform_device_unregister(pdev); |
---|
123 | 123 | |
---|
124 | 124 | return ret; |
---|
125 | 125 | } |
---|
.. | .. |
---|
143 | 143 | class_interface_unregister(&alarmtimer_rtc_interface); |
---|
144 | 144 | } |
---|
145 | 145 | #else |
---|
146 | | -struct rtc_device *alarmtimer_get_rtcdev(void) |
---|
147 | | -{ |
---|
148 | | - return NULL; |
---|
149 | | -} |
---|
150 | | -#define rtcdev (NULL) |
---|
151 | 146 | static inline int alarmtimer_rtc_interface_setup(void) { return 0; } |
---|
152 | 147 | static inline void alarmtimer_rtc_interface_remove(void) { } |
---|
153 | 148 | static inline void alarmtimer_rtc_timer_init(void) { } |
---|
.. | .. |
---|
197 | 192 | * When a alarm timer fires, this runs through the timerqueue to |
---|
198 | 193 | * see which alarms expired, and runs those. If there are more alarm |
---|
199 | 194 | * timers queued for the future, we set the hrtimer to fire when |
---|
200 | | - * when the next future alarm timer expires. |
---|
| 195 | + * the next future alarm timer expires. |
---|
201 | 196 | */ |
---|
202 | 197 | static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) |
---|
203 | 198 | { |
---|
.. | .. |
---|
212 | 207 | spin_unlock_irqrestore(&base->lock, flags); |
---|
213 | 208 | |
---|
214 | 209 | if (alarm->function) |
---|
215 | | - restart = alarm->function(alarm, base->gettime()); |
---|
| 210 | + restart = alarm->function(alarm, base->get_ktime()); |
---|
216 | 211 | |
---|
217 | 212 | spin_lock_irqsave(&base->lock, flags); |
---|
218 | 213 | if (restart != ALARMTIMER_NORESTART) { |
---|
.. | .. |
---|
222 | 217 | } |
---|
223 | 218 | spin_unlock_irqrestore(&base->lock, flags); |
---|
224 | 219 | |
---|
225 | | - trace_alarmtimer_fired(alarm, base->gettime()); |
---|
| 220 | + trace_alarmtimer_fired(alarm, base->get_ktime()); |
---|
226 | 221 | return ret; |
---|
227 | 222 | |
---|
228 | 223 | } |
---|
.. | .. |
---|
230 | 225 | ktime_t alarm_expires_remaining(const struct alarm *alarm) |
---|
231 | 226 | { |
---|
232 | 227 | struct alarm_base *base = &alarm_bases[alarm->type]; |
---|
233 | | - return ktime_sub(alarm->node.expires, base->gettime()); |
---|
| 228 | + return ktime_sub(alarm->node.expires, base->get_ktime()); |
---|
234 | 229 | } |
---|
235 | 230 | EXPORT_SYMBOL_GPL(alarm_expires_remaining); |
---|
236 | 231 | |
---|
.. | .. |
---|
238 | 233 | /** |
---|
239 | 234 | * alarmtimer_suspend - Suspend time callback |
---|
240 | 235 | * @dev: unused |
---|
241 | | - * @state: unused |
---|
242 | 236 | * |
---|
243 | 237 | * When we are going into suspend, we look through the bases |
---|
244 | 238 | * to see which is the soonest timer to expire. We then |
---|
.. | .. |
---|
276 | 270 | spin_unlock_irqrestore(&base->lock, flags); |
---|
277 | 271 | if (!next) |
---|
278 | 272 | continue; |
---|
279 | | - delta = ktime_sub(next->expires, base->gettime()); |
---|
| 273 | + delta = ktime_sub(next->expires, base->get_ktime()); |
---|
280 | 274 | if (!min || (delta < min)) { |
---|
281 | 275 | expires = next->expires; |
---|
282 | 276 | min = delta; |
---|
.. | .. |
---|
287 | 281 | return 0; |
---|
288 | 282 | |
---|
289 | 283 | if (ktime_to_ns(min) < 2 * NSEC_PER_SEC) { |
---|
290 | | - __pm_wakeup_event(ws, 2 * MSEC_PER_SEC); |
---|
| 284 | + pm_wakeup_event(dev, 2 * MSEC_PER_SEC); |
---|
291 | 285 | return -EBUSY; |
---|
292 | 286 | } |
---|
293 | 287 | |
---|
.. | .. |
---|
302 | 296 | /* Set alarm, if in the past reject suspend briefly to handle */ |
---|
303 | 297 | ret = rtc_timer_start(rtc, &rtctimer, now, 0); |
---|
304 | 298 | if (ret < 0) |
---|
305 | | - __pm_wakeup_event(ws, MSEC_PER_SEC); |
---|
| 299 | + pm_wakeup_event(dev, MSEC_PER_SEC); |
---|
306 | 300 | return ret; |
---|
307 | 301 | } |
---|
308 | 302 | |
---|
.. | .. |
---|
370 | 364 | hrtimer_start(&alarm->timer, alarm->node.expires, HRTIMER_MODE_ABS); |
---|
371 | 365 | spin_unlock_irqrestore(&base->lock, flags); |
---|
372 | 366 | |
---|
373 | | - trace_alarmtimer_start(alarm, base->gettime()); |
---|
| 367 | + trace_alarmtimer_start(alarm, base->get_ktime()); |
---|
374 | 368 | } |
---|
375 | 369 | EXPORT_SYMBOL_GPL(alarm_start); |
---|
376 | 370 | |
---|
.. | .. |
---|
383 | 377 | { |
---|
384 | 378 | struct alarm_base *base = &alarm_bases[alarm->type]; |
---|
385 | 379 | |
---|
386 | | - start = ktime_add_safe(start, base->gettime()); |
---|
| 380 | + start = ktime_add_safe(start, base->get_ktime()); |
---|
387 | 381 | alarm_start(alarm, start); |
---|
388 | 382 | } |
---|
389 | 383 | EXPORT_SYMBOL_GPL(alarm_start_relative); |
---|
.. | .. |
---|
420 | 414 | alarmtimer_dequeue(base, alarm); |
---|
421 | 415 | spin_unlock_irqrestore(&base->lock, flags); |
---|
422 | 416 | |
---|
423 | | - trace_alarmtimer_cancel(alarm, base->gettime()); |
---|
| 417 | + trace_alarmtimer_cancel(alarm, base->get_ktime()); |
---|
424 | 418 | return ret; |
---|
425 | 419 | } |
---|
426 | 420 | EXPORT_SYMBOL_GPL(alarm_try_to_cancel); |
---|
.. | .. |
---|
438 | 432 | int ret = alarm_try_to_cancel(alarm); |
---|
439 | 433 | if (ret >= 0) |
---|
440 | 434 | return ret; |
---|
441 | | - hrtimer_grab_expiry_lock(&alarm->timer); |
---|
| 435 | + hrtimer_cancel_wait_running(&alarm->timer); |
---|
442 | 436 | } |
---|
443 | 437 | } |
---|
444 | 438 | EXPORT_SYMBOL_GPL(alarm_cancel); |
---|
.. | .. |
---|
480 | 474 | { |
---|
481 | 475 | struct alarm_base *base = &alarm_bases[alarm->type]; |
---|
482 | 476 | |
---|
483 | | - return alarm_forward(alarm, base->gettime(), interval); |
---|
| 477 | + return alarm_forward(alarm, base->get_ktime(), interval); |
---|
484 | 478 | } |
---|
485 | 479 | EXPORT_SYMBOL_GPL(alarm_forward_now); |
---|
486 | 480 | |
---|
.. | .. |
---|
506 | 500 | return; |
---|
507 | 501 | } |
---|
508 | 502 | |
---|
509 | | - delta = ktime_sub(absexp, base->gettime()); |
---|
| 503 | + delta = ktime_sub(absexp, base->get_ktime()); |
---|
510 | 504 | |
---|
511 | 505 | spin_lock_irqsave(&freezer_delta_lock, flags); |
---|
512 | 506 | if (!freezer_delta || (delta < freezer_delta)) { |
---|
.. | .. |
---|
612 | 606 | } |
---|
613 | 607 | |
---|
614 | 608 | /** |
---|
| 609 | + * alarm_timer_wait_running - Posix timer callback to wait for a timer |
---|
| 610 | + * @timr: Pointer to the posixtimer data struct |
---|
| 611 | + * |
---|
| 612 | + * Called from the core code when timer cancel detected that the callback |
---|
| 613 | + * is running. @timr is unlocked and rcu read lock is held to prevent it |
---|
| 614 | + * from being freed. |
---|
| 615 | + */ |
---|
| 616 | +static void alarm_timer_wait_running(struct k_itimer *timr) |
---|
| 617 | +{ |
---|
| 618 | + hrtimer_cancel_wait_running(&timr->it.alarm.alarmtimer.timer); |
---|
| 619 | +} |
---|
| 620 | + |
---|
| 621 | +/** |
---|
615 | 622 | * alarm_timer_arm - Posix timer callback to arm a timer |
---|
616 | 623 | * @timr: Pointer to the posixtimer data struct |
---|
617 | 624 | * @expires: The new expiry time |
---|
.. | .. |
---|
625 | 632 | struct alarm_base *base = &alarm_bases[alarm->type]; |
---|
626 | 633 | |
---|
627 | 634 | if (!absolute) |
---|
628 | | - expires = ktime_add_safe(expires, base->gettime()); |
---|
| 635 | + expires = ktime_add_safe(expires, base->get_ktime()); |
---|
629 | 636 | if (sigev_none) |
---|
630 | 637 | alarm->node.expires = expires; |
---|
631 | 638 | else |
---|
.. | .. |
---|
650 | 657 | } |
---|
651 | 658 | |
---|
652 | 659 | /** |
---|
653 | | - * alarm_clock_get - posix clock_get interface |
---|
| 660 | + * alarm_clock_get_timespec - posix clock_get_timespec interface |
---|
654 | 661 | * @which_clock: clockid |
---|
655 | 662 | * @tp: timespec to fill. |
---|
656 | 663 | * |
---|
657 | | - * Provides the underlying alarm base time. |
---|
| 664 | + * Provides the underlying alarm base time in a tasks time namespace. |
---|
658 | 665 | */ |
---|
659 | | -static int alarm_clock_get(clockid_t which_clock, struct timespec64 *tp) |
---|
| 666 | +static int alarm_clock_get_timespec(clockid_t which_clock, struct timespec64 *tp) |
---|
660 | 667 | { |
---|
661 | 668 | struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)]; |
---|
662 | 669 | |
---|
663 | 670 | if (!alarmtimer_get_rtcdev()) |
---|
664 | 671 | return -EINVAL; |
---|
665 | 672 | |
---|
666 | | - *tp = ktime_to_timespec64(base->gettime()); |
---|
| 673 | + base->get_timespec(tp); |
---|
| 674 | + |
---|
667 | 675 | return 0; |
---|
| 676 | +} |
---|
| 677 | + |
---|
| 678 | +/** |
---|
| 679 | + * alarm_clock_get_ktime - posix clock_get_ktime interface |
---|
| 680 | + * @which_clock: clockid |
---|
| 681 | + * |
---|
| 682 | + * Provides the underlying alarm base time in the root namespace. |
---|
| 683 | + */ |
---|
| 684 | +static ktime_t alarm_clock_get_ktime(clockid_t which_clock) |
---|
| 685 | +{ |
---|
| 686 | + struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)]; |
---|
| 687 | + |
---|
| 688 | + if (!alarmtimer_get_rtcdev()) |
---|
| 689 | + return -EINVAL; |
---|
| 690 | + |
---|
| 691 | + return base->get_ktime(); |
---|
668 | 692 | } |
---|
669 | 693 | |
---|
670 | 694 | /** |
---|
.. | .. |
---|
740 | 764 | struct timespec64 rmt; |
---|
741 | 765 | ktime_t rem; |
---|
742 | 766 | |
---|
743 | | - rem = ktime_sub(absexp, alarm_bases[type].gettime()); |
---|
| 767 | + rem = ktime_sub(absexp, alarm_bases[type].get_ktime()); |
---|
744 | 768 | |
---|
745 | 769 | if (rem <= 0) |
---|
746 | 770 | return 0; |
---|
.. | .. |
---|
809 | 833 | exp = timespec64_to_ktime(*tsreq); |
---|
810 | 834 | /* Convert (if necessary) to absolute time */ |
---|
811 | 835 | if (flags != TIMER_ABSTIME) { |
---|
812 | | - ktime_t now = alarm_bases[type].gettime(); |
---|
| 836 | + ktime_t now = alarm_bases[type].get_ktime(); |
---|
813 | 837 | |
---|
814 | 838 | exp = ktime_add_safe(now, exp); |
---|
| 839 | + } else { |
---|
| 840 | + exp = timens_ktime_to_host(which_clock, exp); |
---|
815 | 841 | } |
---|
816 | 842 | |
---|
817 | 843 | ret = alarmtimer_do_nsleep(&alarm, exp, type); |
---|
.. | .. |
---|
830 | 856 | |
---|
831 | 857 | const struct k_clock alarm_clock = { |
---|
832 | 858 | .clock_getres = alarm_clock_getres, |
---|
833 | | - .clock_get = alarm_clock_get, |
---|
| 859 | + .clock_get_ktime = alarm_clock_get_ktime, |
---|
| 860 | + .clock_get_timespec = alarm_clock_get_timespec, |
---|
834 | 861 | .timer_create = alarm_timer_create, |
---|
835 | 862 | .timer_set = common_timer_set, |
---|
836 | 863 | .timer_del = common_timer_del, |
---|
.. | .. |
---|
840 | 867 | .timer_forward = alarm_timer_forward, |
---|
841 | 868 | .timer_remaining = alarm_timer_remaining, |
---|
842 | 869 | .timer_try_to_cancel = alarm_timer_try_to_cancel, |
---|
| 870 | + .timer_wait_running = alarm_timer_wait_running, |
---|
843 | 871 | .nsleep = alarm_timer_nsleep, |
---|
844 | 872 | }; |
---|
845 | 873 | #endif /* CONFIG_POSIX_TIMERS */ |
---|
.. | .. |
---|
858 | 886 | } |
---|
859 | 887 | }; |
---|
860 | 888 | |
---|
| 889 | +static void get_boottime_timespec(struct timespec64 *tp) |
---|
| 890 | +{ |
---|
| 891 | + ktime_get_boottime_ts64(tp); |
---|
| 892 | + timens_add_boottime(tp); |
---|
| 893 | +} |
---|
| 894 | + |
---|
861 | 895 | /** |
---|
862 | 896 | * alarmtimer_init - Initialize alarm timer code |
---|
863 | 897 | * |
---|
.. | .. |
---|
866 | 900 | */ |
---|
867 | 901 | static int __init alarmtimer_init(void) |
---|
868 | 902 | { |
---|
869 | | - struct platform_device *pdev; |
---|
870 | | - int error = 0; |
---|
| 903 | + int error; |
---|
871 | 904 | int i; |
---|
872 | 905 | |
---|
873 | 906 | alarmtimer_rtc_timer_init(); |
---|
874 | 907 | |
---|
875 | 908 | /* Initialize alarm bases */ |
---|
876 | 909 | alarm_bases[ALARM_REALTIME].base_clockid = CLOCK_REALTIME; |
---|
877 | | - alarm_bases[ALARM_REALTIME].gettime = &ktime_get_real; |
---|
| 910 | + alarm_bases[ALARM_REALTIME].get_ktime = &ktime_get_real; |
---|
| 911 | + alarm_bases[ALARM_REALTIME].get_timespec = ktime_get_real_ts64; |
---|
878 | 912 | alarm_bases[ALARM_BOOTTIME].base_clockid = CLOCK_BOOTTIME; |
---|
879 | | - alarm_bases[ALARM_BOOTTIME].gettime = &ktime_get_boottime; |
---|
| 913 | + alarm_bases[ALARM_BOOTTIME].get_ktime = &ktime_get_boottime; |
---|
| 914 | + alarm_bases[ALARM_BOOTTIME].get_timespec = get_boottime_timespec; |
---|
880 | 915 | for (i = 0; i < ALARM_NUMTYPE; i++) { |
---|
881 | 916 | timerqueue_init_head(&alarm_bases[i].timerqueue); |
---|
882 | 917 | spin_lock_init(&alarm_bases[i].lock); |
---|
.. | .. |
---|
890 | 925 | if (error) |
---|
891 | 926 | goto out_if; |
---|
892 | 927 | |
---|
893 | | - pdev = platform_device_register_simple("alarmtimer", -1, NULL, 0); |
---|
894 | | - if (IS_ERR(pdev)) { |
---|
895 | | - error = PTR_ERR(pdev); |
---|
896 | | - goto out_drv; |
---|
897 | | - } |
---|
898 | 928 | return 0; |
---|
899 | | - |
---|
900 | | -out_drv: |
---|
901 | | - platform_driver_unregister(&alarmtimer_driver); |
---|
902 | 929 | out_if: |
---|
903 | 930 | alarmtimer_rtc_interface_remove(); |
---|
904 | 931 | return error; |
---|