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
sys_fatal_error_handler.c
thread.c
spec_ctrl.c
)
zephyr_library_sources_if_kconfig( irq_offload.c)
zephyr_library_sources_if_kconfig( x86_mmu.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_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
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
bool "Build with retpolines enabled in x86 assembly code"
depends on USERSPACE

View file

@ -12,44 +12,60 @@
#include <kernel_arch_func.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_SPEC_CTRL BIT(31)
#define SPEC_CTRL_SSBD BIT(2)
/* Bits to check in CPUID extended features */
#define CPUID_SPEC_CTRL_SSBD BIT(31)
#define CPUID_SPEC_CTRL_IBRS BIT(26)
static int
cpu_has_spec_ctrl(void)
/* Bits to set in IA32_SPEC_CTRL_MSR to enable */
#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;
if (!__get_cpuid(CPUID_EXTENDED_FEATURES_LVL,
&eax, &ebx, &ecx, &edx)) {
if (__get_cpuid(CPUID_EXTENDED_FEATURES_LVL,
&eax, &ebx, &ecx, &edx) == 0) {
return 0;
}
ARG_UNUSED(eax);
ARG_UNUSED(ebx);
ARG_UNUSED(ecx);
return edx & CPUID_SPEC_CTRL;
return edx;
}
static int
disable_ssbd_if_needed(struct device *dev)
static int spec_ctrl_init(struct device *dev)
{
/* This is checked in runtime rather than compile time since
* IA32_SPEC_CTRL_MSR might be added in a microcode update.
*/
if (cpu_has_spec_ctrl()) {
ARG_UNUSED(dev);
u32_t enable_bits = 0;
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);
_x86_msr_write(IA32_SPEC_CTRL_MSR,
cur | SPEC_CTRL_SSBD);
cur | enable_bits);
}
ARG_UNUSED(dev);
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 */