mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
exit: Add and use make_task_dead.
There are two big uses of do_exit. The first is it's design use to be the guts of the exit(2) system call. The second use is to terminate a task after something catastrophic has happened like a NULL pointer in kernel code. Add a function make_task_dead that is initialy exactly the same as do_exit to cover the cases where do_exit is called to handle catastrophic failure. In time this can probably be reduced to just a light wrapper around do_task_dead. For now keep it exactly the same so that there will be no behavioral differences introducing this new concept. Replace all of the uses of do_exit that use it for catastraphic task cleanup with make_task_dead to make it clear what the code is doing. As part of this rename rewind_stack_do_exit rewind_stack_and_make_dead. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
This commit is contained in:
parent
5e354747b2
commit
0e25498f8c
39 changed files with 63 additions and 56 deletions
|
@ -190,7 +190,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_MATHEMU
|
#ifndef CONFIG_MATHEMU
|
||||||
|
@ -575,7 +575,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
|
||||||
|
|
||||||
printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
|
printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
|
||||||
pc, va, opcode, reg);
|
pc, va, opcode, reg);
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
|
|
||||||
got_exception:
|
got_exception:
|
||||||
/* Ok, we caught the exception, but we don't want it. Is there
|
/* Ok, we caught the exception, but we don't want it. Is there
|
||||||
|
@ -630,7 +630,7 @@ got_exception:
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -204,7 +204,7 @@ retry:
|
||||||
printk(KERN_ALERT "Unable to handle kernel paging request at "
|
printk(KERN_ALERT "Unable to handle kernel paging request at "
|
||||||
"virtual address %016lx\n", address);
|
"virtual address %016lx\n", address);
|
||||||
die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16);
|
die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16);
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
|
|
||||||
/* We ran out of memory, or some other thing happened to us that
|
/* We ran out of memory, or some other thing happened to us that
|
||||||
made us unable to handle the page fault gracefully. */
|
made us unable to handle the page fault gracefully. */
|
||||||
|
|
|
@ -333,7 +333,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
if (signr)
|
if (signr)
|
||||||
do_exit(signr);
|
make_task_dead(signr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -111,7 +111,7 @@ static void die_kernel_fault(const char *msg, struct mm_struct *mm,
|
||||||
show_pte(KERN_ALERT, mm, addr);
|
show_pte(KERN_ALERT, mm, addr);
|
||||||
die("Oops", regs, fsr);
|
die("Oops", regs, fsr);
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -235,7 +235,7 @@ void die(const char *str, struct pt_regs *regs, int err)
|
||||||
raw_spin_unlock_irqrestore(&die_lock, flags);
|
raw_spin_unlock_irqrestore(&die_lock, flags);
|
||||||
|
|
||||||
if (ret != NOTIFY_STOP)
|
if (ret != NOTIFY_STOP)
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arm64_show_signal(int signo, const char *str)
|
static void arm64_show_signal(int signo, const char *str)
|
||||||
|
|
|
@ -302,7 +302,7 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
|
||||||
show_pte(addr);
|
show_pte(addr);
|
||||||
die("Oops", regs, esr);
|
die("Oops", regs, esr);
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_KASAN_HW_TAGS
|
#ifdef CONFIG_KASAN_HW_TAGS
|
||||||
|
|
|
@ -294,7 +294,7 @@ bad_area:
|
||||||
__func__, opcode, rz, rx, imm, addr);
|
__func__, opcode, rz, rx, imm, addr);
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
do_exit(SIGKILL);
|
make_dead_task(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr);
|
force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr);
|
||||||
|
|
|
@ -109,7 +109,7 @@ void die(struct pt_regs *regs, const char *str)
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
if (ret != NOTIFY_STOP)
|
if (ret != NOTIFY_STOP)
|
||||||
do_exit(SIGSEGV);
|
make_dead_task(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
|
void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
|
||||||
|
|
|
@ -67,7 +67,7 @@ static inline void no_context(struct pt_regs *regs, unsigned long addr)
|
||||||
pr_alert("Unable to handle kernel paging request at virtual "
|
pr_alert("Unable to handle kernel paging request at virtual "
|
||||||
"addr 0x%08lx, pc: 0x%08lx\n", addr, regs->pc);
|
"addr 0x%08lx, pc: 0x%08lx\n", addr, regs->pc);
|
||||||
die(regs, "Oops");
|
die(regs, "Oops");
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_fault_t fault)
|
static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_fault_t fault)
|
||||||
|
|
|
@ -106,7 +106,7 @@ void die(const char *str, struct pt_regs *fp, unsigned long err)
|
||||||
dump(fp);
|
dump(fp);
|
||||||
|
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
do_exit(SIGSEGV);
|
make_dead_task(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kstack_depth_to_print = 24;
|
static int kstack_depth_to_print = 24;
|
||||||
|
|
|
@ -51,7 +51,7 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
|
||||||
printk(" at virtual address %08lx\n", address);
|
printk(" at virtual address %08lx\n", address);
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
die("Oops", regs, error_code);
|
die("Oops", regs, error_code);
|
||||||
do_exit(SIGKILL);
|
make_dead_task(SIGKILL);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,7 @@ int die(const char *str, struct pt_regs *regs, long err)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
|
||||||
oops_exit();
|
oops_exit();
|
||||||
do_exit(err);
|
make_dead_task(err);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ mca_handler_bh(unsigned long paddr, void *iip, unsigned long ipsr)
|
||||||
spin_unlock(&mca_bh_lock);
|
spin_unlock(&mca_bh_lock);
|
||||||
|
|
||||||
/* This process is about to be killed itself */
|
/* This process is about to be killed itself */
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -85,7 +85,7 @@ die (const char *str, struct pt_regs *regs, long err)
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -259,7 +259,7 @@ retry:
|
||||||
regs = NULL;
|
regs = NULL;
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
if (regs)
|
if (regs)
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
out_of_memory:
|
out_of_memory:
|
||||||
|
|
|
@ -1131,7 +1131,7 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr)
|
||||||
pr_crit("%s: %08x\n", str, nr);
|
pr_crit("%s: %08x\n", str, nr);
|
||||||
show_registers(fp);
|
show_registers(fp);
|
||||||
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void set_esp0(unsigned long ssp)
|
asmlinkage void set_esp0(unsigned long ssp)
|
||||||
|
|
|
@ -48,7 +48,7 @@ int send_fault_sig(struct pt_regs *regs)
|
||||||
pr_alert("Unable to handle kernel access");
|
pr_alert("Unable to handle kernel access");
|
||||||
pr_cont(" at virtual address %p\n", addr);
|
pr_cont(" at virtual address %p\n", addr);
|
||||||
die_if_kernel("Oops", regs, 0 /*error_code*/);
|
die_if_kernel("Oops", regs, 0 /*error_code*/);
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -44,10 +44,10 @@ void die(const char *str, struct pt_regs *fp, long err)
|
||||||
pr_warn("Oops: %s, sig: %ld\n", str, err);
|
pr_warn("Oops: %s, sig: %ld\n", str, err);
|
||||||
show_regs(fp);
|
show_regs(fp);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
/* do_exit() should take care of panic'ing from an interrupt
|
/* make_task_dead() should take care of panic'ing from an interrupt
|
||||||
* context so we don't handle it here
|
* context so we don't handle it here
|
||||||
*/
|
*/
|
||||||
do_exit(err);
|
make_task_dead(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for user application debugging */
|
/* for user application debugging */
|
||||||
|
|
|
@ -422,7 +422,7 @@ void __noreturn die(const char *str, struct pt_regs *regs)
|
||||||
if (regs && kexec_should_crash(current))
|
if (regs && kexec_should_crash(current))
|
||||||
crash_kexec(regs);
|
crash_kexec(regs);
|
||||||
|
|
||||||
do_exit(sig);
|
make_task_dead(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern struct exception_table_entry __start___dbe_table[];
|
extern struct exception_table_entry __start___dbe_table[];
|
||||||
|
|
|
@ -223,7 +223,7 @@ inline void handle_fpu_exception(struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
} else if (fpcsr & FPCSR_mskRIT) {
|
} else if (fpcsr & FPCSR_mskRIT) {
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
do_exit(SIGILL);
|
make_task_dead(SIGILL);
|
||||||
si_signo = SIGILL;
|
si_signo = SIGILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ void __noreturn die(const char *str, struct pt_regs *regs, int err)
|
||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(die);
|
EXPORT_SYMBOL(die);
|
||||||
|
@ -240,7 +240,7 @@ void unhandled_interruption(struct pt_regs *regs)
|
||||||
pr_emerg("unhandled_interruption\n");
|
pr_emerg("unhandled_interruption\n");
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
force_sig(SIGKILL);
|
force_sig(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ void unhandled_exceptions(unsigned long entry, unsigned long addr,
|
||||||
addr, type);
|
addr, type);
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
force_sig(SIGKILL);
|
force_sig(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ void do_revinsn(struct pt_regs *regs)
|
||||||
pr_emerg("Reserved Instruction\n");
|
pr_emerg("Reserved Instruction\n");
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
do_exit(SIGILL);
|
make_task_dead(SIGILL);
|
||||||
force_sig(SIGILL);
|
force_sig(SIGILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,10 @@ void die(const char *str, struct pt_regs *regs, long err)
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
/*
|
/*
|
||||||
* do_exit() should take care of panic'ing from an interrupt
|
* make_task_dead() should take care of panic'ing from an interrupt
|
||||||
* context so we don't handle it here
|
* context so we don't handle it here
|
||||||
*/
|
*/
|
||||||
do_exit(err);
|
make_task_dead(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr)
|
void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr)
|
||||||
|
|
|
@ -212,7 +212,7 @@ void __noreturn die(const char *str, struct pt_regs *regs, long err)
|
||||||
__asm__ __volatile__("l.nop 1");
|
__asm__ __volatile__("l.nop 1");
|
||||||
do {} while (1);
|
do {} while (1);
|
||||||
#endif
|
#endif
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is normally the 'Oops' routine */
|
/* This is normally the 'Oops' routine */
|
||||||
|
|
|
@ -269,7 +269,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
|
||||||
oops_exit();
|
oops_exit();
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gdb uses break 4,8 */
|
/* gdb uses break 4,8 */
|
||||||
|
|
|
@ -245,7 +245,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs,
|
||||||
|
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
do_exit(signr);
|
make_task_dead(signr);
|
||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(oops_end);
|
NOKPROBE_SYMBOL(oops_end);
|
||||||
|
|
||||||
|
@ -792,9 +792,9 @@ int machine_check_generic(struct pt_regs *regs)
|
||||||
void die_mce(const char *str, struct pt_regs *regs, long err)
|
void die_mce(const char *str, struct pt_regs *regs, long err)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The machine check wants to kill the interrupted context, but
|
* The machine check wants to kill the interrupted context,
|
||||||
* do_exit() checks for in_interrupt() and panics in that case, so
|
* but make_task_dead() checks for in_interrupt() and panics
|
||||||
* exit the irq/nmi before calling die.
|
* in that case, so exit the irq/nmi before calling die.
|
||||||
*/
|
*/
|
||||||
if (in_nmi())
|
if (in_nmi())
|
||||||
nmi_exit();
|
nmi_exit();
|
||||||
|
|
|
@ -54,7 +54,7 @@ void die(struct pt_regs *regs, const char *str)
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
if (ret != NOTIFY_STOP)
|
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)
|
void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
|
||||||
|
|
|
@ -31,7 +31,7 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
|
||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
die(regs, "Oops");
|
die(regs, "Oops");
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void no_context(struct pt_regs *regs, unsigned long addr)
|
static inline void no_context(struct pt_regs *regs, unsigned long addr)
|
||||||
|
|
|
@ -224,5 +224,5 @@ void __noreturn die(struct pt_regs *regs, const char *str)
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception: panic_on_oops");
|
panic("Fatal exception: panic_on_oops");
|
||||||
oops_exit();
|
oops_exit();
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,7 +175,7 @@ void __s390_handle_mcck(void)
|
||||||
"malfunction (code 0x%016lx).\n", mcck.mcck_code);
|
"malfunction (code 0x%016lx).\n", mcck.mcck_code);
|
||||||
printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
|
printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
|
||||||
current->comm, current->pid);
|
current->comm, current->pid);
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ void __noreturn die(const char *str, struct pt_regs *regs, long err)
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
void die_if_kernel(const char *str, struct pt_regs *regs, long err)
|
void die_if_kernel(const char *str, struct pt_regs *regs, long err)
|
||||||
|
|
|
@ -86,9 +86,7 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
printk("Instruction DUMP:");
|
printk("Instruction DUMP:");
|
||||||
instruction_dump ((unsigned long *) regs->pc);
|
instruction_dump ((unsigned long *) regs->pc);
|
||||||
if(regs->psr & PSR_PS)
|
make_task_dead((regs->psr & PSR_PS) ? SIGKILL : SIGSEGV);
|
||||||
do_exit(SIGKILL);
|
|
||||||
do_exit(SIGSEGV);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_hw_interrupt(struct pt_regs *regs, unsigned long type)
|
void do_hw_interrupt(struct pt_regs *regs, unsigned long type)
|
||||||
|
|
|
@ -2559,9 +2559,7 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
if (regs->tstate & TSTATE_PRIV)
|
make_task_dead((regs->tstate & TSTATE_PRIV)? SIGKILL : SIGSEGV);
|
||||||
do_exit(SIGKILL);
|
|
||||||
do_exit(SIGSEGV);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(die_if_kernel);
|
EXPORT_SYMBOL(die_if_kernel);
|
||||||
|
|
||||||
|
|
|
@ -1248,14 +1248,14 @@ SYM_CODE_START(asm_exc_nmi)
|
||||||
SYM_CODE_END(asm_exc_nmi)
|
SYM_CODE_END(asm_exc_nmi)
|
||||||
|
|
||||||
.pushsection .text, "ax"
|
.pushsection .text, "ax"
|
||||||
SYM_CODE_START(rewind_stack_do_exit)
|
SYM_CODE_START(rewind_stack_and_make_dead)
|
||||||
/* Prevent any naive code from trying to unwind to our caller. */
|
/* Prevent any naive code from trying to unwind to our caller. */
|
||||||
xorl %ebp, %ebp
|
xorl %ebp, %ebp
|
||||||
|
|
||||||
movl PER_CPU_VAR(cpu_current_top_of_stack), %esi
|
movl PER_CPU_VAR(cpu_current_top_of_stack), %esi
|
||||||
leal -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp
|
leal -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp
|
||||||
|
|
||||||
call do_exit
|
call make_task_dead
|
||||||
1: jmp 1b
|
1: jmp 1b
|
||||||
SYM_CODE_END(rewind_stack_do_exit)
|
SYM_CODE_END(rewind_stack_and_make_dead)
|
||||||
.popsection
|
.popsection
|
||||||
|
|
|
@ -1429,7 +1429,7 @@ SYM_CODE_END(ignore_sysret)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.pushsection .text, "ax"
|
.pushsection .text, "ax"
|
||||||
SYM_CODE_START(rewind_stack_do_exit)
|
SYM_CODE_START(rewind_stack_and_make_dead)
|
||||||
UNWIND_HINT_FUNC
|
UNWIND_HINT_FUNC
|
||||||
/* Prevent any naive code from trying to unwind to our caller. */
|
/* Prevent any naive code from trying to unwind to our caller. */
|
||||||
xorl %ebp, %ebp
|
xorl %ebp, %ebp
|
||||||
|
@ -1438,6 +1438,6 @@ SYM_CODE_START(rewind_stack_do_exit)
|
||||||
leaq -PTREGS_SIZE(%rax), %rsp
|
leaq -PTREGS_SIZE(%rax), %rsp
|
||||||
UNWIND_HINT_REGS
|
UNWIND_HINT_REGS
|
||||||
|
|
||||||
call do_exit
|
call make_task_dead
|
||||||
SYM_CODE_END(rewind_stack_do_exit)
|
SYM_CODE_END(rewind_stack_and_make_dead)
|
||||||
.popsection
|
.popsection
|
||||||
|
|
|
@ -351,7 +351,7 @@ unsigned long oops_begin(void)
|
||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(oops_begin);
|
NOKPROBE_SYMBOL(oops_begin);
|
||||||
|
|
||||||
void __noreturn rewind_stack_do_exit(int signr);
|
void __noreturn rewind_stack_and_make_dead(int signr);
|
||||||
|
|
||||||
void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
|
void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
|
||||||
{
|
{
|
||||||
|
@ -386,7 +386,7 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
|
||||||
* reuse the task stack and that existing poisons are invalid.
|
* reuse the task stack and that existing poisons are invalid.
|
||||||
*/
|
*/
|
||||||
kasan_unpoison_task_stack(current);
|
kasan_unpoison_task_stack(current);
|
||||||
rewind_stack_do_exit(signr);
|
rewind_stack_and_make_dead(signr);
|
||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(oops_end);
|
NOKPROBE_SYMBOL(oops_end);
|
||||||
|
|
||||||
|
|
|
@ -552,5 +552,5 @@ void __noreturn die(const char * str, struct pt_regs * regs, long err)
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
|
||||||
do_exit(err);
|
make_task_dead(err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ extern void sched_post_fork(struct task_struct *p,
|
||||||
extern void sched_dead(struct task_struct *p);
|
extern void sched_dead(struct task_struct *p);
|
||||||
|
|
||||||
void __noreturn do_task_dead(void);
|
void __noreturn do_task_dead(void);
|
||||||
|
void __noreturn make_task_dead(int signr);
|
||||||
|
|
||||||
extern void proc_caches_init(void);
|
extern void proc_caches_init(void);
|
||||||
|
|
||||||
|
|
|
@ -884,6 +884,15 @@ void __noreturn do_exit(long code)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(do_exit);
|
EXPORT_SYMBOL_GPL(do_exit);
|
||||||
|
|
||||||
|
void __noreturn make_task_dead(int signr)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Take the task off the cpu after something catastrophic has
|
||||||
|
* happened.
|
||||||
|
*/
|
||||||
|
do_exit(signr);
|
||||||
|
}
|
||||||
|
|
||||||
void complete_and_exit(struct completion *comp, long code)
|
void complete_and_exit(struct completion *comp, long code)
|
||||||
{
|
{
|
||||||
if (comp)
|
if (comp)
|
||||||
|
|
|
@ -168,6 +168,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
|
||||||
"panic",
|
"panic",
|
||||||
"do_exit",
|
"do_exit",
|
||||||
"do_task_dead",
|
"do_task_dead",
|
||||||
|
"make_task_dead",
|
||||||
"__module_put_and_exit",
|
"__module_put_and_exit",
|
||||||
"complete_and_exit",
|
"complete_and_exit",
|
||||||
"__reiserfs_panic",
|
"__reiserfs_panic",
|
||||||
|
@ -175,7 +176,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
|
||||||
"fortify_panic",
|
"fortify_panic",
|
||||||
"usercopy_abort",
|
"usercopy_abort",
|
||||||
"machine_real_restart",
|
"machine_real_restart",
|
||||||
"rewind_stack_do_exit",
|
"rewind_stack_and_make_dead"
|
||||||
"kunit_try_catch_throw",
|
"kunit_try_catch_throw",
|
||||||
"xen_start_kernel",
|
"xen_start_kernel",
|
||||||
"cpu_bringup_and_idle",
|
"cpu_bringup_and_idle",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue