0001
0002 #include <linux/sched.h>
0003 #include <linux/sched/task.h>
0004 #include <linux/sched/task_stack.h>
0005 #include <linux/interrupt.h>
0006 #include <asm/sections.h>
0007 #include <asm/ptrace.h>
0008 #include <asm/bitops.h>
0009 #include <asm/stacktrace.h>
0010 #include <asm/unwind.h>
0011
0012 unsigned long unwind_get_return_address(struct unwind_state *state)
0013 {
0014 if (unwind_done(state))
0015 return 0;
0016 return __kernel_text_address(state->ip) ? state->ip : 0;
0017 }
0018 EXPORT_SYMBOL_GPL(unwind_get_return_address);
0019
0020 static bool outside_of_stack(struct unwind_state *state, unsigned long sp)
0021 {
0022 return (sp <= state->sp) ||
0023 (sp > state->stack_info.end - sizeof(struct stack_frame));
0024 }
0025
0026 static bool update_stack_info(struct unwind_state *state, unsigned long sp)
0027 {
0028 struct stack_info *info = &state->stack_info;
0029 unsigned long *mask = &state->stack_mask;
0030
0031
0032 if (get_stack_info(sp, state->task, info, mask) != 0 ||
0033 !on_stack(info, sp, sizeof(struct stack_frame)))
0034
0035 return false;
0036 return true;
0037 }
0038
0039 static inline bool is_final_pt_regs(struct unwind_state *state,
0040 struct pt_regs *regs)
0041 {
0042
0043 if (task_pt_regs(state->task) == regs)
0044 return true;
0045
0046
0047 return state->stack_info.type == STACK_TYPE_IRQ &&
0048 state->stack_info.end - sizeof(struct pt_regs) == (unsigned long)regs &&
0049 READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE;
0050 }
0051
0052 bool unwind_next_frame(struct unwind_state *state)
0053 {
0054 struct stack_info *info = &state->stack_info;
0055 struct stack_frame *sf;
0056 struct pt_regs *regs;
0057 unsigned long sp, ip;
0058 bool reliable;
0059
0060 regs = state->regs;
0061 if (unlikely(regs)) {
0062 sp = state->sp;
0063 sf = (struct stack_frame *) sp;
0064 ip = READ_ONCE_NOCHECK(sf->gprs[8]);
0065 reliable = false;
0066 regs = NULL;
0067
0068 if (!__kernel_text_address(ip) || state->ip == unwind_recover_ret_addr(state, ip)) {
0069 state->regs = NULL;
0070 return unwind_next_frame(state);
0071 }
0072 } else {
0073 sf = (struct stack_frame *) state->sp;
0074 sp = READ_ONCE_NOCHECK(sf->back_chain);
0075 if (likely(sp)) {
0076
0077 if (unlikely(outside_of_stack(state, sp))) {
0078 if (!update_stack_info(state, sp))
0079 goto out_err;
0080 }
0081 sf = (struct stack_frame *) sp;
0082 ip = READ_ONCE_NOCHECK(sf->gprs[8]);
0083 reliable = true;
0084 } else {
0085
0086 sp = state->sp + STACK_FRAME_OVERHEAD;
0087 if (!on_stack(info, sp, sizeof(struct pt_regs)))
0088 goto out_err;
0089 regs = (struct pt_regs *) sp;
0090 if (is_final_pt_regs(state, regs))
0091 goto out_stop;
0092 ip = READ_ONCE_NOCHECK(regs->psw.addr);
0093 sp = READ_ONCE_NOCHECK(regs->gprs[15]);
0094 if (unlikely(outside_of_stack(state, sp))) {
0095 if (!update_stack_info(state, sp))
0096 goto out_err;
0097 }
0098 reliable = true;
0099 }
0100 }
0101
0102
0103 if (sp & 0x7)
0104 goto out_err;
0105
0106
0107 state->sp = sp;
0108 state->regs = regs;
0109 state->reliable = reliable;
0110 state->ip = unwind_recover_ret_addr(state, ip);
0111 return true;
0112
0113 out_err:
0114 state->error = true;
0115 out_stop:
0116 state->stack_info.type = STACK_TYPE_UNKNOWN;
0117 return false;
0118 }
0119 EXPORT_SYMBOL_GPL(unwind_next_frame);
0120
0121 void __unwind_start(struct unwind_state *state, struct task_struct *task,
0122 struct pt_regs *regs, unsigned long first_frame)
0123 {
0124 struct stack_info *info = &state->stack_info;
0125 struct stack_frame *sf;
0126 unsigned long ip, sp;
0127
0128 memset(state, 0, sizeof(*state));
0129 state->task = task;
0130 state->regs = regs;
0131
0132
0133 if (regs && user_mode(regs)) {
0134 info->type = STACK_TYPE_UNKNOWN;
0135 return;
0136 }
0137
0138
0139 if (regs) {
0140 ip = regs->psw.addr;
0141 sp = regs->gprs[15];
0142 } else if (task == current) {
0143 sp = current_frame_address();
0144 } else {
0145 sp = task->thread.ksp;
0146 }
0147
0148
0149 if (!update_stack_info(state, sp)) {
0150
0151 info->type = STACK_TYPE_UNKNOWN;
0152 state->error = true;
0153 return;
0154 }
0155
0156 if (!regs) {
0157
0158 sf = (struct stack_frame *)sp;
0159 ip = READ_ONCE_NOCHECK(sf->gprs[8]);
0160 }
0161
0162
0163 state->sp = sp;
0164 state->reliable = true;
0165 state->ip = unwind_recover_ret_addr(state, ip);
0166
0167 if (!first_frame)
0168 return;
0169
0170 while (!unwind_done(state)) {
0171 if (on_stack(&state->stack_info, first_frame, sizeof(struct stack_frame))) {
0172 if (state->sp >= first_frame)
0173 break;
0174 }
0175 unwind_next_frame(state);
0176 }
0177 }
0178 EXPORT_SYMBOL_GPL(__unwind_start);