diff options
Diffstat (limited to 'arch/arm/oprofile/common.c')
-rw-r--r-- | arch/arm/oprofile/common.c | 132 |
1 files changed, 0 insertions, 132 deletions
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c deleted file mode 100644 index 7cb3e0453fcd..000000000000 --- a/arch/arm/oprofile/common.c +++ /dev/null @@ -1,132 +0,0 @@ -/** - * @file common.c - * - * @remark Copyright 2004 Oprofile Authors - * @remark Copyright 2010 ARM Ltd. - * @remark Read the file COPYING - * - * @author Zwane Mwaikambo - * @author Will Deacon [move to perf] - */ - -#include <linux/cpumask.h> -#include <linux/init.h> -#include <linux/mutex.h> -#include <linux/oprofile.h> -#include <linux/perf_event.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <asm/stacktrace.h> -#include <linux/uaccess.h> - -#include <asm/perf_event.h> -#include <asm/ptrace.h> - -#ifdef CONFIG_HW_PERF_EVENTS - -/* - * OProfile has a curious naming scheme for the ARM PMUs, but they are - * part of the user ABI so we need to map from the perf PMU name for - * supported PMUs. - */ -static struct op_perf_name { - char *perf_name; - char *op_name; -} op_perf_name_map[] = { - { "armv5_xscale1", "arm/xscale1" }, - { "armv5_xscale2", "arm/xscale2" }, - { "armv6_1136", "arm/armv6" }, - { "armv6_1156", "arm/armv6" }, - { "armv6_1176", "arm/armv6" }, - { "armv6_11mpcore", "arm/mpcore" }, - { "armv7_cortex_a8", "arm/armv7" }, - { "armv7_cortex_a9", "arm/armv7-ca9" }, -}; - -char *op_name_from_perf_id(void) -{ - int i; - struct op_perf_name names; - const char *perf_name = perf_pmu_name(); - - for (i = 0; i < ARRAY_SIZE(op_perf_name_map); ++i) { - names = op_perf_name_map[i]; - if (!strcmp(names.perf_name, perf_name)) - return names.op_name; - } - - return NULL; -} -#endif - -static int report_trace(struct stackframe *frame, void *d) -{ - unsigned int *depth = d; - - if (*depth) { - oprofile_add_trace(frame->pc); - (*depth)--; - } - - return *depth == 0; -} - -/* - * The registers we're interested in are at the end of the variable - * length saved register structure. The fp points at the end of this - * structure so the address of this struct is: - * (struct frame_tail *)(xxx->fp)-1 - */ -struct frame_tail { - struct frame_tail *fp; - unsigned long sp; - unsigned long lr; -} __attribute__((packed)); - -static struct frame_tail* user_backtrace(struct frame_tail *tail) -{ - struct frame_tail buftail[2]; - - /* Also check accessibility of one struct frame_tail beyond */ - if (!access_ok(tail, sizeof(buftail))) - return NULL; - if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail))) - return NULL; - - oprofile_add_trace(buftail[0].lr); - - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if (tail + 1 >= buftail[0].fp) - return NULL; - - return buftail[0].fp-1; -} - -static void arm_backtrace(struct pt_regs * const regs, unsigned int depth) -{ - struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1; - - if (!user_mode(regs)) { - struct stackframe frame; - arm_get_current_stackframe(regs, &frame); - walk_stackframe(&frame, report_trace, &depth); - return; - } - - while (depth-- && tail && !((unsigned long) tail & 3)) - tail = user_backtrace(tail); -} - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - /* provide backtrace support also in timer mode: */ - ops->backtrace = arm_backtrace; - - return oprofile_perf_init(ops); -} - -void oprofile_arch_exit(void) -{ - oprofile_perf_exit(); -} |