From: "Borislav Petkov (AMD)" bp@alien8.de
stable inclusion from stable-v5.10.190 commit b6fc2fbf89089ecfb8eb9a89a7fc91d444f4fec7 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I7WY4J CVE: CVE-2023-20588
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit 77245f1c3c6495521f6a3af082696ee2f8ce3921 upstream.
Under certain circumstances, an integer division by 0 which faults, can leave stale quotient data from a previous division operation on Zen1 microarchitectures.
Do a dummy division 0/1 before returning from the #DE exception handler in order to avoid any leaks of potentially sensitive data.
Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Cc: stable@kernel.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
Conflicts: arch/x86/include/asm/cpufeatures.h arch/x86/include/asm/processor.h arch/x86/kernel/cpu/amd.c
Signed-off-by: Jialin Zhang zhangjialin11@huawei.com --- arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/include/asm/processor.h | 2 ++ arch/x86/kernel/cpu/amd.c | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+)
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 8d591cb0521d..999badbcd2ba 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -435,5 +435,6 @@ #define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* EIBRS is vulnerable to Post Barrier RSB Pre dictions */ #define X86_BUG_GDS X86_BUG(29) /* CPU is affected by Gather Data Sampling */ #define X86_BUG_SMT_RSB X86_BUG(30) /* CPU is vulnerable to Cross-Thread Return Address Predictions */ +#define X86_BUG_DIV0 X86_BUG(31) /* AMD DIV0 speculation bug */
#endif /* _ASM_X86_CPUFEATURES_H */ diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index d725573d957e..b5b92fd35527 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -958,9 +958,11 @@ static inline int mpx_disable_management(void) #ifdef CONFIG_CPU_SUP_AMD extern u16 amd_get_nb_id(int cpu); extern u32 amd_get_nodes_per_socket(void); +extern void amd_clear_divider(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) { } #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 a93262a600be..3abcc656d27f 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -26,6 +26,7 @@ static const int amd_erratum_383[]; static const int amd_erratum_400[]; static const int amd_zenbleed[]; +static const int amd_div0[]; static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum);
/* @@ -1038,6 +1039,11 @@ static void init_amd(struct cpuinfo_x86 *c) check_null_seg_clears_base(c);
zenbleed_check(c); + + if (cpu_has_amd_erratum(c, amd_div0)) { + pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n"); + setup_force_cpu_bug(X86_BUG_DIV0); + } }
#ifdef CONFIG_X86_32 @@ -1171,6 +1177,10 @@ static const int amd_zenbleed[] = AMD_MODEL_RANGE(0x17, 0x90, 0x0, 0x91, 0xf), AMD_MODEL_RANGE(0x17, 0xa0, 0x0, 0xaf, 0xf));
+static const int amd_div0[] = + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x00, 0x0, 0x2f, 0xf), + AMD_MODEL_RANGE(0x17, 0x50, 0x0, 0x5f, 0xf)); + static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) { int osvw_id = *erratum++; @@ -1232,3 +1242,13 @@ void amd_check_microcode(void) { on_each_cpu(zenbleed_check_cpu, NULL, 1); } + +/* + * Issue a DIV 0/1 insn to clear any division data from previous DIV + * operations. + */ +void amd_clear_divider(void) +{ + asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0) + :: "a" (0), "d" (0), "r" (1)); +}