Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/asm/tsc/sync: Use rdtsc_ordered() in check_tsc_warp() and drop extra barriers

Using get_cycles was unnecessary: check_tsc_warp() is not called
on TSC-less systems. Replace rdtsc_barrier(); get_cycles() with
rdtsc_ordered().

While we're at it, make the somewhat more dangerous change of
removing barrier_before_rdtsc after RDTSC in the TSC warp check
code. This should be okay, though -- the vDSO TSC code doesn't
have that barrier, so, if removing the barrier from the warp
check would cause us to detect a warp that we otherwise wouldn't
detect, then we have a genuine bug.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Huang Rui <ray.huang@amd.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Len Brown <lenb@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: kvm ML <kvm@vger.kernel.org>
Link: http://lkml.kernel.org/r/387c4c3a75f875bcde6cd68cee013273a744f364.1434501121.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Andy Lutomirski and committed by
Ingo Molnar
eee6946e 03b9730b

+6 -8
+6 -8
arch/x86/kernel/tsc_sync.c
··· 39 39 static int nr_warps; 40 40 41 41 /* 42 - * TSC-warp measurement loop running on both CPUs: 42 + * TSC-warp measurement loop running on both CPUs. This is not called 43 + * if there is no TSC. 43 44 */ 44 45 static void check_tsc_warp(unsigned int timeout) 45 46 { 46 47 cycles_t start, now, prev, end; 47 48 int i; 48 49 49 - rdtsc_barrier(); 50 - start = get_cycles(); 51 - rdtsc_barrier(); 50 + start = rdtsc_ordered(); 52 51 /* 53 52 * The measurement runs for 'timeout' msecs: 54 53 */ ··· 62 63 */ 63 64 arch_spin_lock(&sync_lock); 64 65 prev = last_tsc; 65 - rdtsc_barrier(); 66 - now = get_cycles(); 67 - rdtsc_barrier(); 66 + now = rdtsc_ordered(); 68 67 last_tsc = now; 69 68 arch_spin_unlock(&sync_lock); 70 69 ··· 123 126 124 127 /* 125 128 * No need to check if we already know that the TSC is not 126 - * synchronized: 129 + * synchronized or if we have no TSC. 127 130 */ 128 131 if (unsynchronized_tsc()) 129 132 return; ··· 187 190 { 188 191 int cpus = 2; 189 192 193 + /* Also aborts if there is no TSC. */ 190 194 if (unsynchronized_tsc() || tsc_clocksource_reliable) 191 195 return; 192 196