summaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorIgor Nabirushkin <inabirushkin@nvidia.com>2015-03-09 20:16:55 +0400
committerWinnie Hsu <whsu@nvidia.com>2015-05-29 14:26:33 -0700
commite30edba528782364cfeb680d9719d1c0a6df4f28 (patch)
treeed6f4c6e483a2cd8f698b0d170be1219aef48d15 /drivers/misc
parent7ab896683d3cb0d6f9bf7758f36fe35a0eabb308 (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.c38
-rw-r--r--drivers/misc/tegra-profiler/power_clk.c4
-rw-r--r--drivers/misc/tegra-profiler/version.h2
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 */