cregit-Linux how code gets into the kernel

Release 4.8 arch/x86/kernel/dumpstack.c

Directory: arch/x86/kernel
/*
 *  Copyright (C) 1991, 1992  Linus Torvalds
 *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
 */
#include <linux/kallsyms.h>
#include <linux/kprobes.h>
#include <linux/uaccess.h>
#include <linux/utsname.h>
#include <linux/hardirq.h>
#include <linux/kdebug.h>
#include <linux/module.h>
#include <linux/ptrace.h>
#include <linux/ftrace.h>
#include <linux/kexec.h>
#include <linux/bug.h>
#include <linux/nmi.h>
#include <linux/sysfs.h>

#include <asm/stacktrace.h>



int panic_on_unrecovered_nmi;

int panic_on_io_nmi;

unsigned int code_bytes = 64;

int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE;

static int die_counter;


static void printk_stack_address(unsigned long address, int reliable, void *data) { printk("%s [<%p>] %s%pB\n", (char *)data, (void *)address, reliable ? "" : "? ", (void *)address); }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman3269.57%133.33%
adrien schildknechtadrien schildknecht1226.09%133.33%
jiri slabyjiri slaby24.35%133.33%
Total46100.00%3100.00%


void printk_address(unsigned long address) { pr_cont(" [<%p>] %pS\n", (void *)address, (void *)address); }

Contributors

PersonTokensPropCommitsCommitProp
jiri slabyjiri slaby26100.00%1100.00%
Total26100.00%1100.00%

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
static void print_ftrace_graph_addr(unsigned long addr, void *data, const struct stacktrace_ops *ops, struct task_struct *task, int *graph) { unsigned long ret_addr; int index; if (addr != (unsigned long)return_to_handler) return; index = task->curr_ret_stack; if (!task->ret_stack || index < *graph) return; index -= *graph; ret_addr = task->ret_stack[index].ret; ops->address(data, ret_addr, 1); (*graph)++; }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt9191.92%133.33%
hugh dickinshugh dickins66.06%133.33%
linus torvaldslinus torvalds22.02%133.33%
Total99100.00%3100.00%

#else
static inline void print_ftrace_graph_addr(unsigned long addr, void *data, const struct stacktrace_ops *ops, struct task_struct *task, int *graph) { }

Contributors

PersonTokensPropCommitsCommitProp
steven rostedtsteven rostedt2793.10%150.00%
linus torvaldslinus torvalds26.90%150.00%
Total29100.00%2100.00%

#endif /* * x86-64 can have up to three kernel stacks: * process stack * interrupt stack * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack */
static inline int valid_stack_ptr(struct task_struct *task, void *p, unsigned int size, void *end) { void *t = task_stack_page(task); if (end) { if (p < end && p >= (end-THREAD_SIZE)) return 1; else return 0; } return p >= t && p < t + THREAD_SIZE - size; }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman6690.41%125.00%
linus torvaldslinus torvalds68.22%250.00%
andy lutomirskiandy lutomirski11.37%125.00%
Total73100.00%4100.00%


unsigned long print_context_stack(struct task_struct *task, unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data, unsigned long *end, int *graph) { struct stack_frame *frame = (struct stack_frame *)bp; /* * If we overflowed the stack into a guard page, jump back to the * bottom of the usable stack. */ if ((unsigned long)task_stack_page(task) - (unsigned long)stack < PAGE_SIZE) stack = (unsigned long *)task_stack_page(task); while (valid_stack_ptr(task, stack, sizeof(*stack), end)) { unsigned long addr; addr = *stack; if (__kernel_text_address(addr)) { if ((unsigned long) stack == bp + sizeof(long)) { ops->address(data, addr, 1); frame = frame->next_frame; bp = (unsigned long) frame; } else { ops->address(data, addr, 0); } print_ftrace_graph_addr(addr, data, ops, task, graph); } stack++; } return bp; }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman14373.33%125.00%
andy lutomirskiandy lutomirski3216.41%125.00%
steven rostedtsteven rostedt168.21%125.00%
linus torvaldslinus torvalds42.05%125.00%
Total195100.00%4100.00%

EXPORT_SYMBOL_GPL(print_context_stack);
unsigned long print_context_stack_bp(struct task_struct *task, unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data, unsigned long *end, int *graph) { struct stack_frame *frame = (struct stack_frame *)bp; unsigned long *ret_addr = &frame->return_address; while (valid_stack_ptr(task, ret_addr, sizeof(*ret_addr), end)) { unsigned long addr = *ret_addr; if (!__kernel_text_address(addr)) break; if (ops->address(data, addr, 1)) break; frame = frame->next_frame; ret_addr = &frame->return_address; print_ftrace_graph_addr(addr, data, ops, task, graph); } return (unsigned long)frame; }

