cregit-Linux how code gets into the kernel

Release 4.7 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 horman6791.78%133.33%
linus torvaldslinus torvalds68.22%266.67%
Total73100.00%3100.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; 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 horman14387.73%133.33%
steven rostedtsteven rostedt169.82%133.33%
linus torvaldslinus torvalds42.45%133.33%
Total163100.00%3100.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%
linus torvaldslinus torvalds42.80%125.00%
alexei starovoitovalexei starovoitov42.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%

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 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"); do_exit(signr); }

Contributors

PersonTokensPropCommitsCommitProp
neil hormanneil horman9897.03%133.33%
rusty russellrusty russell21.98%133.33%
thomas gleixnerthomas gleixner10.99%133.33%
Total101100.00%3100.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%
srikar dronamrajusrikar dronamraju10.47%110.00%
andrey ryabininandrey ryabinin10.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 horman97263.32%13.23%
frederic weisbeckerfrederic weisbecker1509.77%39.68%
steven rostedtsteven rostedt1449.38%26.45%
shuah khanshuah khan553.58%13.23%
tejun heotejun heo422.74%13.23%
jiri slabyjiri slaby291.89%13.23%
rasmus villemoesrasmus villemoes261.69%13.23%
linus torvaldslinus torvalds181.17%26.45%
h. peter anvinh. peter anvin171.11%13.23%
masami hiramatsumasami hiramatsu150.98%13.23%
adrien schildknechtadrien schildknecht140.91%13.23%
namhyung kimnamhyung kim130.85%13.23%
alexei starovoitovalexei starovoitov80.52%13.23%
hugh dickinshugh dickins60.39%13.23%
thomas gleixnerthomas gleixner50.33%39.68%
huang yinghuang ying50.33%13.23%
jan beulichjan beulich40.26%26.45%
kurt garloffkurt garloff30.20%13.23%
rusty russellrusty russell20.13%13.23%
christian borntraegerchristian borntraeger20.13%13.23%
andy lutomirskiandy lutomirski20.13%13.23%
prarit bhargavaprarit bhargava10.07%13.23%
srikar dronamrajusrikar dronamraju10.07%13.23%
andrey ryabininandrey ryabinin10.07%13.23%
Total1535100.00%31100.00%
Directory: arch/x86/kernel
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}