Merge tag 'x86-splitlock-2020-03-30' of git://git.kernel.org/pub/scm/linux/kernel...
[platform/kernel/linux-rpi.git] / arch / x86 / kernel / traps.c
index c0bc9df..d54cffd 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/traps.h>
 #include <asm/desc.h>
 #include <asm/fpu/internal.h>
+#include <asm/cpu.h>
 #include <asm/cpu_entry_area.h>
 #include <asm/mce.h>
 #include <asm/fixmap.h>
@@ -242,7 +243,6 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
 {
        struct task_struct *tsk = current;
 
-
        if (!do_trap_no_signal(tsk, trapnr, str, regs, error_code))
                return;
 
@@ -288,9 +288,29 @@ DO_ERROR(X86_TRAP_OLD_MF, SIGFPE,           0, NULL, "coprocessor segment overru
 DO_ERROR(X86_TRAP_TS,     SIGSEGV,          0, NULL, "invalid TSS",         invalid_TSS)
 DO_ERROR(X86_TRAP_NP,     SIGBUS,           0, NULL, "segment not present", segment_not_present)
 DO_ERROR(X86_TRAP_SS,     SIGBUS,           0, NULL, "stack segment",       stack_segment)
-DO_ERROR(X86_TRAP_AC,     SIGBUS,  BUS_ADRALN, NULL, "alignment check",     alignment_check)
 #undef IP
 
+dotraplinkage void do_alignment_check(struct pt_regs *regs, long error_code)
+{
+       char *str = "alignment check";
+
+       RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+
+       if (notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_AC, SIGBUS) == NOTIFY_STOP)
+               return;
+
+       if (!user_mode(regs))
+               die("Split lock detected\n", regs, error_code);
+
+       local_irq_enable();
+
+       if (handle_user_split_lock(regs, error_code))
+               return;
+
+       do_trap(X86_TRAP_AC, SIGBUS, "alignment check", regs,
+               error_code, BUS_ADRALN, NULL);
+}
+
 #ifdef CONFIG_VMAP_STACK
 __visible void __noreturn handle_stack_overflow(const char *message,
                                                struct pt_regs *regs,