#include <linux/slab.h>
#include <asm/ptrace.h>
-void dtrace_skip_instruction(struct pt_regs *regs) {
+void dtrace_skip_instruction(struct pt_regs *regs)
+{
regs->tpc = regs->tnpc;
regs->tnpc += 4;
}
+void dtrace_handle_badaddr(struct pt_regs *regs) {
+ unsigned long addr = current_thread_info()->fault_address;
+
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+ this_cpu_core->cpuc_dtrace_illval = addr;
+
+ dtrace_skip_instruction(regs);
+}
int dtrace_die_notifier(struct notifier_block *nb, unsigned long val,
void *args)
switch (val) {
case DIE_PAGE_FAULT: {
- unsigned long addr = current_thread_info()->fault_address;
-
if (!DTRACE_CPUFLAG_ISSET(CPU_DTRACE_NOFAULT))
return NOTIFY_DONE;
- DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
- this_cpu_core->cpuc_dtrace_illval = addr;
-
- dtrace_skip_instruction(dargs->regs);
+ dtrace_handle_badaddr(dargs->regs);
return NOTIFY_OK | NOTIFY_STOP_MASK;
}
return NOTIFY_OK | NOTIFY_STOP_MASK;
}
case DIE_TRAP: {
- unsigned long addr = current_thread_info()->fault_address;
-
if (dargs->trapnr != 0x34)
return NOTIFY_DONE;
+
if (!DTRACE_CPUFLAG_ISSET(CPU_DTRACE_NOFAULT))
return NOTIFY_DONE;
- DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
-
- dtrace_skip_instruction(dargs->regs);
+ dtrace_handle_badaddr(dargs->regs);
return NOTIFY_OK | NOTIFY_STOP_MASK;
}
} stacktrace_state_t;
extern void dtrace_stacktrace(stacktrace_state_t *);
-extern int dtrace_handle_no_pf(struct pt_regs *);
+extern void dtrace_handle_badaddr(struct pt_regs *);
/*
* This is only safe to call if we know this is a userspace fault
*/
static inline int dtrace_no_pf(struct pt_regs *regs)
{
- if (unlikely(DTRACE_CPUFLAG_ISSET(CPU_DTRACE_NOPF)))
- return dtrace_handle_no_pf(regs);
+ if (unlikely(DTRACE_CPUFLAG_ISSET(CPU_DTRACE_NOFAULT))) {
+ dtrace_handle_badaddr(regs);
+ return 1;
+ }
+
return 0;
}
}
EXPORT_SYMBOL(dtrace_disable);
-/*
- * The dtrace-is-active body of dtrace_no_pf(), split into a separate function
- * to keep icache pressure down while incurring function call overhead only in
- * the rare dtrace-active, pf-disabled case.
- */
-int dtrace_handle_no_pf(struct pt_regs *regs)
-{
- DTRACE_CPUFLAG_SET(CPU_DTRACE_PF_TRAPPED);
-
- dtrace_skip_instruction(regs);
-
- return 1;
-}
-
/*---------------------------------------------------------------------------*\
(* USER SPACE TRACING (FASTTRAP) SUPPORT *)
\*---------------------------------------------------------------------------*/