summaryrefslogtreecommitdiff
path: root/drivers/misc/tegra-profiler/backtrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/tegra-profiler/backtrace.c')
-rw-r--r--drivers/misc/tegra-profiler/backtrace.c38
1 files changed, 19 insertions, 19 deletions
diff --git a/drivers/misc/tegra-profiler/backtrace.c b/drivers/misc/tegra-profiler/backtrace.c
index 675ce85373f4..2dc39b1d018c 100644
--- a/drivers/misc/tegra-profiler/backtrace.c
+++ b/drivers/misc/tegra-profiler/backtrace.c
@@ -27,16 +27,7 @@
#include "eh_unwind.h"
#include "dwarf_unwind.h"
#include "hrt.h"
-
-static inline int
-is_thumb_mode(struct pt_regs *regs)
-{
-#ifdef CONFIG_ARM64
- return compat_thumb_mode(regs);
-#else
- return thumb_mode(regs);
-#endif
-}
+#include "tegra.h"
unsigned long
quadd_user_stack_pointer(struct pt_regs *regs)
@@ -177,6 +168,8 @@ user_backtrace(struct pt_regs *regs,
}
fp_prev = (unsigned long __user *)value_fp;
+ if (fp_prev <= tail)
+ return NULL;
nr_added = quadd_callchain_store(cc, value_lr, QUADD_UNW_TYPE_FP);
if (nr_added == 0)
@@ -186,9 +179,6 @@ user_backtrace(struct pt_regs *regs,
is_ex_entry_exist(regs, value_lr, task))
return NULL;
- if (fp_prev <= tail)
- return NULL;
-
return fp_prev;
}
@@ -364,6 +354,8 @@ user_backtrace_compat(struct pt_regs *regs,
}
fp_prev = (u32 __user *)(unsigned long)value_fp;
+ if (fp_prev <= tail)
+ return NULL;
nr_added = quadd_callchain_store(cc, value_lr, QUADD_UNW_TYPE_FP);
if (nr_added == 0)
@@ -373,9 +365,6 @@ user_backtrace_compat(struct pt_regs *regs,
is_ex_entry_exist(regs, value_lr, task))
return NULL;
- if (fp_prev <= tail)
- return NULL;
-
return fp_prev;
}
@@ -534,9 +523,11 @@ get_user_callchain_ut(struct pt_regs *regs,
struct task_struct *task)
{
int nr_prev;
+ unsigned long prev_sp;
do {
nr_prev = cc->nr;
+ prev_sp = cc->curr_sp;
quadd_get_user_cc_dwarf(regs, cc, task);
if (nr_prev > 0 && cc->nr == nr_prev)
@@ -545,7 +536,8 @@ get_user_callchain_ut(struct pt_regs *regs,
nr_prev = cc->nr;
quadd_get_user_cc_arm32_ehabi(regs, cc, task);
- } while (nr_prev != cc->nr);
+ } while (nr_prev != cc->nr &&
+ (cc->nr <= 1 || cc->curr_sp > prev_sp));
return cc->nr;
}
@@ -556,18 +548,26 @@ get_user_callchain_mixed(struct pt_regs *regs,
struct task_struct *task)
{
int nr_prev;
+ unsigned long prev_sp;
do {
nr_prev = cc->nr;
+ prev_sp = cc->curr_sp;
quadd_get_user_cc_dwarf(regs, cc, task);
quadd_get_user_cc_arm32_ehabi(regs, cc, task);
- if (nr_prev != cc->nr)
+ if (nr_prev != cc->nr) {
+ if (cc->nr > 1 &&
+ cc->curr_sp <= prev_sp)
+ break;
+
continue;
+ }
__get_user_callchain_fp(regs, cc, task);
- } while (nr_prev != cc->nr);
+ } while (nr_prev != cc->nr &&
+ (cc->nr <= 1 || cc->curr_sp > prev_sp));
return cc->nr;
}