From nobody Sun May 10 22:40:21 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 597B0C433F5 for ; Thu, 21 Apr 2022 19:25:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1391563AbiDUT23 (ORCPT ); Thu, 21 Apr 2022 15:28:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1390623AbiDUT2Y (ORCPT ); Thu, 21 Apr 2022 15:28:24 -0400 Received: from mx-out.tlen.pl (mx-out.tlen.pl [193.222.135.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E4B794CD61 for ; Thu, 21 Apr 2022 12:25:32 -0700 (PDT) Received: (wp-smtpd smtp.tlen.pl 15717 invoked from network); 21 Apr 2022 21:25:26 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=o2.pl; s=1024a; t=1650569127; bh=2/sM7JIlJ22t5YJpvU1AanN1CBxO4H/7QJWPjO4nc4E=; h=From:To:Cc:Subject; b=VpQvY0W+2fHhiExPDX8Sqi4QUsnB61zqHO7sZvJCRzteLAmueqEkok8D0IV2niazZ MS0USbQu7Rj7ifkb7EULGcm+NKf9iXaVYWi4b2aOJcv/9+kk0PF3H/U2cS//Nz528I rTX+eRgQuK2bDK8h9bF4aaAuCbRXgqIVujjau4iQ= Received: from aafl13.neoplus.adsl.tpnet.pl (HELO localhost.localdomain) (mat.jonczyk@o2.pl@[83.4.141.13]) (envelope-sender ) by smtp.tlen.pl (WP-SMTPD) with SMTP for ; 21 Apr 2022 21:25:26 +0200 From: =?UTF-8?q?Mateusz=20Jo=C5=84czyk?= To: linux-kernel@vger.kernel.org, linux-rtc@vger.kernel.org Cc: =?UTF-8?q?Mateusz=20Jo=C5=84czyk?= , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Alessandro Zummo , Alexandre Belloni , Prarit Bhargava Subject: [PATCH v2 1/2] x86/rtc: rewrite mach_get_cmos_time to delete duplicated code Date: Thu, 21 Apr 2022 21:24:48 +0200 Message-Id: <20220421192449.11004-2-mat.jonczyk@o2.pl> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220421192449.11004-1-mat.jonczyk@o2.pl> References: <20220421192449.11004-1-mat.jonczyk@o2.pl> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-WP-MailID: a7ff3857cd10bf8eceb9c703480a15c9 X-WP-AV: skaner antywirusowy Poczty o2 X-WP-SPAM: NO 0000000 [kQNk] Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org There are functions in drivers/rtc/rtc-mc146818-lib.c that handle reading from / writing to the CMOS RTC clock. mach_get_cmos_time() in arch/x86/kernel/rtc.c did not use them and was mostly a duplicate of mc146818_get_time(). Modify mach_get_cmos_time() to use mc146818_get_time() and remove the duplicated code. As a bonus, mach_get_cmos_time() after the modification does not hang indefinitely if the CMOS RTC is not present. mach_get_cmos_time() used a different algorithm than mc146818_get_time(), but these functions are equivalent. The major differences were: - mc146818_get_time() is better refined: it was updated in commit 05a0302c3548 ("rtc: mc146818: Prevent reading garbage") to take account of various edge conditions, - when the UIP ("Update in progress") bit of the RTC is set, mach_get_cmos_time() was busy waiting with cpu_relax() while mc146818_get_time() is now using mdelay(1) in every loop iteration, - mach_get_cmos_time() assumed that the RTC year must be >=3D 2000, which may not be true on some old boxes with a dead battery, - mach_get_cmos_time() was holding the rtc_lock for a long time. The RTC writing counterpart, mach_set_rtc_mmss() is already using mc146818_get_time() from drivers/rtc. This was done in commit 3195ef59cb42 ("x86: Do full rtc synchronization with ntp") It appears that mach_get_cmos_time() was simply forgotten. mach_get_cmos_time() is really used only in read_persistent_clock64(), which is called only in a few places in kernel/time/timekeeping.c . Signed-off-by: Mateusz Jo=C5=84czyk Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: x86@kernel.org Cc: "H. Peter Anvin" Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: Prarit Bhargava --- v2: - use pr_err() in place of pr_err_ratelimited(). mach_get_cmos_time() is not called frequently, so ratelimiting is not necessary. - tweak commit description. arch/x86/kernel/rtc.c | 59 +++++-------------------------------------- 1 file changed, 7 insertions(+), 52 deletions(-) diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 586f718b8e95..1cadc8a15267 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c @@ -4,11 +4,8 @@ */ #include #include -#include -#include #include #include -#include =20 #include #include @@ -20,15 +17,12 @@ /* * This is a special lock that is owned by the CPU and holds the index * register we are working with. It is required for NMI access to the - * CMOS/RTC registers. See include/asm-i386/mc146818rtc.h for details. + * CMOS/RTC registers. See arch/x86/include/asm/mc146818rtc.h for details. */ volatile unsigned long cmos_lock; EXPORT_SYMBOL(cmos_lock); #endif /* CONFIG_X86_32 */ =20 -/* For two digit years assume time is always after that */ -#define CMOS_YEARS_OFFS 2000 - DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); =20 @@ -62,8 +56,7 @@ int mach_set_rtc_mmss(const struct timespec64 *now) =20 void mach_get_cmos_time(struct timespec64 *now) { - unsigned int status, year, mon, day, hour, min, sec, century =3D 0; - unsigned long flags; + struct rtc_time tm; =20 /* * If pm_trace abused the RTC as storage, set the timespec to 0, @@ -74,51 +67,13 @@ void mach_get_cmos_time(struct timespec64 *now) return; } =20 - spin_lock_irqsave(&rtc_lock, flags); - - /* - * If UIP is clear, then we have >=3D 244 microseconds before - * RTC registers will be updated. Spec sheet says that this - * is the reliable way to read RTC - registers. If UIP is set - * then the register access might be invalid. - */ - while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - cpu_relax(); - - sec =3D CMOS_READ(RTC_SECONDS); - min =3D CMOS_READ(RTC_MINUTES); - hour =3D CMOS_READ(RTC_HOURS); - day =3D CMOS_READ(RTC_DAY_OF_MONTH); - mon =3D CMOS_READ(RTC_MONTH); - year =3D CMOS_READ(RTC_YEAR); - -#ifdef CONFIG_ACPI - if (acpi_gbl_FADT.header.revision >=3D FADT2_REVISION_ID && - acpi_gbl_FADT.century) - century =3D CMOS_READ(acpi_gbl_FADT.century); -#endif - - status =3D CMOS_READ(RTC_CONTROL); - WARN_ON_ONCE(RTC_ALWAYS_BCD && (status & RTC_DM_BINARY)); - - spin_unlock_irqrestore(&rtc_lock, flags); - - if (RTC_ALWAYS_BCD || !(status & RTC_DM_BINARY)) { - sec =3D bcd2bin(sec); - min =3D bcd2bin(min); - hour =3D bcd2bin(hour); - day =3D bcd2bin(day); - mon =3D bcd2bin(mon); - year =3D bcd2bin(year); + if (mc146818_get_time(&tm)) { + pr_err("Unable to read current time from RTC\n"); + now->tv_sec =3D now->tv_nsec =3D 0; + return; } =20 - if (century) { - century =3D bcd2bin(century); - year +=3D century * 100; - } else - year +=3D CMOS_YEARS_OFFS; - - now->tv_sec =3D mktime64(year, mon, day, hour, min, sec); + now->tv_sec =3D rtc_tm_to_time64(&tm); now->tv_nsec =3D 0; } =20 --=20 2.25.1 From nobody Sun May 10 22:40:21 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 53BFCC433F5 for ; Thu, 21 Apr 2022 19:25:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1391869AbiDUT2i (ORCPT ); Thu, 21 Apr 2022 15:28:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37614 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1390623AbiDUT2b (ORCPT ); Thu, 21 Apr 2022 15:28:31 -0400 Received: from mx-out.tlen.pl (mx-out.tlen.pl [193.222.135.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D10134551E for ; Thu, 21 Apr 2022 12:25:40 -0700 (PDT) Received: (wp-smtpd smtp.tlen.pl 24171 invoked from network); 21 Apr 2022 21:25:36 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=o2.pl; s=1024a; t=1650569136; bh=KT7q9eMAxby7uyk2jYuKh3OvBVpIpHr8zoPO+QpVv2U=; h=From:To:Cc:Subject; b=DhQE9adGRhpowyJEBc9mhoEvr4wrXxXbN2WV2wNOydYIOjma8KF3+cSjZ1vlgEvSi rf1tJQPKjy0eYkwprTwhvs2DP/aWzKdj4hBmZtfLPayZhEzmEuvRSSwAEOjz3q7EDZ oEIGBNCv6gJipvDvZnmxNiTzPNA322SPd4yAWUZI= Received: from aafl13.neoplus.adsl.tpnet.pl (HELO localhost.localdomain) (mat.jonczyk@o2.pl@[83.4.141.13]) (envelope-sender ) by smtp.tlen.pl (WP-SMTPD) with SMTP for ; 21 Apr 2022 21:25:35 +0200 From: =?UTF-8?q?Mateusz=20Jo=C5=84czyk?= To: linux-kernel@vger.kernel.org, linux-rtc@vger.kernel.org Cc: =?UTF-8?q?Mateusz=20Jo=C5=84czyk?= , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" Subject: [PATCH v2 2/2] x86/rtc: rename mach_set_rtc_mmss Date: Thu, 21 Apr 2022 21:24:49 +0200 Message-Id: <20220421192449.11004-3-mat.jonczyk@o2.pl> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220421192449.11004-1-mat.jonczyk@o2.pl> References: <20220421192449.11004-1-mat.jonczyk@o2.pl> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-WP-MailID: 98bcf9135cc57123f251e21cff7a9931 X-WP-AV: skaner antywirusowy Poczty o2 X-WP-SPAM: NO 0000000 [kbN0] Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Once upon a time, before commit 3195ef59cb42 ("x86: Do full rtc synchronization with ntp") in 2013, the function set only the minute and seconds registers of the CMOS RTC. This is no longer true, so rename the function to mach_set_cmos_time. Signed-off-by: Mateusz Jo=C5=84czyk Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: x86@kernel.org Cc: "H. Peter Anvin" --- arch/x86/include/asm/mc146818rtc.h | 2 +- arch/x86/kernel/rtc.c | 4 ++-- arch/x86/kernel/x86_init.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/mc146818rtc.h b/arch/x86/include/asm/mc14= 6818rtc.h index 97198001e567..6115bb3d5795 100644 --- a/arch/x86/include/asm/mc146818rtc.h +++ b/arch/x86/include/asm/mc146818rtc.h @@ -95,7 +95,7 @@ static inline unsigned char current_lock_cmos_reg(void) unsigned char rtc_cmos_read(unsigned char addr); void rtc_cmos_write(unsigned char val, unsigned char addr); =20 -extern int mach_set_rtc_mmss(const struct timespec64 *now); +extern int mach_set_cmos_time(const struct timespec64 *now); extern void mach_get_cmos_time(struct timespec64 *now); =20 #define RTC_IRQ 8 diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 1cadc8a15267..349046434513 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c @@ -27,13 +27,13 @@ DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); =20 /* - * In order to set the CMOS clock precisely, set_rtc_mmss has to be + * In order to set the CMOS clock precisely, mach_set_cmos_time has to be * called 500 ms after the second nowtime has started, because when * nowtime is written into the registers of the CMOS clock, it will * jump to the next second precisely 500 ms later. Check the Motorola * MC146818A or Dallas DS12887 data sheet for details. */ -int mach_set_rtc_mmss(const struct timespec64 *now) +int mach_set_cmos_time(const struct timespec64 *now) { unsigned long long nowtime =3D now->tv_sec; struct rtc_time tm; diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index e84ee5cdbd8c..57353519bc11 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -138,7 +138,7 @@ struct x86_platform_ops x86_platform __ro_after_init = =3D { .calibrate_cpu =3D native_calibrate_cpu_early, .calibrate_tsc =3D native_calibrate_tsc, .get_wallclock =3D mach_get_cmos_time, - .set_wallclock =3D mach_set_rtc_mmss, + .set_wallclock =3D mach_set_cmos_time, .iommu_shutdown =3D iommu_shutdown_noop, .is_untracked_pat_range =3D is_ISA_range, .nmi_init =3D default_nmi_init, --=20 2.25.1