Skylake-era Intel CPUs are vulnerable to exploits of empty RSB conditions. On hardware, platform vulnerability can be determined simply by checking the processor's DisplayModel/DisplayFamily signature. However, when running in a VM, the operating system should also query IA32_ARCH_CAPABILITIES.RSBA[bit 2], a synthetic bit that can be set by a hypervisor to indicate that the VM might run on a vulnerable physical processor, regardless of the DisplayModel/DisplayFamily reported by CPUID.
Note that IA32_ARCH_CAPABILITIES.RSBA[bit 2] is always clear on hardware, so the DisplayModel/DisplayFamily check is still required. For all of the details, see the Intel white paper, "Retpoline: A Branch Target Injection Mitigation" (document number 337131-001), section 5.3: Virtual Machine CPU Identification. Signed-off-by: Jim Mattson <jmatt...@google.com> Reviewed-by: Peter Shier <psh...@google.com> --- arch/x86/include/asm/msr-index.h | 1 + arch/x86/kernel/cpu/bugs.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 68b2c3150de1..f37ec58c4e04 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -70,6 +70,7 @@ #define MSR_IA32_ARCH_CAPABILITIES 0x0000010a #define ARCH_CAP_RDCL_NO (1 << 0) /* Not susceptible to Meltdown */ #define ARCH_CAP_IBRS_ALL (1 << 1) /* Enhanced IBRS support */ +#define ARCH_CAP_RSBA (1 << 2) /* Vulnerable to empty RSB */ #define ARCH_CAP_SSB_NO (1 << 4) /* * Not susceptible to Speculative Store Bypass * attack, so no Speculative Store Bypass diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 5c0ea39311fe..b6fe335746a4 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -330,6 +330,18 @@ static bool __init is_skylake_era(void) return false; } +/* Check for vulnerability to exploits of empty RSB conditions */ +static bool __init is_vulnerable_to_empty_rsb(void) +{ + u64 ia32_cap = 0; + + if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) + rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); + + return (ia32_cap & ARCH_CAP_RSBA) || is_skylake_era(); +} + + static void __init spectre_v2_select_mitigation(void) { enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline(); @@ -402,7 +414,7 @@ static void __init spectre_v2_select_mitigation(void) * switch is required. */ if ((!boot_cpu_has(X86_FEATURE_PTI) && - !boot_cpu_has(X86_FEATURE_SMEP)) || is_skylake_era()) { + !boot_cpu_has(X86_FEATURE_SMEP)) || is_vulnerable_to_empty_rsb()) { setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW); pr_info("Spectre v2 mitigation: Filling RSB on context switch\n"); } -- 2.18.0.597.ga71716f1ad-goog