Author: markj
Date: Mon Jul 14 04:38:17 2014
New Revision: 268600
URL: http://svnweb.freebsd.org/changeset/base/268600

Log:
  Invoke the DTrace trap handler before calling trap() on amd64. This matches
  the upstream implementation and helps ensure that a trap induced by tracing
  fbt::trap:entry is handled without recursively generating another trap.
  
  This makes it possible to run most (but not all) of the DTrace tests under
  common/safety/ without triggering a kernel panic.
  
  Submitted by: Anton Rang <anton.r...@isilon.com> (original version)
  Phabric:      D95

Modified:
  head/sys/amd64/amd64/exception.S
  head/sys/amd64/amd64/trap.c
  head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
  head/sys/cddl/dev/dtrace/i386/dtrace_subr.c
  head/sys/cddl/dev/dtrace/mips/dtrace_subr.c
  head/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c
  head/sys/i386/i386/trap.c
  head/sys/mips/mips/trap.c
  head/sys/powerpc/aim/trap.c
  head/sys/sys/dtrace_bsd.h

Modified: head/sys/amd64/amd64/exception.S
==============================================================================
--- head/sys/amd64/amd64/exception.S    Mon Jul 14 00:16:49 2014        
(r268599)
+++ head/sys/amd64/amd64/exception.S    Mon Jul 14 04:38:17 2014        
(r268600)
@@ -228,7 +228,24 @@ alltraps_pushregs_no_rdi:
        .type   calltrap,@function
 calltrap:
        movq    %rsp,%rdi
+#ifdef KDTRACE_HOOKS
+       /*
+        * Give DTrace a chance to vet this trap and skip the call to trap() if
+        * it turns out that it was caused by a DTrace probe.
+        */
+       movq    dtrace_trap_func,%rax
+       testq   %rax,%rax
+       je      skiphook
+       call    *%rax
+       testq   %rax,%rax
+       jne     skiptrap
+       movq    %rsp,%rdi
+skiphook:
+#endif
        call    trap
+#ifdef KDTRACE_HOOKS
+skiptrap:
+#endif
        MEXITCOUNT
        jmp     doreti                  /* Handle any pending ASTs */
 

Modified: head/sys/amd64/amd64/trap.c
==============================================================================
--- head/sys/amd64/amd64/trap.c Mon Jul 14 00:16:49 2014        (r268599)
+++ head/sys/amd64/amd64/trap.c Mon Jul 14 04:38:17 2014        (r268600)
@@ -218,18 +218,6 @@ trap(struct trapframe *frame)
                goto out;
        }
 
