From nobody Tue Jun 23 21:23:25 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 0C978C4332F for ; Fri, 25 Feb 2022 21:50:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233174AbiBYVvT (ORCPT ); Fri, 25 Feb 2022 16:51:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232900AbiBYVvR (ORCPT ); Fri, 25 Feb 2022 16:51:17 -0500 Received: from mx-out.tlen.pl (mx-out.tlen.pl [193.222.135.145]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 439D520B176 for ; Fri, 25 Feb 2022 13:50:44 -0800 (PST) Received: (wp-smtpd smtp.tlen.pl 17847 invoked from network); 25 Feb 2022 22:50:41 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=o2.pl; s=1024a; t=1645825841; bh=Y2IT2MD+M5Kuxt46voh5jFtMk8ayrmPXt7vtMwYPIE4=; h=From:To:Cc:Subject; b=YLPEjH9M8sPKGfAxQw4h/EvZs8P3vxr1+LZonwamT7gnbHTYCnHewy130o0ImtIoW j8dX1IaVSVzHuosaPI3mkL88X/J7rsCV7+PeTDRIGCnEIFAwgeNWKZPV3uX/D4tt0G aKTvYXDa75qZFYErLyx56m+vnNlcBS2F25MLOp/4= Received: from aaew227.neoplus.adsl.tpnet.pl (HELO localhost.localdomain) (mat.jonczyk@o2.pl@[83.4.126.227]) (envelope-sender ) by smtp.tlen.pl (WP-SMTPD) with SMTP for ; 25 Feb 2022 22:50:41 +0100 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 Subject: [PATCH 1/3] rtc-mc146818-lib: reduce RTC_UIP polling period Date: Fri, 25 Feb 2022 22:50:09 +0100 Message-Id: <20220225215011.861477-2-mat.jonczyk@o2.pl> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220225215011.861477-1-mat.jonczyk@o2.pl> References: <20220225215011.861477-1-mat.jonczyk@o2.pl> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-WP-MailID: 478f42270233dca8f289efad5e49b1d1 X-WP-AV: skaner antywirusowy Poczty o2 X-WP-SPAM: NO 0000000 [cVNk] Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Waiting 1ms every time is not necessary, for example on some AMD boxes the RTC_UIP bit is documented as being high for around 270 microseconds in some cases [1], which agreed with experiments on an SB710 southbridge. So 100us seems optimal. This in preparation for mach_get_cmos_time() refactoring. The functions mc146818_get_time() and mach_get_cmos_time() in arch/x86/kernel/rtc.c perform the same function and the code is duplicated. mach_get_cmos_time() is busy waiting for the RTC_UIP bit to clear, so make mc146818_get_time() more similar to it by reducing the polling period. [1] AMD SB700/710/750 Register Reference Guide, page 307, https://developer.amd.com/wordpress/media/2012/10/43009_sb7xx_rrg_pub_1.00.= pdf "SB700 A12: The UIP high pulse is 270 =CE=BCS Typical when SS on SRC clock is OFF and 100=CE=BC min when SRC SS is ON." [sic] 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 --- drivers/rtc/rtc-mc146818-lib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-mc146818-lib.c b/drivers/rtc/rtc-mc146818-lib.c index ae9f131b43c0..ae4b19e0a981 100644 --- a/drivers/rtc/rtc-mc146818-lib.c +++ b/drivers/rtc/rtc-mc146818-lib.c @@ -21,13 +21,13 @@ bool mc146818_avoid_UIP(void (*callback)(unsigned char = seconds, void *param), unsigned long flags; unsigned char seconds; =20 - for (i =3D 0; i < 10; i++) { + for (i =3D 0; i < 100; i++) { spin_lock_irqsave(&rtc_lock, flags); =20 /* * Check whether there is an update in progress during which the * readout is unspecified. The maximum update time is ~2ms. Poll - * every msec for completion. + * every 100 usec for completion. * * Store the second value before checking UIP so a long lasting * NMI which happens to hit after the UIP check cannot make @@ -37,7 +37,7 @@ bool mc146818_avoid_UIP(void (*callback)(unsigned char se= conds, void *param), =20 if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) { spin_unlock_irqrestore(&rtc_lock, flags); - mdelay(1); + udelay(100); continue; } =20 @@ -56,7 +56,7 @@ bool mc146818_avoid_UIP(void (*callback)(unsigned char se= conds, void *param), */ if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) { spin_unlock_irqrestore(&rtc_lock, flags); - mdelay(1); + udelay(100); continue; } =20 --=20 2.25.1 From nobody Tue Jun 23 21:23:25 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 48CDBC433FE for ; Fri, 25 Feb 2022 21:50:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233795AbiBYVv1 (ORCPT ); Fri, 25 Feb 2022 16:51:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49142 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233102AbiBYVvX (ORCPT ); Fri, 25 Feb 2022 16:51:23 -0500 Received: from mx-out.tlen.pl (mx-out.tlen.pl [193.222.135.145]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C67171FED81 for ; Fri, 25 Feb 2022 13:50:48 -0800 (PST) Received: (wp-smtpd smtp.tlen.pl 20423 invoked from network); 25 Feb 2022 22:50:45 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=o2.pl; s=1024a; t=1645825846; bh=kIRg5QJjXdMvg4mGdci435YIQdJAxFFxB1p8dHt9xeI=; h=From:To:Cc:Subject; b=RJQeOC8wlOJ8+AMPKXMckG9E8FShXSp3MvGwFUq/VRYDA7z4n2Ua8mMvdeBAtdjdb 6GvspIa8AlakjpkGEwt/XixMJzAI8hM8tFHXfZ0neuE9f/1Fse10o2F5gydYudd+r1 DyPw5QIY8/G7qS+9zBjPfcgcknvd069CJE5vq1+M= Received: from aaew227.neoplus.adsl.tpnet.pl (HELO localhost.localdomain) (mat.jonczyk@o2.pl@[83.4.126.227]) (envelope-sender ) by smtp.tlen.pl (WP-SMTPD) with SMTP for ; 25 Feb 2022 22:50:45 +0100 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 Subject: [PATCH 2/3] x86/rtc: rewrite mach_get_cmos_time Date: Fri, 25 Feb 2022 22:50:10 +0100 Message-Id: <20220225215011.861477-3-mat.jonczyk@o2.pl> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220225215011.861477-1-mat.jonczyk@o2.pl> References: <20220225215011.861477-1-mat.jonczyk@o2.pl> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-WP-MailID: 5bece34e986b7794637f50910b552e53 X-WP-AV: skaner antywirusowy Poczty o2 X-WP-SPAM: NO 0000000 [IYPE] 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. mach_get_cmos_time() used a different algorithm than mc146818_get_time(), but these functions were 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 udelay(100) 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. 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 --- 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..9f251b65219f 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_ratelimited("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 Tue Jun 23 21:23:25 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 772FDC433FE for ; Fri, 25 Feb 2022 21:50:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234208AbiBYVva (ORCPT ); Fri, 25 Feb 2022 16:51:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232900AbiBYVvY (ORCPT ); Fri, 25 Feb 2022 16:51:24 -0500 Received: from mx-out.tlen.pl (mx-out.tlen.pl [193.222.135.145]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ED2B01EF35C for ; Fri, 25 Feb 2022 13:50:51 -0800 (PST) Received: (wp-smtpd smtp.tlen.pl 22558 invoked from network); 25 Feb 2022 22:50:49 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=o2.pl; s=1024a; t=1645825849; bh=HGUXmDpRDjSSSovQwhGF/FGr2kg7ezLYTr/WItdJsF4=; h=From:To:Cc:Subject; b=eIMxMvG4qEngeLUlPqjo76VGQbsB56UGxjbM/uGwpyp6NcfPe6pIEWN+Aw9f1Yu0B bz0It+W3JJDS3YBunt44Ykf806KbaLrCJT10g8N1C+CdXxJLIAzMAyt0VWzGCv66tP ONl99M11Nm0bLpxiPtaYY4mV1FnO7G4NoWlk7Dhs= Received: from aaew227.neoplus.adsl.tpnet.pl (HELO localhost.localdomain) (mat.jonczyk@o2.pl@[83.4.126.227]) (envelope-sender ) by smtp.tlen.pl (WP-SMTPD) with SMTP for ; 25 Feb 2022 22:50:49 +0100 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 3/3] x86/rtc: rename mach_set_rtc_mmss Date: Fri, 25 Feb 2022 22:50:11 +0100 Message-Id: <20220225215011.861477-4-mat.jonczyk@o2.pl> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220225215011.861477-1-mat.jonczyk@o2.pl> References: <20220225215011.861477-1-mat.jonczyk@o2.pl> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-WP-MailID: 247949ee4229b98e2f13ef1e9a6b6fe3 X-WP-AV: skaner antywirusowy Poczty o2 X-WP-SPAM: NO 0000000 [oeO0] 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 used to set only the minutes 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 9f251b65219f..24ca997a210e 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 7d20c1d34a3c..927924a319a7 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -133,7 +133,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