diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/hrtimer.c | 8 | ||||
-rw-r--r-- | kernel/time/clockevents.c | 5 |
2 files changed, 13 insertions, 0 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 22a25142e4cf..e65dd0b47cdc 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -850,6 +850,14 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) #ifdef CONFIG_TIME_LOW_RES tim = ktime_add(tim, base->resolution); #endif + /* + * Careful here: User space might have asked for a + * very long sleep, so the add above might result in a + * negative number, which enqueues the timer in front + * of the queue. + */ + if (tim.tv64 < 0) + tim.tv64 = KTIME_MAX; } timer->expires = tim; diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 822beebe664a..5fb139fef9fa 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -78,6 +78,11 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, unsigned long long clc; int64_t delta; + if (unlikely(expires.tv64 < 0)) { + WARN_ON_ONCE(1); + return -ETIME; + } + delta = ktime_to_ns(ktime_sub(expires, now)); if (delta <= 0) |