Merge patch series "RISC-V: Align the shadow stack"
[sfrench/cifs-2.6.git] / arch / riscv / kernel / traps.c
index 336d4aadadb1cd357ed340870f0e7c9bf44e409d..549bde5c970a13e9412148c7c45aca1ef2034825 100644 (file)
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/irq.h>
+#include <linux/kexec.h>
 
 #include <asm/asm-prototypes.h>
 #include <asm/bug.h>
+#include <asm/csr.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
-#include <asm/csr.h>
+#include <asm/thread_info.h>
 
 int show_unhandled_signals = 1;
 
@@ -31,6 +33,7 @@ void die(struct pt_regs *regs, const char *str)
 {
        static int die_counter;
        int ret;
+       long cause;
 
        oops_enter();
 
@@ -40,9 +43,14 @@ void die(struct pt_regs *regs, const char *str)
 
        pr_emerg("%s [#%d]\n", str, ++die_counter);
        print_modules();
-       show_regs(regs);
+       if (regs)
+               show_regs(regs);
 
-       ret = notify_die(DIE_OOPS, str, regs, 0, regs->cause, SIGSEGV);
+       cause = regs ? regs->cause : -1;
+       ret = notify_die(DIE_OOPS, str, regs, 0, cause, SIGSEGV);
+
+       if (kexec_should_crash(current))
+               crash_kexec(regs);
 
        bust_spinlocks(0);
        add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
@@ -54,7 +62,7 @@ void die(struct pt_regs *regs, const char *str)
        if (panic_on_oops)
                panic("Fatal exception");
        if (ret != NOTIFY_STOP)
-               do_exit(SIGSEGV);
+               make_task_dead(SIGSEGV);
 }
 
 void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
@@ -86,8 +94,13 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,
        }
 }
 
+#if defined(CONFIG_XIP_KERNEL) && defined(CONFIG_RISCV_ALTERNATIVE)
+#define __trap_section         __section(".xip.traps")
+#else
+#define __trap_section
+#endif
 #define DO_ERROR_INFO(name, signo, code, str)                          \
-asmlinkage __visible void name(struct pt_regs *regs)                   \
+asmlinkage __visible __trap_section void name(struct pt_regs *regs)    \
 {                                                                      \
        do_trap_error(regs, signo, code, regs->epc, "Oops - " str);     \
 }
@@ -111,7 +124,7 @@ DO_ERROR_INFO(do_trap_store_misaligned,
 int handle_misaligned_load(struct pt_regs *regs);
 int handle_misaligned_store(struct pt_regs *regs);
 
-asmlinkage void do_trap_load_misaligned(struct pt_regs *regs)
+asmlinkage void __trap_section do_trap_load_misaligned(struct pt_regs *regs)
 {
        if (!handle_misaligned_load(regs))
                return;
@@ -119,7 +132,7 @@ asmlinkage void do_trap_load_misaligned(struct pt_regs *regs)
                      "Oops - load address misaligned");
 }
 
-asmlinkage void do_trap_store_misaligned(struct pt_regs *regs)
+asmlinkage void __trap_section do_trap_store_misaligned(struct pt_regs *regs)
 {
        if (!handle_misaligned_store(regs))
                return;
@@ -146,7 +159,7 @@ static inline unsigned long get_break_insn_length(unsigned long pc)
        return GET_INSN_LENGTH(insn);
 }
 
-asmlinkage __visible void do_trap_break(struct pt_regs *regs)
+asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs)
 {
 #ifdef CONFIG_KPROBES
        if (kprobe_single_step_handler(regs))
@@ -194,11 +207,6 @@ int is_valid_bugaddr(unsigned long pc)
 }
 #endif /* CONFIG_GENERIC_BUG */
 
-/* stvec & scratch is already set from head.S */
-void __init trap_init(void)
-{
-}
-
 #ifdef CONFIG_VMAP_STACK
 /*
  * Extra stack space that allows us to provide panic messages when the kernel