Commit fde1b3fa authored by Andi Kleen's avatar Andi Kleen Committed by Ingo Molnar

x86: introduce rdtsc_barrier()

rdtsc_barrier() is a new barrier primitive that stops RDTSC speculation
to avoid races with timer interrupts on other CPUs.

It expands either to LFENCE (for Intel CPUs) or MFENCE (for
AMD CPUs) which stops RDTSC on all currently known microarchitectures
that implement SSE. On CPUs without SSE there is generally no RDTSC
speculation.

[ mingo@elte.hu: renamed it to rdtsc_barrier() and made it x86-only ]
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 2a10e7c4
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/cmpxchg.h> #include <asm/cmpxchg.h>
#include <asm/nops.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/irqflags.h> #include <linux/irqflags.h>
...@@ -395,5 +396,17 @@ void default_idle(void); ...@@ -395,5 +396,17 @@ void default_idle(void);
#define set_mb(var, value) do { var = value; barrier(); } while (0) #define set_mb(var, value) do { var = value; barrier(); } while (0)
#endif #endif
/*
* Stop RDTSC speculation. This is needed when you need to use RDTSC
* (or get_cycles or vread that possibly accesses the TSC) in a defined
* code region.
*
* (Could use an alternative three way for this if there was one.)
*/
static inline void rdtsc_barrier(void)
{
alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
}
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment