lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <473B9D8A.5000006@reed.com>
Date:	Wed, 14 Nov 2007 20:14:50 -0500
From:	"David P. Reed" <dpreed@...d.com>
To:	Thomas Gleixner <tglx@...utronix.de>, linux-kernel@...r.kernel.org
CC:	Allessandro Zummo <a.zummo@...ertech.it>,
	Matt Mackall <mpm@...enic.com>
Subject: [PATCH] x86: on x86_64, correct reading of PC RTC when update in
 progress in time_64.c

Correct potentially unstable PC RTC time register reading in time_64.c

Stop the use of an incorrect technique for reading the standard PC RTC
timer, which is documented to "disconnect" time registers from the bus
while updates are in progress.  The use of UIP flag while interrupts
are disabled to protect a 244 microsecond window is one of the
Motorola spec sheet's documented ways to read the RTC time registers
reliably.

The patch updates the misleading comments and also minimizes the amount of
time that the kernel disables interrupts during the reading.

Signed-off-by: David P. Reed <dpreed@...d.com>
---
Index: linux-2.6/arch/x86/kernel/time_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/time_64.c
+++ linux-2.6/arch/x86/kernel/time_64.c
@@ -160,22 +160,30 @@ unsigned long read_persistent_clock(void
  	unsigned long flags;
  	unsigned century = 0;

-	spin_lock_irqsave(&rtc_lock, flags);
+ retry:	spin_lock_irqsave(&rtc_lock, flags);
+	/* if UIP is clear, then we have >= 244 microseconds before RTC
+	 * registers will be updated.  Spec sheet says that this is the
+	 * reliable way to read RTC - registers invalid (off bus) during update
+	 */
+	if ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) {
+	  spin_unlock_irqrestore(&rtc_lock, flags);
+	  cpu_relax();
+	  goto retry;
+	}

-	do {
-		sec = CMOS_READ(RTC_SECONDS);
-		min = CMOS_READ(RTC_MINUTES);
-		hour = CMOS_READ(RTC_HOURS);
-		day = CMOS_READ(RTC_DAY_OF_MONTH);
-		mon = CMOS_READ(RTC_MONTH);
-		year = CMOS_READ(RTC_YEAR);
+	/* now read all RTC registers while stable with interrupts disabled */
+
+	sec = CMOS_READ(RTC_SECONDS);
+	min = CMOS_READ(RTC_MINUTES);
+	hour = CMOS_READ(RTC_HOURS);
+	day = CMOS_READ(RTC_DAY_OF_MONTH);
+	mon = CMOS_READ(RTC_MONTH);
+	year = CMOS_READ(RTC_YEAR);
  #ifdef CONFIG_ACPI
-		if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
-					acpi_gbl_FADT.century)
-			century = CMOS_READ(acpi_gbl_FADT.century);
+	if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
+				acpi_gbl_FADT.century)
+		century = CMOS_READ(acpi_gbl_FADT.century);
  #endif
-	} while (sec != CMOS_READ(RTC_SECONDS));
-
  	spin_unlock_irqrestore(&rtc_lock, flags);

  	/*


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