]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.arch/x86-vmware-tsc-04-use-TSC_RELIABLE
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / x86-vmware-tsc-04-use-TSC_RELIABLE
CommitLineData
2cb7cef9
BS
1From: Alok Kataria <akataria@vmware.com>
2Subject: x86: USE the synthetic TSC_RELIABLE feature bit.
3Patch-mainline:
4References: bnc#441338
5
6Impact: Changes timebase calibration on Vmware.
7
8Use the synthetic TSC_RELIABLE bit to workaround virtualization anomalies.
9
10Virtual TSCs can be kept nearly in sync, but because the virtual TSC
11offset is set by software, it's not perfect. So, the TSC
12synchronization test can fail. Even then the TSC can be used as a
13clocksource since the VMware platform exports a reliable TSC to the
14guest for timekeeping purposes. Use this bit to check if we need to
15skip the TSC sync checks.
16
17Along with this also set the CONSTANT_TSC bit when on VMware, since we
18still want to use TSC as clocksource on VM running over hardware which
19has unsynchronized TSC's (opteron's), since the hypervisor will take
20care of providing consistent TSC to the guest.
21
22Signed-off-by: Alok N Kataria <akataria@vmware.com>
23Signed-off-by: Dan Hecht <dhecht@vmware.com>
24Signed-off-by: H. Peter Anvin <hpa@zytor.com>
25Signed-off-by: Takashi Iwai <tiwai@suse.de>
26
27---
28
29 arch/x86/kernel/cpu/hypervisor.c | 11 ++++++++++-
30 arch/x86/kernel/cpu/vmware.c | 18 ++++++++++++++++++
31 arch/x86/kernel/tsc_sync.c | 8 +++++++-
32 include/asm-x86/vmware.h | 1 +
33 4 files changed, 36 insertions(+), 2 deletions(-)
34
35
36diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
37index 7bd5506..35ae2b7 100644
38--- a/arch/x86/kernel/cpu/hypervisor.c
39+++ b/arch/x86/kernel/cpu/hypervisor.c
40@@ -41,8 +41,17 @@ unsigned long get_hypervisor_tsc_freq(void)
41 return 0;
42 }
43
44+static inline void __cpuinit
45+hypervisor_set_feature_bits(struct cpuinfo_x86 *c)
46+{
47+ if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) {
48+ vmware_set_feature_bits(c);
49+ return;
50+ }
51+}
52+
53 void __cpuinit init_hypervisor(struct cpuinfo_x86 *c)
54 {
55 detect_hypervisor_vendor(c);
56+ hypervisor_set_feature_bits(c);
57 }
58-
59diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
60index d5d1b75..2ac4394 100644
61--- a/arch/x86/kernel/cpu/vmware.c
62+++ b/arch/x86/kernel/cpu/vmware.c
63@@ -86,3 +86,21 @@ unsigned long vmware_get_tsc_khz(void)
64 BUG_ON(!vmware_platform());
65 return __vmware_get_tsc_khz();
66 }
67+
68+/*
69+ * VMware hypervisor takes care of exporting a reliable TSC to the guest.
70+ * Still, due to timing difference when running on virtual cpus, the TSC can
71+ * be marked as unstable in some cases. For example, the TSC sync check at
72+ * bootup can fail due to a marginal offset between vcpus' TSCs (though the
73+ * TSCs do not drift from each other). Also, the ACPI PM timer clocksource
74+ * is not suitable as a watchdog when running on a hypervisor because the
75+ * kernel may miss a wrap of the counter if the vcpu is descheduled for a
76+ * long time. To skip these checks at runtime we set these capability bits,
77+ * so that the kernel could just trust the hypervisor with providing a
78+ * reliable virtual TSC that is suitable for timekeeping.
79+ */
80+void __cpuinit vmware_set_feature_bits(struct cpuinfo_x86 *c)
81+{
82+ set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
83+ set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE);
84+}
85diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
86index 9ffb01c..5977c40 100644
87--- a/arch/x86/kernel/tsc_sync.c
88+++ b/arch/x86/kernel/tsc_sync.c
89@@ -108,6 +108,12 @@ void __cpuinit check_tsc_sync_source(int cpu)
90 if (unsynchronized_tsc())
91 return;
92
93+ if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
94+ printk(KERN_INFO
95+ "Skipping synchronization checks as TSC is reliable.\n");
96+ return;
97+ }
98+
99 printk(KERN_INFO "checking TSC synchronization [CPU#%d -> CPU#%d]:",
100 smp_processor_id(), cpu);
101
102@@ -161,7 +167,7 @@ void __cpuinit check_tsc_sync_target(void)
103 {
104 int cpus = 2;
105
106- if (unsynchronized_tsc())
107+ if (unsynchronized_tsc() || boot_cpu_has(X86_FEATURE_TSC_RELIABLE))
108 return;
109
110 /*
111diff --git a/include/asm-x86/vmware.h b/include/asm-x86/vmware.h
112index 02dfea5..c11b7e1 100644
113--- a/include/asm-x86/vmware.h
114+++ b/include/asm-x86/vmware.h
115@@ -22,5 +22,6 @@
116
117 extern unsigned long vmware_get_tsc_khz(void);
118 extern int vmware_platform(void);
119+extern void vmware_set_feature_bits(struct cpuinfo_x86 *c);
120
121 #endif