unwind_bc.c (355a47ae7ebcf9d605aa809b259d380422e81b8d) | unwind_bc.c (20955746320e252b41c6b3505587766012e3e06d) |
---|---|
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> --- 32 unchanged lines hidden (view full) --- 41 struct stack_info *info = &state->stack_info; 42 struct stack_frame *sf; 43 struct pt_regs *regs; 44 unsigned long sp, ip; 45 bool reliable; 46 47 regs = state->regs; 48 if (unlikely(regs)) { | 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> --- 32 unchanged lines hidden (view full) --- 41 struct stack_info *info = &state->stack_info; 42 struct stack_frame *sf; 43 struct pt_regs *regs; 44 unsigned long sp, ip; 45 bool reliable; 46 47 regs = state->regs; 48 if (unlikely(regs)) { |
49 sp = READ_ONCE_TASK_STACK(state->task, regs->gprs[15]); | 49 sp = READ_ONCE_NOCHECK(regs->gprs[15]); |
50 if (unlikely(outside_of_stack(state, sp))) { 51 if (!update_stack_info(state, sp)) 52 goto out_err; 53 } 54 sf = (struct stack_frame *) sp; | 50 if (unlikely(outside_of_stack(state, sp))) { 51 if (!update_stack_info(state, sp)) 52 goto out_err; 53 } 54 sf = (struct stack_frame *) sp; |
55 ip = READ_ONCE_TASK_STACK(state->task, sf->gprs[8]); | 55 ip = READ_ONCE_NOCHECK(sf->gprs[8]); |
56 reliable = false; 57 regs = NULL; 58 } else { 59 sf = (struct stack_frame *) state->sp; | 56 reliable = false; 57 regs = NULL; 58 } else { 59 sf = (struct stack_frame *) state->sp; |
60 sp = READ_ONCE_TASK_STACK(state->task, sf->back_chain); | 60 sp = READ_ONCE_NOCHECK(sf->back_chain); |
61 if (likely(sp)) { 62 /* Non-zero back-chain points to the previous frame */ 63 if (unlikely(outside_of_stack(state, sp))) { 64 if (!update_stack_info(state, sp)) 65 goto out_err; 66 } 67 sf = (struct stack_frame *) sp; | 61 if (likely(sp)) { 62 /* Non-zero back-chain points to the previous frame */ 63 if (unlikely(outside_of_stack(state, sp))) { 64 if (!update_stack_info(state, sp)) 65 goto out_err; 66 } 67 sf = (struct stack_frame *) sp; |
68 ip = READ_ONCE_TASK_STACK(state->task, sf->gprs[8]); | 68 ip = READ_ONCE_NOCHECK(sf->gprs[8]); |
69 reliable = true; 70 } else { 71 /* No back-chain, look for a pt_regs structure */ 72 sp = state->sp + STACK_FRAME_OVERHEAD; 73 if (!on_stack(info, sp, sizeof(struct pt_regs))) 74 goto out_stop; 75 regs = (struct pt_regs *) sp; | 69 reliable = true; 70 } else { 71 /* No back-chain, look for a pt_regs structure */ 72 sp = state->sp + STACK_FRAME_OVERHEAD; 73 if (!on_stack(info, sp, sizeof(struct pt_regs))) 74 goto out_stop; 75 regs = (struct pt_regs *) sp; |
76 if (user_mode(regs)) | 76 if (READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE) |
77 goto out_stop; | 77 goto out_stop; |
78 ip = READ_ONCE_TASK_STACK(state->task, regs->psw.addr); | 78 ip = READ_ONCE_NOCHECK(regs->psw.addr); |
79 reliable = true; 80 } 81 } 82 83#ifdef CONFIG_FUNCTION_GRAPH_TRACER 84 /* Decode any ftrace redirection */ 85 if (ip == (unsigned long) return_to_handler) 86 ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, --- 40 unchanged lines hidden (view full) --- 127 /* Something is wrong with the stack pointer */ 128 info->type = STACK_TYPE_UNKNOWN; 129 state->error = true; 130 return; 131 } 132 133 /* Get the instruction pointer from pt_regs or the stack frame */ 134 if (regs) { | 79 reliable = true; 80 } 81 } 82 83#ifdef CONFIG_FUNCTION_GRAPH_TRACER 84 /* Decode any ftrace redirection */ 85 if (ip == (unsigned long) return_to_handler) 86 ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, --- 40 unchanged lines hidden (view full) --- 127 /* Something is wrong with the stack pointer */ 128 info->type = STACK_TYPE_UNKNOWN; 129 state->error = true; 130 return; 131 } 132 133 /* Get the instruction pointer from pt_regs or the stack frame */ 134 if (regs) { |
135 ip = READ_ONCE_TASK_STACK(state->task, regs->psw.addr); | 135 ip = READ_ONCE_NOCHECK(regs->psw.addr); |
136 reliable = true; 137 } else { 138 sf = (struct stack_frame *) sp; | 136 reliable = true; 137 } else { 138 sf = (struct stack_frame *) sp; |
139 ip = READ_ONCE_TASK_STACK(state->task, sf->gprs[8]); | 139 ip = READ_ONCE_NOCHECK(sf->gprs[8]); |
140 reliable = false; 141 } 142 143#ifdef CONFIG_FUNCTION_GRAPH_TRACER 144 /* Decode any ftrace redirection */ 145 if (ip == (unsigned long) return_to_handler) 146 ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, 147 ip, NULL); 148#endif 149 150 /* Update unwind state */ 151 state->sp = sp; 152 state->ip = ip; 153 state->reliable = reliable; 154} 155EXPORT_SYMBOL_GPL(__unwind_start); | 140 reliable = false; 141 } 142 143#ifdef CONFIG_FUNCTION_GRAPH_TRACER 144 /* Decode any ftrace redirection */ 145 if (ip == (unsigned long) return_to_handler) 146 ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, 147 ip, NULL); 148#endif 149 150 /* Update unwind state */ 151 state->sp = sp; 152 state->ip = ip; 153 state->reliable = reliable; 154} 155EXPORT_SYMBOL_GPL(__unwind_start); |