From d8e79953332c96786da5f57475013b045d7ef817 Mon Sep 17 00:00:00 2001 From: Igor Nabirushkin Date: Mon, 9 Mar 2015 20:16:55 +0400 Subject: [PATCH] misc: tegra-profiler: prevent infinite loop * Prevent false recursion in mixed mode. * Unwinding based on frame pointers: do not save lr address if previous frame is incorrect. Bug 1619030 Change-Id: Iadeb8ca87ead576b18821964878cddf7aa94cf27 Signed-off-by: Igor Nabirushkin Reviewed-on: http://git-master/r/715291 Tested-by: Maxim Morin GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani --- drivers/misc/tegra-profiler/backtrace.c | 38 ++++++++++++------------- drivers/misc/tegra-profiler/power_clk.c | 4 +-- drivers/misc/tegra-profiler/version.h | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/misc/tegra-profiler/backtrace.c b/drivers/misc/tegra-profiler/backtrace.c index 675ce85373f..2dc39b1d018 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; } diff --git a/drivers/misc/tegra-profiler/power_clk.c b/drivers/misc/tegra-profiler/power_clk.c index b29c24dde32..fc31eccb436 100644 --- a/drivers/misc/tegra-profiler/power_clk.c +++ b/drivers/misc/tegra-profiler/power_clk.c @@ -118,11 +118,11 @@ static void make_sample(void) power_rate->emc = 0; mutex_unlock(&s->lock); - +/* pr_debug("make_sample: cpu: %u/%u/%u/%u, gpu: %u, emc: %u\n", extra_cpus[0], extra_cpus[1], extra_cpus[2], extra_cpus[3], power_rate->gpu, power_rate->emc); - +*/ vec.base = extra_cpus; vec.len = power_rate->nr_cpus * sizeof(extra_cpus[0]); diff --git a/drivers/misc/tegra-profiler/version.h b/drivers/misc/tegra-profiler/version.h index e92e395940f..bf4c27597c4 100644 --- a/drivers/misc/tegra-profiler/version.h +++ b/drivers/misc/tegra-profiler/version.h @@ -18,7 +18,7 @@ #ifndef __QUADD_VERSION_H #define __QUADD_VERSION_H -#define QUADD_MODULE_VERSION "1.94" +#define QUADD_MODULE_VERSION "1.95" #define QUADD_MODULE_BRANCH "Dev" #endif /* __QUADD_VERSION_H */ -- 2.39.2