summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/aim
diff options
context:
space:
mode:
authorjhibbits <jhibbits@FreeBSD.org>2012-11-07 23:45:09 +0000
committerjhibbits <jhibbits@FreeBSD.org>2012-11-07 23:45:09 +0000
commit99d6a5644c78b3f3504ecbf7be003b7c3e99a62a (patch)
tree8d8c4ccbc7450fce2f9dc5ef56aa8edccb25145d /sys/powerpc/aim
parentc0efff79f978db7391db5e3e771dd9eaaf68abc5 (diff)
downloadFreeBSD-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/aim')
-rw-r--r--sys/powerpc/aim/locore32.S2
-rw-r--r--sys/powerpc/aim/locore64.S2
-rw-r--r--sys/powerpc/aim/trap.c53
-rw-r--r--sys/powerpc/aim/trap_subr32.S20
-rw-r--r--sys/powerpc/aim/trap_subr64.S20
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
OpenPOWER on IntegriCloud