x86: enable Extended IBRS

This is a CPU mitigation feature for Spectre V2 attacks

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2019-02-28 15:51:56 -08:00 committed by Andrew Boie
commit 10040f603d
3 changed files with 47 additions and 22 deletions

View file

@ -23,12 +23,12 @@ zephyr_library_sources(
swap.S swap.S
sys_fatal_error_handler.c sys_fatal_error_handler.c
thread.c thread.c
spec_ctrl.c
) )
zephyr_library_sources_if_kconfig( irq_offload.c) zephyr_library_sources_if_kconfig( irq_offload.c)
zephyr_library_sources_if_kconfig( x86_mmu.c) zephyr_library_sources_if_kconfig( x86_mmu.c)
zephyr_library_sources_if_kconfig( reboot_rst_cnt.c) zephyr_library_sources_if_kconfig( reboot_rst_cnt.c)
zephyr_library_sources_ifdef(CONFIG_DISABLE_SSBD spec_ctrl.c)
zephyr_library_sources_ifdef(CONFIG_FP_SHARING float.c) zephyr_library_sources_ifdef(CONFIG_FP_SHARING float.c)
zephyr_library_sources_ifdef(CONFIG_X86_USERSPACE userspace.S) zephyr_library_sources_ifdef(CONFIG_X86_USERSPACE userspace.S)

View file

@ -83,6 +83,15 @@ config DISABLE_SSBD
Even if enabled, will have no effect on CPUs that do not Even if enabled, will have no effect on CPUs that do not
require this feature. require this feature.
config ENABLE_EXTENDED_IBRS
bool "Enable Extended IBRS"
depends on USERSPACE
default y if !X86_NO_SPECTRE_V2
help
This option will enable the Extended Indirect Branch Restricted
Speculation 'always on' feature. This mitigates Indirect Branch
Control vulnerabilities (aka Spectre V2).
config X86_RETPOLINE config X86_RETPOLINE
bool "Build with retpolines enabled in x86 assembly code" bool "Build with retpolines enabled in x86 assembly code"
depends on USERSPACE depends on USERSPACE

View file

@ -12,44 +12,60 @@
#include <kernel_arch_func.h> #include <kernel_arch_func.h>
#include <kernel.h> #include <kernel.h>
/*
* See:
* https://software.intel.com/security-software-guidance/api-app/sites/default/files/336996-Speculative-Execution-Side-Channel-Mitigations.pdf
*/
#define CPUID_EXTENDED_FEATURES_LVL 7 #define CPUID_EXTENDED_FEATURES_LVL 7
#define CPUID_SPEC_CTRL BIT(31) /* Bits to check in CPUID extended features */
#define SPEC_CTRL_SSBD BIT(2) #define CPUID_SPEC_CTRL_SSBD BIT(31)
#define CPUID_SPEC_CTRL_IBRS BIT(26)
static int /* Bits to set in IA32_SPEC_CTRL_MSR to enable */
cpu_has_spec_ctrl(void) #define SPEC_CTRL_IBRS BIT(0)
#define SPEC_CTRL_SSBD BIT(2)
#if defined(CONFIG_DISABLE_SSBD) || defined(CONFIG_ENABLE_EXTENDED_IBRS)
static u32_t cpuid_extended_features(void)
{ {
u32_t eax, ebx, ecx = 0U, edx; u32_t eax, ebx, ecx = 0U, edx;
if (!__get_cpuid(CPUID_EXTENDED_FEATURES_LVL, if (__get_cpuid(CPUID_EXTENDED_FEATURES_LVL,
&eax, &ebx, &ecx, &edx)) { &eax, &ebx, &ecx, &edx) == 0) {
return 0; return 0;
} }
ARG_UNUSED(eax); return edx;
ARG_UNUSED(ebx);
ARG_UNUSED(ecx);
return edx & CPUID_SPEC_CTRL;
} }
static int static int spec_ctrl_init(struct device *dev)
disable_ssbd_if_needed(struct device *dev)
{ {
/* This is checked in runtime rather than compile time since ARG_UNUSED(dev);
* IA32_SPEC_CTRL_MSR might be added in a microcode update.
*/ u32_t enable_bits = 0;
if (cpu_has_spec_ctrl()) { u32_t cpuid7 = cpuid_extended_features();
#ifdef CONFIG_DISABLE_SSBD
if ((cpuid7 & CPUID_SPEC_CTRL_SSBD) != 0) {
enable_bits |= SPEC_CTRL_SSBD;
}
#endif
#ifdef CONFIG_ENABLE_EXTENDED_IBRS
if ((cpuid7 & CPUID_SPEC_CTRL_IBRS) != 0) {
enable_bits |= SPEC_CTRL_IBRS;
}
#endif
if (enable_bits != 0) {
u64_t cur = _x86_msr_read(IA32_SPEC_CTRL_MSR); u64_t cur = _x86_msr_read(IA32_SPEC_CTRL_MSR);
_x86_msr_write(IA32_SPEC_CTRL_MSR, _x86_msr_write(IA32_SPEC_CTRL_MSR,
cur | SPEC_CTRL_SSBD); cur | enable_bits);
} }
ARG_UNUSED(dev);
return 0; return 0;
} }
SYS_INIT(disable_ssbd_if_needed, PRE_KERNEL_1, 0); SYS_INIT(spec_ctrl_init, PRE_KERNEL_1, 0);
#endif /* CONFIG_DISABLE_SSBD || CONFIG_ENABLE_EXTENDED_IBRS */