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