Commit 6933c11f authored by Tiezhu Yang's avatar Tiezhu Yang Committed by Huacai Chen
Browse files

LoongArch: Do not kill the task in die() if notify_die() returns NOTIFY_STOP

If notify_die() returns NOTIFY_STOP, honor the return value from the
handler chain invocation in die() and return without killing the task
as, through a debugger, the fault may have been fixed. It makes sense
even if ignoring the event will make the system unstable: by allowing
access through a debugger it has been compromised already anyway. It
makes our port consistent with x86, arm64, riscv and csky.

Commit 20c0d2d4 ("[PATCH] i386: pass proper trap numbers to die
chain handlers") may be the earliest of similar changes.

Link: https://lore.kernel.org/r/43DDF02E.76F0.0078.0@novell.com/


Signed-off-by: default avatarTiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent a746ceb1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long val
#define instruction_pointer(regs) ((regs)->csr_era)
#define profile_pc(regs) instruction_pointer(regs)

extern void die(const char *, struct pt_regs *) __noreturn;
extern void die(const char *, struct pt_regs *);

static inline void die_if_kernel(const char *str, struct pt_regs *regs)
{
+6 −6
Original line number Diff line number Diff line
@@ -383,16 +383,15 @@ void show_registers(struct pt_regs *regs)

static DEFINE_RAW_SPINLOCK(die_lock);

void __noreturn die(const char *str, struct pt_regs *regs)
void die(const char *str, struct pt_regs *regs)
{
	int ret;
	static int die_counter;
	int sig = SIGSEGV;

	oops_enter();

	if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_nr,
		       SIGSEGV) == NOTIFY_STOP)
		sig = 0;
	ret = notify_die(DIE_OOPS, str, regs, 0,
			 current->thread.trap_nr, SIGSEGV);

	console_verbose();
	raw_spin_lock_irq(&die_lock);
@@ -414,7 +413,8 @@ void __noreturn die(const char *str, struct pt_regs *regs)
	if (panic_on_oops)
		panic("Fatal exception");

	make_task_dead(sig);
	if (ret != NOTIFY_STOP)
		make_task_dead(SIGSEGV);
}

static inline void setup_vint_size(unsigned int size)