1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #include <linux/sched.h> 3 #include <linux/sched/task.h> 4 #include <linux/sched/task_stack.h> 5 #include <linux/interrupt.h> 6 #include <asm/sections.h> 7 #include <asm/ptrace.h> 8 #include <asm/bitops.h> 9 #include <asm/stacktrace.h> 10 #include <asm/unwind.h> 11 12 unsigned long unwind_get_return_address(struct unwind_state *state) 13 { 14 if (unwind_done(state)) 15 return 0; 16 return __kernel_text_address(state->ip) ? state->ip : 0; 17 } 18 EXPORT_SYMBOL_GPL(unwind_get_return_address); 19 20 static bool outside_of_stack(struct unwind_state *state, unsigned long sp) 21 { 22 return (sp <= state->sp) || 23 (sp > state->stack_info.end - sizeof(struct stack_frame)); 24 } 25 26 static bool update_stack_info(struct unwind_state *state, unsigned long sp) 27 { 28 struct stack_info *info = &state->stack_info; 29 unsigned long *mask = &state->stack_mask; 30 31 /* New stack pointer leaves the current stack */ 32 if (get_stack_info(sp, state->task, info, mask) != 0 || 33 !on_stack(info, sp, sizeof(struct stack_frame))) 34 /* 'sp' does not point to a valid stack */ 35 return false; 36 return true; 37 } 38 39 static inline bool is_task_pt_regs(struct unwind_state *state, 40 struct pt_regs *regs) 41 { 42 return task_pt_regs(state->task) == regs; 43 } 44 45 bool unwind_next_frame(struct unwind_state *state) 46 { 47 struct stack_info *info = &state->stack_info; 48 struct stack_frame *sf; 49 struct pt_regs *regs; 50 unsigned long sp, ip; 51 bool reliable; 52 53 regs = state->regs; 54 if (unlikely(regs)) { 55 sp = state->sp; 56 sf = (struct stack_frame *) sp; 57 ip = READ_ONCE_NOCHECK(sf->gprs[8]); 58 reliable = false; 59 regs = NULL; 60 } else { 61 sf = (struct stack_frame *) state->sp; 62 sp = READ_ONCE_NOCHECK(sf->back_chain); 63 if (likely(sp)) { 64 /* Non-zero back-chain points to the previous frame */ 65 if (unlikely(outside_of_stack(state, sp))) { 66 if (!update_stack_info(state, sp)) 67 goto out_err; 68 } 69 sf = (struct stack_frame *) sp; 70 ip = READ_ONCE_NOCHECK(sf->gprs[8]); 71 reliable = true; 72 } else { 73 /* No back-chain, look for a pt_regs structure */ 74 sp = state->sp + STACK_FRAME_OVERHEAD; 75 if (!on_stack(info, sp, sizeof(struct pt_regs))) 76 goto out_err; 77 regs = (struct pt_regs *) sp; 78 if (is_task_pt_regs(state, regs)) 79 goto out_stop; 80 ip = READ_ONCE_NOCHECK(regs->psw.addr); 81 sp = READ_ONCE_NOCHECK(regs->gprs[15]); 82 if (unlikely(outside_of_stack(state, sp))) { 83 if (!update_stack_info(state, sp)) 84 goto out_err; 85 } 86 reliable = true; 87 } 88 } 89 90 ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, ip, (void *) sp); 91 92 /* Update unwind state */ 93 state->sp = sp; 94 state->ip = ip; 95 state->regs = regs; 96 state->reliable = reliable; 97 return true; 98 99 out_err: 100 state->error = true; 101 out_stop: 102 state->stack_info.type = STACK_TYPE_UNKNOWN; 103 return false; 104 } 105 EXPORT_SYMBOL_GPL(unwind_next_frame); 106 107 void __unwind_start(struct unwind_state *state, struct task_struct *task, 108 struct pt_regs *regs, unsigned long first_frame) 109 { 110 struct stack_info *info = &state->stack_info; 111 struct stack_frame *sf; 112 unsigned long ip, sp; 113 114 memset(state, 0, sizeof(*state)); 115 state->task = task; 116 state->regs = regs; 117 118 /* Don't even attempt to start from user mode regs: */ 119 if (regs && user_mode(regs)) { 120 info->type = STACK_TYPE_UNKNOWN; 121 return; 122 } 123 124 /* Get the instruction pointer from pt_regs or the stack frame */ 125 if (regs) { 126 ip = regs->psw.addr; 127 sp = regs->gprs[15]; 128 } else if (task == current) { 129 sp = current_frame_address(); 130 } else { 131 sp = task->thread.ksp; 132 } 133 134 /* Get current stack pointer and initialize stack info */ 135 if (!update_stack_info(state, sp)) { 136 /* Something is wrong with the stack pointer */ 137 info->type = STACK_TYPE_UNKNOWN; 138 state->error = true; 139 return; 140 } 141 142 if (!regs) { 143 /* Stack frame is within valid stack */ 144 sf = (struct stack_frame *)sp; 145 ip = READ_ONCE_NOCHECK(sf->gprs[8]); 146 } 147 148 ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, ip, NULL); 149 150 /* Update unwind state */ 151 state->sp = sp; 152 state->ip = ip; 153 state->reliable = true; 154 155 if (!first_frame) 156 return; 157 /* Skip through the call chain to the specified starting frame */ 158 while (!unwind_done(state)) { 159 if (on_stack(&state->stack_info, first_frame, sizeof(struct stack_frame))) { 160 if (state->sp >= first_frame) 161 break; 162 } 163 unwind_next_frame(state); 164 } 165 } 166 EXPORT_SYMBOL_GPL(__unwind_start); 167