From e85a3f5fa483147203e37197f6cbc60fc21ea1c0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 17 Sep 2015 10:16:38 +0000 Subject: [PATCH] x86: fix Geode LX timekeeping (#20531) Signed-off-by: Felix Fietkau Backport of r46985 git-svn-id: svn://svn.openwrt.org/openwrt/branches/chaos_calmer@46987 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- ...-Geode-LX-timekeeping-in-the-generic.patch | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 target/linux/x86/patches-3.18/001-x86-platform-Fix-Geode-LX-timekeeping-in-the-generic.patch diff --git a/target/linux/x86/patches-3.18/001-x86-platform-Fix-Geode-LX-timekeeping-in-the-generic.patch b/target/linux/x86/patches-3.18/001-x86-platform-Fix-Geode-LX-timekeeping-in-the-generic.patch new file mode 100644 index 0000000000..8bd1699627 --- /dev/null +++ b/target/linux/x86/patches-3.18/001-x86-platform-Fix-Geode-LX-timekeeping-in-the-generic.patch @@ -0,0 +1,61 @@ +From: David Woodhouse +Date: Thu, 17 Sep 2015 10:16:54 +0100 +Subject: [PATCH] x86/platform: Fix Geode LX timekeeping in the generic x86 + build + +In 2007, commit 07190a08eef36 ("Mark TSC on GeodeLX reliable") +bypassed verification of the TSC on Geode LX. However, this code +(now in the check_system_tsc_reliable() function in +arch/x86/kernel/tsc.c) was only present if CONFIG_MGEODE_LX was +set. + +OpenWRT has recently started building its generic Geode target +for Geode GX, not LX, to include support for additional +platforms. This broke the timekeeping on LX-based devices, +because the TSC wasn't marked as reliable: +https://dev.openwrt.org/ticket/20531 + +By adding a runtime check on is_geode_lx(), we can also include +the fix if CONFIG_MGEODEGX1 or CONFIG_X86_GENERIC are set, thus +fixing the problem. + +Signed-off-by: David Woodhouse +Signed-off-by: Ingo Molnar +Closes #20531 +--- + +--- a/arch/x86/kernel/tsc.c ++++ b/arch/x86/kernel/tsc.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ + EXPORT_SYMBOL(cpu_khz); +@@ -1004,15 +1005,17 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable); + + static void __init check_system_tsc_reliable(void) + { +-#ifdef CONFIG_MGEODE_LX +- /* RTSC counts during suspend */ ++#if defined(CONFIG_MGEODEGX1) || defined(CONFIG_MGEODE_LX) || defined(CONFIG_X86_GENERIC) ++ if (is_geode_lx()) { ++ /* RTSC counts during suspend */ + #define RTSC_SUSP 0x100 +- unsigned long res_low, res_high; ++ unsigned long res_low, res_high; + +- rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); +- /* Geode_LX - the OLPC CPU has a very reliable TSC */ +- if (res_low & RTSC_SUSP) +- tsc_clocksource_reliable = 1; ++ rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); ++ /* Geode_LX - the OLPC CPU has a very reliable TSC */ ++ if (res_low & RTSC_SUSP) ++ tsc_clocksource_reliable = 1; ++ } + #endif + if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) + tsc_clocksource_reliable = 1;