Module Name: src
Committed By: cegger
Date: Tue Feb 23 06:27:40 UTC 2010
Modified Files:
src/sys/arch/amd64/amd64: trap.c vector.S
Log Message:
dtrace kernel hooks
ok darran@
To generate a diff of this commit:
cvs rdiff -u -r1.60 -r1.61 src/sys/arch/amd64/amd64/trap.c
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/amd64/amd64/vector.S
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/amd64/amd64/trap.c
diff -u src/sys/arch/amd64/amd64/trap.c:1.60 src/sys/arch/amd64/amd64/trap.c:1.61
--- src/sys/arch/amd64/amd64/trap.c:1.60 Sat Nov 21 03:11:01 2009
+++ src/sys/arch/amd64/amd64/trap.c Tue Feb 23 06:27:40 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.60 2009/11/21 03:11:01 rmind Exp $ */
+/* $NetBSD: trap.c,v 1.61 2010/02/23 06:27:40 cegger Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -68,11 +68,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.60 2009/11/21 03:11:01 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.61 2010/02/23 06:27:40 cegger Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "opt_xen.h"
+#include "opt_dtrace.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -111,6 +112,19 @@
#include <sys/kgdb.h>
#endif
+#ifdef KDTRACE_HOOKS
+#include <sys/dtrace_bsd.h>
+
+/*
+ * This is a hook which is initialized by the dtrace module
+ * to handle traps which might occur during DTrace probe
+ * execution.
+ */
+dtrace_trap_func_t dtrace_trap_func = NULL;
+
+dtrace_doubletrap_func_t dtrace_doubletrap_func = NULL;
+#endif
+
void trap(struct trapframe *);
const char * const trap_type[] = {
@@ -232,6 +246,27 @@
LWP_CACHE_CREDS(l, p);
}
+#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 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.
+ */
+ if ((type == T_PROTFLT || type == T_PAGEFLT) &&
+ dtrace_trap_func != NULL) {
+ if ((*dtrace_trap_func)(frame, type)) {
+ return;
+ }
+ }
+#endif
+
switch (type) {
default:
Index: src/sys/arch/amd64/amd64/vector.S
diff -u src/sys/arch/amd64/amd64/vector.S:1.32 src/sys/arch/amd64/amd64/vector.S:1.33
--- src/sys/arch/amd64/amd64/vector.S:1.32 Tue Feb 23 00:23:36 2010
+++ src/sys/arch/amd64/amd64/vector.S Tue Feb 23 06:27:40 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: vector.S,v 1.32 2010/02/23 00:23:36 cegger Exp $ */
+/* $NetBSD: vector.S,v 1.33 2010/02/23 06:27:40 cegger Exp $ */
/*-
* Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc.
@@ -69,6 +69,7 @@
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
#include "opt_xen.h"
+#include "opt_dtrace.h"
#define ALIGN_TEXT .align 16,0x90
@@ -112,6 +113,21 @@
#define BPTTRAP(a) ZTRAP(a)
+#ifdef KDTRACE_HOOKS
+ .bss
+ .globl dtrace_invop_jump_addr
+ .align 8
+ .type dtrace_invop_jump_addr, @object
+ .size dtrace_invop_jump_addr, 8
+dtrace_invop_jump_addr:
+ .zero 8
+ .globl dtrace_invop_calltrap_addr
+ .align 8
+ .type dtrace_invop_calltrap_addr, @object
+ .size dtrace_invop_calltrap_addr, 8
+dtrace_invop_calltrap_addr:
+ .zero 8
+#endif
.text
IDTVEC(trap00)
@@ -283,6 +299,30 @@
NENTRY(alltraps)
INTRENTRY
STI(si)
+#ifdef KDTRACE_HOOKS
+ /*
+ * DTrace Function Boundary Trace (fbt) probes are triggered
+ * by int3 (0xcc) which causes the #BP (T_BPTFLT) breakpoint
+ * interrupt. For all other trap types, just handle them in
+ * the usual way.
+ */
+ cmpl $T_BPTFLT,TF_TRAPNO(%rsp)
+ jne calltrap
+
+ /* Check if there is no DTrace hook registered. */
+ cmpq $0,dtrace_invop_jump_addr
+ je calltrap
+
+ /*
+ * Set our jump address for the jump back in the event that
+ * the exception wasn't caused by DTrace at all.
+ */
+ movq $calltrap, dtrace_invop_calltrap_addr(%rip)
+
+ /* Jump to the code hooked in by DTrace. */
+ movq dtrace_invop_jump_addr, %rax
+ jmpq *dtrace_invop_jump_addr
+#endif
calltrap:
#ifdef DIAGNOSTIC
movl CPUVAR(ILEVEL),%ebx