]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
x86/CPU/AMD: Fix the DIV(0) initial fix attempt
authorBorislav Petkov (AMD) <bp@alien8.de>
Fri, 11 Aug 2023 21:38:24 +0000 (23:38 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 26 Aug 2023 12:23:40 +0000 (14:23 +0200)
commit f58d6fbcb7c848b7f2469be339bc571f2e9d245b upstream.

Initially, it was thought that doing an innocuous division in the #DE
handler would take care to prevent any leaking of old data from the
divider but by the time the fault is raised, the speculation has already
advanced too far and such data could already have been used by younger
operations.

Therefore, do the innocuous division on every exit to userspace so that
userspace doesn't see any potentially old data from integer divisions in
kernel space.

Do the same before VMRUN too, to protect host data from leaking into the
guest too.

Fixes: 77245f1c3c64 ("x86/CPU/AMD: Do not leak quotient data after a division by 0")
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Cc: <stable@kernel.org>
Link: https://lore.kernel.org/r/20230811213824.10025-1-bp@alien8.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/include/asm/entry-common.h
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/traps.c
arch/x86/kvm/svm/svm.c

index 43184640b579a45565919801e8a23a2301e69017..a12fdf01dc2601ae613d256e2afea1dd2a0617d6 100644 (file)
@@ -92,6 +92,7 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
 static __always_inline void arch_exit_to_user_mode(void)
 {
        mds_user_clear_cpu_buffers();
+       amd_clear_divider();
 }
 #define arch_exit_to_user_mode arch_exit_to_user_mode
 
index 0ca7123417aba8fba4be787c88815245e1bc6e0f..0a0230bd5089a55c37e206c647d012b605449dce 100644 (file)
@@ -1320,3 +1320,4 @@ void noinstr amd_clear_divider(void)
        asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0)
                     :: "a" (0), "d" (0), "r" (1));
 }
+EXPORT_SYMBOL_GPL(amd_clear_divider);
index 3361d32d090f83aac071e3e347f4caee9c8ee00e..ca47080e37741f1913898c39587b532cabeb6b06 100644 (file)
@@ -202,8 +202,6 @@ 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)
index d63c3843e493519f484152dec43763af04665807..8e9a6c41f9eea18b97f8c0c7d602db44ceeeedb3 100644 (file)
@@ -1452,6 +1452,8 @@ static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu)
        struct vcpu_svm *svm = to_svm(vcpu);
        struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
 
+       amd_clear_divider();
+
        if (sev_es_guest(vcpu->kvm))
                sev_es_unmap_ghcb(svm);