Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Jul 2014 04:38:17 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r268600 - in head/sys: amd64/amd64 cddl/dev/dtrace/amd64 cddl/dev/dtrace/i386 cddl/dev/dtrace/mips cddl/dev/dtrace/powerpc i386/i386 mips/mips powerpc/aim sys
Message-ID:  <201407140438.s6E4cHCh016707@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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.rang@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;
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407140438.s6E4cHCh016707>