linux/arch/s390/kernel/dumpstack.c
<<
>>
Prefs
   1/*
   2 * Stack dumping functions
   3 *
   4 *  Copyright IBM Corp. 1999, 2013
   5 */
   6
   7#include <linux/kallsyms.h>
   8#include <linux/hardirq.h>
   9#include <linux/kprobes.h>
  10#include <linux/utsname.h>
  11#include <linux/export.h>
  12#include <linux/kdebug.h>
  13#include <linux/ptrace.h>
  14#include <linux/mm.h>
  15#include <linux/module.h>
  16#include <linux/sched.h>
  17#include <asm/processor.h>
  18#include <asm/debug.h>
  19#include <asm/dis.h>
  20#include <asm/ipl.h>
  21
  22/*
  23 * For dump_trace we have tree different stack to consider:
  24 *   - the panic stack which is used if the kernel stack has overflown
  25 *   - the asynchronous interrupt stack (cpu related)
  26 *   - the synchronous kernel stack (process related)
  27 * The stack trace can start at any of the three stacks and can potentially
  28 * touch all of them. The order is: panic stack, async stack, sync stack.
  29 */
  30static unsigned long
  31__dump_trace(dump_trace_func_t func, void *data, unsigned long sp,
  32             unsigned long low, unsigned long high)
  33{
  34        struct stack_frame *sf;
  35        struct pt_regs *regs;
  36
  37        while (1) {
  38                if (sp < low || sp > high - sizeof(*sf))
  39                        return sp;
  40                sf = (struct stack_frame *) sp;
  41                if (func(data, sf->gprs[8], 0))
  42                        return sp;
  43                /* Follow the backchain. */
  44                while (1) {
  45                        low = sp;
  46                        sp = sf->back_chain;
  47                        if (!sp)
  48                                break;
  49                        if (sp <= low || sp > high - sizeof(*sf))
  50                                return sp;
  51                        sf = (struct stack_frame *) sp;
  52                        if (func(data, sf->gprs[8], 1))
  53                                return sp;
  54                }
  55                /* Zero backchain detected, check for interrupt frame. */
  56                sp = (unsigned long) (sf + 1);
  57                if (sp <= low || sp > high - sizeof(*regs))
  58                        return sp;
  59                regs = (struct pt_regs *) sp;
  60                if (!user_mode(regs)) {
  61                        if (func(data, regs->psw.addr, 1))
  62                                return sp;
  63                }
  64                low = sp;
  65                sp = regs->gprs[15];
  66        }
  67}
  68
  69void dump_trace(dump_trace_func_t func, void *data, struct task_struct *task,
  70                unsigned long sp)
  71{
  72        unsigned long frame_size;
  73
  74        frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
  75#ifdef CONFIG_CHECK_STACK
  76        sp = __dump_trace(func, data, sp,
  77                          S390_lowcore.panic_stack + frame_size - 4096,
  78                          S390_lowcore.panic_stack + frame_size);
  79#endif
  80        sp = __dump_trace(func, data, sp,
  81                          S390_lowcore.async_stack + frame_size - ASYNC_SIZE,
  82                          S390_lowcore.async_stack + frame_size);
  83        task = task ?: current;
  84        __dump_trace(func, data, sp,
  85                     (unsigned long)task_stack_page(task),
  86                     (unsigned long)task_stack_page(task) + THREAD_SIZE);
  87}
  88EXPORT_SYMBOL_GPL(dump_trace);
  89
  90static int show_address(void *data, unsigned long address, int reliable)
  91{
  92        if (reliable)
  93                printk(" [<%016lx>] %pSR \n", address, (void *)address);
  94        else
  95                printk("([<%016lx>] %pSR)\n", address, (void *)address);
  96        return 0;
  97}
  98
  99static void show_trace(struct task_struct *task, unsigned long sp)
 100{
 101        if (!sp)
 102                sp = task ? task->thread.ksp : current_stack_pointer();
 103        printk("Call Trace:\n");
 104        dump_trace(show_address, NULL, task, sp);
 105        if (!task)
 106                task = current;
 107        debug_show_held_locks(task);
 108}
 109
 110void show_stack(struct task_struct *task, unsigned long *sp)
 111{
 112        unsigned long *stack;
 113        int i;
 114
 115        stack = sp;
 116        if (!stack) {
 117                if (!task)
 118                        stack = (unsigned long *)current_stack_pointer();
 119                else
 120                        stack = (unsigned long *)task->thread.ksp;
 121        }
 122        printk(KERN_DEFAULT "Stack:\n");
 123        for (i = 0; i < 20; i++) {
 124                if (((addr_t) stack & (THREAD_SIZE-1)) == 0)
 125                        break;
 126                if (i % 4 == 0)
 127                        printk(KERN_DEFAULT "       ");
 128                pr_cont("%016lx%c", *stack++, i % 4 == 3 ? '\n' : ' ');
 129        }
 130        show_trace(task, (unsigned long)sp);
 131}
 132
 133static void show_last_breaking_event(struct pt_regs *regs)
 134{
 135        printk("Last Breaking-Event-Address:\n");
 136        printk(" [<%016lx>] %pSR\n", regs->args[0], (void *)regs->args[0]);
 137}
 138
 139void show_registers(struct pt_regs *regs)
 140{
 141        struct psw_bits *psw = &psw_bits(regs->psw);
 142        char *mode;
 143
 144        mode = user_mode(regs) ? "User" : "Krnl";
 145        printk("%s PSW : %p %p", mode, (void *)regs->psw.mask, (void *)regs->psw.addr);
 146        if (!user_mode(regs))
 147                pr_cont(" (%pSR)", (void *)regs->psw.addr);
 148        pr_cont("\n");
 149        printk("           R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x "
 150               "P:%x AS:%x CC:%x PM:%x", psw->r, psw->t, psw->i, psw->e,
 151               psw->key, psw->m, psw->w, psw->p, psw->as, psw->cc, psw->pm);
 152        pr_cont(" RI:%x EA:%x\n", psw->ri, psw->eaba);
 153        printk("%s GPRS: %016lx %016lx %016lx %016lx\n", mode,
 154               regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]);
 155        printk("           %016lx %016lx %016lx %016lx\n",
 156               regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]);
 157        printk("           %016lx %016lx %016lx %016lx\n",
 158               regs->gprs[8], regs->gprs[9], regs->gprs[10], regs->gprs[11]);
 159        printk("           %016lx %016lx %016lx %016lx\n",
 160               regs->gprs[12], regs->gprs[13], regs->gprs[14], regs->gprs[15]);
 161        show_code(regs);
 162}
 163
 164void show_regs(struct pt_regs *regs)
 165{
 166        show_regs_print_info(KERN_DEFAULT);
 167        show_registers(regs);
 168        /* Show stack backtrace if pt_regs is from kernel mode */
 169        if (!user_mode(regs))
 170                show_trace(NULL, regs->gprs[15]);
 171        show_last_breaking_event(regs);
 172}
 173
 174static DEFINE_SPINLOCK(die_lock);
 175
 176void die(struct pt_regs *regs, const char *str)
 177{
 178        static int die_counter;
 179
 180        oops_enter();
 181        lgr_info_log();
 182        debug_stop_all();
 183        console_verbose();
 184        spin_lock_irq(&die_lock);
 185        bust_spinlocks(1);
 186        printk("%s: %04x ilc:%d [#%d] ", str, regs->int_code & 0xffff,
 187               regs->int_code >> 17, ++die_counter);
 188#ifdef CONFIG_PREEMPT
 189        pr_cont("PREEMPT ");
 190#endif
 191#ifdef CONFIG_SMP
 192        pr_cont("SMP ");
 193#endif
 194        if (debug_pagealloc_enabled())
 195                pr_cont("DEBUG_PAGEALLOC");
 196        pr_cont("\n");
 197        notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV);
 198        print_modules();
 199        show_regs(regs);
 200        bust_spinlocks(0);
 201        add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
 202        spin_unlock_irq(&die_lock);
 203        if (in_interrupt())
 204                panic("Fatal exception in interrupt");
 205        if (panic_on_oops)
 206                panic("Fatal exception: panic_on_oops");
 207        oops_exit();
 208        do_exit(SIGSEGV);
 209}
 210