diff options
Diffstat (limited to 'drivers/misc/tegra-profiler/backtrace.c')
-rw-r--r-- | drivers/misc/tegra-profiler/backtrace.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/misc/tegra-profiler/backtrace.c b/drivers/misc/tegra-profiler/backtrace.c index 340f4faa1405..3191def82ce0 100644 --- a/drivers/misc/tegra-profiler/backtrace.c +++ b/drivers/misc/tegra-profiler/backtrace.c @@ -17,7 +17,9 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/module.h> -#include <asm-generic/uaccess.h> +#include <linux/uaccess.h> +#include <linux/sched.h> +#include <linux/mm.h> #include <linux/tegra_profiler.h> @@ -111,7 +113,7 @@ quadd_get_user_callchain(struct pt_regs *regs, callchain_data->nr = 0; - if (!regs || !user_mode(regs) || !mm) + if (!regs || !mm) return 0; if (thumb_mode(regs)) @@ -126,12 +128,18 @@ quadd_get_user_callchain(struct pt_regs *regs, return 0; vma = find_vma(mm, sp); + if (!vma) + return 0; + if (check_vma_address(fp, vma)) return 0; - if (__copy_from_user_inatomic(®, (unsigned long __user *)fp, - sizeof(unsigned long))) + if (probe_kernel_address(fp, reg)) { + pr_warn_once("frame error: sp/fp: %#lx/%#lx, pc/lr: %#lx/%#lx, vma: %#lx-%#lx\n", + sp, fp, regs->ARM_pc, regs->ARM_lr, + vma->vm_start, vma->vm_end); return 0; + } if (thumb_mode(regs)) { if (reg <= fp || check_vma_address(reg, vma)) |