提交 5841266c 编写于 作者: W Wu Liliu 提交者: guzitao

sw64: reimplement die_if_kernel()

Sunway inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I56OLG

--------------------------------

In the original implementation, incorrent printing may occur when
multiple processes die at the same time. To fix this, we use lock.
Signed-off-by: NWu Liliu <wuliliu@wxiat.com>
Signed-off-by: NGu Zitao <guzitao@wxiat.com>
上级 0f449948
...@@ -13,7 +13,7 @@ extern int ptrace_cancel_bpt(struct task_struct *child); ...@@ -13,7 +13,7 @@ extern int ptrace_cancel_bpt(struct task_struct *child);
/* traps.c */ /* traps.c */
extern void dik_show_regs(struct pt_regs *regs); extern void dik_show_regs(struct pt_regs *regs);
extern void die_if_kernel(char *str, struct pt_regs *regs, long err); extern void die(char *str, struct pt_regs *regs, long err);
/* timer.c */ /* timer.c */
extern void setup_timer(void); extern void setup_timer(void);
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
#include <linux/sched/debug.h> #include <linux/sched/debug.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <asm/gentrap.h> #include <asm/gentrap.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
...@@ -75,33 +77,47 @@ dik_show_code(unsigned int *pc) ...@@ -75,33 +77,47 @@ dik_show_code(unsigned int *pc)
printk("\n"); printk("\n");
} }
void die_if_kernel(char *str, struct pt_regs *regs, long err) static DEFINE_SPINLOCK(die_lock);
void die(char *str, struct pt_regs *regs, long err)
{ {
if (user_mode(regs)) static int die_counter;
return; unsigned long flags;
int ret;
oops_enter();
spin_lock_irqsave(&die_lock, flags);
console_verbose();
bust_spinlocks(1);
pr_emerg("%s [#%d]\n", str, ++die_counter);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
printk("CPU %d ", hard_smp_processor_id()); printk("CPU %d ", hard_smp_processor_id());
#endif #endif
printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err); printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
ret = notify_die(DIE_OOPS, str, regs, err, 0, SIGSEGV);
print_modules();
dik_show_regs(regs); dik_show_regs(regs);
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
show_stack(current, NULL, KERN_EMERG); show_stack(current, NULL, KERN_EMERG);
dik_show_code((unsigned int *)regs->pc);
if (test_and_set_thread_flag(TIF_DIE_IF_KERNEL)) { bust_spinlocks(0);
printk("die_if_kernel recursion detected.\n"); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
local_irq_enable(); spin_unlock_irqrestore(&die_lock, flags);
while (1) oops_exit();
asm("nop");
}
if (kexec_should_crash(current)) if (kexec_should_crash(current))
crash_kexec(regs); crash_kexec(regs);
if (in_interrupt())
panic("Fatal exception in interrupt");
if (panic_on_oops) if (panic_on_oops)
panic("Fatal exception"); panic("Fatal exception");
do_exit(SIGSEGV); if (ret != NOTIFY_STOP)
do_exit(SIGSEGV);
} }
#ifndef CONFIG_MATHEMU #ifndef CONFIG_MATHEMU
...@@ -135,7 +151,9 @@ do_entArith(unsigned long summary, unsigned long write_mask, ...@@ -135,7 +151,9 @@ do_entArith(unsigned long summary, unsigned long write_mask,
if (si_code == 0) if (si_code == 0)
return; return;
} }
die_if_kernel("Arithmetic fault", regs, 0);
if (!user_mode(regs))
die("Arithmetic fault", regs, 0);
force_sig_fault(SIGFPE, si_code, (void __user *)regs->pc, 0); force_sig_fault(SIGFPE, si_code, (void __user *)regs->pc, 0);
} }
...@@ -161,7 +179,7 @@ do_entIF(unsigned long inst_type, struct pt_regs *regs) ...@@ -161,7 +179,7 @@ do_entIF(unsigned long inst_type, struct pt_regs *regs)
notify_die(0, "kgdb trap", regs, 0, 0, SIGTRAP); notify_die(0, "kgdb trap", regs, 0, 0, SIGTRAP);
return; return;
} }
die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"), die((type == 1 ? "Kernel Bug" : "Instruction fault"),
regs, type); regs, type);
} }
...@@ -254,7 +272,7 @@ do_entIF(unsigned long inst_type, struct pt_regs *regs) ...@@ -254,7 +272,7 @@ do_entIF(unsigned long inst_type, struct pt_regs *regs)
return; return;
} }
if (!user_mode(regs)) if (!user_mode(regs))
die_if_kernel("Instruction fault", regs, type); die("Instruction fault", regs, type);
break; break;
case 3: /* FEN fault */ case 3: /* FEN fault */
......
...@@ -31,7 +31,7 @@ static inline int notify_page_fault(struct pt_regs *regs, unsigned long mmcsr) ...@@ -31,7 +31,7 @@ static inline int notify_page_fault(struct pt_regs *regs, unsigned long mmcsr)
} }
#endif #endif
extern void die_if_kernel(char *, struct pt_regs *, long); extern void die(char *, struct pt_regs *, long);
extern void dik_show_regs(struct pt_regs *regs); extern void dik_show_regs(struct pt_regs *regs);
void show_all_vma(void) void show_all_vma(void)
...@@ -301,7 +301,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, ...@@ -301,7 +301,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
*/ */
pr_alert("Unable to handle kernel paging request at virtual address %016lx\n", pr_alert("Unable to handle kernel paging request at virtual address %016lx\n",
address); address);
die_if_kernel("Oops", regs, cause); die("Oops", regs, cause);
do_exit(SIGKILL); do_exit(SIGKILL);
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册