linux/arch/x86/kernel/dumpstack_32.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 1991, 1992  Linus Torvalds
   3 *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
   4 */
   5#include <linux/sched/debug.h>
   6#include <linux/kallsyms.h>
   7#include <linux/kprobes.h>
   8#include <linux/uaccess.h>
   9#include <linux/hardirq.h>
  10#include <linux/kdebug.h>
  11#include <linux/export.h>
  12#include <linux/ptrace.h>
  13#include <linux/kexec.h>
  14#include <linux/sysfs.h>
  15#include <linux/bug.h>
  16#include <linux/nmi.h>
  17
  18#include <asm/stacktrace.h>
  19
  20const char *stack_type_name(enum stack_type type)
  21{
  22        if (type == STACK_TYPE_IRQ)
  23                return "IRQ";
  24
  25        if (type == STACK_TYPE_SOFTIRQ)
  26                return "SOFTIRQ";
  27
  28        return NULL;
  29}
  30
  31static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info)
  32{
  33        unsigned long *begin = (unsigned long *)this_cpu_read(hardirq_stack);
  34        unsigned long *end   = begin + (THREAD_SIZE / sizeof(long));
  35
  36        /*
  37         * This is a software stack, so 'end' can be a valid stack pointer.
  38         * It just means the stack is empty.
  39         */
  40        if (stack < begin || stack > end)
  41                return false;
  42
  43        info->type      = STACK_TYPE_IRQ;
  44        info->begin     = begin;
  45        info->end       = end;
  46
  47        /*
  48         * See irq_32.c -- the next stack pointer is stored at the beginning of
  49         * the stack.
  50         */
  51        info->next_sp   = (unsigned long *)*begin;
  52
  53        return true;
  54}
  55
  56static bool in_softirq_stack(unsigned long *stack, struct stack_info *info)
  57{
  58        unsigned long *begin = (unsigned long *)this_cpu_read(softirq_stack);
  59        unsigned long *end   = begin + (THREAD_SIZE / sizeof(long));
  60
  61        /*
  62         * This is a software stack, so 'end' can be a valid stack pointer.
  63         * It just means the stack is empty.
  64         */
  65        if (stack < begin || stack > end)
  66                return false;
  67
  68        info->type      = STACK_TYPE_SOFTIRQ;
  69        info->begin     = begin;
  70        info->end       = end;
  71
  72        /*
  73         * The next stack pointer is stored at the beginning of the stack.
  74         * See irq_32.c.
  75         */
  76        info->next_sp   = (unsigned long *)*begin;
  77
  78        return true;
  79}
  80
  81int get_stack_info(unsigned long *stack, struct task_struct *task,
  82                   struct stack_info *info, unsigned long *visit_mask)
  83{
  84        if (!stack)
  85                goto unknown;
  86
  87        task = task ? : current;
  88
  89        if (in_task_stack(stack, task, info))
  90                goto recursion_check;
  91
  92        if (task != current)
  93                goto unknown;
  94
  95        if (in_hardirq_stack(stack, info))
  96                goto recursion_check;
  97
  98        if (in_softirq_stack(stack, info))
  99                goto recursion_check;
 100
 101        goto unknown;
 102
 103recursion_check:
 104        /*
 105         * Make sure we don't iterate through any given stack more than once.
 106         * If it comes up a second time then there's something wrong going on:
 107         * just break out and report an unknown stack type.
 108         */
 109        if (visit_mask) {
 110                if (*visit_mask & (1UL << info->type)) {
 111                        printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type);
 112                        goto unknown;
 113                }
 114                *visit_mask |= 1UL << info->type;
 115        }
 116
 117        return 0;
 118
 119unknown:
 120        info->type = STACK_TYPE_UNKNOWN;
 121        return -EINVAL;
 122}
 123
 124void show_regs(struct pt_regs *regs)
 125{
 126        int i;
 127
 128        show_regs_print_info(KERN_EMERG);
 129        __show_regs(regs, !user_mode(regs));
 130
 131        /*
 132         * When in-kernel, we also print out the stack and code at the
 133         * time of the fault..
 134         */
 135        if (!user_mode(regs)) {
 136                unsigned int code_prologue = code_bytes * 43 / 64;
 137                unsigned int code_len = code_bytes;
 138                unsigned char c;
 139                u8 *ip;
 140
 141                show_trace_log_lvl(current, regs, NULL, KERN_EMERG);
 142
 143                pr_emerg("Code:");
 144
 145                ip = (u8 *)regs->ip - code_prologue;
 146                if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
 147                        /* try starting at IP */
 148                        ip = (u8 *)regs->ip;
 149                        code_len = code_len - code_prologue + 1;
 150                }
 151                for (i = 0; i < code_len; i++, ip++) {
 152                        if (ip < (u8 *)PAGE_OFFSET ||
 153                                        probe_kernel_address(ip, c)) {
 154                                pr_cont("  Bad EIP value.");
 155                                break;
 156                        }
 157                        if (ip == (u8 *)regs->ip)
 158                                pr_cont(" <%02x>", c);
 159                        else
 160                                pr_cont(" %02x", c);
 161                }
 162        }
 163        pr_cont("\n");
 164}
 165