static inline void
ia64_do_profile (struct pt_regs * regs)
{
- unsigned long ip, slot;
+ unsigned long ip;
profile_hook(regs);
if (!prof_buffer)
return;
- ip = instruction_pointer(regs);
/* Conserve space in histogram by encoding slot bits in address
* bits 2 and 3 rather than bits 0 and 1.
*/
- slot = ip & 3;
- ip = (ip & ~3UL) + 4*slot;
+ ip = profile_pc(regs);
/*
* Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
if (!prof_buffer || !current->pid)
return;
- if (pc >= 0xa0000000UL && pc < 0xc0000000UL)
- pc -= 0x20000000;
-
pc -= (unsigned long)&_stext;
pc >>= prof_shift;
do_timer(regs);
if (!user_mode(regs))
- sh_do_profile(regs->pc);
+ sh_do_profile(profile_pc(regs));
#ifdef CONFIG_HEARTBEAT
if (sh_mv.mv_heartbeat != NULL)
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/swap.h>
+#include <linux/profile.h>
#include <asm/ptrace.h>
#include <asm/atomic.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/swap.h>
+#include <linux/profile.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#endif
+unsigned long profile_pc(struct pt_regs *regs)
+{
+ extern int __copy_user_begin, __copy_user_end;
+ extern int __atomic_begin, __atomic_end;
+ extern int __bzero_begin, __bzero_end;
+ extern int __bitops_begin, __bitops_end;
+ unsigned long pc = regs->pc;
+
+ if ((pc >= (unsigned long) &__copy_user_begin &&
+ pc < (unsigned long) &__copy_user_end) ||
+ (pc >= (unsigned long) &__atomic_begin &&
+ pc < (unsigned long) &__atomic_end) ||
+ (pc >= (unsigned long) &__bzero_begin &&
+ pc < (unsigned long) &__bzero_end) ||
+ (pc >= (unsigned long) &__bitops_begin &&
+ pc < (unsigned long) &__bitops_end))
+ pc = regs->u_regs[UREG_RETPC];
+ return pc;
+}
+
static spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED;
/* 32-bit Sparc specific profiling function. */
{
if(prof_buffer && current->pid) {
extern int _stext;
- extern int __copy_user_begin, __copy_user_end;
- extern int __atomic_begin, __atomic_end;
- extern int __bzero_begin, __bzero_end;
- extern int __bitops_begin, __bitops_end;
-
- if ((pc >= (unsigned long) &__copy_user_begin &&
- pc < (unsigned long) &__copy_user_end) ||
- (pc >= (unsigned long) &__atomic_begin &&
- pc < (unsigned long) &__atomic_end) ||
- (pc >= (unsigned long) &__bzero_begin &&
- pc < (unsigned long) &__bzero_end) ||
- (pc >= (unsigned long) &__bitops_begin &&
- pc < (unsigned long) &__bitops_end))
- pc = o7;
pc -= (unsigned long) &_stext;
pc >>= prof_shift;
#ifndef CONFIG_SMP
if(!user_mode(regs))
- sparc_do_profile(regs->pc, regs->u_regs[UREG_RETPC]);
+ sparc_do_profile(profile_pc(regs));
#endif
/* Protect counter clear so that do_gettimeoffset works */
#include <linux/seq_file.h>
#include <linux/cache.h>
#include <linux/jiffies.h>
+#include <linux/profile.h>
#include <asm/head.h>
#include <asm/ptrace.h>
#include <linux/jiffies.h>
#include <linux/cpufreq.h>
#include <linux/percpu.h>
+#include <linux/profile.h>
#include <asm/oplib.h>
#include <asm/mostek.h>
if (!prof_buffer)
return;
- pc = regs->tpc;
-
- pc -= (unsigned long) _stext;
- pc >>= prof_shift;
-
- if(pc >= prof_len)
- pc = prof_len - 1;
- atomic_inc((atomic_t *)&prof_buffer[pc]);
+ pc = (profile_pc(regs) - (unsigned long)_stext) >> prof_shift;
+ atomic_inc((atomic_t *)&prof_buffer[min(pc, prof_len-1)]);
}
static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
#ifdef __KERNEL__
#define user_mode(regs) (((regs)->ps & 8) != 0)
#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs *);
#define alpha_task_regs(task) \
#define instruction_pointer(regs) \
(pc_pointer((regs)->ARM_pc))
+#define profile_pc(regs) instruction_pointer(regs)
#ifdef __KERNEL__
extern void show_regs(struct pt_regs *);
#define pc_pointer(v) ((v) & ~PCMASK) /* convert v to pc type address */
#define instruction_pointer(regs) (pc_pointer((regs)->ARM_pc)) /* get pc */
+#define profile_pc(regs) instruction_pointer(regs)
/* this struct defines the way the registers are stored on the
stack during a system call. */
/* bit 8 is user-mode flag */
#define user_mode(regs) (((regs)->dccr & 0x100) != 0)
#define instruction_pointer(regs) ((regs)->irp)
+#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs *);
#endif
#define user_mode(regs) (!((regs)->ccr & PS_S))
#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs *);
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#ifdef __KERNEL__
#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs))
#define instruction_pointer(regs) ((regs)->eip)
+#define profile_pc(regs) instruction_pointer(regs)
#endif
#endif
* the canonical representation by adding to instruction pointer.
*/
# define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
+/* Conserve space in histogram by encoding slot bits in address
+ * bits 2 and 3 rather than bits 0 and 1.
+ */
+#define profile_pc(regs) \
+({ \
+ unsigned long __ip = instruction_pointer(regs); \
+ (__ip & ~3UL) + ((__ip & 3UL) << 2); \
+})
+
/* given a pointer to a task_struct, return the user's pt_regs */
# define ia64_task_regs(t) (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1)
# define ia64_psr(regs) ((struct ia64_psr *) &(regs)->cr_ipsr)
#define user_mode(regs) (!((regs)->sr & PS_S))
#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs *);
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#define user_mode(regs) (!((regs)->sr & PS_S))
#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs *);
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#define user_mode(regs) (((regs)->cp0_status & KU_MASK) == KU_USER)
#define instruction_pointer(regs) ((regs)->cp0_epc)
+#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs *);
/* XXX should we use iaoq[1] or iaoq[0] ? */
#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0)
#define instruction_pointer(regs) ((regs)->iaoq[0] & ~3)
+#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs *);
#endif
#ifndef __ASSEMBLY__
#define instruction_pointer(regs) ((regs)->nip)
+#define profile_pc(regs) instruction_pointer(regs)
#define user_mode(regs) (((regs)->msr & MSR_PR) != 0)
#define force_successful_syscall_return() \
#define __SIGNAL_FRAMESIZE32 64
#define instruction_pointer(regs) ((regs)->nip)
+#define profile_pc(regs) instruction_pointer(regs)
#define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
#define force_successful_syscall_return() \
#ifdef __KERNEL__
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
+#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs * regs);
#endif
#define user_mode(regs) (((regs)->sr & 0x40000000)==0)
#define instruction_pointer(regs) ((regs)->pc)
extern void show_regs(struct pt_regs *);
+
+static inline unsigned long profile_pc(struct pt_regs *regs)
+{
+ unsigned long pc = instruction_pointer(regs);
+
+ if (pc >= 0xa0000000UL && pc < 0xc0000000UL)
+ pc -= 0x20000000;
+ return pc;
+}
#endif
#endif /* __ASM_SH_PTRACE_H */
#ifdef __KERNEL__
#define user_mode(regs) (((regs)->sr & 0x40000000)==0)
#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs *);
#endif
#ifdef __KERNEL__
#define user_mode(regs) (!((regs)->psr & PSR_PS))
#define instruction_pointer(regs) ((regs)->pc)
+unsigned long profile_pc(struct pt_regs *);
extern void show_regs(struct pt_regs *);
#endif
set_thread_flag(TIF_SYSCALL_SUCCESS)
#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
#define instruction_pointer(regs) ((regs)->tpc)
+#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs *);
#endif
#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
#define user_mode(regs) (!(regs)->kernel_mode)
/* When a struct pt_regs is used to save user state for a system call in
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
#define user_mode(regs) (!!((regs)->cs & 3))
#define instruction_pointer(regs) ((regs)->rip)
+#define profile_pc(regs) instruction_pointer(regs)
void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
enum {