0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef __ASM_STACKTRACE_COMMON_H
0017 #define __ASM_STACKTRACE_COMMON_H
0018
0019 #include <linux/bitmap.h>
0020 #include <linux/bitops.h>
0021 #include <linux/kprobes.h>
0022 #include <linux/types.h>
0023
0024 enum stack_type {
0025 STACK_TYPE_UNKNOWN,
0026 STACK_TYPE_TASK,
0027 STACK_TYPE_IRQ,
0028 STACK_TYPE_OVERFLOW,
0029 STACK_TYPE_SDEI_NORMAL,
0030 STACK_TYPE_SDEI_CRITICAL,
0031 STACK_TYPE_HYP,
0032 __NR_STACK_TYPES
0033 };
0034
0035 struct stack_info {
0036 unsigned long low;
0037 unsigned long high;
0038 enum stack_type type;
0039 };
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 struct unwind_state {
0065 unsigned long fp;
0066 unsigned long pc;
0067 DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES);
0068 unsigned long prev_fp;
0069 enum stack_type prev_type;
0070 #ifdef CONFIG_KRETPROBES
0071 struct llist_node *kr_cur;
0072 #endif
0073 struct task_struct *task;
0074 };
0075
0076 static inline bool on_stack(unsigned long sp, unsigned long size,
0077 unsigned long low, unsigned long high,
0078 enum stack_type type, struct stack_info *info)
0079 {
0080 if (!low)
0081 return false;
0082
0083 if (sp < low || sp + size < sp || sp + size > high)
0084 return false;
0085
0086 if (info) {
0087 info->low = low;
0088 info->high = high;
0089 info->type = type;
0090 }
0091 return true;
0092 }
0093
0094 static inline void unwind_init_common(struct unwind_state *state,
0095 struct task_struct *task)
0096 {
0097 state->task = task;
0098 #ifdef CONFIG_KRETPROBES
0099 state->kr_cur = NULL;
0100 #endif
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 bitmap_zero(state->stacks_done, __NR_STACK_TYPES);
0112 state->prev_fp = 0;
0113 state->prev_type = STACK_TYPE_UNKNOWN;
0114 }
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 typedef bool (*stack_trace_translate_fp_fn)(unsigned long *fp,
0127 enum stack_type type);
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 typedef bool (*on_accessible_stack_fn)(const struct task_struct *tsk,
0139 unsigned long sp, unsigned long size,
0140 struct stack_info *info);
0141
0142 static inline int unwind_next_common(struct unwind_state *state,
0143 struct stack_info *info,
0144 on_accessible_stack_fn accessible,
0145 stack_trace_translate_fp_fn translate_fp)
0146 {
0147 unsigned long fp = state->fp, kern_fp = fp;
0148 struct task_struct *tsk = state->task;
0149
0150 if (fp & 0x7)
0151 return -EINVAL;
0152
0153 if (!accessible(tsk, fp, 16, info))
0154 return -EINVAL;
0155
0156 if (test_bit(info->type, state->stacks_done))
0157 return -EINVAL;
0158
0159
0160
0161
0162
0163 if (translate_fp && !translate_fp(&kern_fp, info->type))
0164 return -EINVAL;
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 if (info->type == state->prev_type) {
0181 if (fp <= state->prev_fp)
0182 return -EINVAL;
0183 } else {
0184 __set_bit(state->prev_type, state->stacks_done);
0185 }
0186
0187
0188
0189
0190
0191 state->fp = READ_ONCE(*(unsigned long *)(kern_fp));
0192 state->pc = READ_ONCE(*(unsigned long *)(kern_fp + 8));
0193 state->prev_fp = fp;
0194 state->prev_type = info->type;
0195
0196 return 0;
0197 }
0198
0199 #endif