aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt7
-rw-r--r--arch/x86/kernel/tsc.c33
2 files changed, 28 insertions, 12 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 1bbcaa8982b6..dc6b06f67fca 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2267,6 +2267,13 @@ and is between 256 and 4096 characters. It is defined in the file
2267 Format: 2267 Format:
2268 <io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq> 2268 <io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
2269 2269
2270 tsc= Disable clocksource-must-verify flag for TSC.
2271 Format: <string>
2272 [x86] reliable: mark tsc clocksource as reliable, this
2273 disables clocksource verification at runtime.
2274 Used to enable high-resolution timer mode on older
2275 hardware, and in virtualized environment.
2276
2270 turbografx.map[2|3]= [HW,JOY] 2277 turbografx.map[2|3]= [HW,JOY]
2271 TurboGraFX parallel port interface 2278 TurboGraFX parallel port interface
2272 Format: 2279 Format:
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 6dbf0bcb44a8..ee01cd96b5e1 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -32,6 +32,7 @@ static int tsc_unstable;
32 erroneous rdtsc usage on !cpu_has_tsc processors */ 32 erroneous rdtsc usage on !cpu_has_tsc processors */
33static int tsc_disabled = -1; 33static int tsc_disabled = -1;
34 34
35static int tsc_clocksource_reliable;
35/* 36/*
36 * Scheduler clock - returns current time in nanosec units. 37 * Scheduler clock - returns current time in nanosec units.
37 */ 38 */
@@ -99,6 +100,15 @@ int __init notsc_setup(char *str)
99 100
100__setup("notsc", notsc_setup); 101__setup("notsc", notsc_setup);
101 102
103static int __init tsc_setup(char *str)
104{
105 if (!strcmp(str, "reliable"))
106 tsc_clocksource_reliable = 1;
107 return 1;
108}
109
110__setup("tsc=", tsc_setup);
111
102#define MAX_RETRIES 5 112#define MAX_RETRIES 5
103#define SMI_TRESHOLD 50000 113#define SMI_TRESHOLD 50000
104 114
@@ -738,24 +748,21 @@ static struct dmi_system_id __initdata bad_tsc_dmi_table[] = {
738 {} 748 {}
739}; 749};
740 750
741/* 751static void __init check_system_tsc_reliable(void)
742 * Geode_LX - the OLPC CPU has a possibly a very reliable TSC 752{
743 */
744#ifdef CONFIG_MGEODE_LX 753#ifdef CONFIG_MGEODE_LX
745/* RTSC counts during suspend */ 754 /* RTSC counts during suspend */
746#define RTSC_SUSP 0x100 755#define RTSC_SUSP 0x100
747
748static void __init check_geode_tsc_reliable(void)
749{
750 unsigned long res_low, res_high; 756 unsigned long res_low, res_high;
751 757
752 rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); 758 rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high);
759 /* Geode_LX - the OLPC CPU has a possibly a very reliable TSC */
753 if (res_low & RTSC_SUSP) 760 if (res_low & RTSC_SUSP)
754 clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; 761 tsc_clocksource_reliable = 1;
755}
756#else
757static inline void check_geode_tsc_reliable(void) { }
758#endif 762#endif
763 if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE))
764 tsc_clocksource_reliable = 1;
765}
759 766
760/* 767/*
761 * Make an educated guess if the TSC is trustworthy and synchronized 768 * Make an educated guess if the TSC is trustworthy and synchronized
@@ -790,6 +797,8 @@ static void __init init_tsc_clocksource(void)
790{ 797{
791 clocksource_tsc.mult = clocksource_khz2mult(tsc_khz, 798 clocksource_tsc.mult = clocksource_khz2mult(tsc_khz,
792 clocksource_tsc.shift); 799 clocksource_tsc.shift);
800 if (tsc_clocksource_reliable)
801 clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
793 /* lower the rating if we already know its unstable: */ 802 /* lower the rating if we already know its unstable: */
794 if (check_tsc_unstable()) { 803 if (check_tsc_unstable()) {
795 clocksource_tsc.rating = 0; 804 clocksource_tsc.rating = 0;
@@ -850,7 +859,7 @@ void __init tsc_init(void)
850 if (unsynchronized_tsc()) 859 if (unsynchronized_tsc())
851 mark_tsc_unstable("TSCs unsynchronized"); 860 mark_tsc_unstable("TSCs unsynchronized");
852 861
853 check_geode_tsc_reliable(); 862 check_system_tsc_reliable();
854 init_tsc_clocksource(); 863 init_tsc_clocksource();
855} 864}
856 865