All of lore.kernel.org
 help / color / mirror / Atom feed
From: tip-bot for Chen Yu <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, lenb@kernel.org,
	richardcochran@gmail.com, mingo@kernel.org, xlpang@redhat.com,
	pavel@ucw.cz, yu.c.chen@intel.com, rjw@rjwysocki.net,
	hpa@zytor.com, tglx@linutronix.de, john.stultz@linaro.org,
	prarit@redhat.com
Subject: [tip:timers/core] timekeeping: Ignore the bogus sleep time if pm_trace is enabled
Date: Tue, 29 Nov 2016 09:10:51 -0800	[thread overview]
Message-ID: <tip-ba58d1020a54933c6b087a3107661c8513556cb8@git.kernel.org> (raw)
In-Reply-To: <1480372524-15181-3-git-send-email-john.stultz@linaro.org>

Commit-ID:  ba58d1020a54933c6b087a3107661c8513556cb8
Gitweb:     http://git.kernel.org/tip/ba58d1020a54933c6b087a3107661c8513556cb8
Author:     Chen Yu <yu.c.chen@intel.com>
AuthorDate: Mon, 28 Nov 2016 14:35:19 -0800
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Tue, 29 Nov 2016 18:02:58 +0100

timekeeping: Ignore the bogus sleep time if pm_trace is enabled

Power management suspend/resume tracing (ab)uses the RTC to store
suspend/resume information persistently. As a consequence the RTC value is
clobbered when timekeeping is resumed and tries to inject the sleep time.

Commit a4f8f6667f09 ("timekeeping: Cap array access in timekeeping_debug")
plugged a out of bounds array access in the timekeeping debug code which
was caused by the clobbered RTC value, but we still use the clobbered RTC
value for sleep time injection into kernel timekeeping, which will result
in random adjustments depending on the stored "hash" value.

To prevent this keep track of the RTC clobbering and ignore the invalid RTC
timestamp at resume. If the system resumed successfully clear the flag,
which marks the RTC as unusable, warn the user about the RTC clobber and
recommend to adjust the RTC with 'ntpdate' or 'rdate'.

[jstultz: Fixed up pr_warn formating, and implemented suggestions from Ingo]
[ tglx: Rewrote changelog ]

Originally-from: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Pavel Machek <pavel@ucw.cz>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Xunlei Pang <xlpang@redhat.com>
Cc: Len Brown <lenb@kernel.org>
Link: http://lkml.kernel.org/r/1480372524-15181-3-git-send-email-john.stultz@linaro.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

---
 arch/x86/kernel/rtc.c       |  9 +++++++++
 drivers/base/power/trace.c  | 27 +++++++++++++++++++++++++++
 drivers/rtc/rtc-cmos.c      |  7 +++++++
 include/linux/mc146818rtc.h |  1 +
 include/linux/pm-trace.h    |  9 ++++++++-
 5 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 79c6311c..5b21cb7 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -64,6 +64,15 @@ void mach_get_cmos_time(struct timespec *now)
 	unsigned int status, year, mon, day, hour, min, sec, century = 0;
 	unsigned long flags;
 
+	/*
+	 * If pm_trace abused the RTC as storage, set the timespec to 0,
+	 * which tells the caller that this RTC value is unusable.
+	 */
+	if (!pm_trace_rtc_valid()) {
+		now->tv_sec = now->tv_nsec = 0;
+		return;
+	}
+
 	spin_lock_irqsave(&rtc_lock, flags);
 
 	/*
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c
index efec10b..1cda505 100644
--- a/drivers/base/power/trace.c
+++ b/drivers/base/power/trace.c
@@ -10,6 +10,7 @@
 #include <linux/pm-trace.h>
 #include <linux/export.h>
 #include <linux/rtc.h>
+#include <linux/suspend.h>
 
 #include <linux/mc146818rtc.h>
 
@@ -74,6 +75,9 @@
 
 #define DEVSEED (7919)
 
+bool pm_trace_rtc_abused __read_mostly;
+EXPORT_SYMBOL_GPL(pm_trace_rtc_abused);
+
 static unsigned int dev_hash_value;
 
 static int set_magic_time(unsigned int user, unsigned int file, unsigned int device)
@@ -104,6 +108,7 @@ static int set_magic_time(unsigned int user, unsigned int file, unsigned int dev
 	time.tm_min = (n % 20) * 3;
 	n /= 20;
 	mc146818_set_time(&time);
+	pm_trace_rtc_abused = true;
 	return n ? -1 : 0;
 }
 
@@ -239,9 +244,31 @@ int show_trace_dev_match(char *buf, size_t size)
 	return ret;
 }
 
+static int
+pm_trace_notify(struct notifier_block *nb, unsigned long mode, void *_unused)
+{
+	switch (mode) {
+	case PM_POST_HIBERNATION:
+	case PM_POST_SUSPEND:
+		if (pm_trace_rtc_abused) {
+			pm_trace_rtc_abused = false;
+			pr_warn("Possible incorrect RTC due to pm_trace, please use 'ntpdate' or 'rdate' to reset it.\n");
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static struct notifier_block pm_trace_nb = {
+	.notifier_call = pm_trace_notify,
+};
+
 static int early_resume_init(void)
 {
 	hash_value_early_read = read_magic_time();
+	register_pm_notifier(&pm_trace_nb);
 	return 0;
 }
 
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index dd3d598..b27a189 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -191,6 +191,13 @@ static inline void cmos_write_bank2(unsigned char val, unsigned char addr)
 
 static int cmos_read_time(struct device *dev, struct rtc_time *t)
 {
+	/*
+	 * If pm_trace abused the RTC for storage, set the timespec to 0,
+	 * which tells the caller that this RTC value is unusable.
+	 */
+	if (!pm_trace_rtc_valid())
+		return -EIO;
+
 	/* REVISIT:  if the clock has a "century" register, use
 	 * that instead of the heuristic in mc146818_get_time().
 	 * That'll make Y3K compatility (year > 2070) easy!
diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h
index a585b4b..0661af1 100644
--- a/include/linux/mc146818rtc.h
+++ b/include/linux/mc146818rtc.h
@@ -16,6 +16,7 @@
 #include <asm/mc146818rtc.h>		/* register access macros */
 #include <linux/bcd.h>
 #include <linux/delay.h>
