The new speculative execution barrier, nospec_barrier(), ensures that any userspace controllable speculation doesn't cross the boundary. Any user observable speculative activity on this CPU thread before this point either completes, reaches a state it can no longer cause an observable activity, or is aborted before instructions after the barrier execute. In the x86 case nospec_barrier() resolves to an lfence if X86_FEATURE_LFENCE_RDTSC is present. Other architectures can define their variants. Note the expectation is that this barrier is never used directly, at least outside of architecture specific code. It is implied by the nospec_{array_ptr,ptr} macros. x86, for now, depends on the barrier for protection while other architectures place their speculation prevention in nospec_{ptr,array_ptr} when a barrier instruction is not available or too heavy-weight. In the x86 case lfence is not a fully serializing instruction so it is not as expensive as other barriers. Suggested-by: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Suggested-by: Arjan van de Ven <arjan@xxxxxxxxxxxxxxx> Suggested-by: Alan Cox <alan.cox@xxxxxxxxx> Cc: Mark Rutland <mark.rutland@xxxxxxx> Cc: Greg KH <gregkh@xxxxxxxxxxxxxxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Alan Cox <alan@xxxxxxxxxxxxxxx> Signed-off-by: Elena Reshetova <elena.reshetova@xxxxxxxxx> Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx> --- arch/x86/include/asm/barrier.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h index 7fb336210e1b..1148cd9f5ae7 100644 --- a/arch/x86/include/asm/barrier.h +++ b/arch/x86/include/asm/barrier.h @@ -24,6 +24,12 @@ #define wmb() asm volatile("sfence" ::: "memory") #endif +/* + * CPUs without LFENCE don't really speculate much. Possibly fall back to IRET-to-self. + */ +#define __nospec_barrier() alternative("", "lfence", X86_FEATURE_LFENCE_RDTSC) +#define nospec_barrier __nospec_barrier + #ifdef CONFIG_X86_PPRO_FENCE #define dma_rmb() rmb() #else