From 3ed0dc37f6f690c74a14fbaaa86e94ce7827b7de Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Aug 2023 10:54:21 +0200 Subject: [PATCH] 5.15-stable patches added patches: x86-cpu-amd-do-not-leak-quotient-data-after-a-division-by-0.patch --- queue-5.15/series | 1 + ...-quotient-data-after-a-division-by-0.patch | 100 ++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 queue-5.15/x86-cpu-amd-do-not-leak-quotient-data-after-a-division-by-0.patch diff --git a/queue-5.15/series b/queue-5.15/series index f3d930b0982..570b8f9fadd 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -56,6 +56,7 @@ libceph-fix-potential-hang-in-ceph_osdc_notify.patch usb-zaurus-add-id-for-a-300-b-500-c-700.patch ceph-defer-stopping-mdsc-delayed_work.patch firmware-arm_scmi-drop-of-node-reference-in-the-transport-channel-setup.patch +x86-cpu-amd-do-not-leak-quotient-data-after-a-division-by-0.patch exfat-use-kvmalloc_array-kvfree-instead-of-kmalloc_array-kfree.patch exfat-release-s_lock-before-calling-dir_emit.patch mtd-spinand-toshiba-fix-ecc_get_status.patch diff --git a/queue-5.15/x86-cpu-amd-do-not-leak-quotient-data-after-a-division-by-0.patch b/queue-5.15/x86-cpu-amd-do-not-leak-quotient-data-after-a-division-by-0.patch new file mode 100644 index 00000000000..2da6c098a8e --- /dev/null +++ b/queue-5.15/x86-cpu-amd-do-not-leak-quotient-data-after-a-division-by-0.patch @@ -0,0 +1,100 @@ +From 77245f1c3c6495521f6a3af082696ee2f8ce3921 Mon Sep 17 00:00:00 2001 +From: "Borislav Petkov (AMD)" +Date: Sat, 5 Aug 2023 00:06:43 +0200 +Subject: x86/CPU/AMD: Do not leak quotient data after a division by 0 + +From: Borislav Petkov (AMD) + +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) +Cc: +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/cpufeatures.h | 1 + + arch/x86/include/asm/processor.h | 2 ++ + arch/x86/kernel/cpu/amd.c | 19 +++++++++++++++++++ + arch/x86/kernel/traps.c | 2 ++ + 4 files changed, 24 insertions(+) + +--- a/arch/x86/include/asm/cpufeatures.h ++++ b/arch/x86/include/asm/cpufeatures.h +@@ -465,4 +465,5 @@ + + /* BUG word 2 */ + #define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */ ++#define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */ + #endif /* _ASM_X86_CPUFEATURES_H */ +--- a/arch/x86/include/asm/processor.h ++++ b/arch/x86/include/asm/processor.h +@@ -804,10 +804,12 @@ extern u16 get_llc_id(unsigned int cpu); + extern u32 amd_get_nodes_per_socket(void); + extern u32 amd_get_highest_perf(void); + extern bool cpu_has_ibpb_brtype_microcode(void); ++extern void amd_clear_divider(void); + #else + static inline u32 amd_get_nodes_per_socket(void) { return 0; } + static inline u32 amd_get_highest_perf(void) { return 0; } + static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; } ++static inline void amd_clear_divider(void) { } + #endif + + static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves) +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -75,6 +75,10 @@ static const int amd_zenbleed[] = + AMD_MODEL_RANGE(0x17, 0x60, 0x0, 0x7f, 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++; +@@ -1140,6 +1144,11 @@ static void init_amd(struct cpuinfo_x86 + 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 +@@ -1300,3 +1309,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 noinstr amd_clear_divider(void) ++{ ++ asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0) ++ :: "a" (0), "d" (0), "r" (1)); ++} +--- a/arch/x86/kernel/traps.c ++++ b/arch/x86/kernel/traps.c +@@ -202,6 +202,8 @@ DEFINE_IDTENTRY(exc_divide_error) + { + do_error_trap(regs, 0, "divide error", X86_TRAP_DE, SIGFPE, + FPE_INTDIV, error_get_trap_addr(regs)); ++ ++ amd_clear_divider(); + } + + DEFINE_IDTENTRY(exc_overflow) -- 2.47.3