+#include <linux/pm-trace.h>
 
 #ifdef __KERNEL__
 #include <linux/spinlock.h>		/* spinlock_t */
diff --git a/include/linux/pm-trace.h b/include/linux/pm-trace.h
index ecbde7a..7b78793 100644
--- a/include/linux/pm-trace.h
+++ b/include/linux/pm-trace.h
@@ -1,11 +1,17 @@
 #ifndef PM_TRACE_H
 #define PM_TRACE_H
 
+#include <linux/types.h>
 #ifdef CONFIG_PM_TRACE
 #include <asm/pm-trace.h>
-#include <linux/types.h>
 
 extern int pm_trace_enabled;
+extern bool pm_trace_rtc_abused;
+
+static inline bool pm_trace_rtc_valid(void)
+{
+	return !pm_trace_rtc_abused;
+}
 
 static inline int pm_trace_is_enabled(void)
 {
@@ -24,6 +30,7 @@ extern int show_trace_dev_match(char *buf, size_t size);
 
 #else
 
+static inline bool pm_trace_rtc_valid(void) { return true; }
 static inline int pm_trace_is_enabled(void) { return 0; }
 
 #define TRACE_DEVICE(dev) do { } while (0)

  parent reply	other threads:[~2016-11-29 17:11 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-28 22:35 [GIT PULL][PATCH 0/7] Timekeeping changes for 4.10 (take 2) John Stultz
2016-11-28 22:35 ` [PATCH 1/7] selftests/timers: Fix spelling mistake "Asyncrhonous" -> "Asynchronous" John Stultz
2016-11-29 17:10   ` [tip:timers/core] " tip-bot for Colin Ian King
2016-11-28 22:35 ` [PATCH 2/7] timekeeping: Ignore the bogus sleep time if pm_trace is enabled John Stultz
2016-11-29  7:19   ` Ingo Molnar
2016-11-29  9:38     ` Chen Yu
2016-11-29 17:10   ` tip-bot for Chen Yu [this message]
2016-11-28 22:35 ` [PATCH 3/7] timekeeping: clocksource_cyc2ns: Document intended range limitation John Stultz
2016-11-29 17:11   ` [tip:timers/core] timekeeping/clocksource_cyc2ns: " tip-bot for Chris Metcalf
2016-11-28 22:35 ` [PATCH 4/7] time: alarmtimer: Add the tracepoints for alarmtimer John Stultz
2016-11-29  7:23   ` Ingo Molnar
2016-11-29  8:23     ` Baolin Wang
2016-11-29  9:12       ` Ingo Molnar
2016-11-29 11:52         ` Baolin Wang
2016-11-29 12:06   ` Thomas Gleixner
2016-11-30 11:43     ` Baolin Wang
2016-12-01  2:34     ` Baolin Wang
2016-12-01 13:52   ` [tip:timers/core] alarmtimer: Add tracepoints for alarm timers tip-bot for Baolin Wang
2016-11-28 22:35 ` [PATCH 5/7] timekeeping: Add a fast and NMI safe boot clock John Stultz
2016-11-29 17:11   ` [tip:timers/core] " tip-bot for Joel Fernandes
2016-11-28 22:35 ` [PATCH 6/7] trace: Add an option for boot clock as trace clock John Stultz
2016-11-28 23:05   ` Steven Rostedt
2016-11-29 17:12   ` [tip:timers/core] " tip-bot for Joel Fernandes
2016-11-28 22:35 ` [PATCH 7/7] trace: Update documentation for mono, mono_raw and boot clock John Stultz
2016-11-28 23:07   ` Steven Rostedt
2016-11-29  7:26   ` Ingo Molnar
2016-11-29 16:10     ` Joel Fernandes
2016-11-29 16:11       ` Thomas Gleixner
2016-11-29 17:13   ` [tip:timers/core] " tip-bot for Joel Fernandes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tip-ba58d1020a54933c6b087a3107661c8513556cb8@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=hpa@zytor.com \
    --cc=john.stultz@linaro.org \
    --cc=lenb@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=pavel@ucw.cz \
    --cc=prarit@redhat.com \
    --cc=richardcochran@gmail.com \
    --cc=rjw@rjwysocki.net \
    --cc=tglx@linutronix.de \
    --cc=xlpang@redhat.com \
    --cc=yu.c.chen@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.