mainline inclusion from mainline-v6.12-rc5 commit 86e6b1547b3d013bc392adf775b89318441403c2 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IB2BWT CVE: CVE-2024-50102
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
Revert "x86/srso: Fix vulnerability reporting for missing microcode"
This reverts commit ae070226773a7937f3fd39031b191fde26bdf9c9.
Revert "x86/srso: Don't probe microcode in a guest"
This reverts commit 09c5239e6f37d4662387bb769fa586f3801b05b8.
Revert "x86/srso: Set CPUID feature bits independently of bug or mitigation status"
This reverts commit 49bd6ecf52538402dd47e98ca8017398249e4cba. --- Documentation/admin-guide/hw-vuln/srso.rst | 19 +++------ arch/x86/include/asm/processor.h | 2 + arch/x86/kernel/cpu/amd.c | 28 +++++++++---- arch/x86/kernel/cpu/bugs.c | 49 ++++++++++++---------- 4 files changed, 53 insertions(+), 45 deletions(-)
diff --git a/Documentation/admin-guide/hw-vuln/srso.rst b/Documentation/admin-guide/hw-vuln/srso.rst index 33d9108affa7..f79cb11b080f 100644 --- a/Documentation/admin-guide/hw-vuln/srso.rst +++ b/Documentation/admin-guide/hw-vuln/srso.rst @@ -44,19 +44,12 @@ The possible values in this file are:
- 'Not affected' The processor is not vulnerable
- - 'Vulnerable' The processor is vulnerable and no mitigations have been applied. - 'Vulnerable: no microcode' The processor is vulnerable, no microcode extending IBPB functionality to address the vulnerability has been applied. - - 'Vulnerable: Safe RET, no microcode' - The "Safe RET" mitigation (see below) has - been applied to protect the kernel, but the - IBPB-extending microcode has not been applied. - User space tasks may still be vulnerable. - - - 'Vulnerable: Microcode, no safe RET' - Extended IBPB functionality microcode + + - 'Mitigation: microcode' Extended IBPB functionality microcode patch has been applied. It does not address User->Kernel and Guest->Host transitions protection but it does @@ -65,9 +58,9 @@ The possible values in this file are:
(spec_rstack_overflow=microcode)
- - 'Mitigation: Safe RET' Combined microcode/software mitigation. - It complements the extended IBPB microcode - patch functionality by addressing User->Kernel + - 'Mitigation: safe RET' Software-only mitigation. It complements + the extended IBPB microcode patch + functionality by addressing User->Kernel and Guest->Host transitions protection.
Selected by default or by @@ -119,7 +112,7 @@ an indrect branch prediction barrier after having applied the required microcode patch for one's system. This mitigation comes also at a performance cost.
-Mitigation: Safe RET +Mitigation: safe RET --------------------
The mitigation works by ensuring all RET instructions speculate to diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 920c76eca146..4a9cb0c2d580 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -839,10 +839,12 @@ extern u16 get_llc_id(unsigned int cpu); extern u16 amd_get_nb_id(int cpu); extern u32 amd_get_nodes_per_socket(void); extern void amd_clear_divider(void); +extern bool cpu_has_ibpb_brtype_microcode(void); #else static inline u16 amd_get_nb_id(int cpu) { return 0; } static inline u32 amd_get_nodes_per_socket(void) { return 0; } static inline void amd_clear_divider(void) { } +static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; } #endif
static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 688c9ca69852..006bb73d985c 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -783,15 +783,6 @@ static void early_init_amd(struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_TOPOEXT)) smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1; - - if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && !cpu_has(c, X86_FEATURE_IBPB_BRTYPE)) { - if (c->x86 == 0x17 && boot_cpu_has(X86_FEATURE_AMD_IBPB)) - setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); - else if (c->x86 >= 0x19 && !wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { - setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); - setup_force_cpu_cap(X86_FEATURE_SBPB); - } - } }
static void init_amd_k8(struct cpuinfo_x86 *c) @@ -1335,6 +1326,25 @@ void set_dr_addr_mask(unsigned long mask, int dr) } }
+bool cpu_has_ibpb_brtype_microcode(void) +{ + switch (boot_cpu_data.x86) { + /* Zen1/2 IBPB flushes branch type predictions too. */ + case 0x17: + return boot_cpu_has(X86_FEATURE_AMD_IBPB); + case 0x19: + /* Poke the MSR bit on Zen3/4 to check its presence. */ + if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { + setup_force_cpu_cap(X86_FEATURE_SBPB); + return true; + } else { + return false; + } + default: + return false; + } +} + static void zenbleed_check_cpu(void *unused) { struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 7fa570534df8..cf6e6cb95940 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -2251,8 +2251,6 @@ early_param("l1tf", l1tf_cmdline);
enum srso_mitigation { SRSO_MITIGATION_NONE, - SRSO_MITIGATION_UCODE_NEEDED, - SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED, SRSO_MITIGATION_MICROCODE, SRSO_MITIGATION_SAFE_RET, SRSO_MITIGATION_IBPB, @@ -2268,13 +2266,11 @@ enum srso_mitigation_cmd { };
static const char * const srso_strings[] = { - [SRSO_MITIGATION_NONE] = "Vulnerable", - [SRSO_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode", - [SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED] = "Vulnerable: Safe RET, no microcode", - [SRSO_MITIGATION_MICROCODE] = "Vulnerable: Microcode, no safe RET", - [SRSO_MITIGATION_SAFE_RET] = "Mitigation: Safe RET", - [SRSO_MITIGATION_IBPB] = "Mitigation: IBPB", - [SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only" + [SRSO_MITIGATION_NONE] = "Vulnerable", + [SRSO_MITIGATION_MICROCODE] = "Mitigation: microcode", + [SRSO_MITIGATION_SAFE_RET] = "Mitigation: safe RET", + [SRSO_MITIGATION_IBPB] = "Mitigation: IBPB", + [SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only" };
static enum srso_mitigation srso_mitigation __ro_after_init = SRSO_MITIGATION_NONE; @@ -2306,12 +2302,26 @@ early_param("spec_rstack_overflow", srso_parse_cmdline);
static void __init srso_select_mitigation(void) { - bool has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE); + bool has_microcode;
if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off()) goto pred_cmd;
- if (has_microcode) { + /* + * The first check is for the kernel running as a guest in order + * for guests to verify whether IBPB is a viable mitigation. + */ + has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) || cpu_has_ibpb_brtype_microcode(); + if (!has_microcode) { + pr_warn("IBPB-extending microcode not applied!\n"); + pr_warn(SRSO_NOTICE); + } else { + /* + * Enable the synthetic (even if in a real CPUID leaf) + * flags for guests. + */ + setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); + /* * Zen1/2 with SMT off aren't vulnerable after the right * IBPB microcode has been applied. @@ -2328,12 +2338,6 @@ static void __init srso_select_mitigation(void) srso_mitigation = SRSO_MITIGATION_IBPB; goto pred_cmd; } - } else { - pr_warn("IBPB-extending microcode not applied!\n"); - pr_warn(SRSO_NOTICE); - - /* may be overwritten by SRSO_CMD_SAFE_RET below */ - srso_mitigation = SRSO_MITIGATION_UCODE_NEEDED; }
switch (srso_cmd) { @@ -2363,10 +2367,7 @@ static void __init srso_select_mitigation(void) setup_force_cpu_cap(X86_FEATURE_SRSO); x86_return_thunk = srso_return_thunk; } - if (has_microcode) - srso_mitigation = SRSO_MITIGATION_SAFE_RET; - else - srso_mitigation = SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED; + srso_mitigation = SRSO_MITIGATION_SAFE_RET; } else { pr_err("WARNING: kernel not compiled with CPU_SRSO.\n"); goto pred_cmd; @@ -2401,7 +2402,7 @@ static void __init srso_select_mitigation(void) break; }
- pr_info("%s\n", srso_strings[srso_mitigation]); + pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode"));
pred_cmd: if ((!boot_cpu_has_bug(X86_BUG_SRSO) || srso_cmd == SRSO_CMD_OFF) && @@ -2618,7 +2619,9 @@ static ssize_t srso_show_state(char *buf) if (boot_cpu_has(X86_FEATURE_SRSO_NO)) return sysfs_emit(buf, "Mitigation: SMT disabled\n");
- return sysfs_emit(buf, "%s\n", srso_strings[srso_mitigation]); + return sysfs_emit(buf, "%s%s\n", + srso_strings[srso_mitigation], + boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode"); }
static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,