diff options
author | Igor Nabirushkin <inabirushkin@nvidia.com> | 2015-03-09 20:16:55 +0400 |
---|---|---|
committer | Winnie Hsu <whsu@nvidia.com> | 2015-05-29 14:26:33 -0700 |
commit | e30edba528782364cfeb680d9719d1c0a6df4f28 (patch) | |
tree | ed6f4c6e483a2cd8f698b0d170be1219aef48d15 /drivers/misc | |
parent | 7ab896683d3cb0d6f9bf7758f36fe35a0eabb308 (diff) |
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 <inabirushkin@nvidia.com>
Reviewed-on: http://git-master/r/715291
(cherry picked from commit d8e79953332c96786da5f57475013b045d7ef817)
Reviewed-on: http://git-master/r/747752
GVS: Gerrit_Virtual_Submit
Reviewed-by: Andrey Trachenko <atrachenko@nvidia.com>
Reviewed-by: Winnie Hsu <whsu@nvidia.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/tegra-profiler/backtrace.c | 38 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/power_clk.c | 4 | ||||
-rw-r--r-- | 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 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; } diff --git a/drivers/misc/tegra-profiler/power_clk.c b/drivers/misc/tegra-profiler/power_clk.c index b29c24dde327..fc31eccb436d 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 e92e395940fd..bf4c27597c4a 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 */ |