From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8DFCCA9EA0 for ; Sun, 20 Oct 2019 23:14:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8317620869 for ; Sun, 20 Oct 2019 23:14:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726684AbfJTXN0 (ORCPT ); Sun, 20 Oct 2019 19:13:26 -0400 Received: from relay2-d.mail.gandi.net ([217.70.183.194]:57447 "EHLO relay2-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726565AbfJTXN0 (ORCPT ); Sun, 20 Oct 2019 19:13:26 -0400 X-Originating-IP: 86.202.229.42 Received: from localhost (lfbn-lyo-1-146-42.w86-202.abo.wanadoo.fr [86.202.229.42]) (Authenticated sender: alexandre.belloni@bootlin.com) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 6B16040003; Sun, 20 Oct 2019 23:13:23 +0000 (UTC) From: Alexandre Belloni To: linux-rtc@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Alexandre Belloni , syzbot+08116743f8ad6f9a6de7@syzkaller.appspotmail.com Subject: [PATCH] rtc: disable uie before setting time and enable after Date: Mon, 21 Oct 2019 01:13:20 +0200 Message-Id: <20191020231320.8191-1-alexandre.belloni@bootlin.com> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When setting the time in the future with the uie timer enabled, rtc_timer_do_work will loop for a while because the expiration of the uie timer was way before the current RTC time and a new timer will be enqueued until the current rtc time is reached. If the uie timer is enabled, disable it before setting the time and enable it after expiring current timers (which may actually be an alarm). This is the safest thing to do to ensure the uie timer is still synchronized with the RTC, especially in the UIE emulation case. Reported-by: syzbot+08116743f8ad6f9a6de7@syzkaller.appspotmail.com Fixes: 6610e0893b8b ("RTC: Rework RTC code to use timerqueue for events") Signed-off-by: Alexandre Belloni --- drivers/rtc/interface.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index eea700723976..f8b7c004d6ec 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -125,7 +125,7 @@ EXPORT_SYMBOL_GPL(rtc_read_time); int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) { - int err; + int err, uie; err = rtc_valid_tm(tm); if (err != 0) @@ -137,6 +137,17 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) rtc_subtract_offset(rtc, tm); +#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL + uie = rtc->uie_rtctimer.enabled || rtc->uie_irq_active; +#else + uie = rtc->uie_rtctimer.enabled; +#endif + if (uie) { + err = rtc_update_irq_enable(rtc, 0); + if (err) + return err; + } + err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; @@ -153,6 +164,12 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) /* A timer might have just expired */ schedule_work(&rtc->irqwork); + if (uie) { + err = rtc_update_irq_enable(rtc, 1); + if (err) + return err; + } + trace_rtc_set_time(rtc_tm_to_time64(tm), err); return err; } -- 2.21.0