-#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 its 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 (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type))
-               goto out;
-#endif
-
        if ((frame->tf_rflags & PSL_I) == 0) {
                /*
                 * Buggy application or kernel code has disabled

Modified: head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
==============================================================================
--- head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c        Mon Jul 14 00:16:49 
2014        (r268599)
+++ head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c        Mon Jul 14 04:38:17 
2014        (r268600)
@@ -462,29 +462,27 @@ dtrace_gethrestime(void)
        return (current_time.tv_sec * 1000000000ULL + current_time.tv_nsec);
 }
 
-/* Function to handle DTrace traps during probes. See amd64/amd64/trap.c */
+/*
+ * Function to handle DTrace traps during probes. See amd64/amd64/exception.S.
+ */
 int
-dtrace_trap(struct trapframe *frame, u_int type)
+dtrace_trap(struct trapframe *frame)
 {
        /*
         * 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
+        * a flag in its 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.
         *
         * Check if DTrace has enabled 'no-fault' mode:
-        *
         */
        if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) {
                /*
                 * There are only a couple of trap types that are expected.
                 * All the rest will be handled in the usual way.
                 */
-               switch (type) {
-               /* Privilieged instruction fault. */
-               case T_PRIVINFLT:
-                       break;
+               switch (frame->tf_trapno) {
                /* General protection fault. */
                case T_PROTFLT:
                        /* Flag an illegal operation. */

Modified: head/sys/cddl/dev/dtrace/i386/dtrace_subr.c
==============================================================================
--- head/sys/cddl/dev/dtrace/i386/dtrace_subr.c Mon Jul 14 00:16:49 2014        
(r268599)
+++ head/sys/cddl/dev/dtrace/i386/dtrace_subr.c Mon Jul 14 04:38:17 2014        
(r268600)
@@ -473,24 +473,23 @@ dtrace_gethrestime(void)
 
 /* Function to handle DTrace traps during probes. See i386/i386/trap.c */
 int
-dtrace_trap(struct trapframe *frame, u_int type)
+dtrace_trap(struct trapframe *frame)
 {
        /*
         * 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
+        * a flag in its 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.
         *
         * Check if DTrace has enabled 'no-fault' mode:
-        *
         */
        if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) {
                /*
                 * There are only a couple of trap types that are expected.
                 * All the rest will be handled in the usual way.
                 */
-               switch (type) {
+               switch (frame->tf_trapno) {
                /* General protection fault. */
                case T_PROTFLT:
                        /* Flag an illegal operation. */

Modified: head/sys/cddl/dev/dtrace/mips/dtrace_subr.c
==============================================================================
--- head/sys/cddl/dev/dtrace/mips/dtrace_subr.c Mon Jul 14 00:16:49 2014        
(r268599)
+++ head/sys/cddl/dev/dtrace/mips/dtrace_subr.c Mon Jul 14 04:38:17 2014        
(r268600)
@@ -137,17 +137,20 @@ dtrace_gethrestime(void)
 
 /* Function to handle DTrace traps during probes. See amd64/amd64/trap.c */
 int
-dtrace_trap(struct trapframe *frame, u_int type)
+dtrace_trap(struct trapframe *frame)
 {
+       u_int type;
+
+       type = (trapframe->cause & MIPS_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
+
        /*
         * 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
+        * a flag in its 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.
         *
         * Check if DTrace has enabled 'no-fault' mode:
-        *
         */
        if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) {
                /*

Modified: head/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c
==============================================================================
--- head/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c      Mon Jul 14 00:16:49 
2014        (r268599)
+++ head/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c      Mon Jul 14 04:38:17 
2014        (r268600)
@@ -262,24 +262,23 @@ dtrace_gethrestime(void)
 
 /* Function to handle DTrace traps during probes. See powerpc/powerpc/trap.c */
 int
-dtrace_trap(struct trapframe *frame, u_int type)
+dtrace_trap(struct trapframe *frame)
 {
        /*
         * 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
+        * a flag in its 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.
         *
         * Check if DTrace has enabled 'no-fault' mode:
-        *
         */
        if ((cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT) != 0) {
                /*
                 * There are only a couple of trap types that are expected.
                 * All the rest will be handled in the usual way.
                 */
-               switch (type) {
+               switch (frame->exc) {
                /* Page fault. */
                case EXC_DSI:
                case EXC_DSE:

Modified: head/sys/i386/i386/trap.c
==============================================================================
--- head/sys/i386/i386/trap.c   Mon Jul 14 00:16:49 2014        (r268599)
+++ head/sys/i386/i386/trap.c   Mon Jul 14 04:38:17 2014        (r268600)
@@ -246,7 +246,7 @@ trap(struct trapframe *frame)
         * flag is cleared and finally re-scheduling is enabled.
         */
        if ((type == T_PROTFLT || type == T_PAGEFLT) &&
-           dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type))
+           dtrace_trap_func != NULL && (*dtrace_trap_func)(frame))
                goto out;
 #endif
 

Modified: head/sys/mips/mips/trap.c
==============================================================================
--- head/sys/mips/mips/trap.c   Mon Jul 14 00:16:49 2014        (r268599)
+++ head/sys/mips/mips/trap.c   Mon Jul 14 04:38:17 2014        (r268600)
@@ -605,7 +605,7 @@ trap(struct trapframe *trapframe)
        /*
         * 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
+        * a flag in its 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.
         *
@@ -618,7 +618,7 @@ trap(struct trapframe *trapframe)
         * XXXDTRACE: add pid probe handler here (if ever)
         */
        if (!usermode) {
-               if (dtrace_trap_func != NULL && (*dtrace_trap_func)(trapframe, 
type))
+               if (dtrace_trap_func != NULL && (*dtrace_trap_func)(trapframe))
                        return (trapframe->pc);
        }
 #endif

Modified: head/sys/powerpc/aim/trap.c
==============================================================================
--- head/sys/powerpc/aim/trap.c Mon Jul 14 00:16:49 2014        (r268599)
+++ head/sys/powerpc/aim/trap.c Mon Jul 14 04:38:17 2014        (r268600)
@@ -167,7 +167,7 @@ trap(struct trapframe *frame)
        /*
         * 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
+        * a flag in its 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.
         *
@@ -176,7 +176,7 @@ trap(struct trapframe *frame)
         * handled the trap and modified the trap frame so that this
         * function can return normally.
         */
-       if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type))
+       if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame))
                return;
 #endif
 

Modified: head/sys/sys/dtrace_bsd.h
==============================================================================
--- head/sys/sys/dtrace_bsd.h   Mon Jul 14 00:16:49 2014        (r268599)
+++ head/sys/sys/dtrace_bsd.h   Mon Jul 14 04:38:17 2014        (r268600)
@@ -48,15 +48,14 @@ extern cyclic_clock_func_t  cyclic_clock_
 
 void clocksource_cyc_set(const struct bintime *t);
 
+int dtrace_trap(struct trapframe *);
+
 /*
  * The dtrace module handles traps that occur during a DTrace probe.
  * This type definition is used in the trap handler to provide a
- * hook for the dtrace module to register it's handler with.
+ * hook for the dtrace module to register its handler with.
  */
-typedef int (*dtrace_trap_func_t)(struct trapframe *, u_int);
-
-int    dtrace_trap(struct trapframe *, u_int);
-
+typedef int (*dtrace_trap_func_t)(struct trapframe *);
 extern dtrace_trap_func_t      dtrace_trap_func;
 
 /*
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to