[PATCH 22/35] x86/cpufeatures: Detect Speculation control feature

From: Peter Zijlstra
Date: Thu Jan 18 2018 - 10:00:13 EST


From: Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx>

CPUs can expose a MSR to control speculation. The initial function of this
MSR is to control Indirect Branch Speculation, which is required to
mitigate the Spectre_V2 attack on certain CPU generations.

If CPUID(7).RDX[26] is set then MSR_IA32_SPEC_CTRL (0x48) is available and
bit 0 of that MSR controls whether Indirect Branch Speculation is
restricted or not. The control bit is named IBRS (Indirect Branch
Restricted Speculation). The IBSR bit can be unconditionally set to 1
without clearing it before.

If IBRS is set, near returns and near indirect jumps/calls will not allow
their predicted target address to be controlled by code that executed in a
less privileged prediction mode before the IBRS mode was last written with
a value of 1 or on another logical processor so long as all Return Stack
Buffer (RSB) entries from the previous less privileged prediction mode are
overwritten.

Thus a near indirect jump/call/return may be affected by code in a less
privileged prediction mode that executed AFTER IBRS mode was last written
with a value of 1.

Code executed by a sibling logical processor cannot control indirect
jump/call/return predicted target when IBRS is set

IBRS is not required in order to isolate branch predictions for SMM or SGX
enclaves.

Enabling IBRS can cause a measurable and depending on the workload
significant CPU performance penalty.

[ tglx: Steam blastered changelog ]

Cc: Arjan Van De Ven <arjan.van.de.ven@xxxxxxxxx>
Cc: Dave Hansen <dave.hansen@xxxxxxxxx>
Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Cc: Andi Kleen <ak@xxxxxxxxxxxxxxx>
Cc: Andrea Arcangeli <aarcange@xxxxxxxxxx>
Cc: David Woodhouse <dwmw@xxxxxxxxxxxx>
Cc: Andy Lutomirski <luto@xxxxxxxxxx>
Cc: Greg KH <gregkh@xxxxxxxxxxxxxxxxxxx>
Signed-off-by: Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
---
arch/x86/include/asm/cpufeatures.h | 2 ++
arch/x86/include/asm/msr-index.h | 4 ++++
arch/x86/kernel/cpu/scattered.c | 1 +
3 files changed, 7 insertions(+)

--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -211,6 +211,8 @@

#define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */
#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* Fill RSB on context switches */
+#define X86_FEATURE_SPEC_CTRL ( 7*32+20) /* Speculation Control */
+#define X86_FEATURE_IBRS ( 7*32+21) /* Indirect Branch Restricted Speculation */

/* Virtualization flags: Linux defined, word 8 */
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -42,6 +42,10 @@
#define MSR_PPIN_CTL 0x0000004e
#define MSR_PPIN 0x0000004f

+#define MSR_IA32_SPEC_CTRL 0x00000048
+#define SPEC_CTRL_DISABLE_IBRS (0 << 0)
+#define SPEC_CTRL_ENABLE_IBRS (1 << 0)
+
#define MSR_IA32_PERFCTR0 0x000000c1
#define MSR_IA32_PERFCTR1 0x000000c2
#define MSR_FSB_FREQ 0x000000cd
--- a/arch/x86/kernel/cpu/scattered.c
+++ b/arch/x86/kernel/cpu/scattered.c
@@ -23,6 +23,7 @@ static const struct cpuid_bit cpuid_bits
{ X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 },
{ X86_FEATURE_AVX512_4VNNIW, CPUID_EDX, 2, 0x00000007, 0 },
{ X86_FEATURE_AVX512_4FMAPS, CPUID_EDX, 3, 0x00000007, 0 },
+ { X86_FEATURE_SPEC_CTRL, CPUID_EDX, 26, 0x00000007, 0 },
{ X86_FEATURE_CAT_L3, CPUID_EBX, 1, 0x00000010, 0 },
{ X86_FEATURE_CAT_L2, CPUID_EBX, 2, 0x00000010, 0 },
{ X86_FEATURE_CDP_L3, CPUID_ECX, 2, 0x00000010, 1 },