Contributors

PersonTokensPropCommitsCommitProp
frederic weisbeckerfrederic weisbecker13594.41%250.00%
alexei starovoitovalexei starovoitov42.80%125.00%
linus torvaldslinus torvalds42.80%125.00%
Total143100.00%4100.00%

EXPORT_SYMBOL_GPL(print_context_stack_bp);
static int print_trace_stack(void *data, char *name) { printk("%s <%s> ", (char *)data, name); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman30100.00%1100.00%
Total30100.00%1100.00%

/* * Print one address/symbol entries per line. */
static int print_trace_address(void *data, unsigned long addr, int reliable) { touch_nmi_watchdog(); printk_stack_address(addr, reliable, data); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman2578.12%125.00%
alexei starovoitovalexei starovoitov412.50%125.00%
adrien schildknechtadrien schildknecht26.25%125.00%
jiri slabyjiri slaby13.12%125.00%
Total32100.00%4100.00%

static const struct stacktrace_ops print_trace_ops = { .stack = print_trace_stack, .address = print_trace_address, .walk_stack = print_context_stack, };
void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, unsigned long bp, char *log_lvl) { printk("%sCall Trace:\n", log_lvl); dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl); }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman4588.24%150.00%
namhyung kimnamhyung kim611.76%150.00%
Total51100.00%2100.00%


void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, unsigned long bp) { show_trace_log_lvl(task, regs, stack, bp, ""); }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman3183.78%150.00%
namhyung kimnamhyung kim616.22%150.00%
Total37100.00%2100.00%


void show_stack(struct task_struct *task, unsigned long *sp) { unsigned long bp = 0; unsigned long stack; /* * Stack frames below this one aren't interesting. Don't show them * if we're printing for %current. */ if (!sp && (!task || task == current)) { sp = &stack; bp = stack_frame(current, NULL); } show_stack_log_lvl(task, NULL, sp, bp, ""); }

Contributors

PersonTokensPropCommitsCommitProp
tejun heotejun heo4260.87%133.33%
neil hormanneil horman2637.68%133.33%
namhyung kimnamhyung kim11.45%133.33%
Total69100.00%3100.00%


void show_stack_regs(struct pt_regs *regs) { show_stack_log_lvl(current, regs, (unsigned long *)regs->sp, regs->bp, ""); }

Contributors

PersonTokensPropCommitsCommitProp
borislav petkovborislav petkov32100.00%1100.00%
Total32100.00%1100.00%

static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; static int die_owner = -1; static unsigned int die_nest_count;
unsigned long oops_begin(void) { int cpu; unsigned long flags; oops_enter(); /* racy, but better than risking deadlock. */ raw_local_irq_save(flags); cpu = smp_processor_id(); if (!arch_spin_trylock(&die_lock)) { if (cpu == die_owner) /* nested oops. should stop eventually */; else arch_spin_lock(&die_lock); } die_nest_count++; die_owner = cpu; console_verbose(); bust_spinlocks(1); return flags; }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman7197.26%150.00%
thomas gleixnerthomas gleixner22.74%150.00%
Total73100.00%2100.00%

EXPORT_SYMBOL_GPL(oops_begin); NOKPROBE_SYMBOL(oops_begin); void __noreturn rewind_stack_do_exit(int signr);
void oops_end(unsigned long flags, struct pt_regs *regs, int signr) { if (regs && kexec_should_crash(current)) crash_kexec(regs); bust_spinlocks(0); die_owner = -1; add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); die_nest_count--; if (!die_nest_count) /* Nest count reaches zero, release the lock. */ arch_spin_unlock(&die_lock); raw_local_irq_restore(flags); oops_exit(); if (!signr) return; if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) panic("Fatal exception"); /* * We're not going to return, but we might be on an IST stack or * have very little stack space left. Rewind the stack and kill * the task. */ rewind_stack_do_exit(signr); }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman9795.10%125.00%
andy lutomirskiandy lutomirski21.96%125.00%
rusty russellrusty russell21.96%125.00%
thomas gleixnerthomas gleixner10.98%125.00%
Total102100.00%4100.00%

