X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=kernel%2Ftime%2Fclockevents.c;h=3d1e3e1a19716e94cdad4116b1ca73242ac45f1e;hb=c58310bf4933986513020fa90b4190c7492995ae;hp=822beebe664a59e98d3557c98a7ff8632423f6a1;hpb=37ca506adc395a028cd12760eca419dd0dc14b5c;p=linux-2.6 diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 822beebe66..3d1e3e1a19 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -41,6 +41,11 @@ unsigned long clockevent_delta2ns(unsigned long latch, { u64 clc = ((u64) latch << evt->shift); + if (unlikely(!evt->mult)) { + evt->mult = 1; + WARN_ON(1); + } + do_div(clc, evt->mult); if (clc < 1000) clc = 1000; @@ -78,6 +83,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) @@ -123,7 +133,7 @@ static void clockevents_do_notify(unsigned long reason, void *dev) } /* - * Called after a notify add to make devices availble which were + * Called after a notify add to make devices available which were * released from the notifier call. */ static void clockevents_notify_released(void) @@ -146,6 +156,14 @@ static void clockevents_notify_released(void) void clockevents_register_device(struct clock_event_device *dev) { BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED); + /* + * A nsec2cyc multiplicator of 0 is invalid and we'd crash + * on it, so fix it up and emit a warning: + */ + if (unlikely(!dev->mult)) { + dev->mult = 1; + WARN_ON(1); + } spin_lock(&clockevents_lock); @@ -200,6 +218,8 @@ void clockevents_exchange_device(struct clock_event_device *old, */ void clockevents_notify(unsigned long reason, void *arg) { + struct list_head *node, *tmp; + spin_lock(&clockevents_lock); clockevents_do_notify(reason, arg); @@ -209,13 +229,8 @@ void clockevents_notify(unsigned long reason, void *arg) * Unregister the clock event devices which were * released from the users in the notify chain. */ - while (!list_empty(&clockevents_released)) { - struct clock_event_device *dev; - - dev = list_entry(clockevents_released.next, - struct clock_event_device, list); - list_del(&dev->list); - } + list_for_each_safe(node, tmp, &clockevents_released) + list_del(node); break; default: break;