diff --git a/arch/x86/core/CMakeLists.txt b/arch/x86/core/CMakeLists.txt index cf5603809a8..425f98a0440 100644 --- a/arch/x86/core/CMakeLists.txt +++ b/arch/x86/core/CMakeLists.txt @@ -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) diff --git a/arch/x86/core/Kconfig b/arch/x86/core/Kconfig index b14705f80ad..ba155dde940 100644 --- a/arch/x86/core/Kconfig +++ b/arch/x86/core/Kconfig @@ -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 diff --git a/arch/x86/core/spec_ctrl.c b/arch/x86/core/spec_ctrl.c index cc8c917f0ce..b887d1ddd0d 100644 --- a/arch/x86/core/spec_ctrl.c +++ b/arch/x86/core/spec_ctrl.c @@ -12,44 +12,60 @@ #include #include +/* + * 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 */