dumpstack_64.c (5492B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs 5 */ 6#include <linux/sched/debug.h> 7#include <linux/kallsyms.h> 8#include <linux/kprobes.h> 9#include <linux/uaccess.h> 10#include <linux/hardirq.h> 11#include <linux/kdebug.h> 12#include <linux/export.h> 13#include <linux/ptrace.h> 14#include <linux/kexec.h> 15#include <linux/sysfs.h> 16#include <linux/bug.h> 17#include <linux/nmi.h> 18 19#include <asm/cpu_entry_area.h> 20#include <asm/stacktrace.h> 21 22static const char * const exception_stack_names[] = { 23 [ ESTACK_DF ] = "#DF", 24 [ ESTACK_NMI ] = "NMI", 25 [ ESTACK_DB ] = "#DB", 26 [ ESTACK_MCE ] = "#MC", 27 [ ESTACK_VC ] = "#VC", 28 [ ESTACK_VC2 ] = "#VC2", 29}; 30 31const char *stack_type_name(enum stack_type type) 32{ 33 BUILD_BUG_ON(N_EXCEPTION_STACKS != 6); 34 35 if (type == STACK_TYPE_TASK) 36 return "TASK"; 37 38 if (type == STACK_TYPE_IRQ) 39 return "IRQ"; 40 41 if (type == STACK_TYPE_SOFTIRQ) 42 return "SOFTIRQ"; 43 44 if (type == STACK_TYPE_ENTRY) { 45 /* 46 * On 64-bit, we have a generic entry stack that we 47 * use for all the kernel entry points, including 48 * SYSENTER. 49 */ 50 return "ENTRY_TRAMPOLINE"; 51 } 52 53 if (type >= STACK_TYPE_EXCEPTION && type <= STACK_TYPE_EXCEPTION_LAST) 54 return exception_stack_names[type - STACK_TYPE_EXCEPTION]; 55 56 return NULL; 57} 58 59/** 60 * struct estack_pages - Page descriptor for exception stacks 61 * @offs: Offset from the start of the exception stack area 62 * @size: Size of the exception stack 63 * @type: Type to store in the stack_info struct 64 */ 65struct estack_pages { 66 u32 offs; 67 u16 size; 68 u16 type; 69}; 70 71#define EPAGERANGE(st) \ 72 [PFN_DOWN(CEA_ESTACK_OFFS(st)) ... \ 73 PFN_DOWN(CEA_ESTACK_OFFS(st) + CEA_ESTACK_SIZE(st) - 1)] = { \ 74 .offs = CEA_ESTACK_OFFS(st), \ 75 .size = CEA_ESTACK_SIZE(st), \ 76 .type = STACK_TYPE_EXCEPTION + ESTACK_ ##st, } 77 78/* 79 * Array of exception stack page descriptors. If the stack is larger than 80 * PAGE_SIZE, all pages covering a particular stack will have the same 81 * info. The guard pages including the not mapped DB2 stack are zeroed 82 * out. 83 */ 84static const 85struct estack_pages estack_pages[CEA_ESTACK_PAGES] ____cacheline_aligned = { 86 EPAGERANGE(DF), 87 EPAGERANGE(NMI), 88 EPAGERANGE(DB), 89 EPAGERANGE(MCE), 90 EPAGERANGE(VC), 91 EPAGERANGE(VC2), 92}; 93 94static __always_inline bool in_exception_stack(unsigned long *stack, struct stack_info *info) 95{ 96 unsigned long begin, end, stk = (unsigned long)stack; 97 const struct estack_pages *ep; 98 struct pt_regs *regs; 99 unsigned int k; 100 101 BUILD_BUG_ON(N_EXCEPTION_STACKS != 6); 102 103 begin = (unsigned long)__this_cpu_read(cea_exception_stacks); 104 /* 105 * Handle the case where stack trace is collected _before_ 106 * cea_exception_stacks had been initialized. 107 */ 108 if (!begin) 109 return false; 110 111 end = begin + sizeof(struct cea_exception_stacks); 112 /* Bail if @stack is outside the exception stack area. */ 113 if (stk < begin || stk >= end) 114 return false; 115 116 /* Calc page offset from start of exception stacks */ 117 k = (stk - begin) >> PAGE_SHIFT; 118 /* Lookup the page descriptor */ 119 ep = &estack_pages[k]; 120 /* Guard page? */ 121 if (!ep->size) 122 return false; 123 124 begin += (unsigned long)ep->offs; 125 end = begin + (unsigned long)ep->size; 126 regs = (struct pt_regs *)end - 1; 127 128 info->type = ep->type; 129 info->begin = (unsigned long *)begin; 130 info->end = (unsigned long *)end; 131 info->next_sp = (unsigned long *)regs->sp; 132 return true; 133} 134 135static __always_inline bool in_irq_stack(unsigned long *stack, struct stack_info *info) 136{ 137 unsigned long *end = (unsigned long *)this_cpu_read(hardirq_stack_ptr); 138 unsigned long *begin; 139 140 /* 141 * @end points directly to the top most stack entry to avoid a -8 142 * adjustment in the stack switch hotpath. Adjust it back before 143 * calculating @begin. 144 */ 145 end++; 146 begin = end - (IRQ_STACK_SIZE / sizeof(long)); 147 148 /* 149 * Due to the switching logic RSP can never be == @end because the 150 * final operation is 'popq %rsp' which means after that RSP points 151 * to the original stack and not to @end. 152 */ 153 if (stack < begin || stack >= end) 154 return false; 155 156 info->type = STACK_TYPE_IRQ; 157 info->begin = begin; 158 info->end = end; 159 160 /* 161 * The next stack pointer is stored at the top of the irq stack 162 * before switching to the irq stack. Actual stack entries are all 163 * below that. 164 */ 165 info->next_sp = (unsigned long *)*(end - 1); 166 167 return true; 168} 169 170bool noinstr get_stack_info_noinstr(unsigned long *stack, struct task_struct *task, 171 struct stack_info *info) 172{ 173 if (in_task_stack(stack, task, info)) 174 return true; 175 176 if (task != current) 177 return false; 178 179 if (in_exception_stack(stack, info)) 180 return true; 181 182 if (in_irq_stack(stack, info)) 183 return true; 184 185 if (in_entry_stack(stack, info)) 186 return true; 187 188 return false; 189} 190 191int get_stack_info(unsigned long *stack, struct task_struct *task, 192 struct stack_info *info, unsigned long *visit_mask) 193{ 194 task = task ? : current; 195 196 if (!stack) 197 goto unknown; 198 199 if (!get_stack_info_noinstr(stack, task, info)) 200 goto unknown; 201 202 /* 203 * Make sure we don't iterate through any given stack more than once. 204 * If it comes up a second time then there's something wrong going on: 205 * just break out and report an unknown stack type. 206 */ 207 if (visit_mask) { 208 if (*visit_mask & (1UL << info->type)) { 209 if (task == current) 210 printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n", info->type); 211 goto unknown; 212 } 213 *visit_mask |= 1UL << info->type; 214 } 215 216 return 0; 217 218unknown: 219 info->type = STACK_TYPE_UNKNOWN; 220 return -EINVAL; 221}