提交 3283d4d0 编写于 作者: P Pawan Gupta 提交者: Zheng Zengkai

x86/speculation: Add spectre_v2=ibrs option to support Kernel IBRS

stable inclusion
from stable-v5.10.133
commit dabc2a1b406ae0ff5286c91f7519b3e20ec2aa63
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5PTAS
CVE: CVE-2022-29900,CVE-2022-23816,CVE-2022-29901

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=dabc2a1b406ae0ff5286c91f7519b3e20ec2aa63

--------------------------------

commit 7c693f54 upstream.

Extend spectre_v2= boot option with Kernel IBRS.

  [jpoimboe: no STIBP with IBRS]
Signed-off-by: NPawan Gupta <pawan.kumar.gupta@linux.intel.com>
Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: NBorislav Petkov <bp@suse.de>
Reviewed-by: NJosh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: NBorislav Petkov <bp@suse.de>
Signed-off-by: NThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Signed-off-by: NBen Hutchings <ben@decadent.org.uk>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NLin Yujun <linyujun809@huawei.com>
Reviewed-by: NZhang Jianhua <chris.zjh@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 18de7ac7
...@@ -5201,6 +5201,7 @@ ...@@ -5201,6 +5201,7 @@
eibrs - enhanced IBRS eibrs - enhanced IBRS
eibrs,retpoline - enhanced IBRS + Retpolines eibrs,retpoline - enhanced IBRS + Retpolines
eibrs,lfence - enhanced IBRS + LFENCE eibrs,lfence - enhanced IBRS + LFENCE
ibrs - use IBRS to protect kernel
Not specifying this option is equivalent to Not specifying this option is equivalent to
spectre_v2=auto. spectre_v2=auto.
......
...@@ -219,6 +219,7 @@ enum spectre_v2_mitigation { ...@@ -219,6 +219,7 @@ enum spectre_v2_mitigation {
SPECTRE_V2_EIBRS, SPECTRE_V2_EIBRS,
SPECTRE_V2_EIBRS_RETPOLINE, SPECTRE_V2_EIBRS_RETPOLINE,
SPECTRE_V2_EIBRS_LFENCE, SPECTRE_V2_EIBRS_LFENCE,
SPECTRE_V2_IBRS,
}; };
/* The indirect branch speculation control variants */ /* The indirect branch speculation control variants */
......
...@@ -928,6 +928,7 @@ enum spectre_v2_mitigation_cmd { ...@@ -928,6 +928,7 @@ enum spectre_v2_mitigation_cmd {
SPECTRE_V2_CMD_EIBRS, SPECTRE_V2_CMD_EIBRS,
SPECTRE_V2_CMD_EIBRS_RETPOLINE, SPECTRE_V2_CMD_EIBRS_RETPOLINE,
SPECTRE_V2_CMD_EIBRS_LFENCE, SPECTRE_V2_CMD_EIBRS_LFENCE,
SPECTRE_V2_CMD_IBRS,
}; };
enum spectre_v2_user_cmd { enum spectre_v2_user_cmd {
...@@ -1000,11 +1001,12 @@ spectre_v2_parse_user_cmdline(enum spectre_v2_mitigation_cmd v2_cmd) ...@@ -1000,11 +1001,12 @@ spectre_v2_parse_user_cmdline(enum spectre_v2_mitigation_cmd v2_cmd)
return SPECTRE_V2_USER_CMD_AUTO; return SPECTRE_V2_USER_CMD_AUTO;
} }
static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode) static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode)
{ {
return (mode == SPECTRE_V2_EIBRS || return mode == SPECTRE_V2_IBRS ||
mode == SPECTRE_V2_EIBRS_RETPOLINE || mode == SPECTRE_V2_EIBRS ||
mode == SPECTRE_V2_EIBRS_LFENCE); mode == SPECTRE_V2_EIBRS_RETPOLINE ||
mode == SPECTRE_V2_EIBRS_LFENCE;
} }
static void __init static void __init
...@@ -1069,12 +1071,12 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) ...@@ -1069,12 +1071,12 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
} }
/* /*
* If no STIBP, enhanced IBRS is enabled or SMT impossible, STIBP is not * If no STIBP, IBRS or enhanced IBRS is enabled, or SMT impossible,
* required. * STIBP is not required.
*/ */
if (!boot_cpu_has(X86_FEATURE_STIBP) || if (!boot_cpu_has(X86_FEATURE_STIBP) ||
!smt_possible || !smt_possible ||
spectre_v2_in_eibrs_mode(spectre_v2_enabled)) spectre_v2_in_ibrs_mode(spectre_v2_enabled))
return; return;
/* /*
...@@ -1106,6 +1108,7 @@ static const char * const spectre_v2_strings[] = { ...@@ -1106,6 +1108,7 @@ static const char * const spectre_v2_strings[] = {
[SPECTRE_V2_EIBRS] = "Mitigation: Enhanced IBRS", [SPECTRE_V2_EIBRS] = "Mitigation: Enhanced IBRS",
[SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced IBRS + LFENCE", [SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced IBRS + LFENCE",
[SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced IBRS + Retpolines", [SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced IBRS + Retpolines",
[SPECTRE_V2_IBRS] = "Mitigation: IBRS",
}; };
static const struct { static const struct {
...@@ -1123,6 +1126,7 @@ static const struct { ...@@ -1123,6 +1126,7 @@ static const struct {
{ "eibrs,lfence", SPECTRE_V2_CMD_EIBRS_LFENCE, false }, { "eibrs,lfence", SPECTRE_V2_CMD_EIBRS_LFENCE, false },
{ "eibrs,retpoline", SPECTRE_V2_CMD_EIBRS_RETPOLINE, false }, { "eibrs,retpoline", SPECTRE_V2_CMD_EIBRS_RETPOLINE, false },
{ "auto", SPECTRE_V2_CMD_AUTO, false }, { "auto", SPECTRE_V2_CMD_AUTO, false },
{ "ibrs", SPECTRE_V2_CMD_IBRS, false },
}; };
static void __init spec_v2_print_cond(const char *reason, bool secure) static void __init spec_v2_print_cond(const char *reason, bool secure)
...@@ -1185,6 +1189,24 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) ...@@ -1185,6 +1189,24 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
return SPECTRE_V2_CMD_AUTO; return SPECTRE_V2_CMD_AUTO;
} }
if (cmd == SPECTRE_V2_CMD_IBRS && boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) {
pr_err("%s selected but not Intel CPU. Switching to AUTO select\n",
mitigation_options[i].option);
return SPECTRE_V2_CMD_AUTO;
}
if (cmd == SPECTRE_V2_CMD_IBRS && !boot_cpu_has(X86_FEATURE_IBRS)) {
pr_err("%s selected but CPU doesn't have IBRS. Switching to AUTO select\n",
mitigation_options[i].option);
return SPECTRE_V2_CMD_AUTO;
}
if (cmd == SPECTRE_V2_CMD_IBRS && boot_cpu_has(X86_FEATURE_XENPV)) {
pr_err("%s selected but running as XenPV guest. Switching to AUTO select\n",
mitigation_options[i].option);
return SPECTRE_V2_CMD_AUTO;
}
spec_v2_print_cond(mitigation_options[i].option, spec_v2_print_cond(mitigation_options[i].option,
mitigation_options[i].secure); mitigation_options[i].secure);
return cmd; return cmd;
...@@ -1224,6 +1246,14 @@ static void __init spectre_v2_select_mitigation(void) ...@@ -1224,6 +1246,14 @@ static void __init spectre_v2_select_mitigation(void)
break; break;
} }
if (boot_cpu_has_bug(X86_BUG_RETBLEED) &&
retbleed_cmd != RETBLEED_CMD_OFF &&
boot_cpu_has(X86_FEATURE_IBRS) &&
boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
mode = SPECTRE_V2_IBRS;
break;
}
mode = spectre_v2_select_retpoline(); mode = spectre_v2_select_retpoline();
break; break;
...@@ -1240,6 +1270,10 @@ static void __init spectre_v2_select_mitigation(void) ...@@ -1240,6 +1270,10 @@ static void __init spectre_v2_select_mitigation(void)
mode = spectre_v2_select_retpoline(); mode = spectre_v2_select_retpoline();
break; break;
case SPECTRE_V2_CMD_IBRS:
mode = SPECTRE_V2_IBRS;
break;
case SPECTRE_V2_CMD_EIBRS: case SPECTRE_V2_CMD_EIBRS:
mode = SPECTRE_V2_EIBRS; mode = SPECTRE_V2_EIBRS;
break; break;
...@@ -1256,7 +1290,7 @@ static void __init spectre_v2_select_mitigation(void) ...@@ -1256,7 +1290,7 @@ static void __init spectre_v2_select_mitigation(void)
if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
pr_err(SPECTRE_V2_EIBRS_EBPF_MSG); pr_err(SPECTRE_V2_EIBRS_EBPF_MSG);
if (spectre_v2_in_eibrs_mode(mode)) { if (spectre_v2_in_ibrs_mode(mode)) {
/* Force it so VMEXIT will restore correctly */ /* Force it so VMEXIT will restore correctly */
x86_spec_ctrl_base |= SPEC_CTRL_IBRS; x86_spec_ctrl_base |= SPEC_CTRL_IBRS;
write_spec_ctrl_current(x86_spec_ctrl_base, true); write_spec_ctrl_current(x86_spec_ctrl_base, true);
...@@ -1267,6 +1301,10 @@ static void __init spectre_v2_select_mitigation(void) ...@@ -1267,6 +1301,10 @@ static void __init spectre_v2_select_mitigation(void)
case SPECTRE_V2_EIBRS: case SPECTRE_V2_EIBRS:
break; break;
case SPECTRE_V2_IBRS:
setup_force_cpu_cap(X86_FEATURE_KERNEL_IBRS);
break;
case SPECTRE_V2_LFENCE: case SPECTRE_V2_LFENCE:
case SPECTRE_V2_EIBRS_LFENCE: case SPECTRE_V2_EIBRS_LFENCE:
setup_force_cpu_cap(X86_FEATURE_RETPOLINE_LFENCE); setup_force_cpu_cap(X86_FEATURE_RETPOLINE_LFENCE);
...@@ -1293,17 +1331,17 @@ static void __init spectre_v2_select_mitigation(void) ...@@ -1293,17 +1331,17 @@ static void __init spectre_v2_select_mitigation(void)
pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n"); pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n");
/* /*
* Retpoline means the kernel is safe because it has no indirect * Retpoline protects the kernel, but doesn't protect firmware. IBRS
* branches. Enhanced IBRS protects firmware too, so, enable restricted * and Enhanced IBRS protect firmware too, so enable IBRS around
* speculation around firmware calls only when Enhanced IBRS isn't * firmware calls only when IBRS / Enhanced IBRS aren't otherwise
* supported. * enabled.
* *
* Use "mode" to check Enhanced IBRS instead of boot_cpu_has(), because * Use "mode" to check Enhanced IBRS instead of boot_cpu_has(), because
* the user might select retpoline on the kernel command line and if * the user might select retpoline on the kernel command line and if
* the CPU supports Enhanced IBRS, kernel might un-intentionally not * the CPU supports Enhanced IBRS, kernel might un-intentionally not
* enable IBRS around firmware calls. * enable IBRS around firmware calls.
*/ */
if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_eibrs_mode(mode)) { if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_ibrs_mode(mode)) {
setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW); setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW);
pr_info("Enabling Restricted Speculation for firmware calls\n"); pr_info("Enabling Restricted Speculation for firmware calls\n");
} }
...@@ -2012,7 +2050,7 @@ static ssize_t mmio_stale_data_show_state(char *buf) ...@@ -2012,7 +2050,7 @@ static ssize_t mmio_stale_data_show_state(char *buf)
static char *stibp_state(void) static char *stibp_state(void)
{ {
if (spectre_v2_in_eibrs_mode(spectre_v2_enabled)) if (spectre_v2_in_ibrs_mode(spectre_v2_enabled))
return ""; return "";
switch (spectre_v2_user_stibp) { switch (spectre_v2_user_stibp) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册