From: tip-bot for Thomas Gleixner <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, bruce.schlobohm@intel.com,
hpa@zytor.com, tglx@linutronix.de, bp@alien8.de,
rscheidegger_lists@hispeed.ch, mingo@kernel.org,
kevin.b.stanton@intel.com, allen_hung@dell.com,
peterz@infradead.org
Subject: [tip:x86/timers] x86/tsc: Validate TSC_ADJUST after resume
Date: Thu, 15 Dec 2016 02:52:31 -0800 [thread overview]
Message-ID: <tip-6a369583178d0b89c2c3919c4456ee22fee0f249@git.kernel.org> (raw)
In-Reply-To: <20161213131211.317654500@linutronix.de>
Commit-ID: 6a369583178d0b89c2c3919c4456ee22fee0f249
Gitweb: http://git.kernel.org/tip/6a369583178d0b89c2c3919c4456ee22fee0f249
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 13 Dec 2016 13:14:17 +0000
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 15 Dec 2016 11:44:29 +0100
x86/tsc: Validate TSC_ADJUST after resume
Some 'feature' BIOSes fiddle with the TSC_ADJUST register during
suspend/resume which renders the TSC unusable.
Add sanity checks into the resume path and restore the
original value if it was adjusted.
Reported-and-tested-by: Roland Scheidegger <rscheidegger_lists@hispeed.ch>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Bruce Schlobohm <bruce.schlobohm@intel.com>
Cc: Kevin Stanton <kevin.b.stanton@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Allen Hung <allen_hung@dell.com>
Cc: Borislav Petkov <bp@alien8.de>
Link: http://lkml.kernel.org/r/20161213131211.317654500@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/include/asm/tsc.h | 4 ++--
arch/x86/kernel/process.c | 2 +-
arch/x86/kernel/tsc.c | 6 ++++++
arch/x86/kernel/tsc_sync.c | 6 +++---
arch/x86/power/cpu.c | 1 +
5 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index c054eaa..372ad0c 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -47,12 +47,12 @@ extern int tsc_clocksource_reliable;
*/
#ifdef CONFIG_X86_TSC
extern bool tsc_store_and_check_tsc_adjust(void);
-extern void tsc_verify_tsc_adjust(void);
+extern void tsc_verify_tsc_adjust(bool resume);
extern void check_tsc_sync_source(int cpu);
extern void check_tsc_sync_target(void);
#else
static inline bool tsc_store_and_check_tsc_adjust(void) { return false; }
-static inline void tsc_verify_tsc_adjust(void) { }
+static inline void tsc_verify_tsc_adjust(bool resume) { }
static inline void check_tsc_sync_source(int cpu) { }
static inline void check_tsc_sync_target(void) { }
#endif
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 4fe5dc8..a67e0f0 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -277,7 +277,7 @@ void exit_idle(void)
void arch_cpu_idle_enter(void)
{
- tsc_verify_tsc_adjust();
+ tsc_verify_tsc_adjust(false);
local_touch_nmi();
enter_idle();
}
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 2bb8de4..bfb541a 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1080,6 +1080,11 @@ static void detect_art(void)
static struct clocksource clocksource_tsc;
+static void tsc_resume(struct clocksource *cs)
+{
+ tsc_verify_tsc_adjust(true);
+}
+
/*
* We used to compare the TSC to the cycle_last value in the clocksource
* structure to avoid a nasty time-warp. This can be observed in a
@@ -1112,6 +1117,7 @@ static struct clocksource clocksource_tsc = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
CLOCK_SOURCE_MUST_VERIFY,
.archdata = { .vclock_mode = VCLOCK_TSC },
+ .resume = tsc_resume,
};
void mark_tsc_unstable(char *reason)
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index a75f696..94f2ce5 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -30,7 +30,7 @@ struct tsc_adjust {
static DEFINE_PER_CPU(struct tsc_adjust, tsc_adjust);
-void tsc_verify_tsc_adjust(void)
+void tsc_verify_tsc_adjust(bool resume)
{
struct tsc_adjust *adj = this_cpu_ptr(&tsc_adjust);
s64 curval;
@@ -39,7 +39,7 @@ void tsc_verify_tsc_adjust(void)
return;
/* Rate limit the MSR check */
- if (time_before(jiffies, adj->nextcheck))
+ if (!resume && time_before(jiffies, adj->nextcheck))
return;
adj->nextcheck = jiffies + HZ;
@@ -51,7 +51,7 @@ void tsc_verify_tsc_adjust(void)
/* Restore the original value */
wrmsrl(MSR_IA32_TSC_ADJUST, adj->adjusted);
- if (!adj->warned) {
+ if (!adj->warned || resume) {
pr_warn(FW_BUG "TSC ADJUST differs: CPU%u %lld --> %lld. Restoring\n",
smp_processor_id(), adj->adjusted, curval);
adj->warned = true;
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 53cace2..66ade16 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -252,6 +252,7 @@ static void notrace __restore_processor_state(struct saved_context *ctxt)
fix_processor_context();
do_fpu_end();
+ tsc_verify_tsc_adjust(true);
x86_platform.restore_sched_clock_state();
mtrr_bp_restore();
perf_restore_debug_store();
next prev parent reply other threads:[~2016-12-15 10:56 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-13 13:14 [patch 0/2] tsc/adjust: Cure suspend/resume issues and prevent TSC deadline timer irq storm Thomas Gleixner
2016-12-13 13:14 ` [patch 2/2] x86/tsc: Force TSC_ADJUST register to value >= zero Thomas Gleixner
2016-12-13 13:43 ` Peter Zijlstra
2016-12-13 15:49 ` Thomas Gleixner
2016-12-15 10:53 ` [tip:x86/timers] " tip-bot for Thomas Gleixner
2016-12-16 11:46 ` [patch 2/2] " Thomas Gleixner
2016-12-16 11:52 ` Ingo Molnar
2016-12-16 11:53 ` Thomas Gleixner
2016-12-16 13:33 ` Thomas Gleixner
2016-12-13 13:14 ` [patch 1/2] x86/tsc: Validate TSC_ADJUST after resume Thomas Gleixner
2016-12-13 13:22 ` Peter Zijlstra
2016-12-13 13:23 ` Thomas Gleixner
2016-12-15 10:52 ` tip-bot for Thomas Gleixner [this message]
2016-12-13 16:34 ` [patch 0/2] tsc/adjust: Cure suspend/resume issues and prevent TSC deadline timer irq storm Roland Scheidegger
2016-12-13 16:46 ` Thomas Gleixner
2016-12-14 1:36 ` Roland Scheidegger
2016-12-14 7:31 ` Thomas Gleixner
2016-12-14 20:59 ` Thomas Gleixner
2016-12-14 21:40 ` Thomas Gleixner
2016-12-14 22:54 ` Roland Scheidegger
2016-12-15 9:31 ` Thomas Gleixner
2017-01-26 23:40 ` Stanton, Kevin B
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-6a369583178d0b89c2c3919c4456ee22fee0f249@git.kernel.org \
--to=tipbot@zytor.com \
--cc=allen_hung@dell.com \
--cc=bp@alien8.de \
--cc=bruce.schlobohm@intel.com \
--cc=hpa@zytor.com \
--cc=kevin.b.stanton@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=rscheidegger_lists@hispeed.ch \
--cc=tglx@linutronix.de \
/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.