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:
parent
e27ce67d25
commit
10040f603d
3 changed files with 47 additions and 22 deletions
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 CPUID_SPEC_CTRL_SSBD BIT(31)
|
||||||
|
#define CPUID_SPEC_CTRL_IBRS BIT(26)
|
||||||
|
|
||||||
|
/* Bits to set in IA32_SPEC_CTRL_MSR to enable */
|
||||||
|
#define SPEC_CTRL_IBRS BIT(0)
|
||||||
#define SPEC_CTRL_SSBD BIT(2)
|
#define SPEC_CTRL_SSBD BIT(2)
|
||||||
|
|
||||||
static int
|
#if defined(CONFIG_DISABLE_SSBD) || defined(CONFIG_ENABLE_EXTENDED_IBRS)
|
||||||
cpu_has_spec_ctrl(void)
|
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 */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue