Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  Copyright (C) 1991, 1992  Linus Torvalds
0004  *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
0005  */
0006 #include <linux/sched/debug.h>
0007 #include <linux/kallsyms.h>
0008 #include <linux/kprobes.h>
0009 #include <linux/uaccess.h>
0010 #include <linux/hardirq.h>
0011 #include <linux/kdebug.h>
0012 #include <linux/export.h>
0013 #include <linux/ptrace.h>
0014 #include <linux/kexec.h>
0015 #include <linux/sysfs.h>
0016 #include <linux/bug.h>
0017 #include <linux/nmi.h>
0018 
0019 #include <asm/stacktrace.h>
0020 
0021 const char *stack_type_name(enum stack_type type)
0022 {
0023     if (type == STACK_TYPE_IRQ)
0024         return "IRQ";
0025 
0026     if (type == STACK_TYPE_SOFTIRQ)
0027         return "SOFTIRQ";
0028 
0029     if (type == STACK_TYPE_ENTRY)
0030         return "ENTRY_TRAMPOLINE";
0031 
0032     if (type == STACK_TYPE_EXCEPTION)
0033         return "#DF";
0034 
0035     return NULL;
0036 }
0037 
0038 static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info)
0039 {
0040     unsigned long *begin = (unsigned long *)this_cpu_read(hardirq_stack_ptr);
0041     unsigned long *end   = begin + (THREAD_SIZE / sizeof(long));
0042 
0043     /*
0044      * This is a software stack, so 'end' can be a valid stack pointer.
0045      * It just means the stack is empty.
0046      */
0047     if (stack < begin || stack > end)
0048         return false;
0049 
0050     info->type  = STACK_TYPE_IRQ;
0051     info->begin = begin;
0052     info->end   = end;
0053 
0054     /*
0055      * See irq_32.c -- the next stack pointer is stored at the beginning of
0056      * the stack.
0057      */
0058     info->next_sp   = (unsigned long *)*begin;
0059 
0060     return true;
0061 }
0062 
0063 static bool in_softirq_stack(unsigned long *stack, struct stack_info *info)
0064 {
0065     unsigned long *begin = (unsigned long *)this_cpu_read(softirq_stack_ptr);
0066     unsigned long *end   = begin + (THREAD_SIZE / sizeof(long));
0067 
0068     /*
0069      * This is a software stack, so 'end' can be a valid stack pointer.
0070      * It just means the stack is empty.
0071      */
0072     if (stack < begin || stack > end)
0073         return false;
0074 
0075     info->type  = STACK_TYPE_SOFTIRQ;
0076     info->begin = begin;
0077     info->end   = end;
0078 
0079     /*
0080      * The next stack pointer is stored at the beginning of the stack.
0081      * See irq_32.c.
0082      */
0083     info->next_sp   = (unsigned long *)*begin;
0084 
0085     return true;
0086 }
0087 
0088 static bool in_doublefault_stack(unsigned long *stack, struct stack_info *info)
0089 {
0090     struct cpu_entry_area *cea = get_cpu_entry_area(raw_smp_processor_id());
0091     struct doublefault_stack *ss = &cea->doublefault_stack;
0092 
0093     void *begin = ss->stack;
0094     void *end = begin + sizeof(ss->stack);
0095 
0096     if ((void *)stack < begin || (void *)stack >= end)
0097         return false;
0098 
0099     info->type  = STACK_TYPE_EXCEPTION;
0100     info->begin = begin;
0101     info->end   = end;
0102     info->next_sp   = (unsigned long *)this_cpu_read(cpu_tss_rw.x86_tss.sp);
0103 
0104     return true;
0105 }
0106 
0107 
0108 int get_stack_info(unsigned long *stack, struct task_struct *task,
0109            struct stack_info *info, unsigned long *visit_mask)
0110 {
0111     if (!stack)
0112         goto unknown;
0113 
0114     task = task ? : current;
0115 
0116     if (in_task_stack(stack, task, info))
0117         goto recursion_check;
0118 
0119     if (task != current)
0120         goto unknown;
0121 
0122     if (in_entry_stack(stack, info))
0123         goto recursion_check;
0124 
0125     if (in_hardirq_stack(stack, info))
0126         goto recursion_check;
0127 
0128     if (in_softirq_stack(stack, info))
0129         goto recursion_check;
0130 
0131     if (in_doublefault_stack(stack, info))
0132         goto recursion_check;
0133 
0134     goto unknown;
0135 
0136 recursion_check:
0137     /*
0138      * Make sure we don't iterate through any given stack more than once.
0139      * If it comes up a second time then there's something wrong going on:
0140      * just break out and report an unknown stack type.
0141      */
0142     if (visit_mask) {
0143         if (*visit_mask & (1UL << info->type)) {
0144             printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type);
0145             goto unknown;
0146         }
0147         *visit_mask |= 1UL << info->type;
0148     }
0149 
0150     return 0;
0151 
0152 unknown:
0153     info->type = STACK_TYPE_UNKNOWN;
0154     return -EINVAL;
0155 }