]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - arch/x86/kernel/traps.c
UBUNTU: SAUCE: Synchronize MDS mitigations with upstream
[mirror_ubuntu-bionic-kernel.git] / arch / x86 / kernel / traps.c
index 446c9ef8cfc32b68d77d4429128b3c794b3fc069..20542b1a788a9a7e5f07758a852ba9e13991a6a0 100644 (file)
@@ -58,6 +58,7 @@
 #include <asm/alternative.h>
 #include <asm/fpu/xstate.h>
 #include <asm/trace/mpx.h>
+#include <asm/nospec-branch.h>
 #include <asm/mpx.h>
 #include <asm/vm86.h>
 #include <asm/umip.h>
@@ -181,7 +182,7 @@ int fixup_bug(struct pt_regs *regs, int trapnr)
                break;
 
        case BUG_TRAP_TYPE_WARN:
-               regs->ip += LEN_UD0;
+               regs->ip += LEN_UD2;
                return 1;
        }
 
@@ -386,6 +387,13 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
                regs->ip = (unsigned long)general_protection;
                regs->sp = (unsigned long)&gpregs->orig_ax;
 
+               /*
+                * This situation can be triggered by userspace via
+                * modify_ldt(2) and the return does not take the regular
+                * user space exit, so a CPU buffer clear is required when
+                * MDS mitigation is enabled.
+                */
+               mds_user_clear_cpu_buffers();
                return;
        }
 #endif
@@ -577,7 +585,6 @@ do_general_protection(struct pt_regs *regs, long error_code)
 }
 NOKPROBE_SYMBOL(do_general_protection);
 
-/* May run on IST stack. */
 dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
 {
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -592,6 +599,13 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
        if (poke_int3_handler(regs))
                return;
 
+       /*
+        * Use ist_enter despite the fact that we don't use an IST stack.
+        * We can be called from a kprobe in non-CONTEXT_KERNEL kernel
+        * mode or even during context tracking state changes.
+        *
+        * This means that we can't schedule.  That's okay.
+        */
        ist_enter(regs);
        RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
@@ -609,15 +623,10 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
                        SIGTRAP) == NOTIFY_STOP)
                goto exit;
 
-       /*
-        * Let others (NMI) know that the debug stack is in use
-        * as we may switch to the interrupt stack.
-        */
-       debug_stack_usage_inc();
        cond_local_irq_enable(regs);
        do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL);
        cond_local_irq_disable(regs);
-       debug_stack_usage_dec();
+
 exit:
        ist_exit(regs);
 }
@@ -833,16 +842,18 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr)
        char *str = (trapnr == X86_TRAP_MF) ? "fpu exception" :
                                                "simd exception";
 
-       if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP)
-               return;
        cond_local_irq_enable(regs);
 
        if (!user_mode(regs)) {
-               if (!fixup_exception(regs, trapnr)) {
-                       task->thread.error_code = error_code;
-                       task->thread.trap_nr = trapnr;
+               if (fixup_exception(regs, trapnr))
+                       return;
+
+               task->thread.error_code = error_code;
+               task->thread.trap_nr = trapnr;
+
+               if (notify_die(DIE_TRAP, str, regs, error_code,
+                                       trapnr, SIGFPE) != NOTIFY_STOP)
                        die(str, regs, error_code);
-               }
                return;
        }