[PATCH v2 2/8] x86/enter: MACROS to set/clear IBRS

From: Tim Chen
Date: Fri Jan 05 2018 - 21:33:10 EST


Create macros to control IBRS. Use these macros to enable IBRS on kernel entry
paths and disable IBRS on kernel exit paths.

The registers rax, rcx and rdx are touched when controlling IBRS
so they need to be saved when they can't be clobbered.

Signed-off-by: Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx>
---
arch/x86/entry/calling.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)

diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 45a63e0..09c870d 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -6,6 +6,8 @@
#include <asm/percpu.h>
#include <asm/asm-offsets.h>
#include <asm/processor-flags.h>
+#include <asm/msr-index.h>
+#include <asm/cpufeatures.h>

/*

@@ -347,3 +349,75 @@ For 32-bit we have the following conventions - kernel is built with
.Lafter_call_\@:
#endif
.endm
+
+/*
+ * IBRS related macros
+ */
+
+.macro PUSH_MSR_REGS
+ pushq %rax
+ pushq %rcx
+ pushq %rdx
+.endm
+
+.macro POP_MSR_REGS
+ popq %rdx
+ popq %rcx
+ popq %rax
+.endm
+
+.macro WRMSR_ASM msr_nr:req eax_val:req
+ movl \msr_nr, %ecx
+ movl $0, %edx
+ movl \eax_val, %eax
+.endm
+
+.macro ENABLE_IBRS
+ ALTERNATIVE "jmp .Lskip_\@", "", X86_FEATURE_SPEC_CTRL
+ PUSH_MSR_REGS
+ WRMSR_ASM $MSR_IA32_SPEC_CTRL, $SPEC_CTRL_FEATURE_ENABLE_IBRS
+ POP_MSR_REGS
+.Lskip_\@:
+.endm
+
+.macro DISABLE_IBRS
+ ALTERNATIVE "jmp .Lskip_\@", "", X86_FEATURE_SPEC_CTRL
+ PUSH_MSR_REGS
+ WRMSR_ASM $MSR_IA32_SPEC_CTRL, $SPEC_CTRL_FEATURE_DISABLE_IBRS
+ POP_MSR_REGS
+.Lskip_\@:
+.endm
+
+.macro ENABLE_IBRS_CLOBBER
+ ALTERNATIVE "jmp .Lskip_\@", "", X86_FEATURE_SPEC_CTRL
+ WRMSR_ASM $MSR_IA32_SPEC_CTRL, $SPEC_CTRL_FEATURE_ENABLE_IBRS
+.Lskip_\@:
+.endm
+
+.macro DISABLE_IBRS_CLOBBER
+ ALTERNATIVE "jmp .Lskip_\@", "", X86_FEATURE_SPEC_CTRL
+ WRMSR_ASM $MSR_IA32_SPEC_CTRL, $SPEC_CTRL_FEATURE_DISABLE_IBRS
+.Lskip_\@:
+.endm
+
+.macro ENABLE_IBRS_SAVE_AND_CLOBBER save_reg:req
+ ALTERNATIVE "jmp .Lskip_\@", "", X86_FEATURE_SPEC_CTRL
+ movl $MSR_IA32_SPEC_CTRL, %ecx
+ rdmsr
+ movl %eax, \save_reg
+
+ movl $0, %edx
+ movl $SPEC_CTRL_FEATURE_ENABLE_IBRS, %eax
+ wrmsr
+.Lskip_\@:
+.endm
+
+.macro RESTORE_IBRS_CLOBBER save_reg:req
+ ALTERNATIVE "jmp .Lskip_\@", "", X86_FEATURE_SPEC_CTRL
+ /* Set IBRS to the value saved in the save_reg */
+ movl $MSR_IA32_SPEC_CTRL, %ecx
+ movl $0, %edx
+ movl \save_reg, %eax
+ wrmsr
+.Lskip_\@:
+.endm
--
2.9.4