NOKPROBE_SYMBOL(oops_end);
int __die(const char *str, struct pt_regs *regs, long err) { #ifdef CONFIG_X86_32 unsigned short ss; unsigned long sp; #endif printk(KERN_DEFAULT "%s: %04lx [#%d]%s%s%s%s\n", str, err & 0xffff, ++die_counter, IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "", IS_ENABLED(CONFIG_SMP) ? " SMP" : "", debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "", IS_ENABLED(CONFIG_KASAN) ? " KASAN" : ""); if (notify_die(DIE_OOPS, str, regs, err, current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) return 1; print_modules(); show_regs(regs); #ifdef CONFIG_X86_32 if (user_mode(regs)) { sp = regs->sp; ss = regs->ss & 0xffff; } else { sp = kernel_stack_pointer(regs); savesegment(ss, ss); } printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip); print_symbol("%s", regs->ip); printk(" SS:ESP %04x:%08lx\n", ss, sp); #else /* Executive summary in case the oops scrolled away */ printk(KERN_ALERT "RIP "); printk_address(regs->ip); printk(" RSP <%016lx>\n", regs->sp); #endif return 0; }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman16275.35%110.00%
rasmus villemoesrasmus villemoes2612.09%110.00%
h. peter anvinh. peter anvin177.91%110.00%
jan beulichjan beulich41.86%220.00%
christian borntraegerchristian borntraeger20.93%110.00%
andrey ryabininandrey ryabinin10.47%110.00%
srikar dronamrajusrikar dronamraju10.47%110.00%
prarit bhargavaprarit bhargava10.47%110.00%
andy lutomirskiandy lutomirski10.47%110.00%
Total215100.00%10100.00%

NOKPROBE_SYMBOL(__die); /* * This is gone through when something in the kernel has done something bad * and is about to be terminated: */
void die(const char *str, struct pt_regs *regs, long err) { unsigned long flags = oops_begin(); int sig = SIGSEGV; if (!user_mode(regs)) report_bug(regs->ip, regs); if (__die(str, regs, err)) sig = 0; oops_end(flags, regs, sig); }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman7098.59%150.00%
andy lutomirskiandy lutomirski11.41%150.00%
Total71100.00%2100.00%


static int __init kstack_setup(char *s) { ssize_t ret; unsigned long val; if (!s) return -EINVAL; ret = kstrtoul(s, 0, &val); if (ret) return ret; kstack_depth_to_print = val; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman3056.60%150.00%
shuah khanshuah khan2343.40%150.00%
Total53100.00%2100.00%

early_param("kstack", kstack_setup);
static int __init code_bytes_setup(char *s) { ssize_t ret; unsigned long val; if (!s) return -EINVAL; ret = kstrtoul(s, 0, &val); if (ret) return ret; code_bytes = val; if (code_bytes > 8192) code_bytes = 8192; return 1; }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan3250.79%150.00%
neil hormanneil horman3149.21%150.00%
Total63100.00%2100.00%

__setup("code_bytes=", code_bytes_setup);

Overall Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman97060.32%12.94%
frederic weisbeckerfrederic weisbecker1509.33%38.82%
steven rostedtsteven rostedt1448.96%25.88%
shuah khanshuah khan553.42%12.94%
andy lutomirskiandy lutomirski452.80%38.82%
tejun heotejun heo422.61%12.94%
borislav petkovborislav petkov321.99%12.94%
jiri slabyjiri slaby291.80%12.94%
rasmus villemoesrasmus villemoes261.62%12.94%
linus torvaldslinus torvalds181.12%25.88%
h. peter anvinh. peter anvin171.06%12.94%
masami hiramatsumasami hiramatsu150.93%12.94%
adrien schildknechtadrien schildknecht140.87%12.94%
namhyung kimnamhyung kim130.81%12.94%
alexei starovoitovalexei starovoitov80.50%12.94%
hugh dickinshugh dickins60.37%12.94%
huang yinghuang ying50.31%12.94%
thomas gleixnerthomas gleixner50.31%38.82%
jan beulichjan beulich40.25%25.88%
kurt garloffkurt garloff30.19%12.94%
rusty russellrusty russell20.12%12.94%
christian borntraegerchristian borntraeger20.12%12.94%
prarit bhargavaprarit bhargava10.06%12.94%
srikar dronamrajusrikar dronamraju10.06%12.94%
andrey ryabininandrey ryabinin10.06%12.94%
Total1608100.00%34100.00%
Directory: arch/x86/kernel
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.