>From 0c91dc5c02c828b6b57066f99d9d2b853ced5c97 Mon Sep 17 00:00:00 2001 From: Stefan Bader Date: Wed, 4 Jan 2012 15:41:16 +0100 Subject: [PATCH] rtc: Do not schedule work in rtc_initialize_alarm commit 93b2ec0128c431148b216b8f7337c1a52131ef03 rtc: Expire alarms after the time is set. added a schedule_work to rtc_initialize_alarm in order to get alarm processing running, even in case of an alarm that had been in the past. However, this is called from rtc_device_register that in turn is called from cmos_do_probe while rtc_cmos.rtc is still NULL. If the worker fires off and tries to rtc_update_irq it will dereference that potentially NULL pointer (this only was observer running a Xen paravirt guest, but I think if the timing is right could happen anywhere). So it seems better to tickle the interrupt worker just in any case when the probe really is complete. Worst case it should just confirm the fact that there is no alarm. Signed-off-by: Stefan Bader --- drivers/rtc/interface.c | 2 -- drivers/rtc/rtc-cmos.c | 7 +++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 3bcc7cf..084a137 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -407,8 +407,6 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); } mutex_unlock(&rtc->ops_lock); - /* maybe that was in the past.*/ - schedule_work(&rtc->irqwork); return err; } EXPORT_SYMBOL_GPL(rtc_initialize_alarm); diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 05beb6c..21fcb31 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -731,6 +731,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) goto cleanup2; } + /* I hope it will not matter much if there was not actually + * some interrupt work that needed to be done. The worker + * thread just should do nothing (beside of disabling the + * alarm again. At least by now all other setup is done. + */ + schedule_work(&cmos_rtc.rtc->irqwork); + pr_info("%s: %s%s, %zd bytes nvram%s\n", dev_name(&cmos_rtc.rtc->dev), !is_valid_irq(rtc_irq) ? "no alarms" : -- 1.7.5.4