diff options
author | jhibbits <jhibbits@FreeBSD.org> | 2012-11-07 23:45:09 +0000 |
---|---|---|
committer | jhibbits <jhibbits@FreeBSD.org> | 2012-11-07 23:45:09 +0000 |
commit | 99d6a5644c78b3f3504ecbf7be003b7c3e99a62a (patch) | |
tree | 8d8c4ccbc7450fce2f9dc5ef56aa8edccb25145d /sys/powerpc | |
parent | c0efff79f978db7391db5e3e771dd9eaaf68abc5 (diff) | |
download | FreeBSD-src-99d6a5644c78b3f3504ecbf7be003b7c3e99a62a.zip FreeBSD-src-99d6a5644c78b3f3504ecbf7be003b7c3e99a62a.tar.gz |
Implement DTrace for PowerPC. This includes both 32-bit and 64-bit.
There is one known issue: Some probes will display an error message along the
lines of: "Invalid address (0)"
I tested this with both a simple dtrace probe and dtruss on a few different
binaries on 32-bit. I only compiled 64-bit, did not run it, but I don't expect
problems without the modules loaded. Volunteers are welcome.
MFC after: 1 month
Diffstat (limited to 'sys/powerpc')
-rw-r--r-- | sys/powerpc/aim/locore32.S | 2 | ||||
-rw-r--r-- | sys/powerpc/aim/locore64.S | 2 | ||||
-rw-r--r-- | sys/powerpc/aim/trap.c | 53 | ||||
-rw-r--r-- | sys/powerpc/aim/trap_subr32.S | 20 | ||||
-rw-r--r-- | sys/powerpc/aim/trap_subr64.S | 20 |
5 files changed, 97 insertions, 0 deletions
diff --git a/sys/powerpc/aim/locore32.S b/sys/powerpc/aim/locore32.S index 80c3c08..f039db9 100644 --- a/sys/powerpc/aim/locore32.S +++ b/sys/powerpc/aim/locore32.S @@ -65,6 +65,8 @@ #include <machine/spr.h> #include <machine/asm.h> +#include "opt_kdtrace.h" + /* Locate the per-CPU data structure */ #define GET_CPUINFO(r) \ mfsprg0 r diff --git a/sys/powerpc/aim/locore64.S b/sys/powerpc/aim/locore64.S index 65c4999..3b3c8f3 100644 --- a/sys/powerpc/aim/locore64.S +++ b/sys/powerpc/aim/locore64.S @@ -65,6 +65,8 @@ #include <machine/spr.h> #include <machine/asm.h> +#include "opt_kdtrace.h" + /* Locate the per-CPU data structure */ #define GET_CPUINFO(r) \ mfsprg0 r diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c index b55d34b..d30aded 100644 --- a/sys/powerpc/aim/trap.c +++ b/sys/powerpc/aim/trap.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include "opt_hwpmc_hooks.h" +#include "opt_kdtrace.h" #include <sys/param.h> #include <sys/kdb.h> @@ -104,6 +105,33 @@ struct powerpc_exception { char *name; }; +#ifdef KDTRACE_HOOKS +#include <sys/dtrace_bsd.h> + +/* + * This is a hook which is initialised by the dtrace module + * to handle traps which might occur during DTrace probe + * execution. + */ +dtrace_trap_func_t dtrace_trap_func; + +dtrace_doubletrap_func_t dtrace_doubletrap_func; + +/* + * This is a hook which is initialised by the systrace module + * when it is loaded. This keeps the DTrace syscall provider + * implementation opaque. + */ +systrace_probe_func_t systrace_probe_func; + +/* + * These hooks are necessary for the pid, usdt and fasttrap providers. + */ +dtrace_fasttrap_probe_ptr_t dtrace_fasttrap_probe_ptr; +dtrace_pid_probe_ptr_t dtrace_pid_probe_ptr; +dtrace_return_probe_ptr_t dtrace_return_probe_ptr; +#endif + static struct powerpc_exception powerpc_exceptions[] = { { 0x0100, "system reset" }, { 0x0200, "machine check" }, @@ -176,6 +204,28 @@ trap(struct trapframe *frame) } else #endif +#ifdef KDTRACE_HOOKS + /* + * A trap can occur while DTrace executes a probe. Before + * executing the probe, DTrace blocks re-scheduling and sets + * a flag in it's per-cpu flags to indicate that it doesn't + * want to fault. On returning from the probe, the no-fault + * flag is cleared and finally re-scheduling is enabled. + * + * If the DTrace kernel module has registered a trap handler, + * call it and if it returns non-zero, assume that it has + * handled the trap and modified the trap frame so that this + * function can return normally. + */ + /* + * XXXDTRACE: add fasttrap and pid probes handlers here (if ever) + */ + if (!user) { + if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type)) + return; + } +#endif + if (user) { td->td_pticks = 0; td->td_frame = frame; @@ -617,6 +667,9 @@ trap_pfault(struct trapframe *frame, int user) PROC_LOCK(p); --p->p_lock; PROC_UNLOCK(p); + /* + * XXXDTRACE: add dtrace_doubletrap_func here? + */ } else { /* * Don't have to worry about process locking or stacks in the diff --git a/sys/powerpc/aim/trap_subr32.S b/sys/powerpc/aim/trap_subr32.S index cf8d03a..a00cc3d 100644 --- a/sys/powerpc/aim/trap_subr32.S +++ b/sys/powerpc/aim/trap_subr32.S @@ -240,6 +240,26 @@ mfsprg2 %r2; /* restore r2 & r3 */ \ mfsprg3 %r3 +#ifdef KDTRACE_HOOKS + .data + .globl dtrace_invop_jump_addr + .align 4 + .type dtrace_invop_jump_addr, @object + .size dtrace_invop_jump_addr, 4 +dtrace_invop_jump_addr: + .word 0 + .word 0 + .globl dtrace_invop_calltrap_addr + .align 4 + .type dtrace_invop_calltrap_addr, @object + .size dtrace_invop_calltrap_addr, 4 +dtrace_invop_calltrap_addr: + .word 0 + .word 0 + + .text +#endif + /* * The next two routines are 64-bit glue code. The first is used to test if * we are on a 64-bit system. By copying it to the illegal instruction diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S index 8243dc7..0a12753 100644 --- a/sys/powerpc/aim/trap_subr64.S +++ b/sys/powerpc/aim/trap_subr64.S @@ -274,6 +274,26 @@ restore_kernsrs: mtsrr1 %r3; \ mfsprg3 %r3 /* restore r3 */ +#ifdef KDTRACE_HOOKS + .data + .globl dtrace_invop_jump_addr + .align 8 + .type dtrace_invop_jump_addr, @object + .size dtrace_invop_jump_addr, 8 +dtrace_invop_jump_addr: + .word 0 + .word 0 + .globl dtrace_invop_calltrap_addr + .align 8 + .type dtrace_invop_calltrap_addr, @object + .size dtrace_invop_calltrap_addr, 8 +dtrace_invop_calltrap_addr: + .word 0 + .word 0 + + .text +#endif + #ifdef SMP /* * Processor reset exception handler. These are typically |